Skip to content

Implement Unit Tests for Service Commands (Phase 1) #729

@vfusco

Description

@vfusco

Summary

Add basic unit tests for the service commands in cmd/. This phase focuses on testing what's currently testable without code refactoring: flag registration, default values, help/version output, and Viper bindings.

Related:

Affected Services

Command Package
cartesi-rollups-advancer cmd/cartesi-rollups-advancer/
cartesi-rollups-claimer cmd/cartesi-rollups-claimer/
cartesi-rollups-evm-reader cmd/cartesi-rollups-evm-reader/
cartesi-rollups-jsonrpc-api cmd/cartesi-rollups-jsonrpc-api/
cartesi-rollups-node cmd/cartesi-rollups-node/
cartesi-rollups-prt cmd/cartesi-rollups-prt/
cartesi-rollups-validator cmd/cartesi-rollups-validator/

Motivation

Similar to #728, the service commands act as thin shells around the underlying service libraries. While the service logic is tested in its own package, the command layer lacks test coverage for:

  • Flag parsing and default values
  • Environment variable binding via Viper
  • Help/usage text output
  • Version flag output

Scope

In Scope

  • Help output verification
  • Version output verification
  • Flag registration verification
  • Default value verification
  • Viper binding verification

Out of Scope (Covered in Phase 2)

  • Testing the run function execution
  • Testing PreRunE configuration loading with mocks
  • Testing service startup/shutdown behavior

Proposed Approach

Use the test helper pattern from #728, adapted for service commands:

package root_test

import (
    "bytes"
    "testing"

    "github.com/cartesi/rollups-node/cmd/cartesi-rollups-validator/root"
    "github.com/spf13/viper"
    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/require"
)

func TestValidatorCommand_Help(t *testing.T) {
    viper.Reset()

    buf := new(bytes.Buffer)
    cmd := root.Cmd
    cmd.SetOut(buf)
    cmd.SetErr(buf)
    cmd.SetArgs([]string{"--help"})

    err := cmd.Execute()

    require.NoError(t, err)
    assert.Contains(t, buf.String(), "cartesi-rollups-validator")
    assert.Contains(t, buf.String(), "standalone mode")
}

func TestValidatorCommand_Version(t *testing.T) {
    viper.Reset()

    buf := new(bytes.Buffer)
    cmd := root.Cmd
    cmd.SetOut(buf)
    cmd.SetErr(buf)
    cmd.SetArgs([]string{"--version"})

    err := cmd.Execute()

    require.NoError(t, err)
    assert.Contains(t, buf.String(), "cartesi-rollups-validator")
}

func TestValidatorCommand_FlagsRegistered(t *testing.T) {
    viper.Reset()

    buf := new(bytes.Buffer)
    cmd := root.Cmd
    cmd.SetOut(buf)
    cmd.SetErr(buf)
    cmd.SetArgs([]string{"--help"})

    _ = cmd.Execute()

    output := buf.String()
    expectedFlags := []string{
        "--telemetry-address",
        "--log-level",
        "--log-color",
        "--database-connection",
        "--poll-interval",
        "--max-startup-time",
    }
    for _, flag := range expectedFlags {
        assert.Contains(t, output, flag, "flag %s should be registered", flag)
    }
}

func TestValidatorCommand_DefaultValues(t *testing.T) {
    viper.Reset()

    cmd := root.Cmd

    assert.Equal(t, ":10003", cmd.Flags().Lookup("telemetry-address").DefValue)
    assert.Equal(t, "info", cmd.Flags().Lookup("log-level").DefValue)
    assert.Equal(t, "true", cmd.Flags().Lookup("log-color").DefValue)
    assert.Equal(t, "7", cmd.Flags().Lookup("poll-interval").DefValue)
    assert.Equal(t, "15", cmd.Flags().Lookup("max-startup-time").DefValue)
}

Test Categories

For each service, implement:

1. Help Output Test

Verify --help displays correct usage information and command description.

2. Version Output Test

Verify --version displays the service name and version.

3. Flags Registered Test

Verify all expected flags appear in help output.

4. Default Values Test

Verify each flag has the expected default value via cmd.Flags().Lookup("flag-name").DefValue.

5. Viper Binding Test

Verify flags are properly bound to Viper config keys:

func TestValidatorCommand_ViperBinding(t *testing.T) {
    viper.Reset()

    cmd := root.Cmd
    cmd.SetArgs([]string{
        "--log-level", "debug",
        "--help", // Use help to avoid actually running the service
    })

    _ = cmd.Execute()

    // After flag parsing, viper should have the value
    assert.Equal(t, "debug", viper.GetString(config.LOG_LEVEL))
}

File Structure

cmd/
├── cartesi-rollups-advancer/
│   └── root/
│       ├── root.go
│       └── root_test.go
├── cartesi-rollups-claimer/
│   └── root/
│       ├── root.go
│       └── root_test.go
├── cartesi-rollups-evm-reader/
│   └── root/
│       ├── root.go
│       └── root_test.go
├── cartesi-rollups-jsonrpc-api/
│   └── root/
│       ├── root.go
│       └── root_test.go
├── cartesi-rollups-node/
│   └── root/
│       ├── root.go
│       └── root_test.go
├── cartesi-rollups-prt/
│   └── root/
│       ├── root.go
│       └── root_test.go
└── cartesi-rollups-validator/
    └── root/
        ├── root.go
        └── root_test.go

Acceptance Criteria

  • Each service has tests for:
    • Help output
    • Version output
    • Flags registered
    • Default values
    • Viper bindings
  • Tests can reuse shared helper from cmd/cartesi-rollups-cli/testutil/ (from Implement Unit Tests for cartesi-rollups-cli Commands #728)
  • Tests pass with go test ./cmd/...
  • Tests are isolated (use viper.Reset())
  • No test pollution (tests can run in any order)

References

Labels

testing, services, enhancement

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions