genlayer-test 0.7.0__tar.gz → 0.9.0__tar.gz

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.
Files changed (87) hide show
  1. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/PKG-INFO +245 -4
  2. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/README.md +243 -2
  3. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/genlayer_test.egg-info/PKG-INFO +245 -4
  4. genlayer_test-0.9.0/genlayer_test.egg-info/SOURCES.txt +41 -0
  5. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/genlayer_test.egg-info/requires.txt +1 -1
  6. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/genlayer_test.egg-info/top_level.txt +0 -2
  7. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/__init__.py +3 -0
  8. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/types.py +12 -1
  9. genlayer_test-0.9.0/gltest/validators/__init__.py +3 -0
  10. genlayer_test-0.9.0/gltest/validators/validator_factory.py +136 -0
  11. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest_cli/config/constants.py +7 -0
  12. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest_cli/config/plugin.py +22 -4
  13. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest_cli/config/types.py +81 -46
  14. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest_cli/config/user.py +95 -7
  15. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/pyproject.toml +3 -2
  16. genlayer_test-0.7.0/genlayer_test.egg-info/SOURCES.txt +0 -82
  17. genlayer_test-0.7.0/tests/__init__.py +0 -0
  18. genlayer_test-0.7.0/tests/conftest.py +0 -1
  19. genlayer_test-0.7.0/tests/examples/contracts/football_prediction_market.py +0 -100
  20. genlayer_test-0.7.0/tests/examples/contracts/intelligent_oracle.py +0 -370
  21. genlayer_test-0.7.0/tests/examples/contracts/intelligent_oracle_factory.py +0 -49
  22. genlayer_test-0.7.0/tests/examples/contracts/invalid_deploy.py +0 -10
  23. genlayer_test-0.7.0/tests/examples/contracts/llm_erc20.py +0 -70
  24. genlayer_test-0.7.0/tests/examples/contracts/log_indexer.py +0 -69
  25. genlayer_test-0.7.0/tests/examples/contracts/multi_file_contract/__init__.py +0 -24
  26. genlayer_test-0.7.0/tests/examples/contracts/multi_file_contract/other.py +0 -14
  27. genlayer_test-0.7.0/tests/examples/contracts/multi_read_erc20.py +0 -29
  28. genlayer_test-0.7.0/tests/examples/contracts/multi_tenant_storage.py +0 -51
  29. genlayer_test-0.7.0/tests/examples/contracts/read_erc20.py +0 -19
  30. genlayer_test-0.7.0/tests/examples/contracts/simple_time_contract.py +0 -85
  31. genlayer_test-0.7.0/tests/examples/contracts/storage.py +0 -23
  32. genlayer_test-0.7.0/tests/examples/contracts/user_storage.py +0 -25
  33. genlayer_test-0.7.0/tests/examples/contracts/wizard_of_coin.py +0 -57
  34. genlayer_test-0.7.0/tests/examples/tests/test_football_prediction_market.py +0 -38
  35. genlayer_test-0.7.0/tests/examples/tests/test_intelligent_oracle_factory.py +0 -162
  36. genlayer_test-0.7.0/tests/examples/tests/test_invalid_deploy.py +0 -24
  37. genlayer_test-0.7.0/tests/examples/tests/test_llm_erc20.py +0 -60
  38. genlayer_test-0.7.0/tests/examples/tests/test_llm_erc20_analyze.py +0 -54
  39. genlayer_test-0.7.0/tests/examples/tests/test_log_indexer.py +0 -76
  40. genlayer_test-0.7.0/tests/examples/tests/test_multi_file_contract.py +0 -15
  41. genlayer_test-0.7.0/tests/examples/tests/test_multi_read_erc20.py +0 -103
  42. genlayer_test-0.7.0/tests/examples/tests/test_multi_tenant_storage.py +0 -76
  43. genlayer_test-0.7.0/tests/examples/tests/test_read_erc20.py +0 -38
  44. genlayer_test-0.7.0/tests/examples/tests/test_simple_time_contract.py +0 -90
  45. genlayer_test-0.7.0/tests/examples/tests/test_storage.py +0 -26
  46. genlayer_test-0.7.0/tests/examples/tests/test_user_storage.py +0 -87
  47. genlayer_test-0.7.0/tests/examples/tests/test_wizard_of_coin.py +0 -27
  48. genlayer_test-0.7.0/tests/gltest/__init__.py +0 -0
  49. genlayer_test-0.7.0/tests/gltest/artifact/__init__.py +0 -0
  50. genlayer_test-0.7.0/tests/gltest/artifact/contracts/duplicate_ic_contract_1.py +0 -22
  51. genlayer_test-0.7.0/tests/gltest/artifact/contracts/duplicate_ic_contract_2.py +0 -22
  52. genlayer_test-0.7.0/tests/gltest/artifact/contracts/not_ic_contract.py +0 -22
  53. genlayer_test-0.7.0/tests/gltest/artifact/test_contract_definition.py +0 -55
  54. genlayer_test-0.7.0/tests/gltest/assertions/test_assertions.py +0 -344
  55. genlayer_test-0.7.0/tests/gltest_cli/__init__.py +0 -0
  56. genlayer_test-0.7.0/tests/gltest_cli/config/test_config_integration.py +0 -432
  57. genlayer_test-0.7.0/tests/gltest_cli/config/test_general_config.py +0 -406
  58. genlayer_test-0.7.0/tests/gltest_cli/config/test_plugin.py +0 -290
  59. genlayer_test-0.7.0/tests/gltest_cli/config/test_user.py +0 -411
  60. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/LICENSE +0 -0
  61. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/genlayer_test.egg-info/dependency_links.txt +0 -0
  62. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/genlayer_test.egg-info/entry_points.txt +0 -0
  63. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/accounts.py +0 -0
  64. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/artifacts/__init__.py +0 -0
  65. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/artifacts/contract.py +0 -0
  66. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/assertions.py +0 -0
  67. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/clients.py +0 -0
  68. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/contracts/__init__.py +0 -0
  69. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/contracts/contract.py +0 -0
  70. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/contracts/contract_factory.py +0 -0
  71. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/contracts/contract_functions.py +0 -0
  72. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/contracts/method_stats.py +0 -0
  73. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/contracts/stats_collector.py +0 -0
  74. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/contracts/utils.py +0 -0
  75. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/exceptions.py +0 -0
  76. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/fixtures.py +0 -0
  77. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/helpers/__init__.py +0 -0
  78. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/helpers/fixture_snapshot.py +0 -0
  79. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/helpers/take_snapshot.py +0 -0
  80. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/logging.py +0 -0
  81. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest/utils.py +0 -0
  82. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest_cli/config/__init__.py +0 -0
  83. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest_cli/config/general.py +0 -0
  84. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest_cli/config/pytest_context.py +0 -0
  85. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest_cli/logging.py +0 -0
  86. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/gltest_cli/main.py +0 -0
  87. {genlayer_test-0.7.0 → genlayer_test-0.9.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: genlayer-test
3
- Version: 0.7.0
3
+ Version: 0.9.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.8.1
18
+ Requires-Dist: genlayer-py==0.9.0
19
19
  Requires-Dist: colorama>=0.4.6
20
20
  Requires-Dist: pyyaml
21
21
  Requires-Dist: python-dotenv
@@ -140,6 +140,7 @@ networks:
140
140
  custom_network: # Custom network configuration
141
141
  id: 1234
142
142
  url: "http://custom.network:8545"
143
+ chain_type: "localnet" # Required for custom networks: localnet, studionet, or testnet_asimov
143
144
  accounts:
144
145
  - "${CUSTOM_ACCOUNT_1}"
145
146
  - "${CUSTOM_ACCOUNT_2}"
@@ -163,10 +164,11 @@ Key configuration sections:
163
164
  - Network configurations can include:
164
165
  - `url`: The RPC endpoint for the network (optional for pre-configured networks)
165
166
  - `id`: Chain ID (optional for pre-configured networks)
167
+ - `chain_type`: Chain type - one of: `localnet`, `studionet`, or `testnet_asimov` (required for custom networks)
166
168
  - `accounts`: List of account private keys (using environment variables)
167
169
  - `from`: Specify which account to use as the default for transactions (optional, defaults to first account)
168
170
  - `leader_only`: Leader only mode
169
- - For custom networks (non-pre-configured), `id`, `url`, and `accounts` are required fields
171
+ - For custom networks (non-pre-configured), `id`, `url`, `chain_type`, and `accounts` are required fields
170
172
 
171
173
  **Note on Environment Variables**: When using environment variables in your configuration (e.g., `${ACCOUNT_PRIVATE_KEY_1}`), ensure they are properly set in your `environment` file. If an environment variable is not found, the system will raise a clear error message indicating which variable is missing.
172
174
 
@@ -182,6 +184,13 @@ testnet_asimov:
182
184
  from: "${ADMIN_KEY}" # Use ADMIN_KEY as default instead of DEPLOYER_KEY
183
185
  ```
184
186
 
187
+ **Chain vs Network**:
188
+ - **Network**: Defines the connection details (URL, accounts, etc.) for a specific environment
189
+ - **Chain**: Defines the genlayer chain type and its associated behaviors (localnet, studionet, or testnet_asimov)
190
+ - Pre-configured networks automatically have the correct chain type set
191
+ - Custom networks must specify the chain type explicitly
192
+ - The `--chain-type` CLI flag can override the chain type for any network, allowing you to test different chain behaviors with the same network configuration
193
+
185
194
  2. **Paths**: Define important directory paths
186
195
  - `contracts`: Location of your contract files
187
196
  - `artifacts`: Location of your artifacts files (analysis results will be stored here)
@@ -299,6 +308,24 @@ When this flag is enabled, all contracts deployed and all write transactions wil
299
308
 
300
309
  **Note:** Leader-only mode is only available for studio-based networks (localhost, 127.0.0.1, *.genlayer.com, *.genlayerlabs.com). When enabled on other networks, it will have no effect and a warning will be logged.
301
310
 
311
+ 12. Override the chain type
312
+ ```bash
313
+ $ gltest --chain-type localnet
314
+ $ gltest --chain-type studionet
315
+ $ gltest --chain-type testnet_asimov
316
+ ```
317
+ The `--chain-type` flag allows you to override the chain type configured for the network. This is useful when:
318
+ - Testing different chain behaviors without changing network configuration
319
+ - Switching between chain types for testing purposes
320
+ - Using a custom network URL with a specific chain type
321
+
322
+ Available chain types:
323
+ - `localnet`: Local development chain
324
+ - `studionet`: Studio-based chain
325
+ - `testnet_asimov`: Testnet Asimov chain
326
+
327
+ The chain type determines various behaviors including RPC endpoints, consensus mechanisms, and available features. When specified, this flag overrides the chain type configured in your network settings.
328
+
302
329
  ## 🚀 Key Features
303
330
 
304
331
  - **Pytest Integration** – Extends pytest to support intelligent contract testing, making it familiar and easy to adopt.
@@ -308,6 +335,7 @@ When this flag is enabled, all contracts deployed and all write transactions wil
308
335
  - **State Injection & Consensus Simulation** – Modify contract states dynamically and simulate consensus scenarios for advanced testing.
309
336
  - **Prompt Testing & Statistical Analysis** – Evaluate and statistically test prompts for AI-driven contract execution.
310
337
  - **Scalability to Security & Audit Tools** – Designed to extend into security testing and smart contract auditing.
338
+ - **Custom Transaction Context** – Set custom validators with specific LLM providers and models, and configure GenVM datetime for deterministic testing scenarios.
311
339
 
312
340
  ## 📚 Examples
313
341
 
@@ -387,6 +415,7 @@ def test_deployment():
387
415
  args=["initial_value"], # Constructor arguments
388
416
  account=get_default_account(), # Account to deploy from
389
417
  consensus_max_rotations=3, # Optional: max consensus rotations
418
+ transaction_context=None, # Optional: custom transaction context
390
419
  )
391
420
 
392
421
  # Contract is now deployed and ready to use
@@ -419,7 +448,9 @@ def test_read_methods():
419
448
  contract = factory.deploy()
420
449
 
421
450
  # Call a read-only method
422
- result = contract.get_storage(args=[]).call()
451
+ result = contract.get_storage(args=[]).call(
452
+ transaction_context=None, # Optional: custom transaction context
453
+ )
423
454
 
424
455
  # Assert the result matches the initial value
425
456
  assert result == "initial_value"
@@ -446,6 +477,7 @@ def test_write_methods():
446
477
  consensus_max_rotations=3, # Optional: max consensus rotations
447
478
  wait_interval=1, # Optional: seconds between status checks
448
479
  wait_retries=10, # Optional: max number of retries
480
+ transaction_context=None, # Optional: custom transaction context
449
481
  )
450
482
 
451
483
  # Verify the transaction was successful
@@ -609,6 +641,7 @@ def test_analyze_method():
609
641
  config=None, # Optional: provider-specific config
610
642
  plugin=None, # Optional: plugin name
611
643
  plugin_config=None, # Optional: plugin configuration
644
+ genvm_datetime="2024-01-15T10:30:00Z", # Optional: GenVM datetime in ISO format
612
645
  )
613
646
 
614
647
  # Access analysis results
@@ -757,6 +790,214 @@ def test_with_mocked_llm(setup_validators):
757
790
  - The `setup_validators` fixture handles the mock setup when provided with a mock_response
758
791
  - Mocking is particularly useful for CI/CD pipelines where deterministic results are required
759
792
 
793
+ ### Custom Transaction Context
794
+
795
+ 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.
796
+
797
+ #### Using Transaction Context
798
+
799
+ Set custom validators and GenVM datetime for deterministic testing:
800
+
801
+ ```python
802
+ from gltest import get_contract_factory, get_validator_factory
803
+
804
+ def test_with_custom_transaction_context():
805
+ factory = get_contract_factory("MyContract")
806
+ validator_factory = get_validator_factory()
807
+
808
+ # Create custom validators
809
+ validators = validator_factory.batch_create_validators(
810
+ count=3,
811
+ stake=10,
812
+ provider="openai",
813
+ model="gpt-4o",
814
+ config={"temperature": 0.7, "max_tokens": 1000},
815
+ plugin="openai-compatible",
816
+ plugin_config={"api_key_env_var": "OPENAI_API_KEY"}
817
+ )
818
+
819
+ # Create transaction context with custom validators and datetime
820
+ transaction_context = {
821
+ "validators": [v.to_dict() for v in validators],
822
+ "genvm_datetime": "2024-03-15T14:30:00Z" # ISO format datetime
823
+ }
824
+
825
+ # Deploy with custom context
826
+ contract = factory.deploy(
827
+ args=["initial_value"],
828
+ transaction_context=transaction_context
829
+ )
830
+
831
+ # Call methods with custom context
832
+ result = contract.read_method().call(
833
+ transaction_context=transaction_context
834
+ )
835
+
836
+ # Write operations with custom context
837
+ tx_receipt = contract.write_method(args=["value"]).transact(
838
+ transaction_context=transaction_context
839
+ )
840
+ ```
841
+
842
+ #### Mock Validators with Transaction Context
843
+
844
+ Combine mock validators with custom datetime for fully deterministic tests:
845
+
846
+ ```python
847
+ def test_with_mocked_context():
848
+ factory = get_contract_factory("LLMContract")
849
+ validator_factory = get_validator_factory()
850
+
851
+ # Define mock LLM responses
852
+ mock_response = {
853
+ "nondet_exec_prompt": {
854
+ "analyze this": "positive sentiment"
855
+ },
856
+ "eq_principle_prompt_comparative": {
857
+ "values match": True
858
+ }
859
+ }
860
+
861
+ # Create mock validators
862
+ mock_validators = validator_factory.batch_create_mock_validators(
863
+ count=5,
864
+ mock_llm_response=mock_response
865
+ )
866
+
867
+ # Set up deterministic context
868
+ transaction_context = {
869
+ "validators": [v.to_dict() for v in mock_validators],
870
+ "genvm_datetime": "2024-01-01T00:00:00Z" # Fixed datetime for reproducibility
871
+ }
872
+
873
+ # Deploy and test with deterministic context
874
+ contract = factory.deploy(transaction_context=transaction_context)
875
+
876
+ # All operations will use the same mocked validators and datetime
877
+ result = contract.analyze_text(args=["analyze this"]).transact(
878
+ transaction_context=transaction_context
879
+ )
880
+ # Result will consistently return "positive sentiment"
881
+ ```
882
+
883
+ ### Custom Validators
884
+
885
+ The GenLayer Testing Suite includes a `get_validator_factory()` function that allows you to create custom validators with specific configurations for testing different LLM providers and consensus scenarios.
886
+
887
+ #### Creating Custom Validators
888
+
889
+ ```python
890
+ from gltest import get_validator_factory
891
+
892
+ def test_with_custom_validators():
893
+ factory = get_validator_factory()
894
+
895
+ # Create validators with different LLM providers
896
+ openai_validator = factory.create_validator(
897
+ stake=10,
898
+ provider="openai",
899
+ model="gpt-4o",
900
+ config={"temperature": 0.8, "max_tokens": 2000},
901
+ plugin="openai-compatible",
902
+ plugin_config={"api_key_env_var": "OPENAI_API_KEY"}
903
+ )
904
+
905
+ ollama_validator = factory.create_validator(
906
+ stake=8,
907
+ provider="ollama",
908
+ model="mistral",
909
+ config={"temperature": 0.5},
910
+ plugin="ollama",
911
+ plugin_config={"api_url": "http://localhost:11434"}
912
+ )
913
+
914
+ # Use validators in your tests
915
+ validators = [openai_validator, ollama_validator]
916
+ # Configure your test environment with these validators
917
+ ```
918
+
919
+ #### Batch Creation
920
+
921
+ Create multiple validators with the same configuration:
922
+
923
+ ```python
924
+ def test_batch_validators():
925
+ factory = get_validator_factory()
926
+
927
+ # Create 5 validators with identical configuration
928
+ validators = factory.batch_create_validators(
929
+ count=5,
930
+ stake=8,
931
+ provider="openai",
932
+ model="gpt-4o",
933
+ config={"temperature": 0.7, "max_tokens": 1000},
934
+ plugin="openai-compatible",
935
+ plugin_config={"api_key_env_var": "OPENAI_API_KEY"}
936
+ )
937
+ ```
938
+
939
+ #### Mock Validators
940
+
941
+ For deterministic testing, create mock validators that return predefined responses:
942
+
943
+ ```python
944
+ def test_with_mock_validators():
945
+ factory = get_validator_factory()
946
+
947
+ # Define mock responses
948
+ mock_response = {
949
+ "nondet_exec_prompt": {
950
+ "What is 2+2?": "4",
951
+ "Explain quantum physics": "It's complicated"
952
+ },
953
+ "eq_principle_prompt_comparative": {
954
+ "values must match": True
955
+ },
956
+ "eq_principle_prompt_non_comparative": {
957
+ "Is this valid?": True
958
+ }
959
+ }
960
+
961
+ # Create a single mock validator
962
+ mock_validator = factory.create_mock_validator(mock_response)
963
+
964
+ # Create multiple mock validators
965
+ mock_validators = factory.batch_create_mock_validators(
966
+ count=5,
967
+ mock_llm_response=mock_response
968
+ )
969
+ ```
970
+
971
+ #### Validator Methods
972
+
973
+ Each validator object provides useful methods:
974
+ - `to_dict()`: Convert validator to dictionary format for API calls
975
+ - `clone()`: Create an identical copy of the validator
976
+ - `batch_clone(count)`: Create multiple identical copies
977
+
978
+ Example:
979
+ ```python
980
+ def test_validator_cloning():
981
+ factory = get_validator_factory()
982
+
983
+ # Create a base validator
984
+ base_validator = factory.create_validator(
985
+ stake=10,
986
+ provider="openai",
987
+ model="gpt-4o",
988
+ config={"temperature": 0.7},
989
+ plugin="openai-compatible",
990
+ plugin_config={"api_key_env_var": "OPENAI_API_KEY"}
991
+ )
992
+
993
+ # Clone it to create identical validators
994
+ cloned = base_validator.clone()
995
+ multiple_clones = base_validator.batch_clone(3)
996
+
997
+ # Convert to dictionary for API usage
998
+ validator_dict = base_validator.to_dict()
999
+ ```
1000
+
760
1001
  ## 📝 Best Practices
761
1002
 
762
1003
  1. **Test Organization**
@@ -117,6 +117,7 @@ networks:
117
117
  custom_network: # Custom network configuration
118
118
  id: 1234
119
119
  url: "http://custom.network:8545"
120
+ chain_type: "localnet" # Required for custom networks: localnet, studionet, or testnet_asimov
120
121
  accounts:
121
122
  - "${CUSTOM_ACCOUNT_1}"
122
123
  - "${CUSTOM_ACCOUNT_2}"
@@ -140,10 +141,11 @@ Key configuration sections:
140
141
  - Network configurations can include:
141
142
  - `url`: The RPC endpoint for the network (optional for pre-configured networks)
142
143
  - `id`: Chain ID (optional for pre-configured networks)
144
+ - `chain_type`: Chain type - one of: `localnet`, `studionet`, or `testnet_asimov` (required for custom networks)
143
145
  - `accounts`: List of account private keys (using environment variables)
144
146
  - `from`: Specify which account to use as the default for transactions (optional, defaults to first account)
145
147
  - `leader_only`: Leader only mode
146
- - For custom networks (non-pre-configured), `id`, `url`, and `accounts` are required fields
148
+ - For custom networks (non-pre-configured), `id`, `url`, `chain_type`, and `accounts` are required fields
147
149
 
148
150
  **Note on Environment Variables**: When using environment variables in your configuration (e.g., `${ACCOUNT_PRIVATE_KEY_1}`), ensure they are properly set in your `environment` file. If an environment variable is not found, the system will raise a clear error message indicating which variable is missing.
149
151
 
@@ -159,6 +161,13 @@ testnet_asimov:
159
161
  from: "${ADMIN_KEY}" # Use ADMIN_KEY as default instead of DEPLOYER_KEY
160
162
  ```
161
163
 
164
+ **Chain vs Network**:
165
+ - **Network**: Defines the connection details (URL, accounts, etc.) for a specific environment
166
+ - **Chain**: Defines the genlayer chain type and its associated behaviors (localnet, studionet, or testnet_asimov)
167
+ - Pre-configured networks automatically have the correct chain type set
168
+ - Custom networks must specify the chain type explicitly
169
+ - The `--chain-type` CLI flag can override the chain type for any network, allowing you to test different chain behaviors with the same network configuration
170
+
162
171
  2. **Paths**: Define important directory paths
163
172
  - `contracts`: Location of your contract files
164
173
  - `artifacts`: Location of your artifacts files (analysis results will be stored here)
@@ -276,6 +285,24 @@ When this flag is enabled, all contracts deployed and all write transactions wil
276
285
 
277
286
  **Note:** Leader-only mode is only available for studio-based networks (localhost, 127.0.0.1, *.genlayer.com, *.genlayerlabs.com). When enabled on other networks, it will have no effect and a warning will be logged.
278
287
 
288
+ 12. Override the chain type
289
+ ```bash
290
+ $ gltest --chain-type localnet
291
+ $ gltest --chain-type studionet
292
+ $ gltest --chain-type testnet_asimov
293
+ ```
294
+ The `--chain-type` flag allows you to override the chain type configured for the network. This is useful when:
295
+ - Testing different chain behaviors without changing network configuration
296
+ - Switching between chain types for testing purposes
297
+ - Using a custom network URL with a specific chain type
298
+
299
+ Available chain types:
300
+ - `localnet`: Local development chain
301
+ - `studionet`: Studio-based chain
302
+ - `testnet_asimov`: Testnet Asimov chain
303
+
304
+ The chain type determines various behaviors including RPC endpoints, consensus mechanisms, and available features. When specified, this flag overrides the chain type configured in your network settings.
305
+
279
306
  ## 🚀 Key Features
280
307
 
281
308
  - **Pytest Integration** – Extends pytest to support intelligent contract testing, making it familiar and easy to adopt.
@@ -285,6 +312,7 @@ When this flag is enabled, all contracts deployed and all write transactions wil
285
312
  - **State Injection & Consensus Simulation** – Modify contract states dynamically and simulate consensus scenarios for advanced testing.
286
313
  - **Prompt Testing & Statistical Analysis** – Evaluate and statistically test prompts for AI-driven contract execution.
287
314
  - **Scalability to Security & Audit Tools** – Designed to extend into security testing and smart contract auditing.
315
+ - **Custom Transaction Context** – Set custom validators with specific LLM providers and models, and configure GenVM datetime for deterministic testing scenarios.
288
316
 
289
317
  ## 📚 Examples
290
318
 
@@ -364,6 +392,7 @@ def test_deployment():
364
392
  args=["initial_value"], # Constructor arguments
365
393
  account=get_default_account(), # Account to deploy from
366
394
  consensus_max_rotations=3, # Optional: max consensus rotations
395
+ transaction_context=None, # Optional: custom transaction context
367
396
  )
368
397
 
369
398
  # Contract is now deployed and ready to use
@@ -396,7 +425,9 @@ def test_read_methods():
396
425
  contract = factory.deploy()
397
426
 
398
427
  # Call a read-only method
399
- result = contract.get_storage(args=[]).call()
428
+ result = contract.get_storage(args=[]).call(
429
+ transaction_context=None, # Optional: custom transaction context
430
+ )
400
431
 
401
432
  # Assert the result matches the initial value
402
433
  assert result == "initial_value"
@@ -423,6 +454,7 @@ def test_write_methods():
423
454
  consensus_max_rotations=3, # Optional: max consensus rotations
424
455
  wait_interval=1, # Optional: seconds between status checks
425
456
  wait_retries=10, # Optional: max number of retries
457
+ transaction_context=None, # Optional: custom transaction context
426
458
  )
427
459
 
428
460
  # Verify the transaction was successful
@@ -586,6 +618,7 @@ def test_analyze_method():
586
618
  config=None, # Optional: provider-specific config
587
619
  plugin=None, # Optional: plugin name
588
620
  plugin_config=None, # Optional: plugin configuration
621
+ genvm_datetime="2024-01-15T10:30:00Z", # Optional: GenVM datetime in ISO format
589
622
  )
590
623
 
591
624
  # Access analysis results
