Skip to content

Commit

Permalink
test: e2e tests for monitoring init lido
Browse files Browse the repository at this point in the history
  • Loading branch information
khalifaa55 committed Sep 25, 2024
1 parent 5daed63 commit 790a388
Show file tree
Hide file tree
Showing 21 changed files with 517 additions and 523 deletions.
Binary file removed build/lido-exporter
Binary file not shown.
Binary file removed build/sedg.exee
Binary file not shown.
Binary file removed build/sedge.exe
Binary file not shown.
12 changes: 6 additions & 6 deletions cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ import (
"strings"
"time"

eth2 "github.com/protolambda/zrnt/eth2/configs"
"github.com/NethermindEth/sedge/internal/pkg/clients"
"github.com/NethermindEth/sedge/internal/pkg/dependencies"
"github.com/NethermindEth/sedge/internal/pkg/generate"
sedgeOpts "github.com/NethermindEth/sedge/internal/pkg/options"
"github.com/NethermindEth/sedge/internal/ui"
eth2 "github.com/protolambda/zrnt/eth2/configs"

"github.com/NethermindEth/sedge/cli/actions"
"github.com/NethermindEth/sedge/configs"
Expand Down Expand Up @@ -83,7 +83,7 @@ type CliCmdOptions struct {
numberOfValidators int64
existingValidators int64
installDependencies bool
enableMonitoring bool
enableMonitoring bool
}

func CliCmd(p ui.Prompter, actions actions.SedgeActions, depsMgr dependencies.DependenciesManager, monitoringMgr MonitoringManager) *cobra.Command {
Expand Down Expand Up @@ -399,8 +399,8 @@ func postGenerate(p ui.Prompter, o *CliCmdOptions, a actions.SedgeActions, depsM
}
if o.enableMonitoring {
if err := InitMonitoring(true, true, monitoringMgr, nil); err != nil {
return err
}
return err
}
}
if o.withValidator {
log.Info(configs.HappyStakingRun)
Expand Down Expand Up @@ -836,8 +836,8 @@ func confirmEnableMEVBoost(p ui.Prompter, o *CliCmdOptions) (err error) {
}

func confirmEnableMonitoring(p ui.Prompter, o *CliCmdOptions) (err error) {
o.enableMonitoring, err = p.Confirm("Do you want to enable the monitoring stack?", false)
return
o.enableMonitoring, err = p.Confirm("Do you want to enable the monitoring stack?", false)
return
}

func inputCustomNetworkConfig(p ui.Prompter, o *CliCmdOptions) (err error) {
Expand Down
140 changes: 69 additions & 71 deletions cli/monitoring.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,16 @@ import (
"github.com/NethermindEth/sedge/configs"
"github.com/NethermindEth/sedge/internal/common"
"github.com/NethermindEth/sedge/internal/monitoring"
lidoExporter "github.com/NethermindEth/sedge/internal/monitoring/services/lido_exporter"
sedgeOpts "github.com/NethermindEth/sedge/internal/pkg/options"
"github.com/NethermindEth/sedge/internal/ui"
"github.com/NethermindEth/sedge/internal/utils"
sedgeOpts "github.com/NethermindEth/sedge/internal/pkg/options"
lidoExporter "github.com/NethermindEth/sedge/internal/monitoring/services/lido_exporter"
)

var (
lido bool
)
var lido bool

const (
initMonitoring = "init"
initMonitoring = "init"
cleanMonitoring = "clean"
)

Expand Down Expand Up @@ -78,11 +77,11 @@ func CleanSubCmd(mgr MonitoringManager) *cobra.Command {
}

func LidoSubCmd(mgr MonitoringManager, additionalServices []monitoring.ServiceAPI) *cobra.Command {
lido:= &lidoExporter.LidoExporterParams{}
cmd:= &cobra.Command{
lido := &lidoExporter.LidoExporterParams{}
cmd := &cobra.Command{
Use: "lido",
Short: "Configure Lido CSM Node monitoring",
Args: cobra.NoArgs,
Args: cobra.NoArgs,
PreRunE: func(cmd *cobra.Command, args []string) error {
if lido.NodeOperatorID == "" && lido.RewardAddress == "" {
return errors.New("Node Operator ID or Reward Address is required")
Expand All @@ -97,31 +96,30 @@ func LidoSubCmd(mgr MonitoringManager, additionalServices []monitoring.ServiceAP
return InitMonitoring(true, true, mgr, additionalServices)
},
}
cmd.Flags().StringVar(&lido.NodeOperatorID,"node-operator-id", "", "Node Operator ID")
cmd.Flags().StringVar(&lido.RewardAddress,"reward-address", "", "Reward address of Node Operator. It is used to calculate Node Operator ID if not set")
cmd.Flags().StringVar(&lido.Network,"network", "holesky", "Network name")
cmd.Flags().StringSliceVar(&lido.RPCEndpoints,"rpc-endpoints", nil, "List of Ethereum HTTP RPC endpoints")
cmd.Flags().StringSliceVar(&lido.WSEndpoints,"ws-endpoints", nil, "List of Ethereum WebSocket RPC endpoints")
cmd.Flags().Uint16Var(&lido.Port,"port", 8080, "Port where the metrics will be exported.")
cmd.Flags().DurationVar(&lido.ScrapeTime,"scrape-time", 30*time.Second, "Time interval for scraping metrics. Values should be in the format of 10s, 1m, 1h, etc.")
cmd.Flags().StringVar(&lido.NodeOperatorID, "node-operator-id", "", "Node Operator ID")
cmd.Flags().StringVar(&lido.RewardAddress, "reward-address", "", "Reward address of Node Operator. It is used to calculate Node Operator ID if not set")
cmd.Flags().StringVar(&lido.Network, "network", "holesky", "Network name")
cmd.Flags().StringSliceVar(&lido.RPCEndpoints, "rpc-endpoints", nil, "List of Ethereum HTTP RPC endpoints")
cmd.Flags().StringSliceVar(&lido.WSEndpoints, "ws-endpoints", nil, "List of Ethereum WebSocket RPC endpoints")
cmd.Flags().Uint16Var(&lido.Port, "port", 8080, "Port where the metrics will be exported.")
cmd.Flags().DurationVar(&lido.ScrapeTime, "scrape-time", 30*time.Second, "Time interval for scraping metrics. Values should be in the format of 10s, 1m, 1h, etc.")
cmd.Flags().StringVar(&logLevel, "log-level", "info", "Set Log Level, e.g panic, fatal, error, warn, warning, info, debug, trace")

return cmd
}

func DefaultSubCmd(mgr MonitoringManager, additionalServices []monitoring.ServiceAPI) *cobra.Command {
cmd:= &cobra.Command{
cmd := &cobra.Command{
Use: "default",
Short: "Default monitoring configuration",
Args: cobra.NoArgs,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return InitMonitoring(true, true, mgr, nil)
},
}
return cmd
}


// Init initializes the Monitoring Stack. If install is true, it will install the Monitoring Stack if it is not installed.
// If run is true, it will run the Monitoring Stack if it is not running.
func InitMonitoring(install, run bool, monitoringMgr MonitoringManager, additionalServices []monitoring.ServiceAPI) error {
Expand All @@ -146,12 +144,12 @@ func InitMonitoring(install, run bool, monitoringMgr MonitoringManager, addition
}

// Add additional services to the monitoring manager
for _, service := range additionalServices {
if err := monitoringMgr.AddService(service); err != nil {
return fmt.Errorf("failed to add service %s: %w", service.Name(), err)
}
}
for _, service := range additionalServices {
if err := monitoringMgr.AddService(service); err != nil {
return fmt.Errorf("failed to add service %s: %w", service.Name(), err)
}
}

// Check if the monitoring stack is running.
status, err := monitoringMgr.Status()
if err != nil {
Expand Down Expand Up @@ -194,29 +192,29 @@ func CleanMonitoring(monitoringMgr MonitoringManager) error {

func InputLidoExporterParams(p ui.Prompter) (*lidoExporter.LidoExporterParams, error) {
lido := sedgeOpts.CreateSedgeOptions(sedgeOpts.LidoNode)
params := &lidoExporter.LidoExporterParams{}
var err error
params := &lidoExporter.LidoExporterParams{}
var err error

// Node Operator ID
params.NodeOperatorID, err = p.Input("Enter Node Operator ID (leave empty if using Reward Address)", "", false, nil)
if err != nil {
return params, err
}
// Node Operator ID
params.NodeOperatorID, err = p.Input("Enter Node Operator ID (leave empty if using Reward Address)", "", false, nil)
if err != nil {
return params, err
}

// Reward Address
if params.NodeOperatorID == "" {
params.RewardAddress, err = p.EthAddress("Enter Reward Address of Node Operator", "", true)
if err != nil {
return params, err
}
}
if params.NodeOperatorID == "" {
params.RewardAddress, err = p.EthAddress("Enter Reward Address of Node Operator", "", true)
if err != nil {
return params, err
}
}

// Network
options := lido.SupportedNetworks()
index, err := p.Select("Select network", "holesky", options)
if err != nil {
return params, err
}
index, err := p.Select("Select network", "holesky", options)
if err != nil {
return params, err
}
params.Network = options[index]

// RPC URLs
Expand All @@ -233,39 +231,39 @@ func InputLidoExporterParams(p ui.Prompter) (*lidoExporter.LidoExporterParams, e
// WSs URLs
defaultWSURLs, err := configs.GetPublicWSs(params.Network)
wsURLs, err := p.InputList("Insert Ethereum WebSocket RPC endpoints if you don't want to use the default values listed below", defaultWSURLs, nil)
if err != nil {
return params, err
}
if err != nil {
return params, err
}
params.WSEndpoints = wsURLs

// Port
portStr, err := p.Input("Enter port for exporting metrics", "8080", false, nil)
if err != nil {
return params, err
}
port64, err := strconv.ParseUint(portStr, 10, 16)
if err != nil {
return params, fmt.Errorf("invalid port number: %v", err)
}
params.Port = uint16(port64)
portStr, err := p.Input("Enter port for exporting metrics", "8080", false, nil)
if err != nil {
return params, err
}
port64, err := strconv.ParseUint(portStr, 10, 16)
if err != nil {
return params, fmt.Errorf("invalid port number: %v", err)
}
params.Port = uint16(port64)

// Scrape time
scrapeTimeStr, err := p.Input("Enter scrape time interval (e.g., 30s, 1m, 1h)", "30s", false, nil)
if err != nil {
return params, err
}
params.ScrapeTime, err = time.ParseDuration(scrapeTimeStr)
if err != nil {
return params, fmt.Errorf("invalid scrape time: %v", err)
}

//Log level
scrapeTimeStr, err := p.Input("Enter scrape time interval (e.g., 30s, 1m, 1h)", "30s", false, nil)
if err != nil {
return params, err
}
params.ScrapeTime, err = time.ParseDuration(scrapeTimeStr)
if err != nil {
return params, fmt.Errorf("invalid scrape time: %v", err)
}

// Log level
logOptions := []string{"panic", "fatal", "error", "warn", "warning", "info", "debug", "trace"}
index, err = p.Select("Select log level", "info", logOptions)
if err != nil {
return params, err
}
index, err = p.Select("Select log level", "info", logOptions)
if err != nil {
return params, err
}
params.LogLevel = logOptions[index]

return params, nil
}
return params, nil
}
2 changes: 1 addition & 1 deletion cli/monitoringManager.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ package cli

import (
"github.com/NethermindEth/sedge/internal/common"
"github.com/NethermindEth/sedge/internal/monitoring/services/types"
"github.com/NethermindEth/sedge/internal/monitoring"
"github.com/NethermindEth/sedge/internal/monitoring/services/types"
)

type MonitoringManager interface {
Expand Down
5 changes: 3 additions & 2 deletions e2e/sedge/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,10 @@ func checkGrafanaHealth(t *testing.T) {
}

// checkMonitoringStackContainersNotRunning checks that the monitoring stack containers are not running
func checkMonitoringStackContainersNotRunning(t *testing.T) {
func checkMonitoringStackContainersNotRunning(t *testing.T, containerNames ...string) {
t.Logf("Checking monitoring stack containers are not running")
checkContainerNotExisting(t, "sedge_grafana", "sedge_prometheus", "sedge_node_exporter")
containerNames = append(containerNames, "sedge_grafana", "sedge_prometheus", "sedge_node_exporter")
checkContainerNotExisting(t, containerNames...)
}

// checkContainerNotExisting checks that the given containers are not existing
Expand Down
64 changes: 61 additions & 3 deletions e2e/sedge/monitoring_stack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func TestE2E_MonitoringStack_Init(t *testing.T) {
nil,
// Act
func(t *testing.T, binaryPath string, dataDirPath string) {
runErr = base.RunCommand(t, binaryPath, "sedge", "monitoring", "init","default")
runErr = base.RunCommand(t, binaryPath, "sedge", "monitoring", "init", "default")
},
// Assert
func(t *testing.T, dataDirPath string) {
Expand Down Expand Up @@ -90,7 +90,7 @@ func TestE2E_MonitoringStack_NotReinstalled(t *testing.T) {
t,
// Arrange
func(t *testing.T, sedgePath string) error {
err := base.RunCommand(t, sedgePath, "sedge", "monitoring", "init","default")
err := base.RunCommand(t, sedgePath, "sedge", "monitoring", "init", "default")
if err != nil {
return err
}
Expand Down Expand Up @@ -141,7 +141,7 @@ func TestE2E_MonitoringStack_Clean(t *testing.T) {
t,
// Arrange
func(t *testing.T, sedgePath string) error {
return base.RunCommand(t, sedgePath, "sedge", "monitoring", "init","default")
return base.RunCommand(t, sedgePath, "sedge", "monitoring", "init", "default")
},
// Act
func(t *testing.T, binaryPath string, dataDirPath string) {
Expand Down Expand Up @@ -190,3 +190,61 @@ func TestE2E_MonitoringStack_CleanNonExistent(t *testing.T) {
// Run test case
e2eTest.run()
}

func TestE2E_MonitoringStack_InitLido(t *testing.T) {
// Test context
var (
runErr error
)
// Build test case
e2eTest := newE2ESedgeTestCase(
t,
// Arrange
nil,
// Act
func(t *testing.T, binaryPath string, dataDirPath string) {
runErr = base.RunCommand(t, binaryPath, "sedge", "monitoring", "init", "lido", "--node-operator-id", "1")
},
// Assert
func(t *testing.T, dataDirPath string) {
assert.NoError(t, runErr)
checkMonitoringStackDir(t)
checkMonitoringStackContainers(t)
checkPrometheusTargetsUp(t, "sedge_lido_exporter:8080")
checkGrafanaHealth(t)
},
)
// Run test case
e2eTest.run()
}

func TestE2E_MonitoringStack_CleanLido(t *testing.T) {
// Test context
var (
runErr error
)
// Build test case
e2eTest := newE2ESedgeTestCase(
t,
// Arrange
func(t *testing.T, sedgePath string) error {
return base.RunCommand(t, sedgePath, "sedge", "monitoring", "init", "default")
},
// Act
func(t *testing.T, binaryPath string, dataDirPath string) {
runErr = base.RunCommand(t, binaryPath, "sedge", "monitoring", "clean")
},
// Assert
func(t *testing.T, dataDirPath string) {
assert.NoError(t, runErr)

// Check that monitoring stack directory is removed
assert.NoDirExists(t, dataDirPath)

// Check that monitoring stack containers are removed
checkMonitoringStackContainersNotRunning(t, "sedge_lido_exporter")
},
)
// Run test case
e2eTest.run()
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,15 @@ require (
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/term v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
google.golang.org/grpc v1.65.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
mvdan.cc/gofumpt v0.7.0 // indirect
rsc.io/tmplfunc v0.0.3 // indirect
)
Loading

0 comments on commit 790a388

Please sign in to comment.