genlayer-test 0.4.0__py3-none-any.whl → 0.5.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.4.0.dist-info → genlayer_test-0.5.0.dist-info}/METADATA +257 -24
- genlayer_test-0.5.0.dist-info/RECORD +76 -0
- gltest/__init__.py +7 -6
- gltest/{glchain/client.py → clients.py} +1 -1
- gltest/contracts/__init__.py +4 -0
- gltest/contracts/contract.py +205 -0
- gltest/{glchain/contract.py → contracts/contract_factory.py} +47 -144
- gltest/contracts/contract_functions.py +62 -0
- gltest/contracts/method_stats.py +163 -0
- gltest/contracts/stats_collector.py +259 -0
- gltest/contracts/utils.py +12 -0
- gltest/fixtures.py +2 -6
- gltest/helpers/take_snapshot.py +1 -1
- gltest/logging.py +17 -0
- gltest/types.py +1 -0
- gltest_cli/config/constants.py +2 -0
- gltest_cli/config/plugin.py +121 -49
- gltest_cli/config/pytest_context.py +9 -0
- gltest_cli/config/types.py +73 -8
- gltest_cli/config/user.py +71 -28
- gltest_cli/logging.py +4 -3
- tests/examples/contracts/football_prediction_market.py +1 -1
- tests/examples/tests/test_football_prediction_market.py +2 -2
- tests/examples/tests/test_intelligent_oracle_factory.py +8 -24
- tests/examples/tests/test_llm_erc20.py +5 -5
- tests/examples/tests/test_llm_erc20_analyze.py +50 -0
- tests/examples/tests/test_log_indexer.py +23 -11
- tests/examples/tests/test_multi_file_contract.py +2 -2
- tests/examples/tests/test_multi_file_contract_legacy.py +2 -2
- tests/examples/tests/test_multi_read_erc20.py +14 -12
- tests/examples/tests/test_multi_tenant_storage.py +11 -7
- tests/examples/tests/test_read_erc20.py +1 -1
- tests/examples/tests/test_storage.py +4 -4
- tests/examples/tests/test_storage_legacy.py +5 -3
- tests/examples/tests/test_user_storage.py +20 -10
- tests/examples/tests/test_wizard_of_coin.py +1 -1
- tests/gltest_cli/config/test_config_integration.py +432 -0
- tests/gltest_cli/config/test_general_config.py +406 -0
- tests/gltest_cli/config/test_plugin.py +164 -1
- tests/gltest_cli/config/test_user.py +61 -1
- genlayer_test-0.4.0.dist-info/RECORD +0 -66
- gltest/glchain/__init__.py +0 -16
- {genlayer_test-0.4.0.dist-info → genlayer_test-0.5.0.dist-info}/WHEEL +0 -0
- {genlayer_test-0.4.0.dist-info → genlayer_test-0.5.0.dist-info}/entry_points.txt +0 -0
- {genlayer_test-0.4.0.dist-info → genlayer_test-0.5.0.dist-info}/licenses/LICENSE +0 -0
- {genlayer_test-0.4.0.dist-info → genlayer_test-0.5.0.dist-info}/top_level.txt +0 -0
- /gltest/{glchain/account.py → accounts.py} +0 -0
@@ -0,0 +1,259 @@
|
|
1
|
+
"""
|
2
|
+
Stats collector module for contract method analysis.
|
3
|
+
|
4
|
+
This module contains classes and functions to collect and analyze statistics
|
5
|
+
from contract method executions, simplifying the analyze_method implementation.
|
6
|
+
"""
|
7
|
+
|
8
|
+
import time
|
9
|
+
import json
|
10
|
+
import hashlib
|
11
|
+
from datetime import datetime, timezone
|
12
|
+
from typing import List, Dict, Any, Optional
|
13
|
+
from dataclasses import dataclass
|
14
|
+
|
15
|
+
from gltest.clients import get_gl_client
|
16
|
+
from gltest.types import CalldataEncodable
|
17
|
+
from .method_stats import StateGroup, FailedRun, MethodStatsDetailed, MethodStatsSummary
|
18
|
+
from gltest_cli.config.general import get_general_config
|
19
|
+
from gltest_cli.config.pytest_context import get_current_test_nodeid
|
20
|
+
from .utils import safe_filename
|
21
|
+
|
22
|
+
|
23
|
+
@dataclass
|
24
|
+
class SimulationConfig:
|
25
|
+
"""Configuration for simulation runs."""
|
26
|
+
|
27
|
+
provider: str
|
28
|
+
model: str
|
29
|
+
config: Optional[Dict[str, Any]] = None
|
30
|
+
plugin: Optional[str] = None
|
31
|
+
plugin_config: Optional[Dict[str, Any]] = None
|
32
|
+
|
33
|
+
|
34
|
+
@dataclass
|
35
|
+
class SimulationResults:
|
36
|
+
"""Results from simulation runs."""
|
37
|
+
|
38
|
+
sim_results: List[Dict[str, Any]]
|
39
|
+
failed_runs: List[FailedRun]
|
40
|
+
server_errors: int
|
41
|
+
execution_time: float
|
42
|
+
timestamp: str
|
43
|
+
|
44
|
+
|
45
|
+
class StatsCollector:
|
46
|
+
"""Collects and analyzes statistics for contract method executions."""
|
47
|
+
|
48
|
+
def __init__(
|
49
|
+
self,
|
50
|
+
contract_address: str,
|
51
|
+
method_name: str,
|
52
|
+
account: Any,
|
53
|
+
args: Optional[List[CalldataEncodable]] = None,
|
54
|
+
):
|
55
|
+
self.contract_address = contract_address
|
56
|
+
self.method_name = method_name
|
57
|
+
self.account = account
|
58
|
+
self.args = args or []
|
59
|
+
self.client = get_gl_client()
|
60
|
+
|
61
|
+
def run_simulations(
|
62
|
+
self, sim_config: SimulationConfig, runs: int
|
63
|
+
) -> SimulationResults:
|
64
|
+
"""Execute multiple simulation runs and collect results."""
|
65
|
+
start_time = time.time()
|
66
|
+
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
|
67
|
+
|
68
|
+
sim_results = []
|
69
|
+
failed_runs_list = []
|
70
|
+
server_errors = 0
|
71
|
+
|
72
|
+
for run_idx in range(runs):
|
73
|
+
try:
|
74
|
+
sim_result = self._execute_single_simulation(sim_config)
|
75
|
+
sim_results.append(sim_result)
|
76
|
+
|
77
|
+
if sim_result.get("execution_result") != "SUCCESS":
|
78
|
+
failed_runs_list.append(
|
79
|
+
self._create_failed_run(run_idx, sim_result)
|
80
|
+
)
|
81
|
+
except Exception as e:
|
82
|
+
server_errors += 1
|
83
|
+
failed_runs_list.append(
|
84
|
+
FailedRun(
|
85
|
+
run=run_idx,
|
86
|
+
error=str(e),
|
87
|
+
error_type="server",
|
88
|
+
genvm_result=None,
|
89
|
+
)
|
90
|
+
)
|
91
|
+
|
92
|
+
execution_time = time.time() - start_time
|
93
|
+
|
94
|
+
return SimulationResults(
|
95
|
+
sim_results=sim_results,
|
96
|
+
failed_runs=failed_runs_list,
|
97
|
+
server_errors=server_errors,
|
98
|
+
execution_time=execution_time,
|
99
|
+
timestamp=timestamp,
|
100
|
+
)
|
101
|
+
|
102
|
+
def _execute_single_simulation(
|
103
|
+
self, sim_config: SimulationConfig
|
104
|
+
) -> Dict[str, Any]:
|
105
|
+
"""Execute a single simulation."""
|
106
|
+
config_dict = {
|
107
|
+
"provider": sim_config.provider,
|
108
|
+
"model": sim_config.model,
|
109
|
+
}
|
110
|
+
|
111
|
+
if (
|
112
|
+
sim_config.config is not None
|
113
|
+
and sim_config.plugin is not None
|
114
|
+
and sim_config.plugin_config is not None
|
115
|
+
):
|
116
|
+
config_dict["config"] = sim_config.config
|
117
|
+
config_dict["plugin"] = sim_config.plugin
|
118
|
+
config_dict["plugin_config"] = sim_config.plugin_config
|
119
|
+
|
120
|
+
return self.client.simulate_write_contract(
|
121
|
+
address=self.contract_address,
|
122
|
+
function_name=self.method_name,
|
123
|
+
account=self.account,
|
124
|
+
args=self.args,
|
125
|
+
sim_config=config_dict,
|
126
|
+
)
|
127
|
+
|
128
|
+
def _create_failed_run(self, run_idx: int, sim_result: Dict[str, Any]) -> FailedRun:
|
129
|
+
"""Create a FailedRun object from a failed simulation result."""
|
130
|
+
return FailedRun(
|
131
|
+
run=run_idx,
|
132
|
+
error=sim_result.get("error", "unknown error"),
|
133
|
+
error_type="simulation",
|
134
|
+
genvm_result={
|
135
|
+
"stderr": sim_result.get("genvm_result", {}).get("stderr", ""),
|
136
|
+
"stdout": sim_result.get("genvm_result", {}).get("stdout", ""),
|
137
|
+
},
|
138
|
+
)
|
139
|
+
|
140
|
+
def analyze_results(
|
141
|
+
self,
|
142
|
+
sim_results: SimulationResults,
|
143
|
+
runs: int,
|
144
|
+
sim_config: SimulationConfig,
|
145
|
+
) -> MethodStatsSummary:
|
146
|
+
"""Analyze simulation results and generate statistics."""
|
147
|
+
state_groups = self._analyze_states(sim_results.sim_results)
|
148
|
+
|
149
|
+
executed_runs = runs - sim_results.server_errors
|
150
|
+
successful_runs = sum(
|
151
|
+
1
|
152
|
+
for sim_receipt in sim_results.sim_results
|
153
|
+
if sim_receipt.get("execution_result") == "SUCCESS"
|
154
|
+
)
|
155
|
+
|
156
|
+
most_common_count = max((group.count for group in state_groups), default=0)
|
157
|
+
reliability_score = (
|
158
|
+
(most_common_count / executed_runs) if executed_runs > 0 else 0.0
|
159
|
+
)
|
160
|
+
|
161
|
+
# Save detailed stats
|
162
|
+
detailed_stats = self._create_detailed_stats(
|
163
|
+
sim_results=sim_results,
|
164
|
+
state_groups=state_groups,
|
165
|
+
runs=runs,
|
166
|
+
executed_runs=executed_runs,
|
167
|
+
successful_runs=successful_runs,
|
168
|
+
most_common_count=most_common_count,
|
169
|
+
reliability_score=reliability_score,
|
170
|
+
sim_config=sim_config,
|
171
|
+
)
|
172
|
+
self._save_detailed_stats(detailed_stats)
|
173
|
+
|
174
|
+
# Return summary
|
175
|
+
return MethodStatsSummary(
|
176
|
+
method=self.method_name,
|
177
|
+
args=self.args,
|
178
|
+
total_runs=runs,
|
179
|
+
server_error_runs=sim_results.server_errors,
|
180
|
+
executed_runs=executed_runs,
|
181
|
+
failed_runs=len(sim_results.failed_runs),
|
182
|
+
successful_runs=successful_runs,
|
183
|
+
unique_states=len(state_groups),
|
184
|
+
most_common_state_count=most_common_count,
|
185
|
+
reliability_score=reliability_score,
|
186
|
+
execution_time=sim_results.execution_time,
|
187
|
+
provider=sim_config.provider,
|
188
|
+
model=sim_config.model,
|
189
|
+
)
|
190
|
+
|
191
|
+
def _analyze_states(self, sim_results: List[Dict[str, Any]]) -> List[StateGroup]:
|
192
|
+
"""Analyze contract states from simulation results."""
|
193
|
+
state_counts = {}
|
194
|
+
state_to_hash_str = {}
|
195
|
+
|
196
|
+
for sim_receipt in sim_results:
|
197
|
+
contract_state = sim_receipt.get("contract_state", {})
|
198
|
+
state_json = json.dumps(contract_state, sort_keys=True)
|
199
|
+
state_hash = hashlib.sha256(state_json.encode()).hexdigest()
|
200
|
+
state_hash_str = f"0x{state_hash}"
|
201
|
+
state_to_hash_str[state_hash] = state_hash_str
|
202
|
+
state_counts[state_hash] = state_counts.get(state_hash, 0) + 1
|
203
|
+
|
204
|
+
return [
|
205
|
+
StateGroup(count=count, state_hash=state_to_hash_str[state_hash])
|
206
|
+
for state_hash, count in sorted(
|
207
|
+
state_counts.items(), key=lambda x: x[1], reverse=True
|
208
|
+
)
|
209
|
+
]
|
210
|
+
|
211
|
+
def _create_detailed_stats(
|
212
|
+
self,
|
213
|
+
sim_results: SimulationResults,
|
214
|
+
state_groups: List[StateGroup],
|
215
|
+
runs: int,
|
216
|
+
executed_runs: int,
|
217
|
+
successful_runs: int,
|
218
|
+
most_common_count: int,
|
219
|
+
reliability_score: float,
|
220
|
+
sim_config: SimulationConfig,
|
221
|
+
) -> MethodStatsDetailed:
|
222
|
+
"""Create detailed statistics object."""
|
223
|
+
configuration = {
|
224
|
+
"runs": runs,
|
225
|
+
"provider": sim_config.provider,
|
226
|
+
"model": sim_config.model,
|
227
|
+
"config": sim_config.config,
|
228
|
+
"plugin": sim_config.plugin,
|
229
|
+
"plugin_config": sim_config.plugin_config,
|
230
|
+
}
|
231
|
+
|
232
|
+
return MethodStatsDetailed(
|
233
|
+
method=self.method_name,
|
234
|
+
params=self.args,
|
235
|
+
timestamp=sim_results.timestamp,
|
236
|
+
configuration=configuration,
|
237
|
+
execution_time=sim_results.execution_time,
|
238
|
+
executed_runs=executed_runs,
|
239
|
+
failed_runs=len(sim_results.failed_runs),
|
240
|
+
successful_runs=successful_runs,
|
241
|
+
server_error_runs=sim_results.server_errors,
|
242
|
+
unique_states=len(state_groups),
|
243
|
+
most_common_state_count=most_common_count,
|
244
|
+
reliability_score=reliability_score,
|
245
|
+
state_groups=state_groups,
|
246
|
+
failed_runs_results=sim_results.failed_runs,
|
247
|
+
sim_results=sim_results.sim_results,
|
248
|
+
)
|
249
|
+
|
250
|
+
def _save_detailed_stats(self, detailed_stats: MethodStatsDetailed) -> None:
|
251
|
+
"""Save detailed statistics to the configured directory."""
|
252
|
+
general_config = get_general_config()
|
253
|
+
current_nodeid = get_current_test_nodeid()
|
254
|
+
if current_nodeid is None:
|
255
|
+
safe_name = "no_test"
|
256
|
+
else:
|
257
|
+
safe_name = safe_filename(current_nodeid)
|
258
|
+
stats_dir = general_config.get_analysis_dir() / safe_name
|
259
|
+
detailed_stats.save_to_directory(stats_dir)
|
gltest/fixtures.py
CHANGED
@@ -4,12 +4,8 @@ These fixtures can be imported and used in test files.
|
|
4
4
|
"""
|
5
5
|
|
6
6
|
import pytest
|
7
|
-
from gltest.
|
8
|
-
|
9
|
-
get_accounts,
|
10
|
-
get_default_account,
|
11
|
-
get_gl_provider,
|
12
|
-
)
|
7
|
+
from gltest.clients import get_gl_client, get_gl_provider
|
8
|
+
from gltest.accounts import get_accounts, get_default_account
|
13
9
|
from gltest_cli.config.general import get_general_config
|
14
10
|
|
15
11
|
|
gltest/helpers/take_snapshot.py
CHANGED
gltest/logging.py
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
import logging
|
2
|
+
|
3
|
+
|
4
|
+
def setup_logger() -> logging.Logger:
|
5
|
+
"""Setup a logger for the gltest package - disabled by default"""
|
6
|
+
|
7
|
+
logger = logging.getLogger("gltest")
|
8
|
+
|
9
|
+
logger.setLevel(logging.NOTSET)
|
10
|
+
logger.disabled = True
|
11
|
+
logger.addHandler(logging.NullHandler())
|
12
|
+
return logger
|
13
|
+
|
14
|
+
|
15
|
+
logger = setup_logger()
|
16
|
+
|
17
|
+
__all__ = ["logger"]
|
gltest/types.py
CHANGED
gltest_cli/config/constants.py
CHANGED
@@ -4,7 +4,9 @@ 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")
|
11
|
+
DEFAULT_ARTIFACTS_DIR = Path("artifacts")
|
10
12
|
DEFAULT_NETWORK_ID = 61999
|
gltest_cli/config/plugin.py
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
+
import pytest
|
1
2
|
from pathlib import Path
|
3
|
+
import shutil
|
2
4
|
from gltest_cli.logging import logger
|
3
5
|
from gltest_cli.config.user import (
|
4
6
|
user_config_exists,
|
@@ -9,6 +11,7 @@ from gltest_cli.config.general import (
|
|
9
11
|
get_general_config,
|
10
12
|
)
|
11
13
|
from gltest_cli.config.types import PluginConfig
|
14
|
+
from gltest_cli.config.pytest_context import _pytest_context
|
12
15
|
|
13
16
|
|
14
17
|
def pytest_addoption(parser):
|
@@ -20,17 +23,24 @@ def pytest_addoption(parser):
|
|
20
23
|
help="Path to directory containing contract files",
|
21
24
|
)
|
22
25
|
|
26
|
+
group.addoption(
|
27
|
+
"--artifacts-dir",
|
28
|
+
action="store",
|
29
|
+
default=None,
|
30
|
+
help="Path to directory for storing contract artifacts",
|
31
|
+
)
|
32
|
+
|
23
33
|
group.addoption(
|
24
34
|
"--default-wait-interval",
|
25
35
|
action="store",
|
26
|
-
default=
|
36
|
+
default=3000,
|
27
37
|
help="Default interval (ms) between transaction receipt checks",
|
28
38
|
)
|
29
39
|
|
30
40
|
group.addoption(
|
31
41
|
"--default-wait-retries",
|
32
42
|
action="store",
|
33
|
-
default=
|
43
|
+
default=50,
|
34
44
|
help="Default number of retries for transaction receipt checks",
|
35
45
|
)
|
36
46
|
|
@@ -55,61 +65,123 @@ def pytest_addoption(parser):
|
|
55
65
|
help="Test with mocks",
|
56
66
|
)
|
57
67
|
|
68
|
+
group.addoption(
|
69
|
+
"--leader-only",
|
70
|
+
action="store_true",
|
71
|
+
default=False,
|
72
|
+
help="Run contracts in leader-only mode",
|
73
|
+
)
|
58
74
|
|
59
|
-
def pytest_configure(config):
|
60
|
-
general_config = get_general_config()
|
61
75
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
76
|
+
def pytest_configure(config):
|
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
|
66
115
|
)
|
67
|
-
|
68
|
-
|
69
|
-
else:
|
70
|
-
logger.info(
|
71
|
-
"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
|
72
118
|
)
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
default_wait_interval = config.getoption("--default-wait-interval")
|
80
|
-
default_wait_retries = config.getoption("--default-wait-retries")
|
81
|
-
rpc_url = config.getoption("--rpc-url")
|
82
|
-
network = config.getoption("--network")
|
83
|
-
test_with_mocks = config.getoption("--test-with-mocks")
|
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
|
84
125
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
plugin_config.default_wait_interval = int(default_wait_interval)
|
90
|
-
plugin_config.default_wait_retries = int(default_wait_retries)
|
91
|
-
plugin_config.rpc_url = rpc_url
|
92
|
-
plugin_config.network_name = network
|
93
|
-
plugin_config.test_with_mocks = test_with_mocks
|
94
|
-
|
95
|
-
general_config.plugin_config = plugin_config
|
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")
|
96
130
|
|
97
131
|
|
98
132
|
def pytest_sessionstart(session):
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
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:
|
144
|
+
artifacts_dir.mkdir(parents=True, exist_ok=True)
|
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()}"
|
159
|
+
)
|
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")
|
174
|
+
|
175
|
+
|
176
|
+
def pytest_runtest_setup(item):
|
177
|
+
_pytest_context.current_item = item
|
178
|
+
|
179
|
+
|
180
|
+
def pytest_runtest_teardown(item):
|
181
|
+
try:
|
182
|
+
del _pytest_context.current_item
|
183
|
+
except AttributeError:
|
184
|
+
pass
|
113
185
|
|
114
186
|
|
115
187
|
pytest_plugins = ["gltest.fixtures"]
|