tree: b2aa0fd5f2cab9d55030c14849eea3b94d0d270f [path history] [tgz]
  1. config/
  2. config_trees/
  3. ctr/
  4. dev/
  5. docker/
  6. internal/
  7. karte/
  8. logger/
  9. models/
  10. namespace/
  11. scopes/
  12. scripts/
  13. tlw/
  14. upload/
  15. version/
  16. .gitignore
  17. config_test.go
  18. GEMINI.md
  19. init_execs.go
  20. Makefile
  21. OWNERS
  22. README.md
  23. recovery.go
  24. recovery_configs_test.go
  25. recovery_test.go
  26. 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.