Skip to content

Commit dc6466a

Browse files
authored
Test identical functionality across versions (#605)
1 parent 319e0bb commit dc6466a

File tree

5 files changed

+242
-123
lines changed

5 files changed

+242
-123
lines changed

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
black==22.3.0
22
flake8==5.0.4
33
flake8-tidy-imports==4.6.0
4-
graviton@git+https://github.com/algorand/graviton@v0.5.0
4+
graviton@git+https://github.com/algorand/graviton@v0.7.0
55
mypy==0.991
66
pytest==7.2.0
77
pytest-cov==3.0.0

tests/blackbox.py

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Callable, Generic, Sequence, TypeVar, cast
1+
from typing import Any, Callable, Generic, Optional, Sequence, TypeVar, cast
22
from dataclasses import dataclass
33

44
import algosdk.abi
@@ -144,8 +144,14 @@ def decorator_blackbox(func: SubroutineFnWrapper | ABIReturnSubroutine):
144144

145145
@dataclass(frozen=True)
146146
class _MatchMode(Generic[Output]):
147+
runner: Optional["PyTealDryRunExecutor"]
147148
app_case: Lazy
148149
signature_case: Lazy
150+
trace: Any = None
151+
152+
def __post_init__(self):
153+
if self.runner and self.trace:
154+
self.runner.add_trace(self.trace)
149155

150156
def __call__(self, mode: Mode, *args, **kwargs) -> Output:
151157
match mode:
@@ -159,6 +165,7 @@ def __call__(self, mode: Mode, *args, **kwargs) -> Output:
159165

160166
def mode_to_execution_mode(mode: Mode) -> blackbox.ExecutionMode:
161167
return _MatchMode(
168+
runner=None,
162169
app_case=lambda: blackbox.ExecutionMode.Application,
163170
signature_case=lambda: blackbox.ExecutionMode.Signature,
164171
)(mode)
@@ -192,9 +199,31 @@ def __init__(self, subr: BlackboxWrapper, mode: Mode):
192199

193200
self._pyteal_lambda: Callable[..., Expr] = approval
194201

202+
self.traces: list = []
203+
204+
def add_trace(self, trace: Any) -> None:
205+
self.traces.append(trace)
206+
195207
def is_abi(self) -> bool:
196208
return isinstance(self.subr.subroutine, ABIReturnSubroutine)
197209

210+
def abi_method_signature(self) -> None | str:
211+
if self.is_abi():
212+
abi_subr = cast(ABIReturnSubroutine, self.subr.subroutine)
213+
return abi_subr.method_signature()
214+
215+
# create an artificial method signature
216+
# based on the `abi_argument_types()` and `abi_return_type()`
217+
if arg_types := self.abi_argument_types():
218+
if all(t is None for t in arg_types):
219+
return None
220+
221+
ret_type = self.abi_return_type()
222+
ret = str(ret_type) if ret_type else "void"
223+
return f"ptdre_foo({','.join(map(str, arg_types))}){ret}"
224+
225+
return None
226+
198227
def abi_argument_types(self) -> None | list[algosdk.abi.ABIType]:
199228
if not (self.input_types or self.is_abi()):
200229
return None
@@ -389,6 +418,7 @@ def approval():
389418

390419
def compile(self, version: int, assemble_constants: bool = False) -> str:
391420
return _MatchMode(
421+
runner=self,
392422
app_case=lambda: compileTeal(
393423
self.program(),
394424
self.mode,
@@ -408,41 +438,47 @@ def dryrun_on_sequence(
408438
inputs: list[Sequence[PyTypes]],
409439
compiler_version=6,
410440
) -> list[DryRunInspector]:
441+
teal = self.compile(compiler_version)
411442
return _MatchMode(
443+
self,
412444
app_case=lambda: DryRunExecutor.dryrun_app_on_sequence(
413445
algod=algod_with_assertion(),
414-
teal=self.compile(compiler_version),
446+
teal=teal,
415447
inputs=inputs,
416-
abi_argument_types=self.abi_argument_types(),
417-
abi_return_type=self.abi_return_type(),
448+
abi_method_signature=self.abi_method_signature(),
449+
omit_method_selector=True,
418450
),
419451
signature_case=lambda: DryRunExecutor.dryrun_logicsig_on_sequence(
420452
algod=algod_with_assertion(),
421-
teal=self.compile(compiler_version),
453+
teal=teal,
422454
inputs=inputs,
423-
abi_argument_types=self.abi_argument_types(),
424-
abi_return_type=self.abi_return_type(),
455+
abi_method_signature=self.abi_method_signature(),
456+
omit_method_selector=True,
425457
),
458+
trace=teal,
426459
)(self.mode)
427460

428461
def dryrun(
429462
self,
430463
args: Sequence[bytes | str | int],
431464
compiler_version=6,
432465
) -> DryRunInspector:
466+
teal = self.compile(compiler_version)
433467
return _MatchMode(
468+
self,
434469
app_case=lambda: DryRunExecutor.dryrun_app(
435470
algod_with_assertion(),
436-
self.compile(compiler_version),
471+
teal,
437472
args,
438-
self.abi_argument_types(),
439-
self.abi_return_type(),
473+
abi_method_signature=self.abi_method_signature(),
474+
omit_method_selector=True,
440475
),
441476
signature_case=lambda: DryRunExecutor.dryrun_logicsig(
442477
algod_with_assertion(),
443-
self.compile(compiler_version),
478+
teal,
444479
args,
445-
self.abi_argument_types(),
446-
self.abi_return_type(),
480+
abi_method_signature=self.abi_method_signature(),
481+
omit_method_selector=True,
447482
),
483+
trace=teal,
448484
)(self.mode)

tests/integration/graviton_abi_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ def test_integer65(version: int):
312312

313313
bbpt_add = PyTealDryRunExecutor(int65_add, pt.Mode.Application)
314314

315-
def pynum_to_tuple(n):
315+
def pynum_to_int65tuple(n):
316316
return (n >= 0, abs(n))
317317

318318
def pytuple_to_num(t):
@@ -323,10 +323,10 @@ def pytuple_to_num(t):
323323
random.seed(42)
324324

325325
choices = range(-9_999, 10_000)
326-
unary_inputs = [(pynum_to_tuple(x),) for x in random.sample(choices, N)]
326+
unary_inputs = [(pynum_to_int65tuple(x),) for x in random.sample(choices, N)]
327327

328328
binary_inputs = [
329-
(pynum_to_tuple(x), pynum_to_tuple(y))
329+
(pynum_to_int65tuple(x), pynum_to_int65tuple(y))
330330
for x, y in zip(random.sample(choices, N), random.sample(choices, N))
331331
]
332332

0 commit comments

Comments
 (0)