@@ -734,6 +767,214 @@ def test_with_mocked_llm(setup_validators):
734
767
  - The `setup_validators` fixture handles the mock setup when provided with a mock_response
735
768
  - Mocking is particularly useful for CI/CD pipelines where deterministic results are required
736
769
 
770
+ ### Custom Transaction Context
771
+
772
+ 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.
773
+
774
+ #### Using Transaction Context
775
+
776
+ Set custom validators and GenVM datetime for deterministic testing:
777
+
778
+ ```python
779
+ from gltest import get_contract_factory, get_validator_factory
780
+
781
+ def test_with_custom_transaction_context():
782
+ factory = get_contract_factory("MyContract")
783
+ validator_factory = get_validator_factory()
784
+
785
+ # Create custom validators
786
+ validators = validator_factory.batch_create_validators(
787
+ count=3,
788
+ stake=10,
789
+ provider="openai",
790
+ model="gpt-4o",
791
+ config={"temperature": 0.7, "max_tokens": 1000},
792
+ plugin="openai-compatible",
793
+ plugin_config={"api_key_env_var": "OPENAI_API_KEY"}
794
+ )
795
+
796
+ # Create transaction context with custom validators and datetime
797
+ transaction_context = {
798
+ "validators": [v.to_dict() for v in validators],
799
+ "genvm_datetime": "2024-03-15T14:30:00Z" # ISO format datetime
800
+ }
801
+
802
+ # Deploy with custom context
803
+ contract = factory.deploy(
804
+ args=["initial_value"],
805
+ transaction_context=transaction_context
806
+ )
807
+
808
+ # Call methods with custom context
809
+ result = contract.read_method().call(
810
+ transaction_context=transaction_context
811
+ )
812
+
813
+ # Write operations with custom context
814
+ tx_receipt = contract.write_method(args=["value"]).transact(
815
+ transaction_context=transaction_context
816
+ )
817
+ ```
818
+
819
+ #### Mock Validators with Transaction Context
820
+
821
+ Combine mock validators with custom datetime for fully deterministic tests:
822
+
823
+ ```python
824
+ def test_with_mocked_context():
825
+ factory = get_contract_factory("LLMContract")
826
+ validator_factory = get_validator_factory()
827
+
828
+ # Define mock LLM responses
829
+ mock_response = {
830
+ "nondet_exec_prompt": {
831
+ "analyze this": "positive sentiment"
832
+ },
833
+ "eq_principle_prompt_comparative": {
834
+ "values match": True
835
+ }
836
+ }
837
+
838
+ # Create mock validators
839
+ mock_validators = validator_factory.batch_create_mock_validators(
840
+ count=5,
841
+ mock_llm_response=mock_response
842
+ )
843
+
844
+ # Set up deterministic context
845
+ transaction_context = {
846
+ "validators": [v.to_dict() for v in mock_validators],
847
+ "genvm_datetime": "2024-01-01T00:00:00Z" # Fixed datetime for reproducibility
848
+ }
849
+
850
+ # Deploy and test with deterministic context
851
+ contract = factory.deploy(transaction_context=transaction_context)
852
+
853
+ # All operations will use the same mocked validators and datetime
854
+ result = contract.analyze_text(args=["analyze this"]).transact(
855
+ transaction_context=transaction_context
856
+ )
857
+ # Result will consistently return "positive sentiment"
858
+ ```
859
+
860
+ ### Custom Validators
861
+
862
+ The GenLayer Testing Suite includes a `get_validator_factory()` function that allows you to create custom validators with specific configurations for testing different LLM providers and consensus scenarios.
863
+
864
+ #### Creating Custom Validators
865
+
866
+ ```python
867
+ from gltest import get_validator_factory
868
+
869
+ def test_with_custom_validators():
870
+ factory = get_validator_factory()
871
+
872
+ # Create validators with different LLM providers
873
+ openai_validator = factory.create_validator(
874
+ stake=10,
875
+ provider="openai",
876
+ model="gpt-4o",
877
+ config={"temperature": 0.8, "max_tokens": 2000},
878
+ plugin="openai-compatible",
879
+ plugin_config={"api_key_env_var": "OPENAI_API_KEY"}
880
+ )
881
+
882
+ ollama_validator = factory.create_validator(
883
+ stake=8,
884
+ provider="ollama",
885
+ model="mistral",
886
+ config={"temperature": 0.5},
887
+ plugin="ollama",
888
+ plugin_config={"api_url": "http://localhost:11434"}
889
+ )
890
+
891
+ # Use validators in your tests
892
+ validators = [openai_validator, ollama_validator]
893
+ # Configure your test environment with these validators
894
+ ```
895
+
896
+ #### Batch Creation
897
+
898
+ Create multiple validators with the same configuration:
899
+
900
+ ```python
901
+ def test_batch_validators():
902
+ factory = get_validator_factory()
903
+
904
+ # Create 5 validators with identical configuration
905
+ validators = factory.batch_create_validators(
906
+ count=5,
907
+ stake=8,
908
+ provider="openai",
909
+ model="gpt-4o",
910
+ config={"temperature": 0.7, "max_tokens": 1000},
911
+ plugin="openai-compatible",
912
+ plugin_config={"api_key_env_var": "OPENAI_API_KEY"}
913
+ )
914
+ ```
915
+
916
+ #### Mock Validators
917
+
918
+ For deterministic testing, create mock validators that return predefined responses:
919
+
920
+ ```python
921
+ def test_with_mock_validators():
922
+ factory = get_validator_factory()
923
+
924
+ # Define mock responses
925
+ mock_response = {
926
+ "nondet_exec_prompt": {
927
+ "What is 2+2?": "4",
928
+ "Explain quantum physics": "It's complicated"
929
+ },
930
+ "eq_principle_prompt_comparative": {
931
+ "values must match": True
932
+ },
933
+ "eq_principle_prompt_non_comparative": {
934
+ "Is this valid?": True
935
+ }
936
+ }
937
+
938
+ # Create a single mock validator
939
+ mock_validator = factory.create_mock_validator(mock_response)
940
+
941
+ # Create multiple mock validators
942
+ mock_validators = factory.batch_create_mock_validators(
943
+ count=5,
944
+ mock_llm_response=mock_response
945
+ )
946
+ ```
947
+
948
+ #### Validator Methods
949
+
950
+ Each validator object provides useful methods:
951
+ - `to_dict()`: Convert validator to dictionary format for API calls
952
+ - `clone()`: Create an identical copy of the validator
953
+ - `batch_clone(count)`: Create multiple identical copies
954
+
955
+ Example:
956
+ ```python
957
+ def test_validator_cloning():
958
+ factory = get_validator_factory()
959
+
960
+ # Create a base validator
961
+ base_validator = factory.create_validator(
962
+ stake=10,
963
+ provider="openai",
964
+ model="gpt-4o",
965
+ config={"temperature": 0.7},
966
+ plugin="openai-compatible",
967
+ plugin_config={"api_key_env_var": "OPENAI_API_KEY"}
968
+ )
969
+
970
+ # Clone it to create identical validators
971
+ cloned = base_validator.clone()
972
+ multiple_clones = base_validator.batch_clone(3)
973
+
974
+ # Convert to dictionary for API usage
975
+ validator_dict = base_validator.to_dict()
976
+ ```
977
+
737
978
  ## 📝 Best Practices
738
979
 
739
980
  1. **Test Organization**