From ed7d19ce21e68221218585a582da545e1af01829 Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Wed, 18 Dec 2024 17:29:50 +0100 Subject: [PATCH] add function docs to non-deprecated packages (#1500) --- lib/client/github.go | 2 + lib/client/mockserver.go | 3 ++ lib/client/postgres.go | 2 + lib/client/rpc.go | 7 +++ lib/docker/docker.go | 2 + lib/docker/test_env/besu_base.go | 31 +++++++++++- lib/docker/test_env/env_component.go | 21 ++++++++ lib/docker/test_env/erigon_base.go | 30 ++++++++++- lib/docker/test_env/eth2_init_helpers.go | 6 +++ lib/docker/test_env/eth_common.go | 2 +- lib/docker/test_env/ethereum_env.go | 50 +++++++++++++++++++ lib/docker/test_env/genesis_generator.go | 9 ++++ .../test_env/genesis_generator_helpers.go | 9 ++++ lib/docker/test_env/geth_base.go | 30 ++++++++++- lib/docker/test_env/job_distributor/jd.go | 28 +++++++++++ lib/docker/test_env/kafka.go | 20 ++++++++ lib/docker/test_env/killgrave.go | 14 ++++++ lib/docker/test_env/mockserver.go | 11 ++++ lib/docker/test_env/nethermind_base.go | 31 +++++++++++- lib/docker/test_env/postgres.go | 20 ++++++++ lib/docker/test_env/prysm.go | 13 +++++ lib/docker/test_env/reth_base.go | 32 +++++++++++- lib/docker/test_env/schema_registry.go | 17 +++++++ lib/docker/test_env/utils.go | 8 +++ .../test_env/validator_keys_generator.go | 6 +++ lib/docker/test_env/wait_strategy.go | 13 +++++ lib/docker/test_env/zookeeper.go | 9 ++++ lib/grafana/client.go | 40 +++++++++++++++ lib/logging/log.go | 5 ++ 29 files changed, 465 insertions(+), 6 deletions(-) diff --git a/lib/client/github.go b/lib/client/github.go index 6533bbf93..417ec0558 100644 --- a/lib/client/github.go +++ b/lib/client/github.go @@ -17,6 +17,8 @@ type GithubClient struct { const WITHOUT_TOKEN = "" +// NewGithubClient creates a new instance of GithubClient, optionally authenticating with a personal access token. +// This is useful for making authenticated requests to the GitHub API, helping to avoid rate limits. func NewGithubClient(token string) *GithubClient { // Optional: Authenticate with a personal access token if necessary // This is recommended to avoid rate limits for unauthenticated requests diff --git a/lib/client/mockserver.go b/lib/client/mockserver.go index ceb8027e0..9a46cdf75 100644 --- a/lib/client/mockserver.go +++ b/lib/client/mockserver.go @@ -160,6 +160,9 @@ func (em *MockserverClient) SetAnyValuePath(path string, v interface{}) error { return err } +// SetAnyValueResponse configures a mock server to return a specified value for a given path. +// It ensures the path starts with a '/', sanitizes it, and logs the operation. +// This function is useful for testing and simulating API responses in a controlled environment. func (em *MockserverClient) SetAnyValueResponse(path string, v interface{}) error { if !strings.HasPrefix(path, "/") { path = fmt.Sprintf("/%s", path) diff --git a/lib/client/postgres.go b/lib/client/postgres.go index 33b6da694..c786bd4c2 100644 --- a/lib/client/postgres.go +++ b/lib/client/postgres.go @@ -54,6 +54,8 @@ func NewPostgresConnector(cfg *PostgresConfig) (*PostgresConnector, error) { return &PostgresConnector{DB: db, Cfg: cfg}, nil } +// ConnectDB establishes a connection to a PostgreSQL database using the provided environment settings. +// It returns a PostgresConnector instance or an error if the connection fails. func ConnectDB(nodeNum int, e *environment.Environment) (*PostgresConnector, error) { spl := strings.Split(e.URLs["chainlink_db"][nodeNum], ":") port := spl[len(spl)-1] diff --git a/lib/client/rpc.go b/lib/client/rpc.go index 46b6dd1de..e7dad5343 100644 --- a/lib/client/rpc.go +++ b/lib/client/rpc.go @@ -233,6 +233,10 @@ func (m *RPCClient) BlockNumber() (int64, error) { return bn, nil } +// GethSetHead sets the Ethereum node's head to a specified block in the past. +// This function is useful for testing and debugging by allowing developers to +// manipulate the blockchain state to a previous block. It returns an error +// if the operation fails. func (m *RPCClient) GethSetHead(blocksBack int) error { decimalLastBlock, err := m.BlockNumber() if err != nil { @@ -274,6 +278,9 @@ type GethContainer struct { URL string } +// StartAnvil initializes and starts an Anvil container for Ethereum development. +// It returns an AnvilContainer instance containing the container and its accessible URL. +// This function is useful for developers needing a local Ethereum node for testing and development. func StartAnvil(params []string) (*AnvilContainer, error) { entryPoint := []string{"anvil", "--host", "0.0.0.0"} entryPoint = append(entryPoint, params...) diff --git a/lib/docker/docker.go b/lib/docker/docker.go index 67712aecc..bc728deaa 100644 --- a/lib/docker/docker.go +++ b/lib/docker/docker.go @@ -15,6 +15,8 @@ import ( const RetryAttempts = 3 const defaultRyukImage = "testcontainers/ryuk:0.5.1" +// CreateNetwork initializes a new Docker network with a unique name. +// It ensures no duplicate networks exist and returns the created network or an error if the operation fails. func CreateNetwork(l zerolog.Logger) (*tc.DockerNetwork, error) { uuidObj, _ := uuid.NewRandom() var networkName = fmt.Sprintf("network-%s", uuidObj.String()) diff --git a/lib/docker/test_env/besu_base.go b/lib/docker/test_env/besu_base.go index 4339156ce..7093f1098 100644 --- a/lib/docker/test_env/besu_base.go +++ b/lib/docker/test_env/besu_base.go @@ -44,12 +44,17 @@ type Besu struct { powSettings } +// WithTestInstance sets up the execution client for testing by assigning a test logger and the testing context. +// This allows for better logging and error tracking during test execution. func (g *Besu) WithTestInstance(t *testing.T) ExecutionClient { g.l = logging.GetTestLogger(t) g.t = t return g } +// StartContainer initializes and starts a Besu container for Ethereum execution. +// It configures network settings based on the Ethereum version and returns the +// network configuration along with any errors encountered during the process. func (g *Besu) StartContainer() (blockchain.EVMNetwork, error) { var r *tc.ContainerRequest var err error @@ -121,6 +126,9 @@ func (g *Besu) StartContainer() (blockchain.EVMNetwork, error) { return networkConfig, nil } +// GetInternalExecutionURL returns the internal execution URL for the Besu client. +// It is used to retrieve the endpoint for executing transactions in Ethereum 2.0 networks, +// ensuring compatibility with the Ethereum version in use. func (g *Besu) GetInternalExecutionURL() string { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { panic("eth1 node doesn't have an execution URL") @@ -128,6 +136,8 @@ func (g *Besu) GetInternalExecutionURL() string { return g.InternalExecutionURL } +// GetExternalExecutionURL returns the external execution URL for the Besu instance. +// It panics if the Ethereum version is Eth1, as Eth1 nodes do not support execution URLs. func (g *Besu) GetExternalExecutionURL() string { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { panic("eth1 node doesn't have an execution URL") @@ -135,34 +145,50 @@ func (g *Besu) GetExternalExecutionURL() string { return g.ExternalExecutionURL } +// GetInternalHttpUrl returns the internal HTTP URL of the Besu client. +// This URL is essential for establishing communication with the Besu node in a private network setup. func (g *Besu) GetInternalHttpUrl() string { return g.InternalHttpUrl } +// GetInternalWsUrl returns the internal WebSocket URL for the Besu client. +// This URL is essential for establishing WebSocket connections to the Besu node for real-time data and event subscriptions. func (g *Besu) GetInternalWsUrl() string { return g.InternalWsUrl } +// GetExternalHttpUrl returns the external HTTP URL of the Besu client. +// This URL is used to interact with the Besu node from external applications or services. func (g *Besu) GetExternalHttpUrl() string { return g.ExternalHttpUrl } +// GetExternalWsUrl returns the external WebSocket URL for the Besu client. +// This URL is essential for connecting to the Besu node from external services or clients. func (g *Besu) GetExternalWsUrl() string { return g.ExternalWsUrl } +// GetContainerName returns the name of the container associated with the Besu instance. +// This function is useful for identifying and managing the container in a Docker environment. func (g *Besu) GetContainerName() string { return g.ContainerName } +// GetContainer returns a pointer to the container associated with the Besu instance. +// This function is useful for accessing the container's properties and methods in other operations. func (g *Besu) GetContainer() *tc.Container { return &g.Container } +// GetEthereumVersion returns the current Ethereum version of the Besu instance. +// This information is crucial for determining the appropriate container configuration and consensus mechanism. func (g *Besu) GetEthereumVersion() config_types.EthereumVersion { return g.ethereumVersion } +// WaitUntilChainIsReady blocks until the Ethereum chain is ready for operations. +// It is useful for ensuring that the execution client has fully synchronized with the network before proceeding with further actions. func (g *Besu) WaitUntilChainIsReady(ctx context.Context, waitTime time.Duration) error { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { return nil @@ -171,7 +197,10 @@ func (g *Besu) WaitUntilChainIsReady(ctx context.Context, waitTime time.Duration return waitForFirstBlock.WaitUntilReady(ctx, *g.GetContainer()) } -func (g *Besu) GethConsensusMechanism() ConsensusMechanism { +// GetConsensusMechanism returns the consensus mechanism used by the Besu instance. +// It identifies whether the Ethereum version is Eth1 or not, returning either Proof of Authority (PoA) +// or Proof of Stake (PoS) accordingly. This is useful for understanding the network's validation method. +func (g *Besu) GetConsensusMechanism() ConsensusMechanism { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { return ConsensusMechanism_PoA } diff --git a/lib/docker/test_env/env_component.go b/lib/docker/test_env/env_component.go index 6a17ac11e..faad24c3f 100644 --- a/lib/docker/test_env/env_component.go +++ b/lib/docker/test_env/env_component.go @@ -33,6 +33,9 @@ type EnvComponent struct { type EnvComponentOption = func(c *EnvComponent) +// WithContainerName sets the container name for an EnvComponent. +// It allows customization of the container's identity, enhancing clarity +// and organization in containerized environments. func WithContainerName(name string) EnvComponentOption { return func(c *EnvComponent) { if name != "" { @@ -41,6 +44,9 @@ func WithContainerName(name string) EnvComponentOption { } } +// WithStartupTimeout sets a custom startup timeout for an EnvComponent. +// This option allows users to specify how long to wait for the component to start +// before timing out, enhancing control over component initialization. func WithStartupTimeout(timeout time.Duration) EnvComponentOption { return func(c *EnvComponent) { if timeout != 0 { @@ -49,6 +55,9 @@ func WithStartupTimeout(timeout time.Duration) EnvComponentOption { } } +// WithContainerImageWithVersion sets the container image and version for an EnvComponent. +// It splits the provided image string by ':' and assigns the values accordingly. +// This function is useful for configuring specific container images in a deployment. func WithContainerImageWithVersion(imageWithVersion string) EnvComponentOption { return func(c *EnvComponent) { split := strings.Split(imageWithVersion, ":") @@ -59,6 +68,8 @@ func WithContainerImageWithVersion(imageWithVersion string) EnvComponentOption { } } +// WithLogLevel sets the logging level for an environment component. +// It allows customization of log verbosity, enhancing debugging and monitoring capabilities. func WithLogLevel(logLevel string) EnvComponentOption { return func(c *EnvComponent) { if logLevel != "" { @@ -67,28 +78,38 @@ func WithLogLevel(logLevel string) EnvComponentOption { } } +// WithPostStartsHooks sets the PostStarts hooks for an EnvComponent. +// This allows users to define custom actions that should occur after the component starts. func WithPostStartsHooks(hooks ...tc.ContainerHook) EnvComponentOption { return func(c *EnvComponent) { c.PostStartsHooks = hooks } } +// WithPostStopsHooks sets the PostStops hooks for an EnvComponent. +// This allows users to define custom actions that should occur after the component stops. func WithPostStopsHooks(hooks ...tc.ContainerHook) EnvComponentOption { return func(c *EnvComponent) { c.PostStopsHooks = hooks } } +// WithPreTerminatesHooks sets the pre-termination hooks for an EnvComponent. +// This allows users to define custom behavior that should occur before the component is terminated. func WithPreTerminatesHooks(hooks ...tc.ContainerHook) EnvComponentOption { return func(c *EnvComponent) { c.PreTerminatesHooks = hooks } } +// SetDefaultHooks initializes the default hooks for the environment component. +// This function is useful for ensuring that the component has a consistent starting state before further configuration. func (ec *EnvComponent) SetDefaultHooks() { // no default hooks } +// GetImageWithVersion returns the container image name combined with its version. +// This function is useful for generating a complete image identifier needed for container requests. func (ec *EnvComponent) GetImageWithVersion() string { return fmt.Sprintf("%s:%s", ec.ContainerImage, ec.ContainerVersion) } diff --git a/lib/docker/test_env/erigon_base.go b/lib/docker/test_env/erigon_base.go index d1eb687f5..9fac91c74 100644 --- a/lib/docker/test_env/erigon_base.go +++ b/lib/docker/test_env/erigon_base.go @@ -36,12 +36,17 @@ type Erigon struct { posContainerSettings } +// WithTestInstance sets up the execution client with a test logger and test context. +// This is useful for running tests that require a specific logging setup and context. func (g *Erigon) WithTestInstance(t *testing.T) ExecutionClient { g.l = logging.GetTestLogger(t) g.t = t return g } +// StartContainer initializes and starts an Erigon container for Ethereum execution. +// It configures network settings based on the Ethereum version and returns the +// blockchain network configuration along with any errors encountered during the process. func (g *Erigon) StartContainer() (blockchain.EVMNetwork, error) { var r *tc.ContainerRequest var err error @@ -105,6 +110,9 @@ func (g *Erigon) StartContainer() (blockchain.EVMNetwork, error) { return networkConfig, nil } +// GetInternalExecutionURL returns the internal execution URL for the Erigon client. +// It is used to retrieve the execution layer's endpoint, essential for connecting to the Ethereum network. +// If the Ethereum version is Eth1, it panics as Eth1 nodes do not support execution URLs. func (g *Erigon) GetInternalExecutionURL() string { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { panic("eth1 node doesn't have an execution URL") @@ -112,6 +120,8 @@ func (g *Erigon) GetInternalExecutionURL() string { return g.InternalExecutionURL } +// GetExternalExecutionURL returns the external execution URL for the Erigon instance. +// It panics if the Ethereum version is Eth1, as Eth1 nodes do not support execution URLs. func (g *Erigon) GetExternalExecutionURL() string { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { panic("eth1 node doesn't have an execution URL") @@ -119,34 +129,50 @@ func (g *Erigon) GetExternalExecutionURL() string { return g.ExternalExecutionURL } +// GetInternalHttpUrl returns the internal HTTP URL of the Erigon client. +// This URL is used to connect to the Erigon execution layer for internal communications. func (g *Erigon) GetInternalHttpUrl() string { return g.InternalHttpUrl } +// GetInternalWsUrl returns the internal WebSocket URL for the Erigon client. +// This URL is used to establish a WebSocket connection for real-time communication with the Erigon node. func (g *Erigon) GetInternalWsUrl() string { return g.InternalWsUrl } +// GetExternalHttpUrl returns the external HTTP URL for the Erigon client. +// This URL is used to interact with the Erigon execution layer over HTTP. func (g *Erigon) GetExternalHttpUrl() string { return g.ExternalHttpUrl } +// GetExternalWsUrl returns the external WebSocket URL for the Erigon client. +// This URL is essential for connecting to the Erigon node for real-time data and event subscriptions. func (g *Erigon) GetExternalWsUrl() string { return g.ExternalWsUrl } +// GetContainerName returns the name of the container associated with the Erigon instance. +// This function is useful for identifying and managing the container in a Docker environment. func (g *Erigon) GetContainerName() string { return g.ContainerName } +// GetContainer returns a pointer to the Container associated with the Erigon instance. +// This function is useful for accessing the container's properties and methods in a structured manner. func (g *Erigon) GetContainer() *tc.Container { return &g.Container } +// GetEthereumVersion returns the current Ethereum version of the Erigon instance. +// This information is essential for determining the appropriate execution URLs and consensus mechanisms. func (g *Erigon) GetEthereumVersion() config_types.EthereumVersion { return g.ethereumVersion } +// WaitUntilChainIsReady blocks until the Ethereum chain is ready for use, waiting for the first block to be built. +// It returns an error if the chain does not become ready within the specified wait time. func (g *Erigon) WaitUntilChainIsReady(ctx context.Context, waitTime time.Duration) error { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { return nil @@ -155,7 +181,9 @@ func (g *Erigon) WaitUntilChainIsReady(ctx context.Context, waitTime time.Durati return waitForFirstBlock.WaitUntilReady(ctx, *g.GetContainer()) } -func (g *Erigon) GethConsensusMechanism() ConsensusMechanism { +// GetConsensusMechanism returns the consensus mechanism used by the Erigon instance. +// It identifies whether the Ethereum version is Eth1 (Proof of Work) or a later version (Proof of Stake). +func (g *Erigon) GetConsensusMechanism() ConsensusMechanism { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { return ConsensusMechanism_PoW } diff --git a/lib/docker/test_env/eth2_init_helpers.go b/lib/docker/test_env/eth2_init_helpers.go index 9ea440039..9f45da2a0 100644 --- a/lib/docker/test_env/eth2_init_helpers.go +++ b/lib/docker/test_env/eth2_init_helpers.go @@ -29,6 +29,8 @@ type AfterGenesisHelper struct { posContainerSettings } +// NewInitHelper initializes a new AfterGenesisHelper instance with the provided chain configuration and directory paths. +// It sets up necessary environment components and options, facilitating the management of post-genesis operations in a blockchain network. func NewInitHelper(chainConfig config.EthereumChainConfig, generatedDataHostDir, generatedDataContainerDir string, opts ...EnvComponentOption) *AfterGenesisHelper { g := &AfterGenesisHelper{ EnvComponent: EnvComponent{ @@ -47,12 +49,16 @@ func NewInitHelper(chainConfig config.EthereumChainConfig, generatedDataHostDir, return g } +// WithTestInstance sets up the AfterGenesisHelper for testing by assigning a logger and test context. +// This allows for better logging and error tracking during test execution. func (g *AfterGenesisHelper) WithTestInstance(t *testing.T) *AfterGenesisHelper { g.l = logging.GetTestLogger(t) g.t = t return g } +// StartContainer initializes and starts the After Genesis Helper container. +// It handles container requests and logs the startup process, ensuring the container is ready for use. func (g *AfterGenesisHelper) StartContainer() error { r, err := g.getContainerRequest(g.Networks) if err != nil { diff --git a/lib/docker/test_env/eth_common.go b/lib/docker/test_env/eth_common.go index d2e051150..554c0b299 100644 --- a/lib/docker/test_env/eth_common.go +++ b/lib/docker/test_env/eth_common.go @@ -42,7 +42,7 @@ type ExecutionClient interface { GetExternalHttpUrl() string GetExternalWsUrl() string GetEthereumVersion() config_types.EthereumVersion - GethConsensusMechanism() ConsensusMechanism + GetConsensusMechanism() ConsensusMechanism WaitUntilChainIsReady(ctx context.Context, waitTime time.Duration) error WithTestInstance(t *testing.T) ExecutionClient } diff --git a/lib/docker/test_env/ethereum_env.go b/lib/docker/test_env/ethereum_env.go index fa0dc04c0..a06c765eb 100644 --- a/lib/docker/test_env/ethereum_env.go +++ b/lib/docker/test_env/ethereum_env.go @@ -47,6 +47,8 @@ type EthereumNetworkBuilder struct { nodeLogLevel string } +// NewEthereumNetworkBuilder initializes a new EthereumNetworkBuilder with default settings. +// It prepares the builder for configuring an Ethereum network, allowing customization of various parameters. func NewEthereumNetworkBuilder() EthereumNetworkBuilder { return EthereumNetworkBuilder{ dockerNetworks: []string{}, @@ -70,56 +72,86 @@ func (b *EthereumNetworkBuilder) WithConsensusType(consensusType config.Consensu return b } +// WithEthereumVersion sets the Ethereum version for the network builder. +// It allows users to specify whether to use 'eth1' or 'eth2' for their Ethereum network configuration. func (b *EthereumNetworkBuilder) WithEthereumVersion(ethereumVersion config_types.EthereumVersion) *EthereumNetworkBuilder { b.ethereumVersion = ethereumVersion return b } +// WithConsensusLayer sets the consensus layer for the Ethereum network builder. +// It allows users to specify the consensus mechanism to be used, ensuring compatibility +// with the selected Ethereum version and execution layer. func (b *EthereumNetworkBuilder) WithConsensusLayer(consensusLayer config.ConsensusLayer) *EthereumNetworkBuilder { b.consensusLayer = &consensusLayer return b } +// WithExecutionLayer sets the execution layer for the Ethereum network builder. +// It allows users to specify which execution layer to use, ensuring compatibility +// with the selected Ethereum version and consensus layer. func (b *EthereumNetworkBuilder) WithExecutionLayer(executionLayer config_types.ExecutionLayer) *EthereumNetworkBuilder { b.executionLayer = executionLayer return b } +// WithEthereumChainConfig sets the Ethereum chain configuration for the network builder. +// This allows customization of parameters such as validator count and chain ID, enabling tailored network setups. func (b *EthereumNetworkBuilder) WithEthereumChainConfig(config config.EthereumChainConfig) *EthereumNetworkBuilder { b.ethereumChainConfig = &config return b } +// WithDockerNetworks sets the Docker networks for the Ethereum network builder. +// It allows users to specify custom networks for containerized deployments, +// enhancing flexibility in network configuration. func (b *EthereumNetworkBuilder) WithDockerNetworks(networks []string) *EthereumNetworkBuilder { b.dockerNetworks = networks return b } +// WithNodeLogLevel sets the logging level for the Ethereum node. +// This function allows users to customize the verbosity of logs, +// aiding in debugging and monitoring of the node's operations. func (b *EthereumNetworkBuilder) WithNodeLogLevel(nodeLogLevel string) *EthereumNetworkBuilder { b.nodeLogLevel = nodeLogLevel return b } +// WithExistingConfig sets an existing Ethereum network configuration for the builder. +// It allows users to customize the network setup using predefined settings, +// facilitating the creation of a network with specific parameters. func (b *EthereumNetworkBuilder) WithExistingConfig(config config.EthereumNetworkConfig) *EthereumNetworkBuilder { b.existingConfig = &config return b } +// WithExistingConfigFromEnvVar enables the use of an existing Ethereum configuration +// sourced from an environment variable. This allows for flexible deployment +// configurations without hardcoding values, enhancing security and adaptability. func (b *EthereumNetworkBuilder) WithExistingConfigFromEnvVar() *EthereumNetworkBuilder { b.existingFromEnvVar = true return b } +// WithTest sets the testing context for the Ethereum network builder. +// It allows for integration testing by associating a *testing.T instance, +// enabling error reporting and test management during network setup. func (b *EthereumNetworkBuilder) WithTest(t *testing.T) *EthereumNetworkBuilder { b.t = t return b } +// WithCustomDockerImages sets custom Docker images for the Ethereum network builder. +// This allows users to specify their own container images for different components, +// enabling greater flexibility and customization in the network setup. func (b *EthereumNetworkBuilder) WithCustomDockerImages(newImages map[config.ContainerType]string) *EthereumNetworkBuilder { b.customDockerImages = newImages return b } +// WithWaitingForFinalization enables the builder to wait for transaction finalization before proceeding. +// This is useful for ensuring that the blockchain state is stable and confirmed before executing subsequent operations. func (b *EthereumNetworkBuilder) WithWaitingForFinalization() *EthereumNetworkBuilder { b.waitForFinalization = true return b @@ -151,6 +183,9 @@ func (b *EthereumNetworkBuilder) buildNetworkConfig() EthereumNetwork { return n } +// Build constructs an EthereumNetwork based on the provided configuration settings. +// It validates the configuration, auto-fills missing values, and handles both existing and new setups. +// This function is essential for initializing a private Ethereum chain environment. func (b *EthereumNetworkBuilder) Build() (EthereumNetwork, error) { if b.existingFromEnvVar { path := os.Getenv(CONFIG_ENV_VAR_NAME) @@ -392,6 +427,8 @@ type EthereumNetwork struct { t *testing.T } +// Start initializes and starts the Ethereum network based on the specified version. +// It returns the configured blockchain network, RPC provider, and any error encountered during the process. func (en *EthereumNetwork) Start() (blockchain.EVMNetwork, RpcProvider, error) { switch *en.EthereumVersion { //nolint:staticcheck //ignore SA1019 @@ -749,6 +786,9 @@ func (en *EthereumNetwork) getImageOverride(ct config.ContainerType) string { return "" } +// Save persists the configuration of the Ethereum network to a TOML file. +// It generates a unique filename and logs the path for future reference in end-to-end tests. +// This function is essential for maintaining consistent test environments. func (en *EthereumNetwork) Save() error { name := fmt.Sprintf("ethereum_network_%s", uuid.NewString()[0:8]) confPath, err := toml_utils.SaveStructAsToml(en, ".private_chains", name) @@ -799,18 +839,26 @@ func NewRPCProvider( } } +// PrivateHttpUrls returns a slice of private HTTP URLs used by the RPC provider. +// This function is useful for accessing internal endpoints securely in a decentralized application. func (s *RpcProvider) PrivateHttpUrls() []string { return s.privateHttpUrls } +// PrivateWsUrls returns a slice of private WebSocket URLs. +// This function is useful for clients needing to connect to private WebSocket endpoints for secure communication. func (s *RpcProvider) PrivateWsUrsl() []string { return s.privateWsUrls } +// PublicHttpUrls returns a slice of public HTTP URLs for the RPC provider. +// This function is useful for clients needing to connect to the provider's services over HTTP. func (s *RpcProvider) PublicHttpUrls() []string { return s.publiclHttpUrls } +// PublicWsUrls returns a slice of public WebSocket URLs for the RPC provider. +// This function is useful for clients needing to connect to the provider's WebSocket endpoints for real-time data. func (s *RpcProvider) PublicWsUrls() []string { return s.publicWsUrls } @@ -829,6 +877,8 @@ func createHostDirectories() (string, string, error) { return customConfigDataDir, valKeysDir, nil } +// NewPrivateChainEnvConfigFromFile loads an EthereumNetwork configuration from a TOML file specified by the given path. +// It returns the populated EthereumNetwork struct and any error encountered during the file reading or parsing process. func NewPrivateChainEnvConfigFromFile(path string) (EthereumNetwork, error) { c := EthereumNetwork{} err := toml_utils.OpenTomlFileAsStruct(path, &c) diff --git a/lib/docker/test_env/genesis_generator.go b/lib/docker/test_env/genesis_generator.go index 627826c34..c0067451f 100644 --- a/lib/docker/test_env/genesis_generator.go +++ b/lib/docker/test_env/genesis_generator.go @@ -41,6 +41,9 @@ type EthGenesisGenerator struct { t *testing.T } +// NewEthGenesisGenerator initializes a new EthGenesisGenerator instance for generating Ethereum genesis data. +// It requires the Ethereum chain configuration, a directory for generated data, and the last fork used. +// This function is essential for setting up the environment to create and manage Ethereum genesis files. func NewEthGenesisGenerator(chainConfig config.EthereumChainConfig, generatedDataHostDir string, lastFork ethereum.Fork, opts ...EnvComponentOption) (*EthGenesisGenerator, error) { genesisGeneratorImage, ok := generatorForkToImageMap[lastFork] if !ok { @@ -74,12 +77,16 @@ func NewEthGenesisGenerator(chainConfig config.EthereumChainConfig, generatedDat return g, nil } +// WithTestInstance sets up the EthGenesisGenerator for testing by assigning a logger and test context. +// This allows for better logging and error tracking during test execution. func (g *EthGenesisGenerator) WithTestInstance(t *testing.T) *EthGenesisGenerator { g.l = logging.GetTestLogger(t) g.t = t return g } +// StartContainer initializes and starts the Ethereum genesis generation container. +// It ensures the container is ready for use, logging the process and any errors encountered. func (g *EthGenesisGenerator) StartContainer() error { r, err := g.getContainerRequest(g.Networks) if err != nil { @@ -195,6 +202,8 @@ func (g *EthGenesisGenerator) getContainerRequest(networks []string) (*tc.Contai }, nil } +// GetGeneratedDataContainerDir returns the directory path for the generated data container. +// This is useful for accessing the location where the genesis data is stored after generation. func (g *EthGenesisGenerator) GetGeneratedDataContainerDir() string { return g.generatedDataContainerDir } diff --git a/lib/docker/test_env/genesis_generator_helpers.go b/lib/docker/test_env/genesis_generator_helpers.go index 48d44e1a7..f3f92fbc6 100644 --- a/lib/docker/test_env/genesis_generator_helpers.go +++ b/lib/docker/test_env/genesis_generator_helpers.go @@ -291,6 +291,9 @@ type ExitCodeStrategy struct { pollInterval time.Duration } +// NewExitCodeStrategy initializes a new ExitCodeStrategy with default settings. +// It sets the expected exit code to 0, a timeout of 2 minutes, and a poll interval of 2 seconds. +// This function is useful for configuring container readiness checks based on exit codes. func NewExitCodeStrategy() *ExitCodeStrategy { return &ExitCodeStrategy{ expectedExitCode: 0, @@ -299,16 +302,22 @@ func NewExitCodeStrategy() *ExitCodeStrategy { } } +// WithTimeout sets the timeout duration for the ExitCodeStrategy. +// It allows users to specify how long to wait for a process to exit with the expected code. func (w *ExitCodeStrategy) WithTimeout(timeout time.Duration) *ExitCodeStrategy { w.timeout = timeout return w } +// WithExitCode sets the expected exit code for the strategy and returns the updated instance. +// This function is useful for configuring container requests to wait for specific exit conditions. func (w *ExitCodeStrategy) WithExitCode(exitCode int) *ExitCodeStrategy { w.expectedExitCode = exitCode return w } +// WithPollInterval sets the interval for polling the exit code and returns the updated strategy. +// This function is useful for configuring how frequently to check the exit code during container execution. func (w *ExitCodeStrategy) WithPollInterval(pollInterval time.Duration) *ExitCodeStrategy { w.pollInterval = pollInterval return w diff --git a/lib/docker/test_env/geth_base.go b/lib/docker/test_env/geth_base.go index 9a1f0076d..1c3c7c59d 100644 --- a/lib/docker/test_env/geth_base.go +++ b/lib/docker/test_env/geth_base.go @@ -37,12 +37,16 @@ type Geth struct { posContainerSettings } +// WithTestInstance sets up the execution client with a test logger and associates it with the provided testing context. +// This is useful for capturing logs during testing and ensuring that the client operates in a test environment. func (g *Geth) WithTestInstance(t *testing.T) ExecutionClient { g.l = logging.GetTestLogger(t) g.t = t return g } +// StartContainer initializes and starts a Geth container for Ethereum, returning the network configuration. +// It supports both Eth1 and Eth2 versions, setting up necessary URLs for communication with the blockchain. func (g *Geth) StartContainer() (blockchain.EVMNetwork, error) { var r *tc.ContainerRequest var err error @@ -124,6 +128,9 @@ func (g *Geth) StartContainer() (blockchain.EVMNetwork, error) { return networkConfig, nil } +// GetInternalExecutionURL returns the internal execution URL for the Ethereum client. +// It is used to retrieve the endpoint for executing transactions in Ethereum 2.0 environments. +// An error is raised if called on an Ethereum 1.0 node. func (g *Geth) GetInternalExecutionURL() string { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { panic("eth1 node doesn't have an execution URL") @@ -131,6 +138,8 @@ func (g *Geth) GetInternalExecutionURL() string { return g.InternalExecutionURL } +// GetExternalExecutionURL returns the external execution URL for the Geth instance. +// It panics if the Ethereum version is Eth1, as Eth1 nodes do not support execution URLs. func (g *Geth) GetExternalExecutionURL() string { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { panic("eth1 node doesn't have an execution URL") @@ -138,41 +147,60 @@ func (g *Geth) GetExternalExecutionURL() string { return g.ExternalExecutionURL } +// GetInternalHttpUrl returns the internal HTTP URL of the Geth client. +// This URL is essential for connecting to the execution layer in a private network setup. func (g *Geth) GetInternalHttpUrl() string { return g.InternalHttpUrl } +// GetInternalWsUrl returns the internal WebSocket URL for the Geth client. +// This URL is essential for establishing WebSocket connections to the Geth node, enabling real-time data streaming and event handling. func (g *Geth) GetInternalWsUrl() string { return g.InternalWsUrl } +// GetExternalHttpUrl returns the external HTTP URL for the Geth client. +// This URL is used to interact with the Ethereum network externally, enabling communication with other services or clients. func (g *Geth) GetExternalHttpUrl() string { return g.ExternalHttpUrl } +// GetExternalWsUrl returns the external WebSocket URL for the Geth client. +// This URL is essential for connecting to the Ethereum network via WebSocket. func (g *Geth) GetExternalWsUrl() string { return g.ExternalWsUrl } +// GetContainerName returns the name of the container associated with the Geth instance. +// This function is useful for identifying and managing the container in a Docker environment. func (g *Geth) GetContainerName() string { return g.ContainerName } +// GetContainer returns a pointer to the container associated with the Geth instance. +// This function is useful for accessing the container's properties and methods in a seamless manner. func (g *Geth) GetContainer() *tc.Container { return &g.Container } +// GetEthereumVersion returns the current Ethereum version of the Geth instance. +// This information is essential for determining the appropriate execution URL and consensus mechanism. func (g *Geth) GetEthereumVersion() config_types.EthereumVersion { return g.ethereumVersion } -func (g *Geth) GethConsensusMechanism() ConsensusMechanism { +// GetConsensusMechanism returns the consensus mechanism used by the Geth instance. +// It determines whether the Ethereum version is Eth1 or not, returning either Proof of Authority (PoA) +// or Proof of Stake (PoS) accordingly. This is useful for understanding the underlying protocol. +func (g *Geth) GetConsensusMechanism() ConsensusMechanism { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { return ConsensusMechanism_PoA } return ConsensusMechanism_PoS } +// WaitUntilChainIsReady blocks until the Ethereum chain is ready for use, or returns an error if it times out. +// This function is essential for ensuring that the blockchain environment is fully operational before proceeding with further operations. func (g *Geth) WaitUntilChainIsReady(ctx context.Context, waitTime time.Duration) error { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { return nil diff --git a/lib/docker/test_env/job_distributor/jd.go b/lib/docker/test_env/job_distributor/jd.go index c2638ae52..46e10deec 100644 --- a/lib/docker/test_env/job_distributor/jd.go +++ b/lib/docker/test_env/job_distributor/jd.go @@ -113,14 +113,23 @@ func (j *Component) getContainerRequest() *tc.ContainerRequest { } } +// StartContainer initializes and starts a container for the component. +// It ensures the container is ready for use, logging relevant connection details. +// This function is essential for setting up the environment required for the component's operations. func (j *Component) StartContainer() error { return j.startOrRestartContainer(false) } +// RestartContainer restarts the container associated with the Component. +// It ensures that the container is started with the option to reuse resources, +// making it useful for maintaining service continuity during updates or failures. func (j *Component) RestartContainer() error { return j.startOrRestartContainer(true) } +// New creates a new Component instance with a unique container name and specified networks. +// It allows for optional configuration through functional options and sets default values for various parameters. +// This function is useful for initializing components in a test environment. func New(networks []string, opts ...Option) *Component { id, _ := uuid.NewRandom() j := &Component{ @@ -141,6 +150,9 @@ func New(networks []string, opts ...Option) *Component { return j } +// WithTestInstance sets up a test logger and test context for a Component. +// It is useful for initializing components in unit tests, ensuring that logs +// are captured and associated with the provided testing.T instance. func WithTestInstance(t *testing.T) Option { return func(j *Component) { j.l = logging.GetTestLogger(t) @@ -148,18 +160,26 @@ func WithTestInstance(t *testing.T) Option { } } +// WithContainerPort sets the container port for a Component. +// This option allows customization of the network configuration for the container, +// enabling proper communication with external services. func WithContainerPort(port string) Option { return func(j *Component) { j.containerPort = port } } +// WithWSRPCContainerPort sets the WebSocket RPC port for the Component. +// This option allows users to configure the port for WebSocket communication, +// enabling flexibility in service deployment and integration. func WithWSRPCContainerPort(port string) Option { return func(j *Component) { j.wsrpcPort = port } } +// WithDBURL returns an Option that sets the database connection URL for a Component. +// It allows users to configure the Component with a specific database connection string. func WithDBURL(db string) Option { return func(j *Component) { if db != "" { @@ -168,24 +188,32 @@ func WithDBURL(db string) Option { } } +// WithContainerName sets the container name for a Component. +// It returns an Option that can be used to configure the Component during initialization. func WithContainerName(name string) Option { return func(j *Component) { j.ContainerName = name } } +// WithImage sets the container image for a Component. +// This option allows users to specify which image to use, enabling customization of the component's runtime environment. func WithImage(image string) Option { return func(j *Component) { j.ContainerImage = image } } +// WithVersion sets the container version for a Component. +// It allows users to specify the desired version, ensuring the Component runs with the correct configuration. func WithVersion(version string) Option { return func(j *Component) { j.ContainerVersion = version } } +// WithCSAKeyEncryptionKey sets the CSA key encryption key for a Component. +// This function is useful for configuring secure key management in decentralized applications. func WithCSAKeyEncryptionKey(key string) Option { return func(j *Component) { j.csaKeyEncryptionKey = key diff --git a/lib/docker/test_env/kafka.go b/lib/docker/test_env/kafka.go index 7e9da9855..f0014d274 100644 --- a/lib/docker/test_env/kafka.go +++ b/lib/docker/test_env/kafka.go @@ -41,6 +41,8 @@ type KafkaTopicConfig struct { CleanupPolicy string `json:"cleanup_policy"` } +// NewKafka initializes a new Kafka instance with a unique container name and default environment variables. +// It sets up the necessary configurations for Kafka to operate within specified networks, making it easy to deploy and manage Kafka services in a containerized environment. func NewKafka(networks []string) *Kafka { id, _ := uuid.NewRandom() containerName := fmt.Sprintf("kafka-%s", id.String()) @@ -65,12 +67,17 @@ func NewKafka(networks []string) *Kafka { } } +// WithTestInstance configures the Kafka instance for testing by setting up a test logger. +// It returns the modified Kafka instance, allowing for easier testing and logging during unit tests. func (k *Kafka) WithTestInstance(t *testing.T) *Kafka { k.l = logging.GetTestLogger(t) k.t = t return k } +// WithContainerName sets the container name for the Kafka instance. +// It configures the internal and bootstrap server URLs based on the provided name, +// allowing for easy identification and connection to the Kafka service. func (k *Kafka) WithContainerName(name string) *Kafka { k.ContainerName = name internalUrl := fmt.Sprintf("%s:%s", name, "9092") @@ -80,11 +87,15 @@ func (k *Kafka) WithContainerName(name string) *Kafka { return k } +// WithTopics sets the Kafka topic configurations for the Kafka instance. +// It returns the updated Kafka instance, allowing for method chaining. func (k *Kafka) WithTopics(topics []KafkaTopicConfig) *Kafka { k.TopicConfigs = topics return k } +// WithZookeeper sets the Zookeeper connection URL for the Kafka instance. +// It prepares the necessary environment variables and returns the updated Kafka instance. func (k *Kafka) WithZookeeper(zookeeperUrl string) *Kafka { envVars := map[string]string{ "KAFKA_ZOOKEEPER_CONNECT": zookeeperUrl, @@ -92,6 +103,8 @@ func (k *Kafka) WithZookeeper(zookeeperUrl string) *Kafka { return k.WithEnvVars(envVars) } +// WithEnvVars merges the provided environment variables into the Kafka instance's existing environment variables. +// It allows customization of the Kafka container's configuration before starting it. func (k *Kafka) WithEnvVars(envVars map[string]string) *Kafka { if err := mergo.Merge(&k.EnvVars, envVars, mergo.WithOverride); err != nil { k.l.Fatal().Err(err).Msg("Failed to merge env vars") @@ -99,6 +112,9 @@ func (k *Kafka) WithEnvVars(envVars map[string]string) *Kafka { return k } +// StartContainer initializes and starts a Kafka container with specified environment variables. +// It sets internal and external URLs for the container and logs the startup process. +// This function is essential for setting up a Kafka instance for testing or development purposes. func (k *Kafka) StartContainer() error { l := logging.GetTestContainersGoTestLogger(k.t) k.InternalUrl = fmt.Sprintf("%s:%s", k.ContainerName, "9092") @@ -133,6 +149,10 @@ func (k *Kafka) StartContainer() error { return nil } +// CreateLocalTopics creates Kafka topics based on the provided configurations. +// It ensures that topics are only created if they do not already exist, +// and logs the creation details for each topic. This function is useful +// for initializing Kafka environments with predefined topic settings. func (k *Kafka) CreateLocalTopics() error { for _, topicConfig := range k.TopicConfigs { cmd := []string{"kafka-topics", "--bootstrap-server", fmt.Sprintf("http://%s", k.BootstrapServerUrl), diff --git a/lib/docker/test_env/killgrave.go b/lib/docker/test_env/killgrave.go index eb7363f5a..7dbbc620a 100644 --- a/lib/docker/test_env/killgrave.go +++ b/lib/docker/test_env/killgrave.go @@ -79,6 +79,9 @@ type KillgraveAdapterResult struct { Result interface{} `json:"result"` } +// NewKillgrave initializes a new Killgrave instance with specified networks and imposters directory. +// It sets default configurations and allows for optional environment component modifications. +// This function is useful for creating a Killgrave service for testing and simulating APIs. func NewKillgrave(networks []string, impostersDirectoryPath string, opts ...EnvComponentOption) *Killgrave { k := &Killgrave{ EnvComponent: EnvComponent{ @@ -97,12 +100,16 @@ func NewKillgrave(networks []string, impostersDirectoryPath string, opts ...EnvC return k } +// WithTestInstance sets up a Killgrave instance for testing by assigning a test logger and the testing context. +// This allows for better logging during tests and facilitates easier debugging. func (k *Killgrave) WithTestInstance(t *testing.T) *Killgrave { k.l = logging.GetTestLogger(t) k.t = t return k } +// StartContainer initializes and starts the Killgrave container, setting up imposters and request dumping. +// It also configures cleanup for the container and logs the external and internal endpoints for access. func (k *Killgrave) StartContainer() error { err := k.setupImposters() if err != nil { @@ -294,6 +301,9 @@ func (k *Killgrave) SetAdapterBasedAnyValuePath(path string, methods []string, v }, string(data)) } +// SetAnyValueResponse sets a JSON-encoded response for a specified path and HTTP methods. +// It marshals the provided value into JSON format and updates the response headers accordingly. +// This function is useful for configuring dynamic API responses in a flexible manner. func (k *Killgrave) SetAnyValueResponse(path string, methods []string, v interface{}) error { data, err := json.Marshal(v) if err != nil { @@ -318,6 +328,10 @@ type RequestData struct { Body string `json:"body"` } +// GetReceivedRequests retrieves and parses request data from a log file. +// It ensures all requests are written before reading and returns a slice of +// RequestData along with any encountered errors. This function is useful for +// accessing logged request information in a structured format. func (k *Killgrave) GetReceivedRequests() ([]RequestData, error) { // killgrave uses a channel to write the request data to a file so we want to make sure // all requests have been written before reading the file diff --git a/lib/docker/test_env/mockserver.go b/lib/docker/test_env/mockserver.go index 1cb057536..c498f8468 100644 --- a/lib/docker/test_env/mockserver.go +++ b/lib/docker/test_env/mockserver.go @@ -32,6 +32,9 @@ type MockServer struct { l zerolog.Logger } +// NewMockServer creates a new instance of MockServer with specified networks and options. +// It initializes the server with a unique container name and a default startup timeout. +// This function is useful for testing decentralized applications in a controlled environment. func NewMockServer(networks []string, opts ...EnvComponentOption) *MockServer { ms := &MockServer{ EnvComponent: EnvComponent{ @@ -47,12 +50,17 @@ func NewMockServer(networks []string, opts ...EnvComponentOption) *MockServer { return ms } +// WithTestInstance configures the MockServer with a test logger and test context. +// It returns the updated MockServer instance for use in testing scenarios. func (ms *MockServer) WithTestInstance(t *testing.T) *MockServer { ms.l = logging.GetTestLogger(t) ms.t = t return ms } +// SetExternalAdapterMocks configures a specified number of mock external adapter endpoints. +// It generates unique paths for each adapter and stores their URLs for later use. +// This function is useful for testing scenarios that require multiple external adapter interactions. func (ms *MockServer) SetExternalAdapterMocks(count int) error { for i := 0; i < count; i++ { path := fmt.Sprintf("/ea-%d", i) @@ -75,6 +83,9 @@ func (ms *MockServer) SetExternalAdapterMocks(count int) error { return nil } +// StartContainer initializes and starts a MockServer container. +// It sets up logging, retrieves the container request, and establishes endpoints for communication. +// This function is essential for testing environments that require a mock server instance. func (ms *MockServer) StartContainer() error { l := logging.GetTestContainersGoTestLogger(ms.t) cr, err := ms.getContainerRequest() diff --git a/lib/docker/test_env/nethermind_base.go b/lib/docker/test_env/nethermind_base.go index 2bc18d773..732128b6b 100644 --- a/lib/docker/test_env/nethermind_base.go +++ b/lib/docker/test_env/nethermind_base.go @@ -35,12 +35,17 @@ type Nethermind struct { posContainerSettings } +// WithTestInstance sets up the execution client with a test logger and test context. +// This is useful for running tests with specific logging and context requirements. func (g *Nethermind) WithTestInstance(t *testing.T) ExecutionClient { g.l = logging.GetTestLogger(t) g.t = t return g } +// StartContainer initializes and starts a Nethermind container for Ethereum execution. +// It configures network settings based on the Ethereum version and returns the network configuration +// along with any errors encountered during the process. func (g *Nethermind) StartContainer() (blockchain.EVMNetwork, error) { var r *tc.ContainerRequest var err error @@ -110,6 +115,9 @@ func (g *Nethermind) StartContainer() (blockchain.EVMNetwork, error) { return networkConfig, nil } +// GetInternalExecutionURL returns the internal execution URL for the Ethereum client. +// It is used to retrieve the endpoint for executing transactions in a network that supports it. +// If the client is an Eth1 node, it will panic as Eth1 does not have an execution URL. func (g *Nethermind) GetInternalExecutionURL() string { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { panic("eth1 node doesn't have an execution URL") @@ -117,6 +125,8 @@ func (g *Nethermind) GetInternalExecutionURL() string { return g.InternalExecutionURL } +// GetExternalExecutionURL returns the external execution URL for the Nethermind node. +// It panics if the node is running on Ethereum version 1, as it does not support execution URLs. func (g *Nethermind) GetExternalExecutionURL() string { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { panic("eth1 node doesn't have an execution URL") @@ -124,34 +134,50 @@ func (g *Nethermind) GetExternalExecutionURL() string { return g.ExternalExecutionURL } +// GetInternalHttpUrl returns the internal HTTP URL of the Nethermind client. +// This URL is used to communicate with the execution layer in a secure manner. func (g *Nethermind) GetInternalHttpUrl() string { return g.InternalHttpUrl } +// GetInternalWsUrl returns the internal WebSocket URL for the Nethermind client. +// This URL is essential for establishing WebSocket connections to the execution layer. func (g *Nethermind) GetInternalWsUrl() string { return g.InternalWsUrl } +// GetExternalHttpUrl returns the external HTTP URL for the Nethermind client. +// This URL is used to interact with the Nethermind execution layer over HTTP. func (g *Nethermind) GetExternalHttpUrl() string { return g.ExternalHttpUrl } +// GetExternalWsUrl returns the external WebSocket URL for the Nethermind client. +// This URL is essential for connecting to the Nethermind execution layer from external services. func (g *Nethermind) GetExternalWsUrl() string { return g.ExternalWsUrl } +// GetContainerName returns the name of the container associated with the Nethermind instance. +// This function is useful for identifying and managing the container in a Docker environment. func (g *Nethermind) GetContainerName() string { return g.ContainerName } +// GetContainer returns a pointer to the Container associated with the Nethermind instance. +// This function is useful for accessing the container's properties and methods in a Dockerized environment. func (g *Nethermind) GetContainer() *tc.Container { return &g.Container } +// GetEthereumVersion returns the current Ethereum version of the Nethermind instance. +// This information is crucial for determining the appropriate execution URLs and consensus mechanisms. func (g *Nethermind) GetEthereumVersion() config_types.EthereumVersion { return g.ethereumVersion } +// WaitUntilChainIsReady blocks until the Ethereum chain is fully operational or the specified wait time elapses. +// It is useful for ensuring that the blockchain client is ready for transactions or queries before proceeding. func (g *Nethermind) WaitUntilChainIsReady(ctx context.Context, waitTime time.Duration) error { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { return nil @@ -160,7 +186,10 @@ func (g *Nethermind) WaitUntilChainIsReady(ctx context.Context, waitTime time.Du return waitForFirstBlock.WaitUntilReady(ctx, *g.GetContainer()) } -func (g *Nethermind) GethConsensusMechanism() ConsensusMechanism { +// GetConsensusMechanism returns the consensus mechanism used by the Nethermind instance. +// It determines whether the Ethereum version is Eth1 or not, returning either Proof of Authority (PoA) +// or Proof of Stake (PoS) accordingly. This is useful for understanding the network's validation method. +func (g *Nethermind) GetConsensusMechanism() ConsensusMechanism { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { return ConsensusMechanism_PoA } diff --git a/lib/docker/test_env/postgres.go b/lib/docker/test_env/postgres.go index 15806f300..7497cccdb 100644 --- a/lib/docker/test_env/postgres.go +++ b/lib/docker/test_env/postgres.go @@ -51,6 +51,8 @@ func WithPostgresDbContainerName(name string) PostgresDbOption { } } +// WithPostgresImageName sets the Docker image name for the Postgres database container. +// It allows customization of the container image used, enabling users to specify a preferred version or variant. func WithPostgresImageName(imageName string) PostgresDbOption { return func(c *PostgresDb) { if imageName != "" { @@ -59,6 +61,9 @@ func WithPostgresImageName(imageName string) PostgresDbOption { } } +// WithPostgresImageVersion sets the PostgreSQL container image version for the database. +// It allows customization of the database version used in the container, enhancing flexibility +// for development and testing environments. func WithPostgresImageVersion(version string) PostgresDbOption { return func(c *PostgresDb) { if version != "" { @@ -67,6 +72,8 @@ func WithPostgresImageVersion(version string) PostgresDbOption { } } +// WithPostgresDbName sets the database name for a PostgresDb instance. +// It returns a PostgresDbOption that can be used to configure the database connection. func WithPostgresDbName(name string) PostgresDbOption { return func(c *PostgresDb) { if name != "" { @@ -75,12 +82,17 @@ func WithPostgresDbName(name string) PostgresDbOption { } } +// WithContainerEnv sets an environment variable for the Postgres database container. +// It allows users to configure the container's environment by providing a key-value pair. func WithContainerEnv(key, value string) PostgresDbOption { return func(c *PostgresDb) { c.ContainerEnvs[key] = value } } +// NewPostgresDb initializes a new Postgres database instance with specified networks and options. +// It sets up the container environment and default configurations, returning the PostgresDb object +// for use in applications requiring a Postgres database connection. func NewPostgresDb(networks []string, opts ...PostgresDbOption) (*PostgresDb, error) { imageParts := strings.Split(defaultPostgresImage, ":") pg := &PostgresDb{ @@ -115,16 +127,24 @@ func NewPostgresDb(networks []string, opts ...PostgresDbOption) (*PostgresDb, er return pg, nil } +// WithTestInstance sets up a PostgresDb instance for testing, +// initializing a test logger and associating it with the provided +// testing context. This allows for better logging during tests. func (pg *PostgresDb) WithTestInstance(t *testing.T) *PostgresDb { pg.l = logging.GetTestLogger(t) pg.t = t return pg } +// StartContainer initializes and starts a PostgreSQL database container. +// It ensures the container is ready for use, providing both internal and external connection URLs. +// This function is essential for setting up a database environment in testing or development scenarios. func (pg *PostgresDb) StartContainer() error { return pg.startOrRestartContainer(false) } +// RestartContainer restarts the PostgreSQL database container, ensuring it is running with the latest configuration. +// This function is useful for applying changes or recovering from issues without needing to manually stop and start the container. func (pg *PostgresDb) RestartContainer() error { return pg.startOrRestartContainer(true) } diff --git a/lib/docker/test_env/prysm.go b/lib/docker/test_env/prysm.go index 117f2f87d..2d7fd9686 100644 --- a/lib/docker/test_env/prysm.go +++ b/lib/docker/test_env/prysm.go @@ -49,6 +49,8 @@ type PrysmBeaconChain struct { posContainerSettings } +// NewPrysmBeaconChain initializes a new Prysm beacon chain instance with the specified network configurations and parameters. +// It is used to set up a beacon chain for Ethereum 2.0, enabling users to run and manage a consensus layer node. func NewPrysmBeaconChain(networks []string, chainConfig *config.EthereumChainConfig, generatedDataHostDir, generatedDataContainerDir, gethExecutionURL string, baseEthereumFork ethereum.Fork, opts ...EnvComponentOption) (*PrysmBeaconChain, error) { prysmBeaconChainImage, ok := beaconForkToImageMap[baseEthereumFork] if !ok { @@ -77,12 +79,17 @@ func NewPrysmBeaconChain(networks []string, chainConfig *config.EthereumChainCon return g, nil } +// WithTestInstance sets up the PrysmBeaconChain for testing by assigning a test logger and the testing context. +// This allows for better logging and error tracking during test execution. func (g *PrysmBeaconChain) WithTestInstance(t *testing.T) *PrysmBeaconChain { g.l = logging.GetTestLogger(t) g.t = t return g } +// StartContainer initializes and starts the Prysm Beacon Chain container. +// It sets up the necessary RPC endpoints and logs the container's status. +// This function is essential for deploying a Prysm-based Ethereum 2.0 beacon chain in a Docker environment. func (g *PrysmBeaconChain) StartContainer() error { r, err := g.getContainerRequest(g.Networks) if err != nil { @@ -187,6 +194,8 @@ type PrysmValidator struct { posContainerSettings } +// NewPrysmValidator initializes a new Prysm validator instance with the specified network configurations and settings. +// It is used to set up a validator for Ethereum's consensus layer, ensuring proper integration with the blockchain environment. func NewPrysmValidator(networks []string, chainConfig *config.EthereumChainConfig, generatedDataHostDir, generatedDataContainerDir, valKeysDir, internalBeaconRpcProvider string, baseEthereumFork ethereum.Fork, opts ...EnvComponentOption) (*PrysmValidator, error) { pyrsmValidatorImage, ok := validatorForkToImageMap[baseEthereumFork] if !ok { @@ -215,12 +224,16 @@ func NewPrysmValidator(networks []string, chainConfig *config.EthereumChainConfi return g, nil } +// WithTestInstance sets up the PrysmValidator with a test logger and the provided testing context. +// This allows for easier testing and debugging of the validator's behavior during unit tests. func (g *PrysmValidator) WithTestInstance(t *testing.T) *PrysmValidator { g.l = logging.GetTestLogger(t) g.t = t return g } +// StartContainer initializes and starts the Prysm validator container. +// It handles the setup and logging, ensuring the container is ready for use in Ethereum network operations. func (g *PrysmValidator) StartContainer() error { r, err := g.getContainerRequest(g.Networks) if err != nil { diff --git a/lib/docker/test_env/reth_base.go b/lib/docker/test_env/reth_base.go index 1544e755d..5ae6ccd03 100644 --- a/lib/docker/test_env/reth_base.go +++ b/lib/docker/test_env/reth_base.go @@ -37,12 +37,17 @@ type Reth struct { posContainerSettings } +// WithTestInstance sets up the execution client with a test logger and the provided testing context. +// This is useful for integrating testing frameworks with the execution client, enabling better logging and error tracking during tests. func (g *Reth) WithTestInstance(t *testing.T) ExecutionClient { g.l = logging.GetTestLogger(t) g.t = t return g } +// StartContainer initializes and starts a Reth execution client container. +// It returns the configured EVM network details or an error if the process fails. +// This function is essential for setting up a local Ethereum environment for testing or development. func (g *Reth) StartContainer() (blockchain.EVMNetwork, error) { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { return blockchain.EVMNetwork{}, errors.New(config.Eth1NotSupportedByRethMsg) @@ -110,6 +115,9 @@ func (g *Reth) StartContainer() (blockchain.EVMNetwork, error) { return networkConfig, nil } +// GetInternalExecutionURL returns the internal execution URL for the Ethereum client. +// It is used to retrieve the endpoint for interacting with the execution layer, +// ensuring compatibility with Ethereum 2.0 clients. func (g *Reth) GetInternalExecutionURL() string { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { panic("eth1 node doesn't have an execution URL") @@ -117,6 +125,8 @@ func (g *Reth) GetInternalExecutionURL() string { return g.InternalExecutionURL } +// GetExternalExecutionURL returns the external execution URL for the Reth instance. +// It panics if the Ethereum version is Eth1, as Eth1 nodes do not support execution URLs. func (g *Reth) GetExternalExecutionURL() string { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { panic("eth1 node doesn't have an execution URL") @@ -124,34 +134,51 @@ func (g *Reth) GetExternalExecutionURL() string { return g.ExternalExecutionURL } +// GetInternalHttpUrl returns the internal HTTP URL of the execution client. +// This URL is essential for establishing communication with the client in a secure manner. func (g *Reth) GetInternalHttpUrl() string { return g.InternalHttpUrl } +// GetInternalWsUrl returns the internal WebSocket URL for the Reth execution client. +// This URL is essential for establishing WebSocket connections to the client for real-time data streaming. func (g *Reth) GetInternalWsUrl() string { return g.InternalWsUrl } +// GetExternalHttpUrl returns the external HTTP URL for the Reth execution client. +// This URL is useful for connecting to the client from external applications or services. func (g *Reth) GetExternalHttpUrl() string { return g.ExternalHttpUrl } +// GetExternalWsUrl returns the external WebSocket URL for the Reth execution client. +// This URL is essential for connecting to the client for real-time data and event subscriptions. func (g *Reth) GetExternalWsUrl() string { return g.ExternalWsUrl } +// GetContainerName returns the name of the container associated with the Reth instance. +// This function is useful for identifying and managing the container in a Docker environment. func (g *Reth) GetContainerName() string { return g.ContainerName } +// GetContainer returns a pointer to the container associated with the Reth instance. +// This function is useful for accessing the container's properties and methods in order to manage or interact with the execution environment. func (g *Reth) GetContainer() *tc.Container { return &g.Container } +// GetEthereumVersion returns the current Ethereum version of the Reth instance. +// This information is essential for determining compatibility and functionality +// with various Ethereum features and services. func (g *Reth) GetEthereumVersion() config_types.EthereumVersion { return g.ethereumVersion } +// WaitUntilChainIsReady blocks until the Ethereum chain is ready for use, waiting for the first block to be committed if necessary. +// This function is essential for ensuring that the blockchain environment is fully operational before proceeding with further operations. func (g *Reth) WaitUntilChainIsReady(ctx context.Context, waitTime time.Duration) error { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { return nil @@ -160,7 +187,10 @@ func (g *Reth) WaitUntilChainIsReady(ctx context.Context, waitTime time.Duration return waitForFirstBlock.WaitUntilReady(ctx, *g.GetContainer()) } -func (g *Reth) GethConsensusMechanism() ConsensusMechanism { +// GetConsensusMechanism returns the consensus mechanism used by the Ethereum network. +// It identifies whether the network is operating on Proof of Work (PoW) or Proof of Stake (PoS) +// based on the current Ethereum version, aiding in understanding network dynamics. +func (g *Reth) GetConsensusMechanism() ConsensusMechanism { if g.GetEthereumVersion() == config_types.EthereumVersion_Eth1 { return ConsensusMechanism_PoW } diff --git a/lib/docker/test_env/schema_registry.go b/lib/docker/test_env/schema_registry.go index 11e9eb579..fd7e5ce1e 100644 --- a/lib/docker/test_env/schema_registry.go +++ b/lib/docker/test_env/schema_registry.go @@ -27,6 +27,8 @@ type SchemaRegistry struct { t *testing.T } +// NewSchemaRegistry initializes a new SchemaRegistry instance with a unique container name and specified networks. +// It sets default environment variables and a startup timeout, making it suitable for managing schema registries in decentralized applications. func NewSchemaRegistry(networks []string) *SchemaRegistry { id, _ := uuid.NewRandom() defaultEnvVars := map[string]string{ @@ -42,17 +44,25 @@ func NewSchemaRegistry(networks []string) *SchemaRegistry { } } +// WithTestInstance sets up a SchemaRegistry instance for testing purposes. +// It initializes the logger with a test logger and associates the testing context, +// allowing for better logging and error tracking during tests. func (r *SchemaRegistry) WithTestInstance(t *testing.T) *SchemaRegistry { r.l = logging.GetTestLogger(t) r.t = t return r } +// WithContainerName sets the container name for the SchemaRegistry instance. +// This allows users to customize the naming of the container for better organization +// and identification within their application. It returns the updated SchemaRegistry. func (r *SchemaRegistry) WithContainerName(name string) *SchemaRegistry { r.ContainerName = name return r } +// WithKafka sets the Kafka bootstrap servers for the Schema Registry using the provided URL. +// It returns the updated SchemaRegistry instance with the new environment variables applied. func (r *SchemaRegistry) WithKafka(kafkaUrl string) *SchemaRegistry { envVars := map[string]string{ "SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS": kafkaUrl, @@ -60,6 +70,8 @@ func (r *SchemaRegistry) WithKafka(kafkaUrl string) *SchemaRegistry { return r.WithEnvVars(envVars) } +// WithEnvVars merges the provided environment variables into the SchemaRegistry's existing set. +// It allows for dynamic configuration of the Schema Registry based on the specified environment settings. func (r *SchemaRegistry) WithEnvVars(envVars map[string]string) *SchemaRegistry { if err := mergo.Merge(&r.EnvVars, envVars, mergo.WithOverride); err != nil { r.l.Fatal().Err(err).Msg("Failed to merge env vars") @@ -67,6 +79,11 @@ func (r *SchemaRegistry) WithEnvVars(envVars map[string]string) *SchemaRegistry return r } +// StartContainer initializes and starts a Schema Registry container. +// It sets up the necessary environment variables and logs the internal +// and external URLs for accessing the container. This function is +// essential for users needing a running instance of Schema Registry +// for testing or development purposes. func (r *SchemaRegistry) StartContainer() error { r.InternalUrl = fmt.Sprintf("http://%s:%s", r.ContainerName, "8081") l := logging.GetTestContainersGoTestLogger(r.t) diff --git a/lib/docker/test_env/utils.go b/lib/docker/test_env/utils.go index c40deb4f3..41bf39b50 100644 --- a/lib/docker/test_env/utils.go +++ b/lib/docker/test_env/utils.go @@ -9,10 +9,14 @@ import ( tc "github.com/testcontainers/testcontainers-go" ) +// NatPortFormat formats a given port string to include the TCP protocol suffix. +// This is useful for standardizing port representations in container configurations. func NatPortFormat(port string) string { return fmt.Sprintf("%s/tcp", port) } +// NatPort converts a string representation of a port into a nat.Port type. +// This is useful for ensuring that the port is formatted correctly for networking operations. func NatPort(port string) nat.Port { return nat.Port(NatPortFormat(port)) } @@ -56,10 +60,14 @@ func GetEndpoint(ctx context.Context, container tc.Container, endpointType strin return strings.Replace(endpoint, "localhost", "127.0.0.1", 1), nil } +// FormatHttpUrl constructs a standard HTTP URL using the provided host and port. +// This function is useful for generating URLs for services running in a containerized environment. func FormatHttpUrl(host string, port string) string { return fmt.Sprintf("http://%s:%s", host, port) } +// FormatWsUrl constructs a WebSocket URL using the provided host and port. +// This function is useful for establishing WebSocket connections to Ethereum nodes. func FormatWsUrl(host string, port string) string { return fmt.Sprintf("ws://%s:%s", host, port) } diff --git a/lib/docker/test_env/validator_keys_generator.go b/lib/docker/test_env/validator_keys_generator.go index 12e875deb..cfbbdc378 100644 --- a/lib/docker/test_env/validator_keys_generator.go +++ b/lib/docker/test_env/validator_keys_generator.go @@ -30,6 +30,8 @@ type ValKeysGenerator struct { t *testing.T } +// NewValKeysGeneretor initializes a ValKeysGenerator for managing validator key generation in a specified Ethereum environment. +// It sets up the necessary container configuration and options, returning the generator instance or an error if initialization fails. func NewValKeysGeneretor(chainConfig *config.EthereumChainConfig, valKeysHostDataDir string, opts ...EnvComponentOption) (*ValKeysGenerator, error) { parts := strings.Split(defaultEth2ValToolsImage, ":") g := &ValKeysGenerator{ @@ -54,12 +56,16 @@ func NewValKeysGeneretor(chainConfig *config.EthereumChainConfig, valKeysHostDat return g, nil } +// WithTestInstance sets up a test logger and associates it with the ValKeysGenerator instance. +// This is useful for capturing log output during testing, ensuring that logs are directed to the test context. func (g *ValKeysGenerator) WithTestInstance(t *testing.T) *ValKeysGenerator { g.l = logging.GetTestLogger(t) g.t = t return g } +// StartContainer initializes and starts the validation keys generation container. +// It ensures the container is ready for use, logging the start event, and returns any errors encountered during the process. func (g *ValKeysGenerator) StartContainer() error { r, err := g.getContainerRequest(g.Networks) if err != nil { diff --git a/lib/docker/test_env/wait_strategy.go b/lib/docker/test_env/wait_strategy.go index 287955291..eab2d301c 100644 --- a/lib/docker/test_env/wait_strategy.go +++ b/lib/docker/test_env/wait_strategy.go @@ -25,6 +25,8 @@ type HTTPStrategy struct { timeout time.Duration } +// NewHTTPStrategy initializes a new HTTP strategy for waiting on a service to become available. +// It sets the path, port, retry delay, expected status code, and timeout, allowing for flexible service readiness checks. func NewHTTPStrategy(path string, port nat.Port) *HTTPStrategy { return &HTTPStrategy{ Path: path, @@ -35,11 +37,15 @@ func NewHTTPStrategy(path string, port nat.Port) *HTTPStrategy { } } +// WithTimeout sets the timeout duration for HTTP requests. +// It returns the updated HTTPStrategy instance, allowing for method chaining. func (w *HTTPStrategy) WithTimeout(timeout time.Duration) *HTTPStrategy { w.timeout = timeout return w } +// WithStatusCode sets the expected HTTP status code for the HTTP strategy. +// This allows users to specify the desired response code to validate during service startup. func (w *HTTPStrategy) WithStatusCode(statusCode int) *HTTPStrategy { w.ExpectedStatusCode = statusCode return w @@ -124,6 +130,8 @@ type WebSocketStrategy struct { l zerolog.Logger } +// NewWebSocketStrategy initializes a WebSocket strategy for monitoring service readiness. +// It sets the port and defines retry behavior, making it useful for ensuring services are operational before proceeding. func NewWebSocketStrategy(port nat.Port, l zerolog.Logger) *WebSocketStrategy { return &WebSocketStrategy{ Port: port, @@ -132,11 +140,16 @@ func NewWebSocketStrategy(port nat.Port, l zerolog.Logger) *WebSocketStrategy { } } +// WithTimeout sets the timeout duration for the WebSocket strategy. +// It allows users to specify how long to wait for a response before timing out, +// enhancing control over connection behavior in network operations. func (w *WebSocketStrategy) WithTimeout(timeout time.Duration) *WebSocketStrategy { w.timeout = timeout return w } +// WaitUntilReady waits for the WebSocket service to become available by repeatedly attempting to connect. +// It returns an error if the connection cannot be established within the specified timeout. func (w *WebSocketStrategy) WaitUntilReady(ctx context.Context, target tcwait.StrategyTarget) (err error) { var client *rpc.Client var host string diff --git a/lib/docker/test_env/zookeeper.go b/lib/docker/test_env/zookeeper.go index 4f664f04f..353083803 100644 --- a/lib/docker/test_env/zookeeper.go +++ b/lib/docker/test_env/zookeeper.go @@ -25,6 +25,8 @@ type Zookeeper struct { t *testing.T } +// NewZookeeper creates a new Zookeeper instance with a unique container name and specified networks. +// It initializes default hooks and sets a startup timeout, making it suitable for managing distributed systems. func NewZookeeper(networks []string) *Zookeeper { id, _ := uuid.NewRandom() z := &Zookeeper{ @@ -38,17 +40,24 @@ func NewZookeeper(networks []string) *Zookeeper { return z } +// WithTestInstance configures the Zookeeper instance for testing by setting up a test logger. +// It returns the modified Zookeeper instance, allowing for easier testing and logging during test execution. func (z *Zookeeper) WithTestInstance(t *testing.T) *Zookeeper { z.l = logging.GetTestLogger(t) z.t = t return z } +// WithContainerName sets the container name for the Zookeeper instance. +// It returns the updated Zookeeper instance, allowing for method chaining. func (z *Zookeeper) WithContainerName(name string) *Zookeeper { z.ContainerName = name return z } +// StartContainer initializes and starts a Zookeeper container. +// It configures logging, handles errors, and sets the internal URL for the container. +// This function is essential for setting up a Zookeeper instance in a test environment. func (z *Zookeeper) StartContainer() error { l := logging.GetTestContainersGoTestLogger(z.t) cr, err := z.getContainerRequest() diff --git a/lib/grafana/client.go b/lib/grafana/client.go index b5633284b..eafa597fb 100644 --- a/lib/grafana/client.go +++ b/lib/grafana/client.go @@ -27,18 +27,26 @@ type AlertRulerClient struct { resty *resty.Client } +// GetAlertGroups retrieves the alert groups from the AlertManager API. +// It returns a slice of AlertGroupsResponse, the HTTP response, and any error encountered. +// This function is useful for monitoring and managing alert configurations. func (g *AlertManagerClient) GetAlertGroups() ([]AlertGroupsResponse, *resty.Response, error) { var result []AlertGroupsResponse r, err := g.resty.R().SetResult(&result).Get("/api/alertmanager/grafana/api/v2/alerts/groups") return result, r, err } +// GetAlterManagerAlerts retrieves alerts from the AlertManager API. +// It returns a slice of alerts, the HTTP response, and any error encountered. func (g *AlertManagerClient) GetAlterManagerAlerts() ([]interface{}, *resty.Response, error) { var result []interface{} r, err := g.resty.R().SetResult(&result).Get("/api/alertmanager/grafana/api/v2/alerts") return result, r, err } +// GetDatasources retrieves a map of datasource names to their unique identifiers from the API. +// It also identifies the default datasource, if available, and includes it in the returned map. +// This function is useful for applications needing to interact with various datasources dynamically. func (c *Client) GetDatasources() (map[string]string, *resty.Response, error) { var result []struct { UID string `json:"uid"` @@ -63,6 +71,9 @@ func (c *Client) GetDatasources() (map[string]string, *resty.Response, error) { return datasourcesMap, r, err } +// NewGrafanaClient initializes a new Grafana client with the specified URL and API key. +// It sets up the necessary headers and configurations for making API requests to Grafana, +// providing access to AlertManager and AlertRuler functionalities. func NewGrafanaClient(url, apiKey string) *Client { isDebug := os.Getenv("RESTY_DEBUG") == "true" resty := resty.New(). @@ -81,6 +92,8 @@ type GetDashboardResponse struct { Dashboard *dashboard.Dashboard `json:"dashboard"` } +// GetDashboard retrieves the dashboard associated with the given unique identifier (uid). +// It returns the dashboard data, the HTTP response, and any error encountered during the request. func (c *Client) GetDashboard(uid string) (GetDashboardResponse, *resty.Response, error) { var result GetDashboardResponse r, err := c.resty.R().SetResult(&result).Get("/api/dashboards/uid/" + uid) @@ -105,6 +118,10 @@ type GrafanaResponse struct { URL *string `json:"url"` } +// PostDashboard sends a request to create or update a Grafana dashboard. +// It returns the response containing the dashboard details, the HTTP response, +// and any error encountered during the request. This function is useful for +// programmatically managing Grafana dashboards. func (c *Client) PostDashboard(dashboard PostDashboardRequest) (GrafanaResponse, *resty.Response, error) { var grafanaResp GrafanaResponse @@ -126,12 +143,16 @@ func (c *Client) PostDashboard(dashboard PostDashboardRequest) (GrafanaResponse, return grafanaResp, resp, nil } +// GetAlertsRules retrieves all provisioned alert rules from the API. +// It returns a slice of ProvisionedAlertRule, the HTTP response, and any error encountered. func (c *Client) GetAlertsRules() ([]ProvisionedAlertRule, *resty.Response, error) { var result []ProvisionedAlertRule r, err := c.resty.R().SetResult(&result).Get("/api/v1/provisioning/alert-rules") return result, r, err } +// GetAlertRulesForDashboardID retrieves all provisioned alert rules associated with a specific dashboard ID. +// It returns a slice of ProvisionedAlertRule and any error encountered during the process. func (c *Client) GetAlertRulesForDashboardID(dashboardID string) ([]ProvisionedAlertRule, error) { rules, _, err := c.GetAlertsRules() if err != nil { @@ -151,6 +172,9 @@ type CustomTime struct { time.Time } +// UnmarshalJSON parses the JSON-encoded data and sets the CustomTime's value. +// It expects the data to represent a timestamp in milliseconds since the epoch. +// This function is useful for decoding JSON data into a CustomTime type. func (ct *CustomTime) UnmarshalJSON(b []byte) error { // Convert bytes to string and parse the number var ms int64 @@ -180,6 +204,9 @@ type Annotation struct { Data interface{} `json:"data"` } +// FormatAlertsTable formats a slice of alerts into a tabular string representation. +// It provides a clear overview of alert states, including timestamps and IDs, +// making it useful for logging or displaying alert information in a structured format. func FormatAlertsTable(alerts []Annotation) string { var b strings.Builder // Initialize a new tab writer with output directed to b, a min width of 8, a tab width of 8, a padding of 2, and tabs replaced by spaces @@ -227,6 +254,9 @@ type PostAnnotationResponse struct { ID int64 `json:"id"` } +// GetAnnotations retrieves a list of annotations based on specified query parameters. +// It allows filtering by alert ID, dashboard ID, type, and time range, ensuring both From and To are set. +// This function is useful for fetching relevant annotations in a Grafana context. func (c *Client) GetAnnotations(params AnnotationsQueryParams) ([]Annotation, *resty.Response, error) { query := make(url.Values) if params.Limit != nil { @@ -266,6 +296,8 @@ func (c *Client) GetAnnotations(params AnnotationsQueryParams) ([]Annotation, *r return result, r, err } +// DeleteAnnotation removes an annotation identified by its ID from the server. +// It returns the response from the server and any error encountered during the request. func (c *Client) DeleteAnnotation(annotationID int64) (*resty.Response, error) { urlPath := fmt.Sprintf("/api/annotations/%d", annotationID) @@ -275,6 +307,8 @@ func (c *Client) DeleteAnnotation(annotationID int64) (*resty.Response, error) { return r, err } +// PostAnnotation sends a new annotation to a specified dashboard, allowing users to add notes or comments. +// It returns the response containing the annotation details, the HTTP response, and any error encountered. func (c *Client) PostAnnotation(annotation PostAnnotation) (PostAnnotationResponse, *resty.Response, error) { a := map[string]interface{}{ "dashboardUID": annotation.DashboardUID, @@ -301,6 +335,8 @@ func (c *Client) PostAnnotation(annotation PostAnnotation) (PostAnnotationRespon return result, r, err } +// PostAlert retrieves alert rules associated with a specified dashboard UID. +// It returns a map of alert rules, the HTTP response, and any error encountered. func (g *AlertRulerClient) PostAlert(dashboardUID string) (map[string][]interface{}, *resty.Response, error) { var result map[string][]interface{} r, err := g.resty.R().SetResult(&result).Get("/api/ruler/grafana/api/v1/rules?dashboard_uid=" + url.QueryEscape(dashboardUID)) @@ -327,6 +363,10 @@ type ProvisionedAlertRule struct { Annotations map[string]string `json:"annotations"` } +// String returns a formatted string representation of the ProvisionedAlertRule, +// including its ID, UID, title, labels, annotations, and other relevant details. +// This function is useful for logging and debugging purposes, providing a clear +// overview of the alert rule's properties. func (p ProvisionedAlertRule) String() string { var sb strings.Builder sb.WriteString(fmt.Sprintf("ID: %d\n", p.ID)) diff --git a/lib/logging/log.go b/lib/logging/log.go index ad71d663c..2cdfe249f 100644 --- a/lib/logging/log.go +++ b/lib/logging/log.go @@ -33,6 +33,9 @@ type CustomT struct { ended bool } +// Write writes the contents of p to the logger associated with CustomT. +// It handles empty input gracefully and logs a warning if called after the test has ended. +// Returns the number of bytes written and any write error encountered. func (ct *CustomT) Write(p []byte) (n int, err error) { str := string(p) if strings.TrimSpace(str) == "" { @@ -59,6 +62,8 @@ func (ct CustomT) Printf(format string, v ...interface{}) { } } +// Init initializes the logging system by setting up a logger with the specified log level. +// It ensures that logging is configured before any application components are initialized. func Init() { l := GetLogger(nil, config.EnvVarLogLevel) log.Logger = l