2026-01-16 21:47:59 +11:00
|
|
|
import std/httpclient
|
2023-06-22 20:32:18 +10:00
|
|
|
import std/os
|
refactor: multinode integration test refactor (#662)
* refactor multi node test suite
Refactor the multinode test suite into the marketplace test suite.
- Arbitrary number of nodes can be started with each test: clients, providers, validators
- Hardhat can also be started locally with each test, usually for the purpose of saving and inspecting its log file.
- Log files for all nodes can be persisted on disk, with configuration at the test-level
- Log files, if persisted (as specified in the test), will be persisted to a CI artifact
- Node config is specified at the test-level instead of the suite-level
- Node/Hardhat process starting/stopping is now async, and runs much faster
- Per-node config includes:
- simulating proof failures
- logging to file
- log level
- log topics
- storage quota
- debug (print logs to stdout)
- Tests find next available ports when starting nodes, as closing ports on Windows can lag
- Hardhat is no longer required to be running prior to starting the integration tests (as long as Hardhat is configured to run in the tests).
- If Hardhat is already running, a snapshot will be taken and reverted before and after each test, respectively.
- If Hardhat is not already running and configured to run at the test-level, a Hardhat process will be spawned and torn down before and after each test, respectively.
* additional logging for debug purposes
* address PR feedback
- fix spelling
- revert change from catching ProviderError to SignerError -- this should be handled more consistently in the Market abstraction, and will be handled in another PR.
- remove method label from raiseAssert
- remove unused import
* Use API instead of command exec to test for free port
Use chronos `createStreamServer` API to test for free port by binding localhost address and port. Use `ServerFlags.ReuseAddr` to enable reuse of same IP/Port on multiple test runs.
* clean up
* remove upraises annotations from tests
* Update tests to work with updated erasure coding slot sizes
* update dataset size, nodes, tolerance to match valid ec params
Integration tests now have valid dataset sizes (blocks), tolerances, and number of nodes, to work with valid ec params. These values are validated when requested storage.
Print the rest api failure message (via doAssert) when a rest api call fails (eg the rest api may validate some ec params).
All integration tests pass when the async `clock.now` changes are reverted.
* dont use async clock for now
* fix workflow
* move integration logs uplod to reusable
---------
Co-authored-by: Dmitriy Ryajov <dryajov@gmail.com>
2024-02-19 15:55:39 +11:00
|
|
|
import std/sequtils
|
|
|
|
|
import std/strutils
|
|
|
|
|
import std/sugar
|
|
|
|
|
import std/times
|
2026-02-19 15:59:15 +11:00
|
|
|
import pkg/storage/conf
|
|
|
|
|
import pkg/storage/logutils
|
refactor: multinode integration test refactor (#662)
* refactor multi node test suite
Refactor the multinode test suite into the marketplace test suite.
- Arbitrary number of nodes can be started with each test: clients, providers, validators
- Hardhat can also be started locally with each test, usually for the purpose of saving and inspecting its log file.
- Log files for all nodes can be persisted on disk, with configuration at the test-level
- Log files, if persisted (as specified in the test), will be persisted to a CI artifact
- Node config is specified at the test-level instead of the suite-level
- Node/Hardhat process starting/stopping is now async, and runs much faster
- Per-node config includes:
- simulating proof failures
- logging to file
- log level
- log topics
- storage quota
- debug (print logs to stdout)
- Tests find next available ports when starting nodes, as closing ports on Windows can lag
- Hardhat is no longer required to be running prior to starting the integration tests (as long as Hardhat is configured to run in the tests).
- If Hardhat is already running, a snapshot will be taken and reverted before and after each test, respectively.
- If Hardhat is not already running and configured to run at the test-level, a Hardhat process will be spawned and torn down before and after each test, respectively.
* additional logging for debug purposes
* address PR feedback
- fix spelling
- revert change from catching ProviderError to SignerError -- this should be handled more consistently in the Market abstraction, and will be handled in another PR.
- remove method label from raiseAssert
- remove unused import
* Use API instead of command exec to test for free port
Use chronos `createStreamServer` API to test for free port by binding localhost address and port. Use `ServerFlags.ReuseAddr` to enable reuse of same IP/Port on multiple test runs.
* clean up
* remove upraises annotations from tests
* Update tests to work with updated erasure coding slot sizes
* update dataset size, nodes, tolerance to match valid ec params
Integration tests now have valid dataset sizes (blocks), tolerances, and number of nodes, to work with valid ec params. These values are validated when requested storage.
Print the rest api failure message (via doAssert) when a rest api call fails (eg the rest api may validate some ec params).
All integration tests pass when the async `clock.now` changes are reverted.
* dont use async clock for now
* fix workflow
* move integration logs uplod to reusable
---------
Co-authored-by: Dmitriy Ryajov <dryajov@gmail.com>
2024-02-19 15:55:39 +11:00
|
|
|
import pkg/chronos/transports/stream
|
2024-03-12 10:57:13 +01:00
|
|
|
import pkg/questionable
|
2026-02-19 15:59:15 +11:00
|
|
|
import ./storageconfig
|
|
|
|
|
import ./storageprocess
|
2024-03-12 10:57:13 +01:00
|
|
|
import ./nodeconfigs
|
2026-01-16 21:47:59 +11:00
|
|
|
import ./utils
|
refactor: multinode integration test refactor (#662)
* refactor multi node test suite
Refactor the multinode test suite into the marketplace test suite.
- Arbitrary number of nodes can be started with each test: clients, providers, validators
- Hardhat can also be started locally with each test, usually for the purpose of saving and inspecting its log file.
- Log files for all nodes can be persisted on disk, with configuration at the test-level
- Log files, if persisted (as specified in the test), will be persisted to a CI artifact
- Node config is specified at the test-level instead of the suite-level
- Node/Hardhat process starting/stopping is now async, and runs much faster
- Per-node config includes:
- simulating proof failures
- logging to file
- log level
- log topics
- storage quota
- debug (print logs to stdout)
- Tests find next available ports when starting nodes, as closing ports on Windows can lag
- Hardhat is no longer required to be running prior to starting the integration tests (as long as Hardhat is configured to run in the tests).
- If Hardhat is already running, a snapshot will be taken and reverted before and after each test, respectively.
- If Hardhat is not already running and configured to run at the test-level, a Hardhat process will be spawned and torn down before and after each test, respectively.
* additional logging for debug purposes
* address PR feedback
- fix spelling
- revert change from catching ProviderError to SignerError -- this should be handled more consistently in the Market abstraction, and will be handled in another PR.
- remove method label from raiseAssert
- remove unused import
* Use API instead of command exec to test for free port
Use chronos `createStreamServer` API to test for free port by binding localhost address and port. Use `ServerFlags.ReuseAddr` to enable reuse of same IP/Port on multiple test runs.
* clean up
* remove upraises annotations from tests
* Update tests to work with updated erasure coding slot sizes
* update dataset size, nodes, tolerance to match valid ec params
Integration tests now have valid dataset sizes (blocks), tolerances, and number of nodes, to work with valid ec params. These values are validated when requested storage.
Print the rest api failure message (via doAssert) when a rest api call fails (eg the rest api may validate some ec params).
All integration tests pass when the async `clock.now` changes are reverted.
* dont use async clock for now
* fix workflow
* move integration logs uplod to reusable
---------
Co-authored-by: Dmitriy Ryajov <dryajov@gmail.com>
2024-02-19 15:55:39 +11:00
|
|
|
import ../asynctest
|
|
|
|
|
import ../checktest
|
2023-06-22 20:32:18 +10:00
|
|
|
|
refactor: multinode integration test refactor (#662)
* refactor multi node test suite
Refactor the multinode test suite into the marketplace test suite.
- Arbitrary number of nodes can be started with each test: clients, providers, validators
- Hardhat can also be started locally with each test, usually for the purpose of saving and inspecting its log file.
- Log files for all nodes can be persisted on disk, with configuration at the test-level
- Log files, if persisted (as specified in the test), will be persisted to a CI artifact
- Node config is specified at the test-level instead of the suite-level
- Node/Hardhat process starting/stopping is now async, and runs much faster
- Per-node config includes:
- simulating proof failures
- logging to file
- log level
- log topics
- storage quota
- debug (print logs to stdout)
- Tests find next available ports when starting nodes, as closing ports on Windows can lag
- Hardhat is no longer required to be running prior to starting the integration tests (as long as Hardhat is configured to run in the tests).
- If Hardhat is already running, a snapshot will be taken and reverted before and after each test, respectively.
- If Hardhat is not already running and configured to run at the test-level, a Hardhat process will be spawned and torn down before and after each test, respectively.
* additional logging for debug purposes
* address PR feedback
- fix spelling
- revert change from catching ProviderError to SignerError -- this should be handled more consistently in the Market abstraction, and will be handled in another PR.
- remove method label from raiseAssert
- remove unused import
* Use API instead of command exec to test for free port
Use chronos `createStreamServer` API to test for free port by binding localhost address and port. Use `ServerFlags.ReuseAddr` to enable reuse of same IP/Port on multiple test runs.
* clean up
* remove upraises annotations from tests
* Update tests to work with updated erasure coding slot sizes
* update dataset size, nodes, tolerance to match valid ec params
Integration tests now have valid dataset sizes (blocks), tolerances, and number of nodes, to work with valid ec params. These values are validated when requested storage.
Print the rest api failure message (via doAssert) when a rest api call fails (eg the rest api may validate some ec params).
All integration tests pass when the async `clock.now` changes are reverted.
* dont use async clock for now
* fix workflow
* move integration logs uplod to reusable
---------
Co-authored-by: Dmitriy Ryajov <dryajov@gmail.com>
2024-02-19 15:55:39 +11:00
|
|
|
export asynctest
|
2026-02-19 15:59:15 +11:00
|
|
|
export storageprocess
|
|
|
|
|
export storageconfig
|
2025-02-20 16:52:51 +11:00
|
|
|
export nodeconfigs
|
2023-06-22 20:32:18 +10:00
|
|
|
|
2026-01-16 21:47:59 +11:00
|
|
|
{.push raises: [].}
|
|
|
|
|
|
2023-09-13 16:17:56 +02:00
|
|
|
type
|
|
|
|
|
RunningNode* = ref object
|
|
|
|
|
role*: Role
|
|
|
|
|
node*: NodeProcess
|
2025-01-21 21:54:46 +01:00
|
|
|
|
2023-09-13 16:17:56 +02:00
|
|
|
Role* {.pure.} = enum
|
|
|
|
|
Client
|
2025-01-21 21:54:46 +01:00
|
|
|
|
2024-03-12 10:57:13 +01:00
|
|
|
MultiNodeSuiteError = object of CatchableError
|
2026-01-16 21:47:59 +11:00
|
|
|
SuiteTimeoutError = object of MultiNodeSuiteError
|
|
|
|
|
|
|
|
|
|
const HardhatPort {.intdefine.}: int = 8545
|
2026-02-19 15:59:15 +11:00
|
|
|
const StorageApiPort {.intdefine.}: int = 8080
|
|
|
|
|
const StorageDiscPort {.intdefine.}: int = 8090
|
2026-01-16 21:47:59 +11:00
|
|
|
const TestId {.strdefine.}: string = "TestId"
|
2026-02-19 15:59:15 +11:00
|
|
|
const StorageLogToFile {.booldefine.}: bool = false
|
|
|
|
|
const StorageLogLevel {.strdefine.}: string = ""
|
|
|
|
|
const StorageLogsDir {.strdefine.}: string = ""
|
2026-01-16 21:47:59 +11:00
|
|
|
|
|
|
|
|
proc raiseMultiNodeSuiteError(
|
|
|
|
|
msg: string, parent: ref CatchableError = nil
|
|
|
|
|
) {.raises: [MultiNodeSuiteError].} =
|
|
|
|
|
raise newException(MultiNodeSuiteError, msg, parent)
|
|
|
|
|
|
|
|
|
|
template withLock(lock: AsyncLock, body: untyped) =
|
|
|
|
|
if lock.isNil:
|
|
|
|
|
lock = newAsyncLock()
|
|
|
|
|
|
|
|
|
|
await lock.acquire()
|
|
|
|
|
try:
|
|
|
|
|
body
|
|
|
|
|
finally:
|
refactor: multinode integration test refactor (#662)
* refactor multi node test suite
Refactor the multinode test suite into the marketplace test suite.
- Arbitrary number of nodes can be started with each test: clients, providers, validators
- Hardhat can also be started locally with each test, usually for the purpose of saving and inspecting its log file.
- Log files for all nodes can be persisted on disk, with configuration at the test-level
- Log files, if persisted (as specified in the test), will be persisted to a CI artifact
- Node config is specified at the test-level instead of the suite-level
- Node/Hardhat process starting/stopping is now async, and runs much faster
- Per-node config includes:
- simulating proof failures
- logging to file
- log level
- log topics
- storage quota
- debug (print logs to stdout)
- Tests find next available ports when starting nodes, as closing ports on Windows can lag
- Hardhat is no longer required to be running prior to starting the integration tests (as long as Hardhat is configured to run in the tests).
- If Hardhat is already running, a snapshot will be taken and reverted before and after each test, respectively.
- If Hardhat is not already running and configured to run at the test-level, a Hardhat process will be spawned and torn down before and after each test, respectively.
* additional logging for debug purposes
* address PR feedback
- fix spelling
- revert change from catching ProviderError to SignerError -- this should be handled more consistently in the Market abstraction, and will be handled in another PR.
- remove method label from raiseAssert
- remove unused import
* Use API instead of command exec to test for free port
Use chronos `createStreamServer` API to test for free port by binding localhost address and port. Use `ServerFlags.ReuseAddr` to enable reuse of same IP/Port on multiple test runs.
* clean up
* remove upraises annotations from tests
* Update tests to work with updated erasure coding slot sizes
* update dataset size, nodes, tolerance to match valid ec params
Integration tests now have valid dataset sizes (blocks), tolerances, and number of nodes, to work with valid ec params. These values are validated when requested storage.
Print the rest api failure message (via doAssert) when a rest api call fails (eg the rest api may validate some ec params).
All integration tests pass when the async `clock.now` changes are reverted.
* dont use async clock for now
* fix workflow
* move integration logs uplod to reusable
---------
Co-authored-by: Dmitriy Ryajov <dryajov@gmail.com>
2024-02-19 15:55:39 +11:00
|
|
|
try:
|
2026-01-16 21:47:59 +11:00
|
|
|
lock.release()
|
|
|
|
|
except AsyncLockError as parent:
|
|
|
|
|
raiseMultiNodeSuiteError "lock error", parent
|
refactor: multinode integration test refactor (#662)
* refactor multi node test suite
Refactor the multinode test suite into the marketplace test suite.
- Arbitrary number of nodes can be started with each test: clients, providers, validators
- Hardhat can also be started locally with each test, usually for the purpose of saving and inspecting its log file.
- Log files for all nodes can be persisted on disk, with configuration at the test-level
- Log files, if persisted (as specified in the test), will be persisted to a CI artifact
- Node config is specified at the test-level instead of the suite-level
- Node/Hardhat process starting/stopping is now async, and runs much faster
- Per-node config includes:
- simulating proof failures
- logging to file
- log level
- log topics
- storage quota
- debug (print logs to stdout)
- Tests find next available ports when starting nodes, as closing ports on Windows can lag
- Hardhat is no longer required to be running prior to starting the integration tests (as long as Hardhat is configured to run in the tests).
- If Hardhat is already running, a snapshot will be taken and reverted before and after each test, respectively.
- If Hardhat is not already running and configured to run at the test-level, a Hardhat process will be spawned and torn down before and after each test, respectively.
* additional logging for debug purposes
* address PR feedback
- fix spelling
- revert change from catching ProviderError to SignerError -- this should be handled more consistently in the Market abstraction, and will be handled in another PR.
- remove method label from raiseAssert
- remove unused import
* Use API instead of command exec to test for free port
Use chronos `createStreamServer` API to test for free port by binding localhost address and port. Use `ServerFlags.ReuseAddr` to enable reuse of same IP/Port on multiple test runs.
* clean up
* remove upraises annotations from tests
* Update tests to work with updated erasure coding slot sizes
* update dataset size, nodes, tolerance to match valid ec params
Integration tests now have valid dataset sizes (blocks), tolerances, and number of nodes, to work with valid ec params. These values are validated when requested storage.
Print the rest api failure message (via doAssert) when a rest api call fails (eg the rest api may validate some ec params).
All integration tests pass when the async `clock.now` changes are reverted.
* dont use async clock for now
* fix workflow
* move integration logs uplod to reusable
---------
Co-authored-by: Dmitriy Ryajov <dryajov@gmail.com>
2024-02-19 15:55:39 +11:00
|
|
|
|
2025-03-24 16:47:05 +01:00
|
|
|
proc sanitize(pathSegment: string): string =
|
|
|
|
|
var sanitized = pathSegment
|
|
|
|
|
for invalid in invalidFilenameChars.items:
|
|
|
|
|
sanitized = sanitized.replace(invalid, '_').replace(' ', '_')
|
|
|
|
|
sanitized
|
|
|
|
|
|
|
|
|
|
proc getTempDirName*(starttime: string, role: Role, roleIdx: int): string =
|
2025-12-18 18:23:09 +01:00
|
|
|
getTempDir() / "Storage" / sanitize($starttime) / sanitize($role & "_" & $roleIdx)
|
2025-03-24 16:47:05 +01:00
|
|
|
|
2026-01-16 21:47:59 +11:00
|
|
|
template multinodesuite*(suiteName: string, body: untyped) =
|
|
|
|
|
asyncchecksuite suiteName:
|
2024-12-14 06:07:55 +01:00
|
|
|
var running {.inject, used.}: seq[RunningNode]
|
2024-12-18 15:10:36 +07:00
|
|
|
var bootstrapNodes: seq[string]
|
refactor: multinode integration test refactor (#662)
* refactor multi node test suite
Refactor the multinode test suite into the marketplace test suite.
- Arbitrary number of nodes can be started with each test: clients, providers, validators
- Hardhat can also be started locally with each test, usually for the purpose of saving and inspecting its log file.
- Log files for all nodes can be persisted on disk, with configuration at the test-level
- Log files, if persisted (as specified in the test), will be persisted to a CI artifact
- Node config is specified at the test-level instead of the suite-level
- Node/Hardhat process starting/stopping is now async, and runs much faster
- Per-node config includes:
- simulating proof failures
- logging to file
- log level
- log topics
- storage quota
- debug (print logs to stdout)
- Tests find next available ports when starting nodes, as closing ports on Windows can lag
- Hardhat is no longer required to be running prior to starting the integration tests (as long as Hardhat is configured to run in the tests).
- If Hardhat is already running, a snapshot will be taken and reverted before and after each test, respectively.
- If Hardhat is not already running and configured to run at the test-level, a Hardhat process will be spawned and torn down before and after each test, respectively.
* additional logging for debug purposes
* address PR feedback
- fix spelling
- revert change from catching ProviderError to SignerError -- this should be handled more consistently in the Market abstraction, and will be handled in another PR.
- remove method label from raiseAssert
- remove unused import
* Use API instead of command exec to test for free port
Use chronos `createStreamServer` API to test for free port by binding localhost address and port. Use `ServerFlags.ReuseAddr` to enable reuse of same IP/Port on multiple test runs.
* clean up
* remove upraises annotations from tests
* Update tests to work with updated erasure coding slot sizes
* update dataset size, nodes, tolerance to match valid ec params
Integration tests now have valid dataset sizes (blocks), tolerances, and number of nodes, to work with valid ec params. These values are validated when requested storage.
Print the rest api failure message (via doAssert) when a rest api call fails (eg the rest api may validate some ec params).
All integration tests pass when the async `clock.now` changes are reverted.
* dont use async clock for now
* fix workflow
* move integration logs uplod to reusable
---------
Co-authored-by: Dmitriy Ryajov <dryajov@gmail.com>
2024-02-19 15:55:39 +11:00
|
|
|
let starttime = now().format("yyyy-MM-dd'_'HH:mm:ss")
|
|
|
|
|
var currentTestName = ""
|
|
|
|
|
var nodeConfigs: NodeConfigs
|
|
|
|
|
var snapshot: JsonNode
|
2026-01-16 21:47:59 +11:00
|
|
|
var lastUsedHardhatPort = HardhatPort
|
2026-02-19 15:59:15 +11:00
|
|
|
var lastUsedStorageApiPort = StorageApiPort
|
|
|
|
|
var lastUsedStorageDiscPort = StorageDiscPort
|
|
|
|
|
var storagePortLock: AsyncLock
|
refactor: multinode integration test refactor (#662)
* refactor multi node test suite
Refactor the multinode test suite into the marketplace test suite.
- Arbitrary number of nodes can be started with each test: clients, providers, validators
- Hardhat can also be started locally with each test, usually for the purpose of saving and inspecting its log file.
- Log files for all nodes can be persisted on disk, with configuration at the test-level
- Log files, if persisted (as specified in the test), will be persisted to a CI artifact
- Node config is specified at the test-level instead of the suite-level
- Node/Hardhat process starting/stopping is now async, and runs much faster
- Per-node config includes:
- simulating proof failures
- logging to file
- log level
- log topics
- storage quota
- debug (print logs to stdout)
- Tests find next available ports when starting nodes, as closing ports on Windows can lag
- Hardhat is no longer required to be running prior to starting the integration tests (as long as Hardhat is configured to run in the tests).
- If Hardhat is already running, a snapshot will be taken and reverted before and after each test, respectively.
- If Hardhat is not already running and configured to run at the test-level, a Hardhat process will be spawned and torn down before and after each test, respectively.
* additional logging for debug purposes
* address PR feedback
- fix spelling
- revert change from catching ProviderError to SignerError -- this should be handled more consistently in the Market abstraction, and will be handled in another PR.
- remove method label from raiseAssert
- remove unused import
* Use API instead of command exec to test for free port
Use chronos `createStreamServer` API to test for free port by binding localhost address and port. Use `ServerFlags.ReuseAddr` to enable reuse of same IP/Port on multiple test runs.
* clean up
* remove upraises annotations from tests
* Update tests to work with updated erasure coding slot sizes
* update dataset size, nodes, tolerance to match valid ec params
Integration tests now have valid dataset sizes (blocks), tolerances, and number of nodes, to work with valid ec params. These values are validated when requested storage.
Print the rest api failure message (via doAssert) when a rest api call fails (eg the rest api may validate some ec params).
All integration tests pass when the async `clock.now` changes are reverted.
* dont use async clock for now
* fix workflow
* move integration logs uplod to reusable
---------
Co-authored-by: Dmitriy Ryajov <dryajov@gmail.com>
2024-02-19 15:55:39 +11:00
|
|
|
|
|
|
|
|
template test(tname, startNodeConfigs, tbody) =
|
|
|
|
|
currentTestName = tname
|
|
|
|
|
nodeConfigs = startNodeConfigs
|
|
|
|
|
test tname:
|
|
|
|
|
tbody
|
|
|
|
|
|
2026-01-16 21:47:59 +11:00
|
|
|
proc updatePort(url: var string, port: int) =
|
|
|
|
|
let parts = url.split(':')
|
|
|
|
|
url = @[parts[0], parts[1], $port].join(":")
|
2023-06-22 20:32:18 +10:00
|
|
|
|
2026-02-19 15:59:15 +11:00
|
|
|
proc newStorageProcess(
|
|
|
|
|
roleIdx: int, conf: StorageConfig, role: Role
|
2026-01-16 21:47:59 +11:00
|
|
|
): Future[NodeProcess] {.async: (raises: [MultiNodeSuiteError, CancelledError]).} =
|
refactor: multinode integration test refactor (#662)
* refactor multi node test suite
Refactor the multinode test suite into the marketplace test suite.
- Arbitrary number of nodes can be started with each test: clients, providers, validators
- Hardhat can also be started locally with each test, usually for the purpose of saving and inspecting its log file.
- Log files for all nodes can be persisted on disk, with configuration at the test-level
- Log files, if persisted (as specified in the test), will be persisted to a CI artifact
- Node config is specified at the test-level instead of the suite-level
- Node/Hardhat process starting/stopping is now async, and runs much faster
- Per-node config includes:
- simulating proof failures
- logging to file
- log level
- log topics
- storage quota
- debug (print logs to stdout)
- Tests find next available ports when starting nodes, as closing ports on Windows can lag
- Hardhat is no longer required to be running prior to starting the integration tests (as long as Hardhat is configured to run in the tests).
- If Hardhat is already running, a snapshot will be taken and reverted before and after each test, respectively.
- If Hardhat is not already running and configured to run at the test-level, a Hardhat process will be spawned and torn down before and after each test, respectively.
* additional logging for debug purposes
* address PR feedback
- fix spelling
- revert change from catching ProviderError to SignerError -- this should be handled more consistently in the Market abstraction, and will be handled in another PR.
- remove method label from raiseAssert
- remove unused import
* Use API instead of command exec to test for free port
Use chronos `createStreamServer` API to test for free port by binding localhost address and port. Use `ServerFlags.ReuseAddr` to enable reuse of same IP/Port on multiple test runs.
* clean up
* remove upraises annotations from tests
* Update tests to work with updated erasure coding slot sizes
* update dataset size, nodes, tolerance to match valid ec params
Integration tests now have valid dataset sizes (blocks), tolerances, and number of nodes, to work with valid ec params. These values are validated when requested storage.
Print the rest api failure message (via doAssert) when a rest api call fails (eg the rest api may validate some ec params).
All integration tests pass when the async `clock.now` changes are reverted.
* dont use async clock for now
* fix workflow
* move integration logs uplod to reusable
---------
Co-authored-by: Dmitriy Ryajov <dryajov@gmail.com>
2024-02-19 15:55:39 +11:00
|
|
|
let nodeIdx = running.len
|
2024-03-12 10:57:13 +01:00
|
|
|
var config = conf
|
2026-01-16 21:47:59 +11:00
|
|
|
let datadir = getDataDir(TestId, currentTestName, $starttime, $role, some roleIdx)
|
refactor: multinode integration test refactor (#662)
* refactor multi node test suite
Refactor the multinode test suite into the marketplace test suite.
- Arbitrary number of nodes can be started with each test: clients, providers, validators
- Hardhat can also be started locally with each test, usually for the purpose of saving and inspecting its log file.
- Log files for all nodes can be persisted on disk, with configuration at the test-level
- Log files, if persisted (as specified in the test), will be persisted to a CI artifact
- Node config is specified at the test-level instead of the suite-level
- Node/Hardhat process starting/stopping is now async, and runs much faster
- Per-node config includes:
- simulating proof failures
- logging to file
- log level
- log topics
- storage quota
- debug (print logs to stdout)
- Tests find next available ports when starting nodes, as closing ports on Windows can lag
- Hardhat is no longer required to be running prior to starting the integration tests (as long as Hardhat is configured to run in the tests).
- If Hardhat is already running, a snapshot will be taken and reverted before and after each test, respectively.
- If Hardhat is not already running and configured to run at the test-level, a Hardhat process will be spawned and torn down before and after each test, respectively.
* additional logging for debug purposes
* address PR feedback
- fix spelling
- revert change from catching ProviderError to SignerError -- this should be handled more consistently in the Market abstraction, and will be handled in another PR.
- remove method label from raiseAssert
- remove unused import
* Use API instead of command exec to test for free port
Use chronos `createStreamServer` API to test for free port by binding localhost address and port. Use `ServerFlags.ReuseAddr` to enable reuse of same IP/Port on multiple test runs.
* clean up
* remove upraises annotations from tests
* Update tests to work with updated erasure coding slot sizes
* update dataset size, nodes, tolerance to match valid ec params
Integration tests now have valid dataset sizes (blocks), tolerances, and number of nodes, to work with valid ec params. These values are validated when requested storage.
Print the rest api failure message (via doAssert) when a rest api call fails (eg the rest api may validate some ec params).
All integration tests pass when the async `clock.now` changes are reverted.
* dont use async clock for now
* fix workflow
* move integration logs uplod to reusable
---------
Co-authored-by: Dmitriy Ryajov <dryajov@gmail.com>
2024-02-19 15:55:39 +11:00
|
|
|
|
2024-03-12 10:57:13 +01:00
|
|
|
try:
|
2026-02-19 15:59:15 +11:00
|
|
|
if config.logFile.isSome or StorageLogToFile:
|
2026-01-16 21:47:59 +11:00
|
|
|
try:
|
|
|
|
|
let updatedLogFile = getLogFile(
|
2026-02-19 15:59:15 +11:00
|
|
|
StorageLogsDir, starttime, suiteName, currentTestName, $role, some roleIdx
|
2026-01-16 21:47:59 +11:00
|
|
|
)
|
|
|
|
|
config.withLogFile(updatedLogFile)
|
|
|
|
|
except IOError as e:
|
|
|
|
|
raiseMultiNodeSuiteError(
|
|
|
|
|
"failed to start " & $role &
|
|
|
|
|
" because logfile path could not be obtained: " & e.msg,
|
|
|
|
|
e,
|
|
|
|
|
)
|
|
|
|
|
except OSError as e:
|
|
|
|
|
raiseMultiNodeSuiteError(
|
|
|
|
|
"failed to start " & $role &
|
|
|
|
|
" because logfile path could not be obtained: " & e.msg,
|
|
|
|
|
e,
|
|
|
|
|
)
|
|
|
|
|
|
2026-02-19 15:59:15 +11:00
|
|
|
when StorageLogLevel != "":
|
|
|
|
|
config.addCliOption("--log-level", StorageLogLevel)
|
2026-01-16 21:47:59 +11:00
|
|
|
|
|
|
|
|
var apiPort, discPort: int
|
2026-02-19 15:59:15 +11:00
|
|
|
withLock(storagePortLock):
|
|
|
|
|
apiPort = await nextFreePort(lastUsedStorageApiPort + nodeIdx)
|
|
|
|
|
discPort = await nextFreePort(lastUsedStorageDiscPort + nodeIdx)
|
2026-01-16 21:47:59 +11:00
|
|
|
config.addCliOption("--api-port", $apiPort)
|
|
|
|
|
config.addCliOption("--disc-port", $discPort)
|
2026-02-19 15:59:15 +11:00
|
|
|
lastUsedStorageApiPort = apiPort
|
|
|
|
|
lastUsedStorageDiscPort = discPort
|
2024-03-12 10:57:13 +01:00
|
|
|
|
2024-12-18 15:10:36 +07:00
|
|
|
for bootstrapNode in bootstrapNodes:
|
|
|
|
|
config.addCliOption("--bootstrap-node", bootstrapNode)
|
2026-01-16 21:47:59 +11:00
|
|
|
|
2024-03-12 10:57:13 +01:00
|
|
|
config.addCliOption("--data-dir", datadir)
|
2025-01-09 23:41:22 +05:30
|
|
|
config.addCliOption("--nat", "none")
|
2024-03-12 10:57:13 +01:00
|
|
|
config.addCliOption("--listen-addrs", "/ip4/127.0.0.1/tcp/0")
|
2026-02-19 15:59:15 +11:00
|
|
|
except StorageConfigError as e:
|
2024-03-12 10:57:13 +01:00
|
|
|
raiseMultiNodeSuiteError "invalid cli option, error: " & e.msg
|
|
|
|
|
|
|
|
|
|
try:
|
2026-02-19 15:59:15 +11:00
|
|
|
let node = await StorageProcess.startNode(
|
2026-01-16 21:47:59 +11:00
|
|
|
config.cliArgs, config.debugEnabled, $role & $roleIdx
|
|
|
|
|
)
|
2024-03-12 10:57:13 +01:00
|
|
|
await node.waitUntilStarted()
|
|
|
|
|
trace "node started", nodeName = $role & $roleIdx
|
2026-01-16 21:47:59 +11:00
|
|
|
return node
|
2026-02-19 15:59:15 +11:00
|
|
|
except StorageConfigError as e:
|
2026-01-16 21:47:59 +11:00
|
|
|
raiseMultiNodeSuiteError "failed to get cli args from config: " & e.msg, e
|
2024-03-12 10:57:13 +01:00
|
|
|
except NodeProcessError as e:
|
2026-01-16 21:47:59 +11:00
|
|
|
raiseMultiNodeSuiteError "node not started, error: " & e.msg, e
|
refactor: multinode integration test refactor (#662)
* refactor multi node test suite
Refactor the multinode test suite into the marketplace test suite.
- Arbitrary number of nodes can be started with each test: clients, providers, validators
- Hardhat can also be started locally with each test, usually for the purpose of saving and inspecting its log file.
- Log files for all nodes can be persisted on disk, with configuration at the test-level
- Log files, if persisted (as specified in the test), will be persisted to a CI artifact
- Node config is specified at the test-level instead of the suite-level
- Node/Hardhat process starting/stopping is now async, and runs much faster
- Per-node config includes:
- simulating proof failures
- logging to file
- log level
- log topics
- storage quota
- debug (print logs to stdout)
- Tests find next available ports when starting nodes, as closing ports on Windows can lag
- Hardhat is no longer required to be running prior to starting the integration tests (as long as Hardhat is configured to run in the tests).
- If Hardhat is already running, a snapshot will be taken and reverted before and after each test, respectively.
- If Hardhat is not already running and configured to run at the test-level, a Hardhat process will be spawned and torn down before and after each test, respectively.
* additional logging for debug purposes
* address PR feedback
- fix spelling
- revert change from catching ProviderError to SignerError -- this should be handled more consistently in the Market abstraction, and will be handled in another PR.
- remove method label from raiseAssert
- remove unused import
* Use API instead of command exec to test for free port
Use chronos `createStreamServer` API to test for free port by binding localhost address and port. Use `ServerFlags.ReuseAddr` to enable reuse of same IP/Port on multiple test runs.
* clean up
* remove upraises annotations from tests
* Update tests to work with updated erasure coding slot sizes
* update dataset size, nodes, tolerance to match valid ec params
Integration tests now have valid dataset sizes (blocks), tolerances, and number of nodes, to work with valid ec params. These values are validated when requested storage.
Print the rest api failure message (via doAssert) when a rest api call fails (eg the rest api may validate some ec params).
All integration tests pass when the async `clock.now` changes are reverted.
* dont use async clock for now
* fix workflow
* move integration logs uplod to reusable
---------
Co-authored-by: Dmitriy Ryajov <dryajov@gmail.com>
2024-02-19 15:55:39 +11:00
|
|
|
|
2026-02-19 15:59:15 +11:00
|
|
|
proc clients(): seq[StorageProcess] {.used.} =
|
refactor: multinode integration test refactor (#662)
* refactor multi node test suite
Refactor the multinode test suite into the marketplace test suite.
- Arbitrary number of nodes can be started with each test: clients, providers, validators
- Hardhat can also be started locally with each test, usually for the purpose of saving and inspecting its log file.
- Log files for all nodes can be persisted on disk, with configuration at the test-level
- Log files, if persisted (as specified in the test), will be persisted to a CI artifact
- Node config is specified at the test-level instead of the suite-level
- Node/Hardhat process starting/stopping is now async, and runs much faster
- Per-node config includes:
- simulating proof failures
- logging to file
- log level
- log topics
- storage quota
- debug (print logs to stdout)
- Tests find next available ports when starting nodes, as closing ports on Windows can lag
- Hardhat is no longer required to be running prior to starting the integration tests (as long as Hardhat is configured to run in the tests).
- If Hardhat is already running, a snapshot will be taken and reverted before and after each test, respectively.
- If Hardhat is not already running and configured to run at the test-level, a Hardhat process will be spawned and torn down before and after each test, respectively.
* additional logging for debug purposes
* address PR feedback
- fix spelling
- revert change from catching ProviderError to SignerError -- this should be handled more consistently in the Market abstraction, and will be handled in another PR.
- remove method label from raiseAssert
- remove unused import
* Use API instead of command exec to test for free port
Use chronos `createStreamServer` API to test for free port by binding localhost address and port. Use `ServerFlags.ReuseAddr` to enable reuse of same IP/Port on multiple test runs.
* clean up
* remove upraises annotations from tests
* Update tests to work with updated erasure coding slot sizes
* update dataset size, nodes, tolerance to match valid ec params
Integration tests now have valid dataset sizes (blocks), tolerances, and number of nodes, to work with valid ec params. These values are validated when requested storage.
Print the rest api failure message (via doAssert) when a rest api call fails (eg the rest api may validate some ec params).
All integration tests pass when the async `clock.now` changes are reverted.
* dont use async clock for now
* fix workflow
* move integration logs uplod to reusable
---------
Co-authored-by: Dmitriy Ryajov <dryajov@gmail.com>
2024-02-19 15:55:39 +11:00
|
|
|
return collect:
|
|
|
|
|
for r in running:
|
|
|
|
|
if r.role == Role.Client:
|
2026-02-19 15:59:15 +11:00
|
|
|
StorageProcess(r.node)
|
refactor: multinode integration test refactor (#662)
* refactor multi node test suite
Refactor the multinode test suite into the marketplace test suite.
- Arbitrary number of nodes can be started with each test: clients, providers, validators
- Hardhat can also be started locally with each test, usually for the purpose of saving and inspecting its log file.
- Log files for all nodes can be persisted on disk, with configuration at the test-level
- Log files, if persisted (as specified in the test), will be persisted to a CI artifact
- Node config is specified at the test-level instead of the suite-level
- Node/Hardhat process starting/stopping is now async, and runs much faster
- Per-node config includes:
- simulating proof failures
- logging to file
- log level
- log topics
- storage quota
- debug (print logs to stdout)
- Tests find next available ports when starting nodes, as closing ports on Windows can lag
- Hardhat is no longer required to be running prior to starting the integration tests (as long as Hardhat is configured to run in the tests).
- If Hardhat is already running, a snapshot will be taken and reverted before and after each test, respectively.
- If Hardhat is not already running and configured to run at the test-level, a Hardhat process will be spawned and torn down before and after each test, respectively.
* additional logging for debug purposes
* address PR feedback
- fix spelling
- revert change from catching ProviderError to SignerError -- this should be handled more consistently in the Market abstraction, and will be handled in another PR.
- remove method label from raiseAssert
- remove unused import
* Use API instead of command exec to test for free port
Use chronos `createStreamServer` API to test for free port by binding localhost address and port. Use `ServerFlags.ReuseAddr` to enable reuse of same IP/Port on multiple test runs.
* clean up
* remove upraises annotations from tests
* Update tests to work with updated erasure coding slot sizes
* update dataset size, nodes, tolerance to match valid ec params
Integration tests now have valid dataset sizes (blocks), tolerances, and number of nodes, to work with valid ec params. These values are validated when requested storage.
Print the rest api failure message (via doAssert) when a rest api call fails (eg the rest api may validate some ec params).
All integration tests pass when the async `clock.now` changes are reverted.
* dont use async clock for now
* fix workflow
* move integration logs uplod to reusable
---------
Co-authored-by: Dmitriy Ryajov <dryajov@gmail.com>
2024-02-19 15:55:39 +11:00
|
|
|
|
2026-02-19 15:59:15 +11:00
|
|
|
proc startClientNode(conf: StorageConfig): Future[NodeProcess] {.async.} =
|
refactor: multinode integration test refactor (#662)
* refactor multi node test suite
Refactor the multinode test suite into the marketplace test suite.
- Arbitrary number of nodes can be started with each test: clients, providers, validators
- Hardhat can also be started locally with each test, usually for the purpose of saving and inspecting its log file.
- Log files for all nodes can be persisted on disk, with configuration at the test-level
- Log files, if persisted (as specified in the test), will be persisted to a CI artifact
- Node config is specified at the test-level instead of the suite-level
- Node/Hardhat process starting/stopping is now async, and runs much faster
- Per-node config includes:
- simulating proof failures
- logging to file
- log level
- log topics
- storage quota
- debug (print logs to stdout)
- Tests find next available ports when starting nodes, as closing ports on Windows can lag
- Hardhat is no longer required to be running prior to starting the integration tests (as long as Hardhat is configured to run in the tests).
- If Hardhat is already running, a snapshot will be taken and reverted before and after each test, respectively.
- If Hardhat is not already running and configured to run at the test-level, a Hardhat process will be spawned and torn down before and after each test, respectively.
* additional logging for debug purposes
* address PR feedback
- fix spelling
- revert change from catching ProviderError to SignerError -- this should be handled more consistently in the Market abstraction, and will be handled in another PR.
- remove method label from raiseAssert
- remove unused import
* Use API instead of command exec to test for free port
Use chronos `createStreamServer` API to test for free port by binding localhost address and port. Use `ServerFlags.ReuseAddr` to enable reuse of same IP/Port on multiple test runs.
* clean up
* remove upraises annotations from tests
* Update tests to work with updated erasure coding slot sizes
* update dataset size, nodes, tolerance to match valid ec params
Integration tests now have valid dataset sizes (blocks), tolerances, and number of nodes, to work with valid ec params. These values are validated when requested storage.
Print the rest api failure message (via doAssert) when a rest api call fails (eg the rest api may validate some ec params).
All integration tests pass when the async `clock.now` changes are reverted.
* dont use async clock for now
* fix workflow
* move integration logs uplod to reusable
---------
Co-authored-by: Dmitriy Ryajov <dryajov@gmail.com>
2024-02-19 15:55:39 +11:00
|
|
|
let clientIdx = clients().len
|
2026-02-19 15:59:15 +11:00
|
|
|
return await newStorageProcess(clientIdx, conf, Role.Client)
|
2023-06-22 20:32:18 +10:00
|
|
|
|
2026-01-17 06:03:54 +11:00
|
|
|
proc teardownImpl() {.async.} =
|
|
|
|
|
for nodes in @[clients()]:
|
2024-03-12 10:57:13 +01:00
|
|
|
for node in nodes:
|
|
|
|
|
await node.stop() # also stops rest client
|
2026-01-16 21:47:59 +11:00
|
|
|
try:
|
|
|
|
|
node.removeDataDir()
|
2026-02-19 15:59:15 +11:00
|
|
|
except StorageProcessError as e:
|
2026-01-16 21:47:59 +11:00
|
|
|
error "Failed to remove data dir during teardown", error = e.msg
|
2024-03-12 10:57:13 +01:00
|
|
|
|
|
|
|
|
running = @[]
|
|
|
|
|
|
|
|
|
|
template failAndTeardownOnError(message: string, tryBody: untyped) =
|
|
|
|
|
try:
|
|
|
|
|
tryBody
|
2026-01-16 21:47:59 +11:00
|
|
|
except CancelledError as e:
|
|
|
|
|
await teardownImpl()
|
|
|
|
|
when declared(teardownAllIMPL):
|
|
|
|
|
teardownAllIMPL()
|
|
|
|
|
fail()
|
|
|
|
|
quit(1)
|
2024-03-12 10:57:13 +01:00
|
|
|
except CatchableError as er:
|
|
|
|
|
fatal message, error = er.msg
|
|
|
|
|
echo "[FATAL] ", message, ": ", er.msg
|
|
|
|
|
await teardownImpl()
|
|
|
|
|
when declared(teardownAllIMPL):
|
|
|
|
|
teardownAllIMPL()
|
|
|
|
|
fail()
|
|
|
|
|
quit(1)
|
|
|
|
|
|
2025-03-17 17:08:24 -03:00
|
|
|
proc updateBootstrapNodes(
|
2026-02-19 15:59:15 +11:00
|
|
|
node: StorageProcess
|
2026-01-16 21:47:59 +11:00
|
|
|
): Future[void] {.async: (raises: [MultiNodeSuiteError]).} =
|
|
|
|
|
try:
|
|
|
|
|
without ninfo =? await node.client.info():
|
|
|
|
|
# raise CatchableError instead of Defect (with .get or !) so we
|
|
|
|
|
# can gracefully shutdown and prevent zombies
|
|
|
|
|
raiseMultiNodeSuiteError "Failed to get node info"
|
|
|
|
|
bootstrapNodes.add ninfo["spr"].getStr()
|
|
|
|
|
except CatchableError as e:
|
|
|
|
|
raiseMultiNodeSuiteError "Failed to get node info: " & e.msg, e
|
|
|
|
|
|
|
|
|
|
setupAll:
|
|
|
|
|
# When this file is run with `-d:chronicles_sinks=textlines[file]`, we
|
|
|
|
|
# need to set the log file path at runtime, otherwise chronicles didn't seem to
|
|
|
|
|
# create a log file even when using an absolute path
|
2026-02-19 15:59:15 +11:00
|
|
|
when defaultChroniclesStream.outputs is (FileOutput,) and StorageLogsDir.len > 0:
|
2026-01-16 21:47:59 +11:00
|
|
|
let logFile =
|
2026-02-19 15:59:15 +11:00
|
|
|
StorageLogsDir / sanitize(
|
|
|
|
|
getAppFilename().extractFilename & ".chronicles.log"
|
|
|
|
|
)
|
2026-01-16 21:47:59 +11:00
|
|
|
let success = defaultChroniclesStream.outputs[0].open(logFile, fmAppend)
|
|
|
|
|
doAssert success, "Failed to open log file: " & logFile
|
2024-12-18 15:10:36 +07:00
|
|
|
|
2023-06-22 20:32:18 +10:00
|
|
|
setup:
|
2026-01-16 21:47:59 +11:00
|
|
|
trace "Setting up test", suite = suiteName, test = currentTestName, nodeConfigs
|
2024-03-12 10:57:13 +01:00
|
|
|
if var clients =? nodeConfigs.clients:
|
|
|
|
|
failAndTeardownOnError "failed to start client nodes":
|
|
|
|
|
for config in clients.configs:
|
|
|
|
|
let node = await startClientNode(config)
|
|
|
|
|
running.add RunningNode(role: Role.Client, node: node)
|
2026-02-19 15:59:15 +11:00
|
|
|
await StorageProcess(node).updateBootstrapNodes()
|
2024-03-12 10:57:13 +01:00
|
|
|
|
2023-06-22 20:32:18 +10:00
|
|
|
teardown:
|
2024-03-12 10:57:13 +01:00
|
|
|
await teardownImpl()
|
2026-01-16 21:47:59 +11:00
|
|
|
trace "Test completed", suite = suiteName, test = currentTestName
|
2023-06-22 20:32:18 +10:00
|
|
|
|
|
|
|
|
body
|