genlayer-test 0.10.1__py3-none-any.whl → 0.11.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.10.1.dist-info → genlayer_test-0.11.0.dist-info}/METADATA +205 -6
- {genlayer_test-0.10.1.dist-info → genlayer_test-0.11.0.dist-info}/RECORD +9 -9
- {genlayer_test-0.10.1.dist-info → genlayer_test-0.11.0.dist-info}/licenses/LICENSE +2 -2
- gltest/types.py +14 -0
- gltest/validators/validator_factory.py +37 -11
- gltest_cli/config/plugin.py +8 -6
- {genlayer_test-0.10.1.dist-info → genlayer_test-0.11.0.dist-info}/WHEEL +0 -0
- {genlayer_test-0.10.1.dist-info → genlayer_test-0.11.0.dist-info}/entry_points.txt +0 -0
- {genlayer_test-0.10.1.dist-info → genlayer_test-0.11.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.11.0
|
|
4
4
|
Summary: GenLayer Testing Suite
|
|
5
5
|
Author: GenLayer
|
|
6
6
|
License-Expression: MIT
|
|
@@ -24,8 +24,8 @@ Dynamic: license-file
|
|
|
24
24
|
# GenLayer Testing Suite
|
|
25
25
|
|
|
26
26
|
[](https://opensource.org/license/mit/)
|
|
27
|
-
[](https://discord.gg/
|
|
28
|
-
[](https://discord.gg/qjCU4AWnKE)
|
|
28
|
+
[](https://x.com/GenLayer)
|
|
29
29
|
[](https://badge.fury.io/py/genlayer-test)
|
|
30
30
|
[](https://docs.genlayer.com/api-references/genlayer-test)
|
|
31
31
|
[](https://github.com/psf/black)
|
|
@@ -107,7 +107,7 @@ $ pip install genlayer-test
|
|
|
107
107
|
|
|
108
108
|
2. Install from source:
|
|
109
109
|
```bash
|
|
110
|
-
$ git clone https://github.com/
|
|
110
|
+
$ git clone https://github.com/genlayerlabs/genlayer-testing-suite
|
|
111
111
|
$ cd genlayer-testing-suite
|
|
112
112
|
$ pip install -e .
|
|
113
113
|
```
|
|
@@ -622,6 +622,205 @@ The `.analyze()` method helps you:
|
|
|
622
622
|
- Benchmark performance across multiple runs
|
|
623
623
|
|
|
624
624
|
|
|
625
|
+
### Mock Web Responses
|
|
626
|
+
|
|
627
|
+
The Mock Web Response system allows you to simulate HTTP responses for web requests made by intelligent contracts using GenLayer's web methods (`gl.nondet.web.get()`, `gl.nondet.web.post()`, etc.). This feature enables deterministic testing of contracts that interact with external web services without making actual HTTP calls.
|
|
628
|
+
|
|
629
|
+
#### Basic Example
|
|
630
|
+
|
|
631
|
+
Here's a simple example of mocking a web API response:
|
|
632
|
+
|
|
633
|
+
```python
|
|
634
|
+
from gltest import get_contract_factory, get_validator_factory
|
|
635
|
+
from gltest.types import MockedWebResponse
|
|
636
|
+
import json
|
|
637
|
+
|
|
638
|
+
def test_simple_web_mock():
|
|
639
|
+
# Define mock web responses
|
|
640
|
+
mock_web_response: MockedWebResponse = {
|
|
641
|
+
"nondet_web_request": {
|
|
642
|
+
"https://api.example.com/price": {
|
|
643
|
+
"method": "GET",
|
|
644
|
+
"status": 200,
|
|
645
|
+
"body": json.dumps({"price": 100.50})
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
# Create validators with mock web responses
|
|
651
|
+
validator_factory = get_validator_factory()
|
|
652
|
+
validators = validator_factory.batch_create_mock_validators(
|
|
653
|
+
count=5,
|
|
654
|
+
mock_web_response=mock_web_response
|
|
655
|
+
)
|
|
656
|
+
|
|
657
|
+
# Use validators in transaction context
|
|
658
|
+
transaction_context = {"validators": [v.to_dict() for v in validators]}
|
|
659
|
+
|
|
660
|
+
# Deploy and test contract
|
|
661
|
+
factory = get_contract_factory("PriceOracle")
|
|
662
|
+
contract = factory.deploy(transaction_context=transaction_context)
|
|
663
|
+
|
|
664
|
+
# Contract's web requests will receive the mocked response
|
|
665
|
+
result = contract.update_price().transact(transaction_context=transaction_context)
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
#### Supported HTTP Methods
|
|
669
|
+
|
|
670
|
+
Mock web responses support all HTTP methods including GET, POST, PUT, DELETE, PATCH, etc.:
|
|
671
|
+
|
|
672
|
+
```python
|
|
673
|
+
mock_web_response: MockedWebResponse = {
|
|
674
|
+
"nondet_web_request": {
|
|
675
|
+
# GET request
|
|
676
|
+
"https://api.example.com/users/123": {
|
|
677
|
+
"method": "GET",
|
|
678
|
+
"status": 200,
|
|
679
|
+
"body": '{"id": 123, "name": "Alice"}'
|
|
680
|
+
},
|
|
681
|
+
# POST request
|
|
682
|
+
"https://api.example.com/users": {
|
|
683
|
+
"method": "POST",
|
|
684
|
+
"status": 201,
|
|
685
|
+
"body": '{"id": 124, "name": "Bob", "created": true}'
|
|
686
|
+
},
|
|
687
|
+
# DELETE request
|
|
688
|
+
"https://api.example.com/users/123": {
|
|
689
|
+
"method": "DELETE",
|
|
690
|
+
"status": 204,
|
|
691
|
+
"body": ""
|
|
692
|
+
},
|
|
693
|
+
# PUT request
|
|
694
|
+
"https://api.example.com/users/123": {
|
|
695
|
+
"method": "PUT",
|
|
696
|
+
"status": 200,
|
|
697
|
+
"body": '{"id": 123, "name": "Alice Updated"}'
|
|
698
|
+
},
|
|
699
|
+
# Error response
|
|
700
|
+
"https://api.example.com/error": {
|
|
701
|
+
"method": "GET",
|
|
702
|
+
"status": 500,
|
|
703
|
+
"body": "Internal Server Error"
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
#### How It Works
|
|
710
|
+
|
|
711
|
+
When a contract calls any web method (`gl.nondet.web.get()`, `gl.nondet.web.post()`, etc.):
|
|
712
|
+
1. The mock system checks if the URL exists in the mock configuration
|
|
713
|
+
2. If found, it returns the mocked response with the specified status and body
|
|
714
|
+
3. If not found, the actual web request would be made (or fail if network access is disabled)
|
|
715
|
+
|
|
716
|
+
#### Complete Example: Twitter/X Username Storage
|
|
717
|
+
|
|
718
|
+
Here's a real-world example showing how to mock Twitter/X API responses:
|
|
719
|
+
|
|
720
|
+
```python
|
|
721
|
+
# test_x_username_storage.py
|
|
722
|
+
from gltest import get_contract_factory, get_validator_factory
|
|
723
|
+
from gltest.assertions import tx_execution_succeeded
|
|
724
|
+
from gltest.types import MockedWebResponse
|
|
725
|
+
import json
|
|
726
|
+
import urllib.parse
|
|
727
|
+
|
|
728
|
+
def test_x_username_storage():
|
|
729
|
+
# Helper to build URL with query parameters
|
|
730
|
+
def get_username_url(username: str) -> str:
|
|
731
|
+
params = {"user.fields": "public_metrics,verified"}
|
|
732
|
+
return f"https://domain.com/api/twitter/users/by/username/{username}?{urllib.parse.urlencode(params)}"
|
|
733
|
+
|
|
734
|
+
# Define mock responses for different usernames
|
|
735
|
+
mock_web_response: MockedWebResponse = {
|
|
736
|
+
"nondet_web_request": {
|
|
737
|
+
get_username_url("user_a"): {
|
|
738
|
+
"method": "GET",
|
|
739
|
+
"status": 200,
|
|
740
|
+
"body": json.dumps({"username": "user_a", "verified": True})
|
|
741
|
+
},
|
|
742
|
+
get_username_url("user_b"): {
|
|
743
|
+
"method": "GET",
|
|
744
|
+
"status": 200,
|
|
745
|
+
"body": json.dumps({"username": "user_b", "verified": False})
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
# Create validators with mock web responses
|
|
751
|
+
validator_factory = get_validator_factory()
|
|
752
|
+
validators = validator_factory.batch_create_mock_validators(
|
|
753
|
+
count=5,
|
|
754
|
+
mock_web_response=mock_web_response
|
|
755
|
+
)
|
|
756
|
+
transaction_context = {"validators": [v.to_dict() for v in validators]}
|
|
757
|
+
|
|
758
|
+
# Deploy and test contract
|
|
759
|
+
factory = get_contract_factory("XUsernameStorage")
|
|
760
|
+
contract = factory.deploy(transaction_context=transaction_context)
|
|
761
|
+
|
|
762
|
+
# Test updating username - will use mocked response
|
|
763
|
+
tx_receipt = contract.update_username(args=["user_a"]).transact(
|
|
764
|
+
transaction_context=transaction_context
|
|
765
|
+
)
|
|
766
|
+
assert tx_execution_succeeded(tx_receipt)
|
|
767
|
+
|
|
768
|
+
# Verify the username was stored
|
|
769
|
+
username = contract.get_username().call(transaction_context=transaction_context)
|
|
770
|
+
assert username == "user_a"
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
#### Combining Mock LLM and Web Responses
|
|
774
|
+
|
|
775
|
+
You can combine both mock LLM responses and mock web responses in the same test:
|
|
776
|
+
|
|
777
|
+
```python
|
|
778
|
+
def test_combined_mocks():
|
|
779
|
+
# Define both mock types
|
|
780
|
+
mock_llm_response = {
|
|
781
|
+
"eq_principle_prompt_comparative": {
|
|
782
|
+
"values match": True
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
mock_web_response: MockedWebResponse = {
|
|
787
|
+
"nondet_web_request": {
|
|
788
|
+
"https://api.example.com/data": {
|
|
789
|
+
"method": "GET",
|
|
790
|
+
"status": 200,
|
|
791
|
+
"body": '{"value": 42}'
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
# Create validators with both mock types
|
|
797
|
+
validator_factory = get_validator_factory()
|
|
798
|
+
validators = validator_factory.batch_create_mock_validators(
|
|
799
|
+
count=5,
|
|
800
|
+
mock_llm_response=mock_llm_response,
|
|
801
|
+
mock_web_response=mock_web_response
|
|
802
|
+
)
|
|
803
|
+
|
|
804
|
+
# Use in your tests...
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
#### Best Practices
|
|
808
|
+
|
|
809
|
+
1. **URL Matching**: URLs must match exactly, including query parameters
|
|
810
|
+
2. **Response Body**: Always provide the body as a string (use `json.dumps()` for JSON data)
|
|
811
|
+
3. **Status Codes**: Use realistic HTTP status codes (200, 404, 500, etc.)
|
|
812
|
+
4. **Method Matching**: Specify the correct HTTP method that your contract uses
|
|
813
|
+
5. **Error Testing**: Mock error responses to test error handling paths
|
|
814
|
+
6. **Deterministic Tests**: Mock web responses ensure tests don't depend on external services
|
|
815
|
+
|
|
816
|
+
#### Notes
|
|
817
|
+
|
|
818
|
+
- Mock web responses are only available when using mock validators
|
|
819
|
+
- URL matching is exact - the full URL including query parameters must match
|
|
820
|
+
- The method field should match the HTTP method used by the contract
|
|
821
|
+
- Useful for testing contracts that interact with external APIs without network dependencies
|
|
822
|
+
- All standard HTTP methods are supported (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS)
|
|
823
|
+
|
|
625
824
|
### Custom Transaction Context
|
|
626
825
|
|
|
627
826
|
The GenLayer Testing Suite allows you to customize the transaction execution environment by providing a `transaction_context` parameter with custom validators and GenVM datetime settings.
|
|
@@ -1001,8 +1200,8 @@ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file
|
|
|
1001
1200
|
## 💬 Support
|
|
1002
1201
|
|
|
1003
1202
|
- [Documentation](https://docs.genlayer.com/api-references/genlayer-test)
|
|
1004
|
-
- [Discord Community](https://discord.gg/
|
|
1005
|
-
- [GitHub Issues](https://github.com/
|
|
1203
|
+
- [Discord Community](https://discord.gg/qjCU4AWnKE)
|
|
1204
|
+
- [GitHub Issues](https://github.com/genlayerlabs/genlayer-testing-suite/issues)
|
|
1006
1205
|
- [Twitter](https://x.com/GenLayer)
|
|
1007
1206
|
|
|
1008
1207
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
genlayer_test-0.
|
|
1
|
+
genlayer_test-0.11.0.dist-info/licenses/LICENSE,sha256=qeyU7v-TUbXruF0KGiAPMvgxsqxMq1ObA47C0gR5kWI,1070
|
|
2
2
|
gltest/__init__.py,sha256=49112x2CLdYwvCbBZ1laJmMk0NQ7S3u5YUbxPefqhrk,454
|
|
3
3
|
gltest/accounts.py,sha256=HUmWguJMolggQaZNRPw-LGlRlQCjLLdUanKRowMv6pI,812
|
|
4
4
|
gltest/assertions.py,sha256=0dEk0VxcHK4I7GZPHxJmz-2jaA60V499gOSR74rZbfM,1748
|
|
@@ -6,7 +6,7 @@ gltest/clients.py,sha256=1dX6wmG3QCevQRLbSaFlHymZSb-sJ5aYwet1IoX2nbA,1554
|
|
|
6
6
|
gltest/exceptions.py,sha256=deJPmrTe5gF33qkkKF2IVJY7lc_knI7Ql3N7jZ8aLZs,510
|
|
7
7
|
gltest/fixtures.py,sha256=omVjLh1kXXUyL7Oo8zzdooJBbSX-Qk-Aa-prp5MqvFc,833
|
|
8
8
|
gltest/logging.py,sha256=jAkHsuMm-AEx1Xu1srU6W-0YzTwXJB48mCK-OVzAiN4,342
|
|
9
|
-
gltest/types.py,sha256=
|
|
9
|
+
gltest/types.py,sha256=LLkKjkFsKG0AXpqt-qk70YhOm18AGkqmihamG_9kjEc,1305
|
|
10
10
|
gltest/utils.py,sha256=-gHhjrS7i_GhDG3sKOq2qsTtYBt4HHgXHEXh-3RB_rI,573
|
|
11
11
|
gltest/artifacts/__init__.py,sha256=qTt3TE19gVNWnQLUlt5aDe4nNvJ2YJ1jzDkMmYIsCG0,194
|
|
12
12
|
gltest/artifacts/contract.py,sha256=KChpmfjZod_0dVB8y-dvWz6IVm7QlIJsgG2ArtvVDaU,6457
|
|
@@ -21,18 +21,18 @@ gltest/helpers/__init__.py,sha256=I7HiTu_H7_hP65zY6Wl02r-5eAMr2eZvqBVmusuQLX4,18
|
|
|
21
21
|
gltest/helpers/fixture_snapshot.py,sha256=bMgvlEVQBGIQzj7NOyosXWlphI1H2C1o75Zo0C-kGfQ,1931
|
|
22
22
|
gltest/helpers/take_snapshot.py,sha256=-QkaBvFG4ZsNKv_nCSEsy5Ze1pICOHxVhReSeQmZUlY,1276
|
|
23
23
|
gltest/validators/__init__.py,sha256=AXboXORF5a8MVtG7jWMT1fJcwGXNzcX6txXQstwX2EU,152
|
|
24
|
-
gltest/validators/validator_factory.py,sha256=
|
|
24
|
+
gltest/validators/validator_factory.py,sha256=Pu7c5XMc7HgPFIiWet0ybcgtW4T29d0lsgPrpj4tHtk,4957
|
|
25
25
|
gltest_cli/logging.py,sha256=WXVhfq9vT6FtV_jxDqGEGia1ZWSIUKAfmWRnZd_gWQk,1266
|
|
26
26
|
gltest_cli/main.py,sha256=Ti2-0Ev1x5_cM0D1UKqdgaDt80CDHEQGtdRne2qLm4M,53
|
|
27
27
|
gltest_cli/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
28
|
gltest_cli/config/constants.py,sha256=z7njbU8WXYhTnp1NYrW4YI2jN-p114BP2UDSYF0qAJE,571
|
|
29
29
|
gltest_cli/config/general.py,sha256=ezpoGsT8grO9zQH6RugV14b1GzeFt-htYToHQBJhNvY,186
|
|
30
|
-
gltest_cli/config/plugin.py,sha256=
|
|
30
|
+
gltest_cli/config/plugin.py,sha256=jxmdSBq7A1UPpxL4zolhDX53T8Eo4M8xluAsKx_6MTY,6774
|
|
31
31
|
gltest_cli/config/pytest_context.py,sha256=Ze8JSkrwMTCE8jIhpzU_71CEXg92SiEPvSgNTp-gbS4,243
|
|
32
32
|
gltest_cli/config/types.py,sha256=nGKm2qTwo99M8DbGchj14IdIQ4lcNTDODZFHXdsi5rY,9506
|
|
33
33
|
gltest_cli/config/user.py,sha256=JeclpIVv4BT5COMW2xrEbTspI6e1RAYIOvd8ruPc3gM,12887
|
|
34
|
-
genlayer_test-0.
|
|
35
|
-
genlayer_test-0.
|
|
36
|
-
genlayer_test-0.
|
|
37
|
-
genlayer_test-0.
|
|
38
|
-
genlayer_test-0.
|
|
34
|
+
genlayer_test-0.11.0.dist-info/METADATA,sha256=UugYMl8Xl5qnR6yhNAhR2ZhkpnAfGzeskxnDldfr7Io,43279
|
|
35
|
+
genlayer_test-0.11.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
36
|
+
genlayer_test-0.11.0.dist-info/entry_points.txt,sha256=RWPcSArBpz_G4BYioh5L8Q8hyClRbSgzLimjcWMp-BQ,94
|
|
37
|
+
genlayer_test-0.11.0.dist-info/top_level.txt,sha256=GSdrnQbiLcZssmtCpbDgBTygsc8Bt_TPeYjwm0FmpdA,18
|
|
38
|
+
genlayer_test-0.11.0.dist-info/RECORD,,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2024
|
|
3
|
+
Copyright (c) 2024 GenLayer Labs
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
18
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
21
|
+
SOFTWARE.
|
gltest/types.py
CHANGED
|
@@ -20,6 +20,20 @@ class MockedLLMResponse(TypedDict):
|
|
|
20
20
|
eq_principle_prompt_non_comparative: Dict[str, bool]
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
class MockedWebResponseData(TypedDict):
|
|
24
|
+
"""Mocked web response data with method for matching"""
|
|
25
|
+
|
|
26
|
+
method: str # GET, POST, PUT, DELETE, etc.
|
|
27
|
+
status: int # status code of the response
|
|
28
|
+
body: str # body of the response
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class MockedWebResponse(TypedDict):
|
|
32
|
+
"""Maps urls to responses"""
|
|
33
|
+
|
|
34
|
+
nondet_web_request: Dict[str, MockedWebResponseData]
|
|
35
|
+
|
|
36
|
+
|
|
23
37
|
class ValidatorConfig(TypedDict):
|
|
24
38
|
"""Validator information."""
|
|
25
39
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from gltest.types import MockedLLMResponse
|
|
1
|
+
from gltest.types import MockedLLMResponse, MockedWebResponse
|
|
2
2
|
from dataclasses import dataclass
|
|
3
3
|
from typing import Dict, Any, Optional, List
|
|
4
4
|
from copy import deepcopy
|
|
@@ -16,6 +16,7 @@ class Validator:
|
|
|
16
16
|
# Mock configuration
|
|
17
17
|
mock_enabled: bool
|
|
18
18
|
mock_llm_response: Optional[MockedLLMResponse]
|
|
19
|
+
mock_web_response: Optional[MockedWebResponse]
|
|
19
20
|
|
|
20
21
|
def to_dict(self) -> Dict[str, Any]:
|
|
21
22
|
normal_config = {
|
|
@@ -29,21 +30,27 @@ class Validator:
|
|
|
29
30
|
if not self.mock_enabled:
|
|
30
31
|
return normal_config
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
33
|
+
# Mock llm response
|
|
34
|
+
mock_llm = self.mock_llm_response or {}
|
|
35
|
+
mock_llm_config = {
|
|
36
|
+
"response": mock_llm.get("nondet_exec_prompt", {}),
|
|
37
|
+
"eq_principle_prompt_comparative": mock_llm.get(
|
|
36
38
|
"eq_principle_prompt_comparative", {}
|
|
37
39
|
),
|
|
38
|
-
"eq_principle_prompt_non_comparative":
|
|
40
|
+
"eq_principle_prompt_non_comparative": mock_llm.get(
|
|
39
41
|
"eq_principle_prompt_non_comparative", {}
|
|
40
42
|
),
|
|
41
43
|
}
|
|
44
|
+
mock_web = self.mock_web_response or {}
|
|
45
|
+
mock_web_config = {
|
|
46
|
+
"nondet_web_request": mock_web.get("nondet_web_request", {}),
|
|
47
|
+
}
|
|
42
48
|
return {
|
|
43
49
|
**normal_config,
|
|
44
50
|
"plugin_config": {
|
|
45
51
|
**self.plugin_config,
|
|
46
|
-
"mock_response":
|
|
52
|
+
"mock_response": mock_llm_config,
|
|
53
|
+
"mock_web_response": mock_web_config,
|
|
47
54
|
},
|
|
48
55
|
}
|
|
49
56
|
|
|
@@ -60,6 +67,7 @@ class Validator:
|
|
|
60
67
|
plugin_config=deepcopy(self.plugin_config),
|
|
61
68
|
mock_enabled=self.mock_enabled,
|
|
62
69
|
mock_llm_response=deepcopy(self.mock_llm_response),
|
|
70
|
+
mock_web_response=deepcopy(self.mock_web_response),
|
|
63
71
|
)
|
|
64
72
|
|
|
65
73
|
|
|
@@ -85,6 +93,7 @@ class ValidatorFactory:
|
|
|
85
93
|
plugin_config=deepcopy(plugin_config),
|
|
86
94
|
mock_enabled=False,
|
|
87
95
|
mock_llm_response=None,
|
|
96
|
+
mock_web_response=None,
|
|
88
97
|
)
|
|
89
98
|
|
|
90
99
|
def batch_create_validators(
|
|
@@ -109,7 +118,15 @@ class ValidatorFactory:
|
|
|
109
118
|
for _ in range(count)
|
|
110
119
|
]
|
|
111
120
|
|
|
112
|
-
def create_mock_validator(
|
|
121
|
+
def create_mock_validator(
|
|
122
|
+
self,
|
|
123
|
+
mock_llm_response: Optional[MockedLLMResponse] = None,
|
|
124
|
+
mock_web_response: Optional[MockedWebResponse] = None,
|
|
125
|
+
) -> Validator:
|
|
126
|
+
if mock_llm_response is None and mock_web_response is None:
|
|
127
|
+
raise ValueError(
|
|
128
|
+
"mock_llm_response and mock_web_response cannot both be None"
|
|
129
|
+
)
|
|
113
130
|
return Validator(
|
|
114
131
|
stake=8,
|
|
115
132
|
provider="openai",
|
|
@@ -121,15 +138,24 @@ class ValidatorFactory:
|
|
|
121
138
|
"api_url": "https://api.openai.com",
|
|
122
139
|
},
|
|
123
140
|
mock_enabled=True,
|
|
124
|
-
mock_llm_response=
|
|
141
|
+
mock_llm_response=(
|
|
142
|
+
deepcopy(mock_llm_response) if mock_llm_response is not None else None
|
|
143
|
+
),
|
|
144
|
+
mock_web_response=(
|
|
145
|
+
deepcopy(mock_web_response) if mock_web_response is not None else None
|
|
146
|
+
),
|
|
125
147
|
)
|
|
126
148
|
|
|
127
149
|
def batch_create_mock_validators(
|
|
128
150
|
self,
|
|
129
151
|
count: int,
|
|
130
|
-
mock_llm_response: MockedLLMResponse,
|
|
152
|
+
mock_llm_response: Optional[MockedLLMResponse] = None,
|
|
153
|
+
mock_web_response: Optional[MockedWebResponse] = None,
|
|
131
154
|
) -> List[Validator]:
|
|
132
|
-
return [
|
|
155
|
+
return [
|
|
156
|
+
self.create_mock_validator(mock_llm_response, mock_web_response)
|
|
157
|
+
for _ in range(count)
|
|
158
|
+
]
|
|
133
159
|
|
|
134
160
|
|
|
135
161
|
def get_validator_factory() -> ValidatorFactory:
|
gltest_cli/config/plugin.py
CHANGED
|
@@ -13,8 +13,6 @@ from gltest_cli.config.general import (
|
|
|
13
13
|
from gltest_cli.config.types import PluginConfig
|
|
14
14
|
from gltest_cli.config.pytest_context import _pytest_context
|
|
15
15
|
from gltest_cli.config.constants import (
|
|
16
|
-
DEFAULT_WAIT_INTERVAL,
|
|
17
|
-
DEFAULT_WAIT_RETRIES,
|
|
18
16
|
DEFAULT_LEADER_ONLY,
|
|
19
17
|
CHAINS,
|
|
20
18
|
)
|
|
@@ -39,14 +37,14 @@ def pytest_addoption(parser):
|
|
|
39
37
|
group.addoption(
|
|
40
38
|
"--default-wait-interval",
|
|
41
39
|
action="store",
|
|
42
|
-
default=
|
|
40
|
+
default=None,
|
|
43
41
|
help="Default interval (ms) between transaction receipt checks",
|
|
44
42
|
)
|
|
45
43
|
|
|
46
44
|
group.addoption(
|
|
47
45
|
"--default-wait-retries",
|
|
48
46
|
action="store",
|
|
49
|
-
default=
|
|
47
|
+
default=None,
|
|
50
48
|
help="Default number of retries for transaction receipt checks",
|
|
51
49
|
)
|
|
52
50
|
|
|
@@ -122,8 +120,12 @@ def pytest_configure(config):
|
|
|
122
120
|
plugin_config.artifacts_dir = (
|
|
123
121
|
Path(artifacts_dir) if artifacts_dir is not None else None
|
|
124
122
|
)
|
|
125
|
-
plugin_config.default_wait_interval =
|
|
126
|
-
|
|
123
|
+
plugin_config.default_wait_interval = (
|
|
124
|
+
int(default_wait_interval) if default_wait_interval is not None else None
|
|
125
|
+
)
|
|
126
|
+
plugin_config.default_wait_retries = (
|
|
127
|
+
int(default_wait_retries) if default_wait_retries is not None else None
|
|
128
|
+
)
|
|
127
129
|
plugin_config.rpc_url = rpc_url
|
|
128
130
|
plugin_config.network_name = network
|
|
129
131
|
plugin_config.leader_only = leader_only
|
|
File without changes
|
|
File without changes
|
|
File without changes
|