tree: 60ce4d2fb36adea2ee316fde68e5bf07bf3b0693
  1. bols_client/
  2. config/
  3. config_trees/
  4. ctr/
  5. dev/
  6. docker/
  7. internal/
  8. karte/
  9. logger/
  10. loguploader/
  11. models/
  12. namespace/
  13. scopes/
  14. scripts/
  15. tlw/
  16. upload/
  17. version/
  18. .gitignore
  19. config_test.go
  20. GEMINI.md
  21. init_execs.go
  22. Makefile
  23. OWNERS
  24. README.md
  25. recovery.go
  26. recovery_configs_test.go
  27. recovery_test.go
  28. test_labstation_repair.sh
  29. tlw.go
go/src/infra/cros/recovery/README.md

PARIS - Recovery Library

go/fleet-recovery-developer

TL;DR - after making changes in this directory run

make trees
make testf
make test

It is recommended to first run the fast tests using make testf. If those pass, then run the full test suite using make test.

And upload your change to gerrit with

git push origin HEAD:refs/for/main

Testing Exec Functions

Exec functions in the internal/execs subdirectories have the signature func(ctx context.Context, i execs.ExecInfo) error. To test these functions in isolation, use the GoMock generated mocks.

Available GoMocks

  • ExecInfo: go.chromium.org/infra/cros/recovery/internal/execs/mocks/execs.go
    • Mocks execs.ExecInfo
    • Generated from internal/execs/execs.go
  • Components: go.chromium.org/infra/cros/recovery/internal/components/mocks/components.go
    • Mocks interfaces from internal/components/components.go:
      • mocks.MockSSHRunResponse: Mocks components.SSHRunResponse
      • mocks.MockHostAccess: Mocks components.HostAccess
      • mocks.MockServod: Mocks components.Servod
      • mocks.MockCMDExecutor: Mocks components.CMDExecutor

Additionally, the following function types from components can be easily mocked by providing a test function with the same signature:

  • components.Runner: Mock with func(context.Context, time.Duration, string, ...string) (string, error)
  • components.Pinger: Mock with func(context.Context, int) error

Using GoMocks for Testing

  1. Import necessary packages:

    import (
        "testing"
        "github.com/golang/mock/gomock"
        "go.chromium.org/infra/cros/recovery/internal/execs"
        execs_mocks "go.chromium.org/infra/cros/recovery/internal/execs/mocks"\n        // Optional: component mocks
        // "go.chromium.org/infra/cros/recovery/internal/components"
        // components_mocks "go.chromium.org/infra/cros/recovery/internal/components/mocks"
    )
    
  2. Setup Controller and Mocks:

    ctrl := gomock.NewController(t)
    defer ctrl.Finish()
    ctx := context.Background()
    
    mockInfo := execs_mocks.NewMockExecInfo(ctrl)
    
  3. Set Expectations: Use mockInfo.EXPECT() to define expected calls and return values for any ExecInfo methods your function uses. Chain calls to specify arguments and return values.

    // Example: Expect GetActionArgs to be called once and return ParsedArgs
    mockInfo.EXPECT().GetActionArgs(gomock.Any()).Return(execs.ParsedArgs{"my_arg": "some_value"}).Times(1)
    
    // Example: Expect NewServod to be called and return a mocked Servod
    // mockServo := components_mocks.NewMockServod(ctrl)
    // mockServo.EXPECT().Set(gomock.Any(), "some_cmd", gomock.Any()).Return(nil)
    // mockInfo.EXPECT().NewServod().Return(mockServo)
    
  4. Call and Assert: Execute the function under test with mockInfo and assert the results.

    err := myExecFunc(ctx, mockInfo)
    if err != nil {
        t.Errorf("myExecFunc() returned unexpected error: %v", err)
    }
    

Refer to the gomock documentation for more details on setting expectations and matching arguments. See existing tests in the project for practical examples.

Testing Local Config Changes

To test changes made to the recovery configurations in this directory, the easiest method is to use the test_labstation_repair.sh script.

Automated Testing with test_labstation_repair.sh

This script automates the process of building the necessary tools, extracting the current configuration, and scheduling a repair task on a specified labstation. This ensures your local changes are applied.

Usage:

From the root of the infra/go repository, run:

./src/infra/cros/recovery/test_labstation_repair.sh <labstation_hostname>

The script will:

  1. Build the paris tool.
  2. Extract the latest labstation device configuration to /tmp/labstation_config.json.
  3. Build the mallet tool.
  4. Schedule a mallet recovery task on the provided labstation hostname using the extracted configuration.

Manual Steps (Advanced)

If you need more control, you can perform the steps manually:

  1. Build Tools: go build in ../cmd/paris and ../cmd/mallet.
  2. Extract Config: ../cmd/paris/paris config -device labstation > /tmp/labstation_config.json
  3. Run Mallet: ../cmd/mallet/mallet recovery -latest -config /tmp/labstation_config.json <hostname>

Refer to go/fleet-recovery-developer for more detailed guides.