genlayer-test 0.3.0__py3-none-any.whl → 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {genlayer_test-0.3.0.dist-info → genlayer_test-0.4.0.dist-info}/METADATA +125 -5
- genlayer_test-0.4.0.dist-info/RECORD +66 -0
- gltest/fixtures.py +91 -0
- gltest/helpers/fixture_snapshot.py +1 -6
- gltest_cli/config/plugin.py +13 -0
- gltest_cli/config/types.py +11 -0
- tests/examples/contracts/football_prediction_market.py +11 -8
- tests/examples/contracts/intelligent_oracle.py +7 -6
- tests/examples/contracts/intelligent_oracle_factory.py +1 -0
- tests/examples/contracts/llm_erc20.py +3 -2
- tests/examples/contracts/log_indexer.py +7 -5
- tests/examples/contracts/multi_file_contract/__init__.py +5 -2
- tests/examples/contracts/multi_read_erc20.py +2 -1
- tests/examples/contracts/multi_tenant_storage.py +3 -2
- tests/examples/contracts/read_erc20.py +6 -1
- tests/examples/contracts/storage.py +2 -1
- tests/examples/contracts/user_storage.py +2 -1
- tests/examples/contracts/wizard_of_coin.py +4 -3
- tests/examples/tests/test_football_prediction_market.py +20 -1
- tests/examples/tests/test_intelligent_oracle_factory.py +62 -9
- tests/examples/tests/test_llm_erc20.py +20 -1
- tests/examples/tests/test_log_indexer.py +2 -1
- tests/examples/tests/test_multi_file_contract.py +2 -1
- tests/examples/tests/test_multi_file_contract_legacy.py +2 -1
- tests/examples/tests/test_multi_read_erc20.py +9 -3
- tests/examples/tests/test_multi_tenant_storage.py +2 -1
- tests/examples/tests/test_read_erc20.py +2 -1
- tests/examples/tests/test_storage.py +2 -1
- tests/examples/tests/test_storage_legacy.py +2 -1
- tests/examples/tests/test_user_storage.py +9 -3
- tests/examples/tests/test_wizard_of_coin.py +16 -1
- genlayer_test-0.3.0.dist-info/RECORD +0 -65
- {genlayer_test-0.3.0.dist-info → genlayer_test-0.4.0.dist-info}/WHEEL +0 -0
- {genlayer_test-0.3.0.dist-info → genlayer_test-0.4.0.dist-info}/entry_points.txt +0 -0
- {genlayer_test-0.3.0.dist-info → genlayer_test-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {genlayer_test-0.3.0.dist-info → genlayer_test-0.4.0.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: genlayer-test
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.4.0
|
4
4
|
Summary: GenLayer Testing Suite
|
5
5
|
Author: GenLayer
|
6
6
|
License-Expression: MIT
|
@@ -15,7 +15,7 @@ Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE
|
16
16
|
Requires-Dist: pytest
|
17
17
|
Requires-Dist: setuptools>=77.0
|
18
|
-
Requires-Dist: genlayer-py==0.
|
18
|
+
Requires-Dist: genlayer-py==0.6.1
|
19
19
|
Requires-Dist: colorama>=0.4.6
|
20
20
|
Requires-Dist: pyyaml
|
21
21
|
Requires-Dist: python-dotenv
|
@@ -50,7 +50,7 @@ from gltest.assertions import tx_execution_succeeded
|
|
50
50
|
|
51
51
|
factory = get_contract_factory("MyContract")
|
52
52
|
# Deploy a contract with default account
|
53
|
-
contract = factory.deploy() # This will be deployed with
|
53
|
+
contract = factory.deploy() # This will be deployed with the default account
|
54
54
|
assert contract.account == get_default_account()
|
55
55
|
|
56
56
|
# Deploy a contract with other account
|
@@ -207,6 +207,30 @@ $ gltest --default-wait-interval <default_wait_interval>
|
|
207
207
|
$ gltest --default-wait-retries <default_wait_retries>
|
208
208
|
```
|
209
209
|
|
210
|
+
10. Run tests with mocked LLM responses (localnet only)
|
211
|
+
```bash
|
212
|
+
$ gltest --test-with-mocks
|
213
|
+
```
|
214
|
+
The `--test-with-mocks` flag enables mocking of LLM responses when creating validators. This is particularly useful for:
|
215
|
+
- Testing without actual LLM API calls
|
216
|
+
- Ensuring deterministic test results
|
217
|
+
- Faster test execution
|
218
|
+
- Testing specific edge cases with controlled responses
|
219
|
+
|
220
|
+
When using this flag with the `setup_validators` fixture, you can provide custom mock responses:
|
221
|
+
```python
|
222
|
+
def test_with_mocked_llm(setup_validators):
|
223
|
+
# Setup validators with a specific mock response
|
224
|
+
mock_response = {"result": "This is a mocked LLM response"}
|
225
|
+
setup_validators(mock_response=mock_response)
|
226
|
+
|
227
|
+
# Your LLM-based contract will receive the mocked response
|
228
|
+
contract = factory.deploy()
|
229
|
+
result = contract.llm_method() # Will use the mocked response
|
230
|
+
```
|
231
|
+
|
232
|
+
Note: This feature is only available when running tests on localnet.
|
233
|
+
|
210
234
|
## 🚀 Key Features
|
211
235
|
|
212
236
|
- **Pytest Integration** – Extends pytest to support intelligent contract testing, making it familiar and easy to adopt.
|
@@ -275,7 +299,7 @@ Key features demonstrated in this contract:
|
|
275
299
|
Here's how to deploy the Storage contract:
|
276
300
|
|
277
301
|
```python
|
278
|
-
from gltest import get_contract_factory,
|
302
|
+
from gltest import get_contract_factory, get_default_account
|
279
303
|
|
280
304
|
def test_deployment():
|
281
305
|
# Get the contract factory for your contract
|
@@ -285,7 +309,7 @@ def test_deployment():
|
|
285
309
|
# Deploy the contract with constructor arguments
|
286
310
|
contract = factory.deploy(
|
287
311
|
args=["initial_value"], # Constructor arguments
|
288
|
-
account=
|
312
|
+
account=get_default_account(), # Account to deploy from
|
289
313
|
consensus_max_rotations=3, # Optional: max consensus rotations
|
290
314
|
leader_only=False, # Optional: whether to run only on leader
|
291
315
|
)
|
@@ -384,6 +408,102 @@ Both `tx_execution_succeeded` and `tx_execution_failed` accept the following par
|
|
384
408
|
|
385
409
|
For more example contracts, check out the [contracts directory](tests/examples/contracts) which contains various sample contracts demonstrating different features and use cases.
|
386
410
|
|
411
|
+
### Test Fixtures
|
412
|
+
|
413
|
+
The GenLayer Testing Suite provides reusable pytest fixtures in `gltest.fixtures` to simplify common testing operations. These fixtures can be imported and used in your test files to avoid repetitive setup code.
|
414
|
+
|
415
|
+
#### Available Fixtures
|
416
|
+
|
417
|
+
The following fixtures are available in `gltest.fixtures`:
|
418
|
+
|
419
|
+
- **`gl_client`** (session scope) - GenLayer client instance for network operations
|
420
|
+
- **`default_account`** (session scope) - Default account for testing and deployments
|
421
|
+
- **`accounts`** (session scope) - List of test accounts for multi-account scenarios
|
422
|
+
- **`setup_validators`** (function scope) - Function to create test validators for LLM operations
|
423
|
+
|
424
|
+
##### 1. `gl_client` (session scope)
|
425
|
+
Provides a GenLayer PY client instance that's created once per test session. This is useful for operations that interact directly with the GenLayer network.
|
426
|
+
|
427
|
+
```python
|
428
|
+
def test_client_operations(gl_client):
|
429
|
+
# Use the client for network operations
|
430
|
+
tx_hash = "0x1234..."
|
431
|
+
transaction = gl_client.get_transaction(tx_hash)
|
432
|
+
```
|
433
|
+
|
434
|
+
##### 2. `default_account` (session scope)
|
435
|
+
Provides the default account used to execute transactions when no account is specified.
|
436
|
+
|
437
|
+
```python
|
438
|
+
def test_with_default_account(default_account):
|
439
|
+
# Use the default account for deployments
|
440
|
+
factory = get_contract_factory("MyContract")
|
441
|
+
contract = factory.deploy(account=default_account)
|
442
|
+
```
|
443
|
+
|
444
|
+
##### 3. `accounts` (session scope)
|
445
|
+
Provides a list of account objects loaded from the private keys defined in `gltest.config.yaml` for the current network, or pre-created test accounts if no config is present
|
446
|
+
|
447
|
+
```python
|
448
|
+
def test_multiple_accounts(accounts):
|
449
|
+
# Get multiple accounts for testing
|
450
|
+
sender = accounts[0]
|
451
|
+
receiver = accounts[1]
|
452
|
+
|
453
|
+
# Test transfers or multi-party interactions
|
454
|
+
contract.transfer(args=[receiver.address, 100], account=sender)
|
455
|
+
```
|
456
|
+
|
457
|
+
##### 4. `setup_validators` (function scope)
|
458
|
+
Creates test validators for localnet environment. This fixture is particularly useful for testing LLM-based contract methods and consensus behavior. It yields a function that allows you to configure validators with custom settings.
|
459
|
+
|
460
|
+
```python
|
461
|
+
def test_with_validators(setup_validators):
|
462
|
+
# Setup validators with default configuration
|
463
|
+
setup_validators()
|
464
|
+
|
465
|
+
# Or setup with custom mock responses for testing
|
466
|
+
mock_response = {"result": "mocked LLM response"}
|
467
|
+
setup_validators(mock_response=mock_response, n_validators=3)
|
468
|
+
|
469
|
+
# Now test your LLM-based contract methods
|
470
|
+
contract = factory.deploy()
|
471
|
+
result = contract.llm_based_method()
|
472
|
+
```
|
473
|
+
|
474
|
+
Parameters for `setup_validators`:
|
475
|
+
- `mock_response` (dict, optional): Mock validator response when using `--test-with-mocks` flag
|
476
|
+
- `n_validators` (int, optional): Number of validators to create (default: 5)
|
477
|
+
|
478
|
+
#### Using Fixtures in Your Tests
|
479
|
+
|
480
|
+
To use these fixtures, simply import them and include them as parameters in your test functions:
|
481
|
+
|
482
|
+
```python
|
483
|
+
from gltest import get_contract_factory
|
484
|
+
from gltest.assertions import tx_execution_succeeded
|
485
|
+
|
486
|
+
def test_complete_workflow(gl_client, default_account, accounts, setup_validators):
|
487
|
+
# Setup validators for LLM operations
|
488
|
+
setup_validators()
|
489
|
+
|
490
|
+
# Deploy contract with default account
|
491
|
+
factory = get_contract_factory("MyContract")
|
492
|
+
contract = factory.deploy(account=default_account)
|
493
|
+
|
494
|
+
# Interact using other accounts
|
495
|
+
other_account = accounts[1]
|
496
|
+
tx_receipt = contract.some_method(args=["value"], account=other_account)
|
497
|
+
|
498
|
+
assert tx_execution_succeeded(tx_receipt)
|
499
|
+
```
|
500
|
+
|
501
|
+
Fixtures help maintain clean, DRY test code by:
|
502
|
+
- Eliminating repetitive setup code
|
503
|
+
- Ensuring consistent test environments
|
504
|
+
- Managing resource cleanup automatically
|
505
|
+
- Providing appropriate scoping for performance
|
506
|
+
|
387
507
|
## 📝 Best Practices
|
388
508
|
|
389
509
|
1. **Test Organization**
|
@@ -0,0 +1,66 @@
|
|
1
|
+
genlayer_test-0.4.0.dist-info/licenses/LICENSE,sha256=che_H4vE0QUx3HvWrAa1_jDEVInift0U6VO15-QqEls,1064
|
2
|
+
gltest/__init__.py,sha256=Uozr4VS-_oKUxEdXbWoEVLB8JQKBWGs6vGEHDj1-6LY,348
|
3
|
+
gltest/assertions.py,sha256=0dEk0VxcHK4I7GZPHxJmz-2jaA60V499gOSR74rZbfM,1748
|
4
|
+
gltest/exceptions.py,sha256=deJPmrTe5gF33qkkKF2IVJY7lc_knI7Ql3N7jZ8aLZs,510
|
5
|
+
gltest/fixtures.py,sha256=IyaTe3b-4weU2Bb5XKnP23dpk3jNKJDAOmYoYqRXFLQ,2501
|
6
|
+
gltest/types.py,sha256=BODmwTr2gAUEiO9FjiuTiWwuKvXgo4xZWstQWNUfnlw,156
|
7
|
+
gltest/artifacts/__init__.py,sha256=qTt3TE19gVNWnQLUlt5aDe4nNvJ2YJ1jzDkMmYIsCG0,194
|
8
|
+
gltest/artifacts/contract.py,sha256=KChpmfjZod_0dVB8y-dvWz6IVm7QlIJsgG2ArtvVDaU,6457
|
9
|
+
gltest/glchain/__init__.py,sha256=QLd55hVB9xVTAtCKbjmGPAwh0M8_tUNJ5xI0H93YyTY,428
|
10
|
+
gltest/glchain/account.py,sha256=HUmWguJMolggQaZNRPw-LGlRlQCjLLdUanKRowMv6pI,812
|
11
|
+
gltest/glchain/client.py,sha256=urRvnLt8GpdCV3yOBSvJNZQzu_TsZr8HqKn14Q2SpIQ,1547
|
12
|
+
gltest/glchain/contract.py,sha256=RFLbEZseWatX0Xvt3-Eo_zOowxLMhukoXjK8V8Ca0Ok,11370
|
13
|
+
gltest/helpers/__init__.py,sha256=I7HiTu_H7_hP65zY6Wl02r-5eAMr2eZvqBVmusuQLX4,180
|
14
|
+
gltest/helpers/fixture_snapshot.py,sha256=bMgvlEVQBGIQzj7NOyosXWlphI1H2C1o75Zo0C-kGfQ,1931
|
15
|
+
gltest/helpers/take_snapshot.py,sha256=eXqEKXM2hcox3pLGIcNddobU8zXPQvD-Iwf87eHqW2s,1276
|
16
|
+
gltest_cli/logging.py,sha256=2Bkh6OR5C19HefARLQN5xBfam3apXzf7_Wei2PBfKlM,1241
|
17
|
+
gltest_cli/main.py,sha256=Ti2-0Ev1x5_cM0D1UKqdgaDt80CDHEQGtdRne2qLm4M,53
|
18
|
+
gltest_cli/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
|
+
gltest_cli/config/constants.py,sha256=lX8C3aS7zXWazA8LWgE0BkPvy7NopyEMyJNI2yYWX9M,300
|
20
|
+
gltest_cli/config/general.py,sha256=ezpoGsT8grO9zQH6RugV14b1GzeFt-htYToHQBJhNvY,186
|
21
|
+
gltest_cli/config/plugin.py,sha256=8eA19hNI8dmnZLwcruXj6MChyspjtqiiCbfFKRT4_yk,3695
|
22
|
+
gltest_cli/config/types.py,sha256=2mbbEPD15zHh6-BkLSEByalL4-bi2OP4Qy3EFslqs5M,5669
|
23
|
+
gltest_cli/config/user.py,sha256=LjjoqXWRLPeNgOvLKy2tJDNl1M0uLb-5rwEsnGyJunE,8065
|
24
|
+
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
|
+
tests/conftest.py,sha256=RKdoE5_zcMimeojAoA_GSFI9du4pMzMi1vZ1njtfoAs,28
|
26
|
+
tests/examples/contracts/football_prediction_market.py,sha256=0Lm2x2F1DhmUP1fcfzGQAfc50tWFcaHliwyAzXIRFVw,3247
|
27
|
+
tests/examples/contracts/intelligent_oracle.py,sha256=cZNGbjKMXY-pimVmPIKIlS963Gd3L1JAipq0VBR1J5Q,12360
|
28
|
+
tests/examples/contracts/intelligent_oracle_factory.py,sha256=8lBEn3Atb0yUpXwlvnShlcRxCBTXCrrkoITDHWoWuHU,1499
|
29
|
+
tests/examples/contracts/llm_erc20.py,sha256=pOvSUszCtC_f5yDX0tZnj494Ce10uESZ09JLLE8V67o,2534
|
30
|
+
tests/examples/contracts/log_indexer.py,sha256=Nlf8XUt13ujam3k6hbbVrPHK-KJ366Csz1TBjc4P07g,1901
|
31
|
+
tests/examples/contracts/multi_read_erc20.py,sha256=28qYqn191Ro3rP7YJtZwL6Sc7JDXTeh8_QoqvdVPdqM,864
|
32
|
+
tests/examples/contracts/multi_tenant_storage.py,sha256=5F3MCKbzyHMFqLRT9hZNCd3RzjSJvAKVJwLFMeazwog,1906
|
33
|
+
tests/examples/contracts/read_erc20.py,sha256=RgH269F0x482WuLLYcacBnZsGJjhgJp6sG_33cV6Z-w,454
|
34
|
+
tests/examples/contracts/storage.py,sha256=3DD3qvzb0JkVcBtu240e5kaZWgkh-bu6YExqBUYvfaw,501
|
35
|
+
tests/examples/contracts/user_storage.py,sha256=2W2Iv-hQZMkAaPl2RY_F-OeJpD4IlPxgWzN6e1bTkKE,649
|
36
|
+
tests/examples/contracts/wizard_of_coin.py,sha256=Y8daPpoSKdM8wfbCPOIgEdpkLIA1ZMmeg6Hu5fBB-kU,1624
|
37
|
+
tests/examples/contracts/multi_file_contract/__init__.py,sha256=CCdaK5p12GDf35hgbBWURNM5KUn6SWAcuyieTmZwVWE,548
|
38
|
+
tests/examples/contracts/multi_file_contract/other.py,sha256=jHDtjUL3eAUgE6yOYKFw_RfAH7kIwk8CvxUjbWHNruk,236
|
39
|
+
tests/examples/tests/test_football_prediction_market.py,sha256=ADIWjh4zmT_9R0xJ4UU5jchPySxKPG_ujp9fy1i3tvQ,1093
|
40
|
+
tests/examples/tests/test_intelligent_oracle_factory.py,sha256=K2Xhgth1VLpM7C3qUw1PDp3ODNRs56hx-iv7aP1fTzA,8267
|
41
|
+
tests/examples/tests/test_llm_erc20.py,sha256=JZokOzdhxqH9J1x5KrpUukARLOXAGJpIjSh-FImXnN8,2057
|
42
|
+
tests/examples/tests/test_log_indexer.py,sha256=KoOeTkwDmFamE8vyqM95y10cvpr1C22EcsYxv2L5unY,2688
|
43
|
+
tests/examples/tests/test_multi_file_contract.py,sha256=asZ32ZO4LsttLSFq_CNozX_j19PQbRRW81xw0d8HNp0,551
|
44
|
+
tests/examples/tests/test_multi_file_contract_legacy.py,sha256=IovwcE1KzDZ__FszvwQyGFHwlLIxdV4cC9S9hWSGVv4,566
|
45
|
+
tests/examples/tests/test_multi_read_erc20.py,sha256=yBac795CA4_uMmtXtIvPLigfjozWi5nPQK6bcJlafvQ,3635
|
46
|
+
tests/examples/tests/test_multi_tenant_storage.py,sha256=d4c4fNAjc2a6MkkHDexAP-pFf0tqipHwyM_fouGhA0g,2756
|
47
|
+
tests/examples/tests/test_read_erc20.py,sha256=0bMSNUHo9MqRzeJGGKw5ToB9U_MJTa4YFRPdYIeWS-s,1247
|
48
|
+
tests/examples/tests/test_storage.py,sha256=c9Yu8556DyQjJktAPsEUKzeMCn_-5CRNzXFgacVuDNY,751
|
49
|
+
tests/examples/tests/test_storage_legacy.py,sha256=kXxMA-nNTuj4cV8yXkC_6iLJd8yS0HsyeVM9NnvbXLo,716
|
50
|
+
tests/examples/tests/test_user_storage.py,sha256=Kg034FS4sD9p22-S0fEAH0HaDyevk0HQJiiLDjCBCTs,2776
|
51
|
+
tests/examples/tests/test_wizard_of_coin.py,sha256=LiiN86ehRKUTbavGfPdqvkyyyY0DD0pp31j3BEgZciw,843
|
52
|
+
tests/gltest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
53
|
+
tests/gltest/artifact/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
54
|
+
tests/gltest/artifact/test_contract_definition.py,sha256=6R8THNFKKpG7brULzp63vT1_pPd_JFNp3ZS08CJJWrg,3642
|
55
|
+
tests/gltest/artifact/contracts/duplicate_ic_contract_1.py,sha256=bSWsUVjBy5cGtI72cjnkstsMzuUJbB3IG5JjTxOF-dc,500
|
56
|
+
tests/gltest/artifact/contracts/duplicate_ic_contract_2.py,sha256=bSWsUVjBy5cGtI72cjnkstsMzuUJbB3IG5JjTxOF-dc,500
|
57
|
+
tests/gltest/artifact/contracts/not_ic_contract.py,sha256=hQyGnYiiVceYdLI2WrvcFgPqzy1S4-YMb9FPhiHEGSA,510
|
58
|
+
tests/gltest/assertions/test_assertions.py,sha256=qzVrOdOM4xYtIy1sFHVAD_-naDHOequ23tEN0MELh0k,10781
|
59
|
+
tests/gltest_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
60
|
+
tests/gltest_cli/config/test_plugin.py,sha256=06-GENVugrL6mPQkgRgQqRsCTuQMy3WZcbh_9Du6zHo,3502
|
61
|
+
tests/gltest_cli/config/test_user.py,sha256=oJDcM6NbA16tQzQj5s8ZDvQYBm2uuvar5junFcVeitY,12116
|
62
|
+
genlayer_test-0.4.0.dist-info/METADATA,sha256=HVE6uUnkt7Z_Cldbxr-V1JkEGiiqYHyo6HRrThXpb4Q,21928
|
63
|
+
genlayer_test-0.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
64
|
+
genlayer_test-0.4.0.dist-info/entry_points.txt,sha256=RWPcSArBpz_G4BYioh5L8Q8hyClRbSgzLimjcWMp-BQ,94
|
65
|
+
genlayer_test-0.4.0.dist-info/top_level.txt,sha256=-qiGZxTRBytujzgVcKpxjvQ-WNeUDjXa59ceGMwMpko,24
|
66
|
+
genlayer_test-0.4.0.dist-info/RECORD,,
|
gltest/fixtures.py
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
"""
|
2
|
+
This module provides reusable pytest fixtures for common gltest operations.
|
3
|
+
These fixtures can be imported and used in test files.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import pytest
|
7
|
+
from gltest.glchain import (
|
8
|
+
get_gl_client,
|
9
|
+
get_accounts,
|
10
|
+
get_default_account,
|
11
|
+
get_gl_provider,
|
12
|
+
)
|
13
|
+
from gltest_cli.config.general import get_general_config
|
14
|
+
|
15
|
+
|
16
|
+
@pytest.fixture(scope="session")
|
17
|
+
def gl_client():
|
18
|
+
"""
|
19
|
+
Provides a GenLayer client instance.
|
20
|
+
|
21
|
+
Scope: session - created once per test session
|
22
|
+
"""
|
23
|
+
return get_gl_client()
|
24
|
+
|
25
|
+
|
26
|
+
@pytest.fixture(scope="session")
|
27
|
+
def default_account():
|
28
|
+
"""
|
29
|
+
Provides the default account for testing.
|
30
|
+
|
31
|
+
Scope: session - created once per test session
|
32
|
+
"""
|
33
|
+
return get_default_account()
|
34
|
+
|
35
|
+
|
36
|
+
@pytest.fixture(scope="session")
|
37
|
+
def accounts():
|
38
|
+
"""
|
39
|
+
Provides a list of test accounts.
|
40
|
+
|
41
|
+
Scope: session - created once per test session
|
42
|
+
"""
|
43
|
+
return get_accounts()
|
44
|
+
|
45
|
+
|
46
|
+
@pytest.fixture(scope="function")
|
47
|
+
def setup_validators():
|
48
|
+
"""
|
49
|
+
Creates test validators for localnet environment.
|
50
|
+
|
51
|
+
Args:
|
52
|
+
mock_response (dict, optional): Mock validator response when using --test-with-mocks flag
|
53
|
+
n_validators (int, optional): Number of validators to create (default: 5)
|
54
|
+
|
55
|
+
Scope: function - created fresh for each test
|
56
|
+
"""
|
57
|
+
general_config = get_general_config()
|
58
|
+
provider = get_gl_provider()
|
59
|
+
|
60
|
+
def _setup(mock_response=None, n_validators=5):
|
61
|
+
if not general_config.check_local_rpc():
|
62
|
+
return
|
63
|
+
if general_config.get_test_with_mocks():
|
64
|
+
for _ in range(n_validators):
|
65
|
+
provider.make_request(
|
66
|
+
method="sim_createValidator",
|
67
|
+
params=[
|
68
|
+
8,
|
69
|
+
"openai",
|
70
|
+
"gpt-4o",
|
71
|
+
{"temperature": 0.75, "max_tokens": 500},
|
72
|
+
"openai-compatible",
|
73
|
+
{
|
74
|
+
"api_key_env_var": "OPENAIKEY",
|
75
|
+
"api_url": "https://api.openai.com",
|
76
|
+
"mock_response": mock_response if mock_response else {},
|
77
|
+
},
|
78
|
+
],
|
79
|
+
)
|
80
|
+
else:
|
81
|
+
provider.make_request(
|
82
|
+
method="sim_createRandomValidators",
|
83
|
+
params=[n_validators, 8, 12],
|
84
|
+
)
|
85
|
+
|
86
|
+
yield _setup
|
87
|
+
|
88
|
+
if not general_config.check_local_rpc():
|
89
|
+
return
|
90
|
+
|
91
|
+
provider.make_request(method="sim_deleteAllValidators", params=[])
|
@@ -1,6 +1,5 @@
|
|
1
1
|
from typing import TypeVar, Callable, List, Any
|
2
2
|
from dataclasses import dataclass
|
3
|
-
from urllib.parse import urlparse
|
4
3
|
from .take_snapshot import SnapshotRestorer, take_snapshot
|
5
4
|
from gltest.exceptions import (
|
6
5
|
FixtureSnapshotError,
|
@@ -9,8 +8,6 @@ from gltest.exceptions import (
|
|
9
8
|
)
|
10
9
|
from gltest_cli.config.general import get_general_config
|
11
10
|
|
12
|
-
SUPPORTED_RPC_DOMAINS = ["localhost", "127.0.0.1"]
|
13
|
-
|
14
11
|
T = TypeVar("T")
|
15
12
|
|
16
13
|
|
@@ -35,9 +32,7 @@ def load_fixture(fixture: Callable[[], T]) -> T:
|
|
35
32
|
raise FixtureAnonymousFunctionError("Fixtures must be named functions")
|
36
33
|
|
37
34
|
general_config = get_general_config()
|
38
|
-
|
39
|
-
domain = urlparse(rpc_url).netloc.split(":")[0] # Extract domain without port
|
40
|
-
if domain not in SUPPORTED_RPC_DOMAINS:
|
35
|
+
if not general_config.check_local_rpc():
|
41
36
|
return fixture()
|
42
37
|
|
43
38
|
# Find existing snapshot for this fixture
|
gltest_cli/config/plugin.py
CHANGED
@@ -48,6 +48,13 @@ def pytest_addoption(parser):
|
|
48
48
|
help="Target network (defaults to 'localnet' if no config file)",
|
49
49
|
)
|
50
50
|
|
51
|
+
group.addoption(
|
52
|
+
"--test-with-mocks",
|
53
|
+
action="store_true",
|
54
|
+
default=False,
|
55
|
+
help="Test with mocks",
|
56
|
+
)
|
57
|
+
|
51
58
|
|
52
59
|
def pytest_configure(config):
|
53
60
|
general_config = get_general_config()
|
@@ -73,6 +80,7 @@ def pytest_configure(config):
|
|
73
80
|
default_wait_retries = config.getoption("--default-wait-retries")
|
74
81
|
rpc_url = config.getoption("--rpc-url")
|
75
82
|
network = config.getoption("--network")
|
83
|
+
test_with_mocks = config.getoption("--test-with-mocks")
|
76
84
|
|
77
85
|
plugin_config = PluginConfig()
|
78
86
|
plugin_config.contracts_dir = (
|
@@ -82,6 +90,7 @@ def pytest_configure(config):
|
|
82
90
|
plugin_config.default_wait_retries = int(default_wait_retries)
|
83
91
|
plugin_config.rpc_url = rpc_url
|
84
92
|
plugin_config.network_name = network
|
93
|
+
plugin_config.test_with_mocks = test_with_mocks
|
85
94
|
|
86
95
|
general_config.plugin_config = plugin_config
|
87
96
|
|
@@ -100,3 +109,7 @@ def pytest_sessionstart(session):
|
|
100
109
|
f" Default wait interval: {general_config.get_default_wait_interval()} ms"
|
101
110
|
)
|
102
111
|
logger.info(f" Default wait retries: {general_config.get_default_wait_retries()}")
|
112
|
+
logger.info(f" Test with mocks: {general_config.get_test_with_mocks()}")
|
113
|
+
|
114
|
+
|
115
|
+
pytest_plugins = ["gltest.fixtures"]
|
gltest_cli/config/types.py
CHANGED
@@ -4,6 +4,7 @@ from pathlib import Path
|
|
4
4
|
from typing import Dict, List, Optional
|
5
5
|
from genlayer_py.chains import localnet, testnet_asimov
|
6
6
|
from genlayer_py.types import GenLayerChain
|
7
|
+
from urllib.parse import urlparse
|
7
8
|
|
8
9
|
|
9
10
|
class NetworkConfig(str, Enum):
|
@@ -18,6 +19,7 @@ class PluginConfig:
|
|
18
19
|
default_wait_interval: Optional[int] = None
|
19
20
|
default_wait_retries: Optional[int] = None
|
20
21
|
network_name: Optional[str] = None
|
22
|
+
test_with_mocks: bool = False
|
21
23
|
|
22
24
|
|
23
25
|
@dataclass
|
@@ -135,3 +137,12 @@ class GeneralConfig:
|
|
135
137
|
if self.plugin_config.network_name is not None:
|
136
138
|
return self.plugin_config.network_name
|
137
139
|
return self.user_config.default_network
|
140
|
+
|
141
|
+
def get_test_with_mocks(self) -> bool:
|
142
|
+
return self.plugin_config.test_with_mocks
|
143
|
+
|
144
|
+
def check_local_rpc(self) -> bool:
|
145
|
+
SUPPORTED_RPC_DOMAINS = ["localhost", "127.0.0.1"]
|
146
|
+
rpc_url = self.get_rpc_url()
|
147
|
+
domain = urlparse(rpc_url).netloc.split(":")[0] # Extract domain without port
|
148
|
+
return domain in SUPPORTED_RPC_DOMAINS
|
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# v0.1.0
|
2
|
+
# { "Depends": "py-genlayer:latest" }
|
2
3
|
|
3
4
|
from genlayer import *
|
4
5
|
|
@@ -36,7 +37,7 @@ class PredictionMarket(gl.Contract):
|
|
36
37
|
)
|
37
38
|
self.team1 = team1
|
38
39
|
self.team2 = team2
|
39
|
-
self.winner = 0
|
40
|
+
self.winner = u256(0)
|
40
41
|
self.score = ""
|
41
42
|
|
42
43
|
@gl.public.write
|
@@ -49,8 +50,8 @@ class PredictionMarket(gl.Contract):
|
|
49
50
|
team1 = self.team1
|
50
51
|
team2 = self.team2
|
51
52
|
|
52
|
-
def get_match_result() ->
|
53
|
-
web_data = gl.
|
53
|
+
def get_match_result() -> typing.Any:
|
54
|
+
web_data = gl.nondet.web.render(market_resolution_url, mode="text")
|
54
55
|
print(web_data)
|
55
56
|
|
56
57
|
task = f"""
|
@@ -75,11 +76,13 @@ nothing else. Don't include any other words or characters,
|
|
75
76
|
your output must be only JSON without any formatting prefix or suffix.
|
76
77
|
This result should be perfectly parsable by a JSON parser without errors.
|
77
78
|
"""
|
78
|
-
result =
|
79
|
+
result = (
|
80
|
+
gl.nondet.exec_prompt(task).replace("```json", "").replace("```", "")
|
81
|
+
)
|
79
82
|
print(result)
|
80
|
-
return json.
|
83
|
+
return json.loads(result)
|
81
84
|
|
82
|
-
result_json =
|
85
|
+
result_json = gl.eq_principle.strict_eq(get_match_result)
|
83
86
|
|
84
87
|
if result_json["winner"] > -1:
|
85
88
|
self.has_resolved = True
|
@@ -94,4 +97,4 @@ This result should be perfectly parsable by a JSON parser without errors.
|
|
94
97
|
"winner": self.winner,
|
95
98
|
"score": self.score,
|
96
99
|
"has_resolved": self.has_resolved,
|
97
|
-
}
|
100
|
+
}
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# v0.1.0
|
1
2
|
# { "Depends": "py-genlayer:test" }
|
2
3
|
|
3
4
|
import json
|
@@ -139,7 +140,7 @@ class IntelligentOracle(gl.Contract):
|
|
139
140
|
for resource_url in resources_to_check:
|
140
141
|
|
141
142
|
def evaluate_single_source() -> str:
|
142
|
-
resource_web_data = gl.
|
143
|
+
resource_web_data = gl.nondet.web.render(resource_url, mode="text")
|
143
144
|
print(resource_web_data)
|
144
145
|
|
145
146
|
task = f"""
|
@@ -223,11 +224,11 @@ Provide your response in **valid JSON** format with the following structure:
|
|
223
224
|
- **Clarity:** Make sure your reasoning is easy to understand.
|
224
225
|
- **Validity:** Ensure the JSON output is properly formatted and free of errors. Do not include trailing commas.
|
225
226
|
"""
|
226
|
-
result = gl.exec_prompt(task)
|
227
|
+
result = gl.nondet.exec_prompt(task)
|
227
228
|
print(result)
|
228
229
|
return result
|
229
230
|
|
230
|
-
result = gl.
|
231
|
+
result = gl.eq_principle.prompt_comparative(
|
231
232
|
evaluate_single_source,
|
232
233
|
principle="`outcome` field must be exactly the same. All other fields must be similar",
|
233
234
|
)
|
@@ -305,11 +306,11 @@ Provide your response in **valid JSON** format with the following structure:
|
|
305
306
|
|
306
307
|
"""
|
307
308
|
|
308
|
-
result = gl.exec_prompt(task)
|
309
|
+
result = gl.nondet.exec_prompt(task)
|
309
310
|
print(result)
|
310
311
|
return result
|
311
312
|
|
312
|
-
result = gl.
|
313
|
+
result = gl.eq_principle.prompt_comparative(
|
313
314
|
evaluate_all_sources,
|
314
315
|
principle="`outcome` field must be exactly the same. All other fields must be similar",
|
315
316
|
)
|
@@ -331,7 +332,7 @@ Provide your response in **valid JSON** format with the following structure:
|
|
331
332
|
self.status = Status.RESOLVED.value
|
332
333
|
|
333
334
|
@gl.public.view
|
334
|
-
def get_dict(self) -> dict[str, str]:
|
335
|
+
def get_dict(self) -> dict[str, str | list[str]]:
|
335
336
|
return {
|
336
337
|
"title": self.title,
|
337
338
|
"description": self.description,
|
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# v0.1.0
|
2
|
+
# { "Depends": "py-genlayer:latest" }
|
2
3
|
|
3
4
|
import json
|
4
5
|
|
@@ -47,7 +48,7 @@ The balance of the receiver should have increased by the amount sent.
|
|
47
48
|
The total sum of all balances should remain the same before and after the transaction"""
|
48
49
|
|
49
50
|
final_result = (
|
50
|
-
gl.
|
51
|
+
gl.eq_principle.prompt_non_comparative(
|
51
52
|
lambda: input,
|
52
53
|
task=task,
|
53
54
|
criteria=criteria,
|
@@ -1,13 +1,15 @@
|
|
1
|
+
# v0.1.0
|
1
2
|
# {
|
2
3
|
# "Seq": [
|
3
|
-
# { "Depends": "py-lib-
|
4
|
-
# { "Depends": "py-genlayer:
|
4
|
+
# { "Depends": "py-lib-genlayer-embeddings:09h0i209wrzh4xzq86f79c60x0ifs7xcjwl53ysrnw06i54ddxyi" },
|
5
|
+
# { "Depends": "py-genlayer:latest" }
|
5
6
|
# ]
|
6
7
|
# }
|
7
8
|
|
8
9
|
import numpy as np
|
9
10
|
from genlayer import *
|
10
|
-
import
|
11
|
+
import genlayer_embeddings as gle
|
12
|
+
|
11
13
|
from dataclasses import dataclass
|
12
14
|
import typing
|
13
15
|
|
@@ -21,13 +23,13 @@ class StoreValue:
|
|
21
23
|
|
22
24
|
# contract class
|
23
25
|
class LogIndexer(gl.Contract):
|
24
|
-
vector_store: VecDB[np.float32, typing.Literal[384], StoreValue]
|
26
|
+
vector_store: gle.VecDB[np.float32, typing.Literal[384], StoreValue]
|
25
27
|
|
26
28
|
def __init__(self):
|
27
29
|
pass
|
28
30
|
|
29
31
|
def get_embedding_generator(self):
|
30
|
-
return
|
32
|
+
return gle.SentenceTransformer("all-MiniLM-L6-v2")
|
31
33
|
|
32
34
|
def get_embedding(
|
33
35
|
self, txt: str
|
@@ -8,7 +8,10 @@ class MultiFileContract(gl.Contract):
|
|
8
8
|
with open("/contract/other.py", "rt") as f:
|
9
9
|
text = f.read()
|
10
10
|
self.other_addr = gl.deploy_contract(
|
11
|
-
code=text.encode("utf-8"),
|
11
|
+
code=text.encode("utf-8"),
|
12
|
+
args=["123"],
|
13
|
+
salt_nonce=u256(1),
|
14
|
+
value=u256(0),
|
12
15
|
)
|
13
16
|
|
14
17
|
@gl.public.write
|
@@ -17,4 +20,4 @@ class MultiFileContract(gl.Contract):
|
|
17
20
|
|
18
21
|
@gl.public.view
|
19
22
|
def test(self) -> str:
|
20
|
-
return gl.
|
23
|
+
return gl.get_contract_at(self.other_addr).view().test()
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# v0.1.0
|
1
2
|
# { "Depends": "py-genlayer:test" }
|
2
3
|
|
3
4
|
from genlayer import *
|
@@ -14,7 +15,7 @@ class multi_read_erc20(gl.Contract):
|
|
14
15
|
self, account_address: str, token_contracts: list[str]
|
15
16
|
) -> None:
|
16
17
|
for token_contract in token_contracts:
|
17
|
-
contract = gl.
|
18
|
+
contract = gl.get_contract_at(Address(token_contract))
|
18
19
|
balance = contract.view().get_balance_of(account_address)
|
19
20
|
self.balances.get_or_insert_default(Address(account_address))[
|
20
21
|
Address(token_contract)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# v0.1.0
|
1
2
|
# { "Depends": "py-genlayer:test" }
|
2
3
|
|
3
4
|
from genlayer import *
|
@@ -29,7 +30,7 @@ class MultiTentantStorage(gl.Contract):
|
|
29
30
|
@gl.public.view
|
30
31
|
def get_all_storages(self) -> dict[str, str]:
|
31
32
|
return {
|
32
|
-
storage_contract.as_hex: gl.
|
33
|
+
storage_contract.as_hex: gl.get_contract_at(storage_contract)
|
33
34
|
.view()
|
34
35
|
.get_storage()
|
35
36
|
for storage_contract in self.all_storage_contracts
|
@@ -45,4 +46,4 @@ class MultiTentantStorage(gl.Contract):
|
|
45
46
|
self.available_storage_contracts.pop()
|
46
47
|
|
47
48
|
contract_to_use = self.mappings[gl.message.sender_address]
|
48
|
-
gl.
|
49
|
+
gl.get_contract_at(contract_to_use).emit().update_storage(new_storage)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# v0.1.0
|
1
2
|
# { "Depends": "py-genlayer:test" }
|
2
3
|
|
3
4
|
from genlayer import *
|
@@ -11,4 +12,8 @@ class read_erc20(gl.Contract):
|
|
11
12
|
|
12
13
|
@gl.public.view
|
13
14
|
def get_balance_of(self, account_address: str) -> int:
|
14
|
-
return
|
15
|
+
return (
|
16
|
+
gl.get_contract_at(self.token_contract)
|
17
|
+
.view()
|
18
|
+
.get_balance_of(account_address)
|
19
|
+
)
|
@@ -1,4 +1,5 @@
|
|
1
|
-
#
|
1
|
+
# v0.1.0
|
2
|
+
# { "Depends": "py-genlayer:latest" }
|
2
3
|
from genlayer import *
|
3
4
|
|
4
5
|
import json
|
@@ -39,12 +40,12 @@ This result should be perfectly parseable by a JSON parser without errors.
|
|
39
40
|
"""
|
40
41
|
|
41
42
|
def get_wizard_answer():
|
42
|
-
result = gl.exec_prompt(prompt)
|
43
|
+
result = gl.nondet.exec_prompt(prompt)
|
43
44
|
result = result.replace("```json", "").replace("```", "")
|
44
45
|
print(result)
|
45
46
|
return result
|
46
47
|
|
47
|
-
result = gl.
|
48
|
+
result = gl.eq_principle.prompt_comparative(
|
48
49
|
get_wizard_answer, "The value of give_coin has to match"
|
49
50
|
)
|
50
51
|
parsed_result = json.loads(result)
|
@@ -1,8 +1,27 @@
|
|
1
1
|
from gltest import get_contract_factory
|
2
2
|
from gltest.assertions import tx_execution_succeeded
|
3
|
+
import json
|
3
4
|
|
4
5
|
|
5
|
-
def test_football_prediction_market():
|
6
|
+
def test_football_prediction_market(setup_validators):
|
7
|
+
|
8
|
+
# Setup validators with mock response
|
9
|
+
team_1 = "Georgia"
|
10
|
+
team_2 = "Portugal"
|
11
|
+
score = "2:0"
|
12
|
+
winner = 1
|
13
|
+
mock_response = {
|
14
|
+
"response": {
|
15
|
+
f"Team 1: {team_1}\nTeam 2: {team_2}": json.dumps(
|
16
|
+
{
|
17
|
+
"score": score,
|
18
|
+
"winner": winner,
|
19
|
+
}
|
20
|
+
),
|
21
|
+
}
|
22
|
+
}
|
23
|
+
setup_validators(mock_response)
|
24
|
+
|
6
25
|
# Deploy Contract
|
7
26
|
factory = get_contract_factory("PredictionMarket")
|
8
27
|
contract = factory.deploy(args=["2024-06-26", "Georgia", "Portugal"])
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import time
|
2
|
+
import json
|
2
3
|
|
3
4
|
from gltest import get_contract_factory
|
4
5
|
from gltest.assertions import tx_execution_succeeded
|
@@ -18,16 +19,55 @@ def wait_for_contract_deployment(intelligent_oracle_contract, max_retries=10, de
|
|
18
19
|
return False
|
19
20
|
|
20
21
|
|
21
|
-
def
|
22
|
-
|
23
|
-
|
22
|
+
def create_mock_response(markets_data):
|
23
|
+
reasoning_single_source_marathon = "The HTML content contains the results of the Madrid Marathon 2024, which occurred on April 28, 2024. Mitku Tafa won and matches the name 'Tafa Mitku' in the list of potential outcomes."
|
24
|
+
reasoning_all_sources_marathon = "The URL indicates that the Madrid Marathon 2024 has occurred on April 28, 2024, and Mitku Tafa was the winner. The name matches one of the potential outcomes. There are no conflicting sources."
|
25
|
+
reasoning_single_source_election = "The URL is a valid news page. The election has occurred, and Donald Trump is reported to have won with 312 votes. The rule specifies that the outcome is based on official election results."
|
26
|
+
reasoning_all_sources_election = "The only data source provided is from BBC News. It reports that Donald Trump won the 2024 US presidential election with 312 votes. The rule specifies that the outcome is based on official election results. There are no other sources contradicting this information."
|
27
|
+
|
28
|
+
return {
|
29
|
+
"response": {
|
30
|
+
f"outcomes.\n\n### Inputs\n<title>\n{markets_data[0]['title']}": json.dumps(
|
31
|
+
{
|
32
|
+
"valid_source": "true",
|
33
|
+
"event_has_occurred": "true",
|
34
|
+
"reasoning": reasoning_single_source_marathon,
|
35
|
+
"outcome": markets_data[0]["outcome"],
|
36
|
+
}
|
37
|
+
),
|
38
|
+
f"inputs\n\n ### Inputs\n <title>\n {markets_data[0]['title']}\n": json.dumps(
|
39
|
+
{
|
40
|
+
"relevant_sources": [markets_data[0]["evidence_urls"]],
|
41
|
+
"reasoning": reasoning_all_sources_marathon,
|
42
|
+
"outcome": markets_data[0]["outcome"],
|
43
|
+
}
|
44
|
+
),
|
45
|
+
f"outcomes.\n\n### Inputs\n<title>\n{markets_data[1]['title']}": json.dumps(
|
46
|
+
{
|
47
|
+
"valid_source": "true",
|
48
|
+
"event_has_occurred": "true",
|
49
|
+
"reasoning": reasoning_single_source_election,
|
50
|
+
"outcome": markets_data[1]["outcome"],
|
51
|
+
}
|
52
|
+
),
|
53
|
+
f"inputs\n\n ### Inputs\n <title>\n {markets_data[1]['title']}\n": json.dumps(
|
54
|
+
{
|
55
|
+
"relevant_sources": [markets_data[1]["evidence_urls"]],
|
56
|
+
"reasoning": reasoning_all_sources_election,
|
57
|
+
"outcome": markets_data[1]["outcome"],
|
58
|
+
}
|
59
|
+
),
|
60
|
+
},
|
61
|
+
"eq_principle_prompt_comparative": {
|
62
|
+
reasoning_single_source_marathon: True,
|
63
|
+
reasoning_all_sources_marathon: True,
|
64
|
+
reasoning_single_source_election: True,
|
65
|
+
reasoning_all_sources_election: True,
|
66
|
+
},
|
67
|
+
}
|
24
68
|
|
25
|
-
# Deploy the Registry contract with the IntelligentOracle code
|
26
|
-
registry_factory = get_contract_factory("Registry")
|
27
|
-
registry_contract = registry_factory.deploy(
|
28
|
-
args=[intelligent_oracle_factory.contract_code]
|
29
|
-
)
|
30
69
|
|
70
|
+
def test_intelligent_oracle_factory_pattern(setup_validators):
|
31
71
|
markets_data = [
|
32
72
|
{
|
33
73
|
"prediction_market_id": "marathon2024",
|
@@ -56,9 +96,22 @@ def test_intelligent_oracle_factory_pattern():
|
|
56
96
|
"evidence_urls": "https://www.bbc.com/news/election/2024/us/results",
|
57
97
|
},
|
58
98
|
]
|
59
|
-
|
99
|
+
|
100
|
+
mock_response = create_mock_response(markets_data)
|
101
|
+
|
102
|
+
setup_validators(mock_response)
|
103
|
+
|
104
|
+
# Get the intelligent oracle factory
|
105
|
+
intelligent_oracle_factory = get_contract_factory("IntelligentOracle")
|
106
|
+
|
107
|
+
# Deploy the Registry contract with the IntelligentOracle code
|
108
|
+
registry_factory = get_contract_factory("Registry")
|
109
|
+
registry_contract = registry_factory.deploy(
|
110
|
+
args=[intelligent_oracle_factory.contract_code]
|
111
|
+
)
|
60
112
|
|
61
113
|
# Create markets through factory
|
114
|
+
created_market_contracts = []
|
62
115
|
for market_data in markets_data:
|
63
116
|
create_result = registry_contract.create_new_prediction_market(
|
64
117
|
args=[
|
@@ -1,15 +1,34 @@
|
|
1
1
|
from gltest import get_contract_factory, get_default_account, create_account
|
2
2
|
from gltest.assertions import tx_execution_succeeded
|
3
|
+
import json
|
3
4
|
|
4
5
|
TOKEN_TOTAL_SUPPLY = 1000
|
5
6
|
TRANSFER_AMOUNT = 100
|
6
7
|
|
7
8
|
|
8
|
-
def test_llm_erc20():
|
9
|
+
def test_llm_erc20(setup_validators):
|
9
10
|
# Account Setup
|
10
11
|
from_account_a = get_default_account()
|
11
12
|
from_account_b = create_account()
|
12
13
|
|
14
|
+
# Mock Response
|
15
|
+
mock_response = {
|
16
|
+
"response": {
|
17
|
+
"The balance of the sender": json.dumps(
|
18
|
+
{
|
19
|
+
"transaction_success": True,
|
20
|
+
"transaction_error": "",
|
21
|
+
"updated_balances": {
|
22
|
+
from_account_a.address: TOKEN_TOTAL_SUPPLY - TRANSFER_AMOUNT,
|
23
|
+
from_account_b.address: TRANSFER_AMOUNT,
|
24
|
+
},
|
25
|
+
}
|
26
|
+
)
|
27
|
+
},
|
28
|
+
"eq_principle_prompt_non_comparative": {"The balance of the sender": True},
|
29
|
+
}
|
30
|
+
setup_validators(mock_response=mock_response)
|
31
|
+
|
13
32
|
# Deploy Contract
|
14
33
|
factory = get_contract_factory("LlmErc20")
|
15
34
|
contract = factory.deploy(args=[TOKEN_TOTAL_SUPPLY])
|
@@ -2,7 +2,8 @@ from gltest import get_contract_factory
|
|
2
2
|
from gltest.assertions import tx_execution_succeeded
|
3
3
|
|
4
4
|
|
5
|
-
def test_log_indexer():
|
5
|
+
def test_log_indexer(setup_validators):
|
6
|
+
setup_validators()
|
6
7
|
# Deploy Contract
|
7
8
|
factory = get_contract_factory("LogIndexer")
|
8
9
|
contract = factory.deploy(args=[])
|
@@ -2,9 +2,10 @@ from gltest import get_contract_factory
|
|
2
2
|
from gltest.assertions import tx_execution_succeeded
|
3
3
|
|
4
4
|
|
5
|
-
def test_multi_file_contract():
|
5
|
+
def test_multi_file_contract(setup_validators):
|
6
6
|
# Multi file contracts are considered if they are defined in a __init__.py file
|
7
7
|
# Deploy Contract, it will deploy other.py as well
|
8
|
+
setup_validators()
|
8
9
|
factory = get_contract_factory("MultiFileContract")
|
9
10
|
contract = factory.deploy(args=[])
|
10
11
|
|
@@ -2,9 +2,10 @@ from gltest import get_contract_factory
|
|
2
2
|
from gltest.assertions import tx_execution_succeeded
|
3
3
|
|
4
4
|
|
5
|
-
def test_multi_file_contract_legacy():
|
5
|
+
def test_multi_file_contract_legacy(setup_validators):
|
6
6
|
# Multi file contracts are considered if they are defined in a __init__.gpy file
|
7
7
|
# Deploy Contract, it will deploy other.gpy as well
|
8
|
+
setup_validators()
|
8
9
|
factory = get_contract_factory("MultiFileContractLegacy")
|
9
10
|
contract = factory.deploy(args=[])
|
10
11
|
|
@@ -4,7 +4,7 @@ from gltest_cli.config.general import get_general_config
|
|
4
4
|
from genlayer_py.chains import testnet_asimov
|
5
5
|
|
6
6
|
|
7
|
-
def test_multi_read_erc20():
|
7
|
+
def test_multi_read_erc20(setup_validators):
|
8
8
|
"""
|
9
9
|
This test verifies the functionality of a multi-read ERC20 contract. It deploys two separate ERC20 token contracts
|
10
10
|
(referred to as 'doge' and 'shiba') and a multi-read ERC20 contract. The test aims to:
|
@@ -17,14 +17,20 @@ def test_multi_read_erc20():
|
|
17
17
|
|
18
18
|
This test demonstrates the integration contract to contract reads
|
19
19
|
"""
|
20
|
+
setup_validators()
|
20
21
|
general_config = get_general_config()
|
21
22
|
chain = general_config.get_chain()
|
22
23
|
|
23
24
|
TOKEN_TOTAL_SUPPLY = 1000
|
24
25
|
|
25
26
|
if chain.id == testnet_asimov.id:
|
26
|
-
|
27
|
-
|
27
|
+
accounts = get_accounts()
|
28
|
+
if len(accounts) < 2:
|
29
|
+
raise ValueError(
|
30
|
+
f"Test requires at least 2 accounts, but only {len(accounts)} available"
|
31
|
+
)
|
32
|
+
from_account_doge = accounts[0]
|
33
|
+
from_account_shiba = accounts[1]
|
28
34
|
else:
|
29
35
|
from_account_doge = create_account()
|
30
36
|
from_account_shiba = create_account()
|
@@ -4,7 +4,7 @@ from gltest_cli.config.general import get_general_config
|
|
4
4
|
from genlayer_py.chains import testnet_asimov
|
5
5
|
|
6
6
|
|
7
|
-
def test_multi_tenant_storage():
|
7
|
+
def test_multi_tenant_storage(setup_validators):
|
8
8
|
"""
|
9
9
|
This test verifies the functionality of a multi-tenant storage contract. It deploys two separate storage contracts
|
10
10
|
and a multi-tenant storage contract that manages them. The test aims to:
|
@@ -17,6 +17,7 @@ def test_multi_tenant_storage():
|
|
17
17
|
|
18
18
|
This test demonstrates contract-to-contract interactions and multi-tenant data management.
|
19
19
|
"""
|
20
|
+
setup_validators()
|
20
21
|
general_config = get_general_config()
|
21
22
|
chain = general_config.get_chain()
|
22
23
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
from gltest import get_contract_factory, get_default_account
|
2
2
|
|
3
3
|
|
4
|
-
def test_read_erc20():
|
4
|
+
def test_read_erc20(setup_validators):
|
5
5
|
"""
|
6
6
|
Tests that recursive contract calls work by:
|
7
7
|
1. creating an LLM ERC20 contract
|
@@ -11,6 +11,7 @@ def test_read_erc20():
|
|
11
11
|
|
12
12
|
It's like a linked list, but with contracts.
|
13
13
|
"""
|
14
|
+
setup_validators()
|
14
15
|
TOKEN_TOTAL_SUPPLY = 1000
|
15
16
|
|
16
17
|
# LLM ERC20
|
@@ -15,14 +15,20 @@ INITIAL_STATE_USER_B = "user_b_initial_state"
|
|
15
15
|
UPDATED_STATE_USER_B = "user_b_updated_state"
|
16
16
|
|
17
17
|
|
18
|
-
def test_user_storage():
|
18
|
+
def test_user_storage(setup_validators):
|
19
|
+
setup_validators()
|
19
20
|
general_config = get_general_config()
|
20
21
|
chain = general_config.get_chain()
|
21
22
|
|
22
23
|
# Account Setup
|
23
24
|
if chain.id == testnet_asimov.id:
|
24
|
-
|
25
|
-
|
25
|
+
accounts = get_accounts()
|
26
|
+
if len(accounts) < 2:
|
27
|
+
raise ValueError(
|
28
|
+
f"Test requires at least 2 accounts, but only {len(accounts)} available"
|
29
|
+
)
|
30
|
+
from_account_a = accounts[0]
|
31
|
+
from_account_b = accounts[1]
|
26
32
|
else:
|
27
33
|
from_account_a = get_default_account()
|
28
34
|
from_account_b = create_account()
|
@@ -1,8 +1,23 @@
|
|
1
1
|
from gltest import get_contract_factory
|
2
2
|
from gltest.assertions import tx_execution_succeeded
|
3
|
+
import json
|
3
4
|
|
4
5
|
|
5
|
-
def test_wizard_of_coin():
|
6
|
+
def test_wizard_of_coin(setup_validators):
|
7
|
+
mock_response = {
|
8
|
+
"response": {
|
9
|
+
"wizard": json.dumps(
|
10
|
+
{
|
11
|
+
"reasoning": "I am a grumpy wizard and I never give away my coins!",
|
12
|
+
"give_coin": False,
|
13
|
+
}
|
14
|
+
),
|
15
|
+
},
|
16
|
+
"eq_principle_prompt_comparative": {
|
17
|
+
"The value of give_coin has to match": True
|
18
|
+
},
|
19
|
+
}
|
20
|
+
setup_validators(mock_response)
|
6
21
|
factory = get_contract_factory("WizardOfCoin")
|
7
22
|
contract = factory.deploy(args=[True])
|
8
23
|
|
@@ -1,65 +0,0 @@
|
|
1
|
-
genlayer_test-0.3.0.dist-info/licenses/LICENSE,sha256=che_H4vE0QUx3HvWrAa1_jDEVInift0U6VO15-QqEls,1064
|
2
|
-
gltest/__init__.py,sha256=Uozr4VS-_oKUxEdXbWoEVLB8JQKBWGs6vGEHDj1-6LY,348
|
3
|
-
gltest/assertions.py,sha256=0dEk0VxcHK4I7GZPHxJmz-2jaA60V499gOSR74rZbfM,1748
|
4
|
-
gltest/exceptions.py,sha256=deJPmrTe5gF33qkkKF2IVJY7lc_knI7Ql3N7jZ8aLZs,510
|
5
|
-
gltest/types.py,sha256=BODmwTr2gAUEiO9FjiuTiWwuKvXgo4xZWstQWNUfnlw,156
|
6
|
-
gltest/artifacts/__init__.py,sha256=qTt3TE19gVNWnQLUlt5aDe4nNvJ2YJ1jzDkMmYIsCG0,194
|
7
|
-
gltest/artifacts/contract.py,sha256=KChpmfjZod_0dVB8y-dvWz6IVm7QlIJsgG2ArtvVDaU,6457
|
8
|
-
gltest/glchain/__init__.py,sha256=QLd55hVB9xVTAtCKbjmGPAwh0M8_tUNJ5xI0H93YyTY,428
|
9
|
-
gltest/glchain/account.py,sha256=HUmWguJMolggQaZNRPw-LGlRlQCjLLdUanKRowMv6pI,812
|
10
|
-
gltest/glchain/client.py,sha256=urRvnLt8GpdCV3yOBSvJNZQzu_TsZr8HqKn14Q2SpIQ,1547
|
11
|
-
gltest/glchain/contract.py,sha256=RFLbEZseWatX0Xvt3-Eo_zOowxLMhukoXjK8V8Ca0Ok,11370
|
12
|
-
gltest/helpers/__init__.py,sha256=I7HiTu_H7_hP65zY6Wl02r-5eAMr2eZvqBVmusuQLX4,180
|
13
|
-
gltest/helpers/fixture_snapshot.py,sha256=VydrtviG60ukSFIvzO5QwK-SHmkRmbsQFEVdyItvGWI,2142
|
14
|
-
gltest/helpers/take_snapshot.py,sha256=eXqEKXM2hcox3pLGIcNddobU8zXPQvD-Iwf87eHqW2s,1276
|
15
|
-
gltest_cli/logging.py,sha256=2Bkh6OR5C19HefARLQN5xBfam3apXzf7_Wei2PBfKlM,1241
|
16
|
-
gltest_cli/main.py,sha256=Ti2-0Ev1x5_cM0D1UKqdgaDt80CDHEQGtdRne2qLm4M,53
|
17
|
-
gltest_cli/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
|
-
gltest_cli/config/constants.py,sha256=lX8C3aS7zXWazA8LWgE0BkPvy7NopyEMyJNI2yYWX9M,300
|
19
|
-
gltest_cli/config/general.py,sha256=ezpoGsT8grO9zQH6RugV14b1GzeFt-htYToHQBJhNvY,186
|
20
|
-
gltest_cli/config/plugin.py,sha256=zEWsi18hEoK9yloKKPd8y77wXCpgWf7hAWI1JL8S5Ho,3325
|
21
|
-
gltest_cli/config/types.py,sha256=R5ylpHKzoOK43_tXC047mJqAybCZhj615_FWBhsmNAU,5237
|
22
|
-
gltest_cli/config/user.py,sha256=LjjoqXWRLPeNgOvLKy2tJDNl1M0uLb-5rwEsnGyJunE,8065
|
23
|
-
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
24
|
-
tests/conftest.py,sha256=RKdoE5_zcMimeojAoA_GSFI9du4pMzMi1vZ1njtfoAs,28
|
25
|
-
tests/examples/contracts/football_prediction_market.py,sha256=kdouFijjeCdIJyaVJlgXcqbBAXecA9_YdhklSsIW-QM,3219
|
26
|
-
tests/examples/contracts/intelligent_oracle.py,sha256=WrNZWWoi1sz22Azt2EXgdWHDg5Ihca2pWUHrM9pVfQE,12319
|
27
|
-
tests/examples/contracts/intelligent_oracle_factory.py,sha256=ax496IZuDCA728rRcbjwTaM4Q4E-Y1jGkHsEcyf1cig,1490
|
28
|
-
tests/examples/contracts/llm_erc20.py,sha256=nfIs-7A79L46NgHQzWbPyEOUlzAlFLsf4K05acwKr_M,2523
|
29
|
-
tests/examples/contracts/log_indexer.py,sha256=VwMC8_Gy1Z1qjuy5GeEMyepjZ3Z5y7VAOrHMl5MrjxI,1852
|
30
|
-
tests/examples/contracts/multi_read_erc20.py,sha256=HsMJKGT9a9eZAO43Em7hCRfh1yyHDgcUbQ0gmOE1MXs,850
|
31
|
-
tests/examples/contracts/multi_tenant_storage.py,sha256=aGLPC76FegXdnIjMjeGsu3s3AbKK9dtV6t1d_KoI8rI,1897
|
32
|
-
tests/examples/contracts/read_erc20.py,sha256=kstiB93JHHajJe1GldzeawxnVYutjT8KE2d1bYTgggU,390
|
33
|
-
tests/examples/contracts/storage.py,sha256=GZHBXhjc94eEkdSO1UWgcop0fEo0hD57KZM0ds3pUFM,490
|
34
|
-
tests/examples/contracts/user_storage.py,sha256=j-RXxTIqb1dePYqP_pkeoCxxDq07VURryvzF_Q-sZmI,638
|
35
|
-
tests/examples/contracts/wizard_of_coin.py,sha256=BJ0Nv6N-JJP_Pk7YUSXPPRxX5_mDRBDlfL6nabeaoyA,1606
|
36
|
-
tests/examples/contracts/multi_file_contract/__init__.py,sha256=8O3BvoUrLSmc4uTf2jm7MyrmcaiGD0w8wPwotdAqZHQ,485
|
37
|
-
tests/examples/contracts/multi_file_contract/other.py,sha256=jHDtjUL3eAUgE6yOYKFw_RfAH7kIwk8CvxUjbWHNruk,236
|
38
|
-
tests/examples/tests/test_football_prediction_market.py,sha256=wFu024sq3IURLL1zyLyO_G1sRCjPTV7iImi87__dZ4Y,657
|
39
|
-
tests/examples/tests/test_intelligent_oracle_factory.py,sha256=Nw7jO9bjD79AETT2QQl0Vun-yxSAAuqGSdkQn2Y3WUw,5377
|
40
|
-
tests/examples/tests/test_llm_erc20.py,sha256=3-wsZi23TpQ_9HYPfcbyo9206AkDndqTfBzRWXzlsNE,1400
|
41
|
-
tests/examples/tests/test_log_indexer.py,sha256=Km44SiA8dlA4WBqwugXVBCQUlODdf1dB4p4nt24HG9k,2649
|
42
|
-
tests/examples/tests/test_multi_file_contract.py,sha256=pWmK6lcZrSAnDH09Z6Q-cXs8V6VGFhHkvgThvJKEB4U,512
|
43
|
-
tests/examples/tests/test_multi_file_contract_legacy.py,sha256=Jx_u0rDrQJspQgFo1KUddcFgTcOhcE-YLuLgk3tKrCA,527
|
44
|
-
tests/examples/tests/test_multi_read_erc20.py,sha256=A-mRoZPj3_0B6CUnwtPFxtXoOfd1RuB8PIeExniZlCs,3411
|
45
|
-
tests/examples/tests/test_multi_tenant_storage.py,sha256=yliqhit7wWO1Y6OXl_cv3ruTCOto8ZfKGtkT3lRvZpQ,2717
|
46
|
-
tests/examples/tests/test_read_erc20.py,sha256=9bUmigPab2dDf1GElRXVbf1TVbMur37IPT7HFZDmFUg,1208
|
47
|
-
tests/examples/tests/test_storage.py,sha256=jcVNAeBynn70Ov1rF1robZwFZptuNLtHW-u1XfG393k,712
|
48
|
-
tests/examples/tests/test_storage_legacy.py,sha256=RNVnD0G9ilb4I2s0CPAAgJEuKUgEkkbItuesOfmv-pg,677
|
49
|
-
tests/examples/tests/test_user_storage.py,sha256=qUv57rn1X3wAiIglnj3LH3r2clIBwF38MMkKvU4IGaA,2552
|
50
|
-
tests/examples/tests/test_wizard_of_coin.py,sha256=aUDeV5w0XONMMS71Vzw80lHfcSM0z8RKPJSXAuDwRto,392
|
51
|
-
tests/gltest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
52
|
-
tests/gltest/artifact/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
53
|
-
tests/gltest/artifact/test_contract_definition.py,sha256=6R8THNFKKpG7brULzp63vT1_pPd_JFNp3ZS08CJJWrg,3642
|
54
|
-
tests/gltest/artifact/contracts/duplicate_ic_contract_1.py,sha256=bSWsUVjBy5cGtI72cjnkstsMzuUJbB3IG5JjTxOF-dc,500
|
55
|
-
tests/gltest/artifact/contracts/duplicate_ic_contract_2.py,sha256=bSWsUVjBy5cGtI72cjnkstsMzuUJbB3IG5JjTxOF-dc,500
|
56
|
-
tests/gltest/artifact/contracts/not_ic_contract.py,sha256=hQyGnYiiVceYdLI2WrvcFgPqzy1S4-YMb9FPhiHEGSA,510
|
57
|
-
tests/gltest/assertions/test_assertions.py,sha256=qzVrOdOM4xYtIy1sFHVAD_-naDHOequ23tEN0MELh0k,10781
|
58
|
-
tests/gltest_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
59
|
-
tests/gltest_cli/config/test_plugin.py,sha256=06-GENVugrL6mPQkgRgQqRsCTuQMy3WZcbh_9Du6zHo,3502
|
60
|
-
tests/gltest_cli/config/test_user.py,sha256=oJDcM6NbA16tQzQj5s8ZDvQYBm2uuvar5junFcVeitY,12116
|
61
|
-
genlayer_test-0.3.0.dist-info/METADATA,sha256=daKEgnpolSsdJRa4yvqPIiciVNKGKePFWT2H-o-fLiQ,17231
|
62
|
-
genlayer_test-0.3.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
63
|
-
genlayer_test-0.3.0.dist-info/entry_points.txt,sha256=RWPcSArBpz_G4BYioh5L8Q8hyClRbSgzLimjcWMp-BQ,94
|
64
|
-
genlayer_test-0.3.0.dist-info/top_level.txt,sha256=-qiGZxTRBytujzgVcKpxjvQ-WNeUDjXa59ceGMwMpko,24
|
65
|
-
genlayer_test-0.3.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|