genlayer-test 2.1.0__py3-none-any.whl → 2.2.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-2.1.0.dist-info → genlayer_test-2.2.0.dist-info}/METADATA +52 -11
- {genlayer_test-2.1.0.dist-info → genlayer_test-2.2.0.dist-info}/RECORD +12 -12
- gltest_cli/config/constants.py +1 -0
- gltest_cli/config/plugin.py +90 -71
- gltest_cli/config/types.py +32 -8
- gltest_cli/config/user.py +51 -21
- gltest_cli/logging.py +3 -2
- tests/gltest_cli/config/test_plugin.py +2 -6
- {genlayer_test-2.1.0.dist-info → genlayer_test-2.2.0.dist-info}/WHEEL +0 -0
- {genlayer_test-2.1.0.dist-info → genlayer_test-2.2.0.dist-info}/entry_points.txt +0 -0
- {genlayer_test-2.1.0.dist-info → genlayer_test-2.2.0.dist-info}/licenses/LICENSE +0 -0
- {genlayer_test-2.1.0.dist-info → genlayer_test-2.2.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: 2.
|
3
|
+
Version: 2.2.0
|
4
4
|
Summary: GenLayer Testing Suite
|
5
5
|
Author: GenLayer
|
6
6
|
License-Expression: MIT
|
@@ -112,17 +112,29 @@ The GenLayer Testing Suite can be configured using an optional but recommended `
|
|
112
112
|
networks:
|
113
113
|
default: localnet # Default network to use
|
114
114
|
|
115
|
-
localnet: # Local development network configuration
|
115
|
+
localnet: # Local development network configuration (pre-configured)
|
116
116
|
url: "http://127.0.0.1:4000/api"
|
117
117
|
leader_only: false # Set to true to run all contracts in leader-only mode by default
|
118
118
|
|
119
|
-
|
120
|
-
|
121
|
-
|
119
|
+
studionet: # Studio network configuration (pre-configured)
|
120
|
+
# Pre-configured network - accounts are automatically generated
|
121
|
+
# You can override any settings if needed
|
122
|
+
|
123
|
+
testnet_asimov: # Test network configuration (pre-configured)
|
124
|
+
# Pre-configured network - requires accounts to be specified
|
122
125
|
accounts:
|
123
126
|
- "${ACCOUNT_PRIVATE_KEY_1}"
|
124
127
|
- "${ACCOUNT_PRIVATE_KEY_2}"
|
125
128
|
- "${ACCOUNT_PRIVATE_KEY_3}"
|
129
|
+
from: "${ACCOUNT_PRIVATE_KEY_2}" # Optional: specify default account
|
130
|
+
|
131
|
+
custom_network: # Custom network configuration
|
132
|
+
id: 1234
|
133
|
+
url: "http://custom.network:8545"
|
134
|
+
accounts:
|
135
|
+
- "${CUSTOM_ACCOUNT_1}"
|
136
|
+
- "${CUSTOM_ACCOUNT_2}"
|
137
|
+
from: "${CUSTOM_ACCOUNT_1}" # Optional: specify default account
|
126
138
|
|
127
139
|
paths:
|
128
140
|
contracts: "contracts" # Path to your contracts directory
|
@@ -135,14 +147,31 @@ Key configuration sections:
|
|
135
147
|
|
136
148
|
1. **Networks**: Define different network environments
|
137
149
|
- `default`: Specifies which network to use by default
|
150
|
+
- **Pre-configured Networks**:
|
151
|
+
- `localnet`: Local development network with auto-generated test accounts
|
152
|
+
- `studionet`: GenLayer Studio network with auto-generated test accounts
|
153
|
+
- `testnet_asimov`: Public testnet (requires account configuration)
|
138
154
|
- Network configurations can include:
|
139
|
-
- `url`: The RPC endpoint for the network
|
140
|
-
- `id`: Chain ID
|
155
|
+
- `url`: The RPC endpoint for the network (optional for pre-configured networks)
|
156
|
+
- `id`: Chain ID (optional for pre-configured networks)
|
141
157
|
- `accounts`: List of account private keys (using environment variables)
|
158
|
+
- `from`: Specify which account to use as the default for transactions (optional, defaults to first account)
|
142
159
|
- `leader_only`: Leader only mode
|
143
|
-
-
|
144
|
-
|
145
|
-
|
160
|
+
- For custom networks (non-pre-configured), `id`, `url`, and `accounts` are required fields
|
161
|
+
|
162
|
+
**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.
|
163
|
+
|
164
|
+
**Default Account Selection**: The `from` field allows you to specify which account from the `accounts` list should be used as the default for deployments and transactions. If not specified, the first account in the list is used by default. This is useful when you want a specific account to be the primary account for your tests without having to specify it in every transaction.
|
165
|
+
|
166
|
+
Example:
|
167
|
+
```yaml
|
168
|
+
testnet_asimov:
|
169
|
+
accounts:
|
170
|
+
- "${DEPLOYER_KEY}" # accounts[0]
|
171
|
+
- "${USER_KEY}" # accounts[1]
|
172
|
+
- "${ADMIN_KEY}" # accounts[2]
|
173
|
+
from: "${ADMIN_KEY}" # Use ADMIN_KEY as default instead of DEPLOYER_KEY
|
174
|
+
```
|
146
175
|
|
147
176
|
2. **Paths**: Define important directory paths
|
148
177
|
- `contracts`: Location of your contract files
|
@@ -191,11 +220,23 @@ $ gltest --contracts-dir <path_to_contracts>
|
|
191
220
|
# Run tests on localnet (default)
|
192
221
|
$ gltest --network localnet
|
193
222
|
|
194
|
-
# Run tests on
|
223
|
+
# Run tests on studionet
|
224
|
+
$ gltest --network studionet
|
225
|
+
|
226
|
+
# Run tests on testnet (requires account configuration)
|
195
227
|
$ gltest --network testnet_asimov
|
228
|
+
|
229
|
+
# Run tests on a custom network
|
230
|
+
$ gltest --network custom_network
|
196
231
|
```
|
197
232
|
The `--network` flag allows you to specify which network configuration to use from your `gltest.config.yaml`. If not specified, it will use the `default` network defined in your config file.
|
198
233
|
|
234
|
+
**Pre-configured Networks**:
|
235
|
+
- `localnet` and `studionet`: Work out of the box with auto-generated test accounts
|
236
|
+
- `testnet_asimov`: Requires account configuration in `gltest.config.yaml`
|
237
|
+
|
238
|
+
When using `testnet_asimov` without proper account configuration, you'll receive a clear error message directing you to configure accounts in your config file.
|
239
|
+
|
199
240
|
7. Run tests with a custom RPC url
|
200
241
|
```bash
|
201
242
|
$ gltest --rpc-url <custom_rpc_url>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
genlayer_test-2.
|
1
|
+
genlayer_test-2.2.0.dist-info/licenses/LICENSE,sha256=che_H4vE0QUx3HvWrAa1_jDEVInift0U6VO15-QqEls,1064
|
2
2
|
gltest/__init__.py,sha256=qoBV3IgDJr8uh9262XsWNMhi-ilkSgMqKVC9FVMk7cw,372
|
3
3
|
gltest/accounts.py,sha256=HUmWguJMolggQaZNRPw-LGlRlQCjLLdUanKRowMv6pI,812
|
4
4
|
gltest/assertions.py,sha256=0dEk0VxcHK4I7GZPHxJmz-2jaA60V499gOSR74rZbfM,1748
|
@@ -19,15 +19,15 @@ gltest/contracts/utils.py,sha256=TTXgcXn9BuRIlKJrjwmU7R3l1IgXsXk2luM-r3lfbbg,296
|
|
19
19
|
gltest/helpers/__init__.py,sha256=I7HiTu_H7_hP65zY6Wl02r-5eAMr2eZvqBVmusuQLX4,180
|
20
20
|
gltest/helpers/fixture_snapshot.py,sha256=bMgvlEVQBGIQzj7NOyosXWlphI1H2C1o75Zo0C-kGfQ,1931
|
21
21
|
gltest/helpers/take_snapshot.py,sha256=-QkaBvFG4ZsNKv_nCSEsy5Ze1pICOHxVhReSeQmZUlY,1276
|
22
|
-
gltest_cli/logging.py,sha256=
|
22
|
+
gltest_cli/logging.py,sha256=WXVhfq9vT6FtV_jxDqGEGia1ZWSIUKAfmWRnZd_gWQk,1266
|
23
23
|
gltest_cli/main.py,sha256=Ti2-0Ev1x5_cM0D1UKqdgaDt80CDHEQGtdRne2qLm4M,53
|
24
24
|
gltest_cli/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
25
|
-
gltest_cli/config/constants.py,sha256=
|
25
|
+
gltest_cli/config/constants.py,sha256=LG74S_65OXhqweL__PGRV6Ms8UkMFYSeK7Sq88viBis,411
|
26
26
|
gltest_cli/config/general.py,sha256=ezpoGsT8grO9zQH6RugV14b1GzeFt-htYToHQBJhNvY,186
|
27
|
-
gltest_cli/config/plugin.py,sha256=
|
27
|
+
gltest_cli/config/plugin.py,sha256=TsK3JnKKz_9azASHcKKSY5ohCl5TmxVUk_YEGIc4A28,6469
|
28
28
|
gltest_cli/config/pytest_context.py,sha256=Ze8JSkrwMTCE8jIhpzU_71CEXg92SiEPvSgNTp-gbS4,243
|
29
|
-
gltest_cli/config/types.py,sha256=
|
30
|
-
gltest_cli/config/user.py,sha256=
|
29
|
+
gltest_cli/config/types.py,sha256=0x8I-Xvzul9lGkPL0GusxJPhJCNajx-ghm0N-V5P594,8206
|
30
|
+
gltest_cli/config/user.py,sha256=SXGWQnA6422vRhQ9Xwxuzts7ZARcBIJZcRFSxN56PV4,9970
|
31
31
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
32
32
|
tests/conftest.py,sha256=RKdoE5_zcMimeojAoA_GSFI9du4pMzMi1vZ1njtfoAs,28
|
33
33
|
tests/examples/contracts/football_prediction_market.py,sha256=9xwU8f3q73Hae-ByHy_wauhMPLRnLZd4XKNrClnjOJM,3248
|
@@ -67,10 +67,10 @@ tests/gltest/assertions/test_assertions.py,sha256=qzVrOdOM4xYtIy1sFHVAD_-naDHOeq
|
|
67
67
|
tests/gltest_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
68
68
|
tests/gltest_cli/config/test_config_integration.py,sha256=vPTzr3_h9UMw7m72HogBJE2ZPhRduXoLSq18Z7FoCWQ,10105
|
69
69
|
tests/gltest_cli/config/test_general_config.py,sha256=UHtSwVnso-ZwNtYM0Z4v2sCLKwyrVbHlk6b1leVfV84,14703
|
70
|
-
tests/gltest_cli/config/test_plugin.py,sha256=
|
70
|
+
tests/gltest_cli/config/test_plugin.py,sha256=COrEK5tHP1BSzanWbZHmN3EQgE9VuTcPvB95pgOvKS4,7974
|
71
71
|
tests/gltest_cli/config/test_user.py,sha256=JxR655oUFoM9quWQO68CVPKRpT0TMpzS3bF6j6NWyT4,14401
|
72
|
-
genlayer_test-2.
|
73
|
-
genlayer_test-2.
|
74
|
-
genlayer_test-2.
|
75
|
-
genlayer_test-2.
|
76
|
-
genlayer_test-2.
|
72
|
+
genlayer_test-2.2.0.dist-info/METADATA,sha256=FFJ-Iqp1o4mrYhzyYrvGU6N3Fgn0KcfZWhnQjXlXKC0,27320
|
73
|
+
genlayer_test-2.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
74
|
+
genlayer_test-2.2.0.dist-info/entry_points.txt,sha256=RWPcSArBpz_G4BYioh5L8Q8hyClRbSgzLimjcWMp-BQ,94
|
75
|
+
genlayer_test-2.2.0.dist-info/top_level.txt,sha256=-qiGZxTRBytujzgVcKpxjvQ-WNeUDjXa59ceGMwMpko,24
|
76
|
+
genlayer_test-2.2.0.dist-info/RECORD,,
|
gltest_cli/config/constants.py
CHANGED
@@ -4,6 +4,7 @@ from pathlib import Path
|
|
4
4
|
|
5
5
|
GLTEST_CONFIG_FILE = "gltest.config.yaml"
|
6
6
|
DEFAULT_NETWORK = "localnet"
|
7
|
+
PRECONFIGURED_NETWORKS = ["localnet", "studionet", "testnet_asimov"]
|
7
8
|
DEFAULT_RPC_URL = SIMULATOR_JSON_RPC_URL
|
8
9
|
DEFAULT_ENVIRONMENT = ".env"
|
9
10
|
DEFAULT_CONTRACTS_DIR = Path("contracts")
|
gltest_cli/config/plugin.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import pytest
|
1
2
|
from pathlib import Path
|
2
3
|
import shutil
|
3
4
|
from gltest_cli.logging import logger
|
@@ -73,85 +74,103 @@ def pytest_addoption(parser):
|
|
73
74
|
|
74
75
|
|
75
76
|
def pytest_configure(config):
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
77
|
+
try:
|
78
|
+
general_config = get_general_config()
|
79
|
+
|
80
|
+
network_name = config.getoption("--network")
|
81
|
+
|
82
|
+
if not user_config_exists():
|
83
|
+
logger.warning(
|
84
|
+
"File `gltest.config.yaml` not found in the current directory, using default config, create a `gltest.config.yaml` file to manage multiple networks"
|
85
|
+
)
|
86
|
+
user_config = get_default_user_config()
|
87
|
+
|
88
|
+
# Special handling for testnet_asimov - check if accounts are configured
|
89
|
+
if network_name == "testnet_asimov":
|
90
|
+
logger.error(
|
91
|
+
"For testnet_asimov, you need to configure accounts in gltest.config.yaml, see https://docs.genlayer.com/api-references/genlayer-test"
|
92
|
+
)
|
93
|
+
pytest.exit("gltest configuration error")
|
94
|
+
else:
|
95
|
+
logger.info(
|
96
|
+
"File `gltest.config.yaml` found in the current directory, using it"
|
97
|
+
)
|
98
|
+
user_config = load_user_config("gltest.config.yaml")
|
99
|
+
|
100
|
+
general_config.user_config = user_config
|
101
|
+
|
102
|
+
# Handle plugin config from command line
|
103
|
+
contracts_dir = config.getoption("--contracts-dir")
|
104
|
+
artifacts_dir = config.getoption("--artifacts-dir")
|
105
|
+
default_wait_interval = config.getoption("--default-wait-interval")
|
106
|
+
default_wait_retries = config.getoption("--default-wait-retries")
|
107
|
+
rpc_url = config.getoption("--rpc-url")
|
108
|
+
network = config.getoption("--network")
|
109
|
+
test_with_mocks = config.getoption("--test-with-mocks")
|
110
|
+
leader_only = config.getoption("--leader-only")
|
111
|
+
|
112
|
+
plugin_config = PluginConfig()
|
113
|
+
plugin_config.contracts_dir = (
|
114
|
+
Path(contracts_dir) if contracts_dir is not None else None
|
82
115
|
)
|
83
|
-
|
84
|
-
|
85
|
-
else:
|
86
|
-
logger.info(
|
87
|
-
"File `gltest.config.yaml` found in the current directory, using it"
|
116
|
+
plugin_config.artifacts_dir = (
|
117
|
+
Path(artifacts_dir) if artifacts_dir is not None else None
|
88
118
|
)
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
artifacts_dir = config.getoption("--artifacts-dir")
|
96
|
-
default_wait_interval = config.getoption("--default-wait-interval")
|
97
|
-
default_wait_retries = config.getoption("--default-wait-retries")
|
98
|
-
rpc_url = config.getoption("--rpc-url")
|
99
|
-
network = config.getoption("--network")
|
100
|
-
test_with_mocks = config.getoption("--test-with-mocks")
|
101
|
-
leader_only = config.getoption("--leader-only")
|
102
|
-
|
103
|
-
plugin_config = PluginConfig()
|
104
|
-
plugin_config.contracts_dir = (
|
105
|
-
Path(contracts_dir) if contracts_dir is not None else None
|
106
|
-
)
|
107
|
-
plugin_config.artifacts_dir = (
|
108
|
-
Path(artifacts_dir) if artifacts_dir is not None else None
|
109
|
-
)
|
110
|
-
plugin_config.default_wait_interval = int(default_wait_interval)
|
111
|
-
plugin_config.default_wait_retries = int(default_wait_retries)
|
112
|
-
plugin_config.rpc_url = rpc_url
|
113
|
-
plugin_config.network_name = network
|
114
|
-
plugin_config.test_with_mocks = test_with_mocks
|
115
|
-
plugin_config.leader_only = leader_only
|
119
|
+
plugin_config.default_wait_interval = int(default_wait_interval)
|
120
|
+
plugin_config.default_wait_retries = int(default_wait_retries)
|
121
|
+
plugin_config.rpc_url = rpc_url
|
122
|
+
plugin_config.network_name = network
|
123
|
+
plugin_config.test_with_mocks = test_with_mocks
|
124
|
+
plugin_config.leader_only = leader_only
|
116
125
|
|
117
|
-
|
126
|
+
general_config.plugin_config = plugin_config
|
127
|
+
except Exception as e:
|
128
|
+
logger.error(f"Gltest configure error: {e}")
|
129
|
+
pytest.exit("gltest configuration error")
|
118
130
|
|
119
131
|
|
120
132
|
def pytest_sessionstart(session):
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
133
|
+
try:
|
134
|
+
general_config = get_general_config()
|
135
|
+
artifacts_dir = general_config.get_artifacts_dir()
|
136
|
+
if artifacts_dir and artifacts_dir.exists():
|
137
|
+
logger.info(f"Clearing artifacts directory: {artifacts_dir}")
|
138
|
+
try:
|
139
|
+
shutil.rmtree(artifacts_dir)
|
140
|
+
artifacts_dir.mkdir(parents=True, exist_ok=True)
|
141
|
+
except Exception as e:
|
142
|
+
logger.warning(f"Failed to clear artifacts directory: {e}")
|
143
|
+
elif artifacts_dir:
|
128
144
|
artifacts_dir.mkdir(parents=True, exist_ok=True)
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
logger.info(
|
144
|
-
f" Default wait interval: {general_config.get_default_wait_interval()} ms"
|
145
|
-
)
|
146
|
-
logger.info(f" Default wait retries: {general_config.get_default_wait_retries()}")
|
147
|
-
logger.info(f" Test with mocks: {general_config.get_test_with_mocks()}")
|
148
|
-
|
149
|
-
if general_config.get_leader_only() and not general_config.check_studio_based_rpc():
|
150
|
-
logger.warning(
|
151
|
-
"Leader only mode: True (enabled on non-studio network - will have no effect)"
|
145
|
+
logger.info("Using the following configuration:")
|
146
|
+
logger.info(f" RPC URL: {general_config.get_rpc_url()}")
|
147
|
+
logger.info(f" Selected Network: {general_config.get_network_name()}")
|
148
|
+
# Show available networks including preconfigured ones
|
149
|
+
all_networks = general_config.get_networks_keys()
|
150
|
+
logger.info(f" Available networks: {all_networks}")
|
151
|
+
logger.info(f" Contracts directory: {general_config.get_contracts_dir()}")
|
152
|
+
logger.info(f" Artifacts directory: {general_config.get_artifacts_dir()}")
|
153
|
+
logger.info(f" Environment: {general_config.user_config.environment}")
|
154
|
+
logger.info(
|
155
|
+
f" Default wait interval: {general_config.get_default_wait_interval()} ms"
|
156
|
+
)
|
157
|
+
logger.info(
|
158
|
+
f" Default wait retries: {general_config.get_default_wait_retries()}"
|
152
159
|
)
|
153
|
-
|
154
|
-
|
160
|
+
logger.info(f" Test with mocks: {general_config.get_test_with_mocks()}")
|
161
|
+
|
162
|
+
if (
|
163
|
+
general_config.get_leader_only()
|
164
|
+
and not general_config.check_studio_based_rpc()
|
165
|
+
):
|
166
|
+
logger.warning(
|
167
|
+
"Leader only mode: True (enabled on non-studio network - will have no effect)"
|
168
|
+
)
|
169
|
+
else:
|
170
|
+
logger.info(f" Leader only mode: {general_config.get_leader_only()}")
|
171
|
+
except Exception as e:
|
172
|
+
logger.error(f"Gltest session start error: {e}")
|
173
|
+
pytest.exit("gltest session start error")
|
155
174
|
|
156
175
|
|
157
176
|
def pytest_runtest_setup(item):
|
gltest_cli/config/types.py
CHANGED
@@ -2,14 +2,10 @@ from enum import Enum
|
|
2
2
|
from dataclasses import dataclass, field
|
3
3
|
from pathlib import Path
|
4
4
|
from typing import Dict, List, Optional
|
5
|
-
from genlayer_py.chains import localnet, testnet_asimov
|
5
|
+
from genlayer_py.chains import localnet, studionet, testnet_asimov
|
6
6
|
from genlayer_py.types import GenLayerChain
|
7
7
|
from urllib.parse import urlparse
|
8
|
-
|
9
|
-
|
10
|
-
class NetworkConfig(str, Enum):
|
11
|
-
LOCALNET = "localnet"
|
12
|
-
TESTNET_ASIMOV = "testnet_asimov"
|
8
|
+
from gltest_cli.config.constants import PRECONFIGURED_NETWORKS
|
13
9
|
|
14
10
|
|
15
11
|
@dataclass
|
@@ -111,10 +107,17 @@ class GeneralConfig:
|
|
111
107
|
artifacts_dir = self.get_artifacts_dir()
|
112
108
|
return artifacts_dir / "analysis"
|
113
109
|
|
110
|
+
def get_networks_keys(self) -> List[str]:
|
111
|
+
return list(self.user_config.networks.keys())
|
112
|
+
|
114
113
|
def get_rpc_url(self) -> str:
|
115
114
|
if self.plugin_config.rpc_url is not None:
|
116
115
|
return self.plugin_config.rpc_url
|
117
116
|
network_name = self.get_network_name()
|
117
|
+
if network_name not in self.user_config.networks:
|
118
|
+
raise ValueError(
|
119
|
+
f"Unknown network: {network_name}, possible values: {self.get_networks_keys()}"
|
120
|
+
)
|
118
121
|
return self.user_config.networks[network_name].url
|
119
122
|
|
120
123
|
def get_default_account_key(self, network_name: Optional[str] = None) -> str:
|
@@ -128,16 +131,37 @@ class GeneralConfig:
|
|
128
131
|
return self.user_config.networks[self.user_config.default_network].accounts
|
129
132
|
|
130
133
|
def get_chain(self) -> GenLayerChain:
|
134
|
+
network_name = self.get_network_name()
|
135
|
+
if network_name not in self.user_config.networks:
|
136
|
+
raise ValueError(
|
137
|
+
f"Unknown network: {network_name}, possible values: {self.get_networks_keys()}"
|
138
|
+
)
|
139
|
+
|
140
|
+
# Reserved network names
|
141
|
+
chain_map_by_name = {
|
142
|
+
"localnet": localnet,
|
143
|
+
"studionet": studionet,
|
144
|
+
"testnet_asimov": testnet_asimov,
|
145
|
+
}
|
146
|
+
|
147
|
+
if network_name in chain_map_by_name:
|
148
|
+
return chain_map_by_name[network_name]
|
149
|
+
|
150
|
+
if network_name in PRECONFIGURED_NETWORKS:
|
151
|
+
raise ValueError(
|
152
|
+
f"Network {network_name} should be handled by reserved mapping"
|
153
|
+
)
|
154
|
+
|
155
|
+
# Custom networks
|
131
156
|
chain_map_by_id = {
|
132
157
|
61999: localnet,
|
133
158
|
4221: testnet_asimov,
|
134
159
|
}
|
135
|
-
network_name = self.get_network_name()
|
136
160
|
network_id = self.user_config.networks[network_name].id
|
137
161
|
if network_id not in chain_map_by_id:
|
138
162
|
known = ", ".join(map(str, chain_map_by_id.keys()))
|
139
163
|
raise ValueError(
|
140
|
-
f"Unknown network: {
|
164
|
+
f"Unknown network id: {network_id}, possible values: {known}"
|
141
165
|
)
|
142
166
|
return chain_map_by_id[network_id]
|
143
167
|
|
gltest_cli/config/user.py
CHANGED
@@ -8,12 +8,12 @@ from gltest.accounts import create_accounts
|
|
8
8
|
from gltest_cli.config.constants import (
|
9
9
|
GLTEST_CONFIG_FILE,
|
10
10
|
DEFAULT_NETWORK,
|
11
|
-
DEFAULT_RPC_URL,
|
12
11
|
DEFAULT_ENVIRONMENT,
|
13
12
|
DEFAULT_CONTRACTS_DIR,
|
14
13
|
DEFAULT_ARTIFACTS_DIR,
|
15
|
-
|
14
|
+
PRECONFIGURED_NETWORKS,
|
16
15
|
)
|
16
|
+
from genlayer_py.chains import localnet, studionet, testnet_asimov
|
17
17
|
from gltest_cli.config.types import UserConfig, NetworkConfigData, PathConfig
|
18
18
|
|
19
19
|
VALID_ROOT_KEYS = ["networks", "paths", "environment"]
|
@@ -26,16 +26,32 @@ def get_default_user_config() -> UserConfig:
|
|
26
26
|
accounts = create_accounts(n_accounts=10)
|
27
27
|
accounts_private_keys = [account.key.hex() for account in accounts]
|
28
28
|
|
29
|
+
networks = {
|
30
|
+
"localnet": NetworkConfigData(
|
31
|
+
id=localnet.id,
|
32
|
+
url=localnet.rpc_urls["default"]["http"][0],
|
33
|
+
accounts=accounts_private_keys,
|
34
|
+
from_account=accounts_private_keys[0],
|
35
|
+
leader_only=False,
|
36
|
+
),
|
37
|
+
"studionet": NetworkConfigData(
|
38
|
+
id=studionet.id,
|
39
|
+
url=studionet.rpc_urls["default"]["http"][0],
|
40
|
+
accounts=accounts_private_keys,
|
41
|
+
from_account=accounts_private_keys[0],
|
42
|
+
leader_only=False,
|
43
|
+
),
|
44
|
+
"testnet_asimov": NetworkConfigData(
|
45
|
+
id=testnet_asimov.id,
|
46
|
+
url=testnet_asimov.rpc_urls["default"]["http"][0],
|
47
|
+
accounts=None,
|
48
|
+
from_account=None,
|
49
|
+
leader_only=False,
|
50
|
+
),
|
51
|
+
}
|
52
|
+
|
29
53
|
return UserConfig(
|
30
|
-
networks=
|
31
|
-
DEFAULT_NETWORK: NetworkConfigData(
|
32
|
-
id=DEFAULT_NETWORK_ID,
|
33
|
-
url=DEFAULT_RPC_URL,
|
34
|
-
accounts=accounts_private_keys,
|
35
|
-
from_account=accounts_private_keys[0],
|
36
|
-
leader_only=False,
|
37
|
-
),
|
38
|
-
},
|
54
|
+
networks=networks,
|
39
55
|
paths=PathConfig(
|
40
56
|
contracts=DEFAULT_CONTRACTS_DIR, artifacts=DEFAULT_ARTIFACTS_DIR
|
41
57
|
),
|
@@ -46,11 +62,26 @@ def get_default_user_config() -> UserConfig:
|
|
46
62
|
|
47
63
|
def resolve_env_vars(obj):
|
48
64
|
if isinstance(obj, str):
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
65
|
+
|
66
|
+
def replace_env_var(m):
|
67
|
+
try:
|
68
|
+
var_name = m.group(1)
|
69
|
+
if var_name is None:
|
70
|
+
raise ValueError(
|
71
|
+
f"Invalid environment variable pattern: {m.group(0)}"
|
72
|
+
)
|
73
|
+
var_value = os.getenv(var_name)
|
74
|
+
if var_value is None:
|
75
|
+
raise ValueError(
|
76
|
+
f"Environment variable {var_name} is not set, please check your environment file"
|
77
|
+
)
|
78
|
+
return var_value
|
79
|
+
except IndexError as e:
|
80
|
+
raise ValueError(
|
81
|
+
f"Invalid environment variable pattern: {m.group(0)}"
|
82
|
+
) from e
|
83
|
+
|
84
|
+
return re.sub(r"\${(\w+)}", replace_env_var, obj)
|
54
85
|
elif isinstance(obj, dict):
|
55
86
|
return {k: resolve_env_vars(v) for k, v in obj.items()}
|
56
87
|
elif isinstance(obj, list):
|
@@ -90,8 +121,8 @@ def validate_network_config(network_name: str, network_config: dict):
|
|
90
121
|
):
|
91
122
|
raise ValueError(f"network {network_name} leader_only must be a boolean")
|
92
123
|
|
93
|
-
# For non-
|
94
|
-
if network_name
|
124
|
+
# For non-preconfigured networks, url and accounts are required
|
125
|
+
if network_name not in PRECONFIGURED_NETWORKS:
|
95
126
|
if "id" not in network_config:
|
96
127
|
raise ValueError(f"network {network_name} must have an id")
|
97
128
|
if "url" not in network_config:
|
@@ -139,7 +170,6 @@ def validate_raw_user_config(config: dict):
|
|
139
170
|
def load_user_config(path: str) -> UserConfig:
|
140
171
|
with open(path, "r") as f:
|
141
172
|
raw_config = yaml.safe_load(f) or {}
|
142
|
-
|
143
173
|
validate_raw_user_config(raw_config)
|
144
174
|
load_dotenv(
|
145
175
|
dotenv_path=raw_config.get("environment", DEFAULT_ENVIRONMENT), override=True
|
@@ -176,8 +206,8 @@ def _get_overridden_networks(raw_config: dict) -> tuple[dict, str]:
|
|
176
206
|
|
177
207
|
networks_config = {}
|
178
208
|
for network_name, network_config in networks.items():
|
179
|
-
if network_name
|
180
|
-
networks_config[network_name] = default_config.networks[
|
209
|
+
if network_name in PRECONFIGURED_NETWORKS:
|
210
|
+
networks_config[network_name] = default_config.networks[network_name]
|
181
211
|
if network_config is None:
|
182
212
|
continue
|
183
213
|
|
gltest_cli/logging.py
CHANGED
@@ -31,13 +31,14 @@ class ColoredFormatter(logging.Formatter):
|
|
31
31
|
|
32
32
|
def setup_logger():
|
33
33
|
logger = logging.getLogger("gltest_cli")
|
34
|
-
|
34
|
+
log_level = logging.INFO
|
35
|
+
logger.setLevel(log_level)
|
35
36
|
|
36
37
|
if logger.handlers:
|
37
38
|
return logger
|
38
39
|
|
39
40
|
console_handler = logging.StreamHandler()
|
40
|
-
console_handler.setLevel(
|
41
|
+
console_handler.setLevel(log_level)
|
41
42
|
|
42
43
|
formatter = ColoredFormatter("%(levelname)s: %(message)s")
|
43
44
|
console_handler.setFormatter(formatter)
|
@@ -123,12 +123,8 @@ def test_network_testnet(pytester):
|
|
123
123
|
"--network=testnet_asimov", "--rpc-url=http://test.example.com:9151", "-v"
|
124
124
|
)
|
125
125
|
|
126
|
-
|
127
|
-
|
128
|
-
"*::test_network PASSED*",
|
129
|
-
]
|
130
|
-
)
|
131
|
-
assert result.ret == 0
|
126
|
+
# The test should exit with an error code when testnet_asimov is used without accounts
|
127
|
+
assert result.ret != 0
|
132
128
|
|
133
129
|
|
134
130
|
def test_artifacts_dir(pytester):
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|