Add test for 'storage list-allocation(s)' command

This commit is contained in:
Brian Picciano 2024-11-16 11:50:55 +01:00
parent 190beba739
commit 8eb3b1d98f
3 changed files with 450 additions and 0 deletions

View File

@ -0,0 +1,58 @@
package main
import (
"bytes"
"context"
"isle/daemon"
"isle/toolkit"
"reflect"
"testing"
"dev.mediocregopher.com/mediocre-go-lib.git/mlog"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3"
)
type runHarness struct {
ctx context.Context
logger *mlog.Logger
daemonRPC *daemon.MockRPC
stdout *bytes.Buffer
}
func newRunHarness(t *testing.T) *runHarness {
t.Parallel()
var (
ctx = context.Background()
logger = toolkit.NewTestLogger(t)
daemonRPC = daemon.NewMockRPC(t)
stdout = new(bytes.Buffer)
)
return &runHarness{ctx, logger, daemonRPC, stdout}
}
func (h *runHarness) run(_ *testing.T, args ...string) error {
return doRootCmd(h.ctx, h.logger, &subCmdCtxOpts{
args: args,
daemonRPC: h.daemonRPC,
stdout: h.stdout,
})
}
func (h *runHarness) runAssertStdout(
t *testing.T,
want any,
args ...string,
) {
var (
gotType = reflect.ValueOf(want)
got = reflect.New(gotType.Type())
)
h.stdout.Reset()
assert.NoError(t, h.run(t, args...))
assert.NoError(t, yaml.Unmarshal(h.stdout.Bytes(), got.Interface()))
assert.Equal(t, want, got.Elem().Interface())
}

View File

@ -0,0 +1,85 @@
package main
import (
"context"
"isle/daemon/daecommon"
"isle/toolkit"
"testing"
)
func TestStorageAllocationList(t *testing.T) {
t.Parallel()
tests := []struct {
name string
allocs []daecommon.ConfigStorageAllocation
want any
}{
{
name: "empty",
allocs: nil,
want: []any{},
},
{
// results should get sorted according to RPCPort, with index
// reflecting that order.
name: "success",
allocs: []daecommon.ConfigStorageAllocation{
{
DataPath: "b",
MetaPath: "B",
Capacity: 2,
S3APIPort: 2000,
RPCPort: 2001,
AdminPort: 2002,
},
{
DataPath: "a",
MetaPath: "A",
Capacity: 1,
S3APIPort: 1000,
RPCPort: 1001,
AdminPort: 1002,
},
},
want: []map[string]any{
{
"index": 0,
"data_path": "a",
"meta_path": "A",
"capacity": 1,
"s3_api_port": 1000,
"rpc_port": 1001,
"admin_port": 1002,
},
{
"index": 1,
"data_path": "b",
"meta_path": "B",
"capacity": 2,
"s3_api_port": 2000,
"rpc_port": 2001,
"admin_port": 2002,
},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
var (
h = newRunHarness(t)
config daecommon.NetworkConfig
)
config.Storage.Allocations = test.allocs
h.daemonRPC.
On("GetConfig", toolkit.MockArg[context.Context]()).
Return(config, nil).
Once()
h.runAssertStdout(t, test.want, "storage", "list-allocations")
})
}
}

307
go/daemon/rpc_mock.go Normal file
View File

@ -0,0 +1,307 @@
// Code generated by mockery v2.43.1. DO NOT EDIT.
package daemon
import (
context "context"
bootstrap "isle/bootstrap"
daecommon "isle/daemon/daecommon"
mock "github.com/stretchr/testify/mock"
nebula "isle/nebula"
network "isle/daemon/network"
)
// MockRPC is an autogenerated mock type for the RPC type
type MockRPC struct {
mock.Mock
}
// CreateHost provides a mock function with given fields: _a0, _a1, _a2
func (_m *MockRPC) CreateHost(_a0 context.Context, _a1 nebula.HostName, _a2 network.CreateHostOpts) (network.JoiningBootstrap, error) {
ret := _m.Called(_a0, _a1, _a2)
if len(ret) == 0 {
panic("no return value specified for CreateHost")
}
var r0 network.JoiningBootstrap
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, nebula.HostName, network.CreateHostOpts) (network.JoiningBootstrap, error)); ok {
return rf(_a0, _a1, _a2)
}
if rf, ok := ret.Get(0).(func(context.Context, nebula.HostName, network.CreateHostOpts) network.JoiningBootstrap); ok {
r0 = rf(_a0, _a1, _a2)
} else {
r0 = ret.Get(0).(network.JoiningBootstrap)
}
if rf, ok := ret.Get(1).(func(context.Context, nebula.HostName, network.CreateHostOpts) error); ok {
r1 = rf(_a0, _a1, _a2)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CreateNebulaCertificate provides a mock function with given fields: _a0, _a1, _a2
func (_m *MockRPC) CreateNebulaCertificate(_a0 context.Context, _a1 nebula.HostName, _a2 nebula.EncryptingPublicKey) (nebula.Certificate, error) {
ret := _m.Called(_a0, _a1, _a2)
if len(ret) == 0 {
panic("no return value specified for CreateNebulaCertificate")
}
var r0 nebula.Certificate
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, nebula.HostName, nebula.EncryptingPublicKey) (nebula.Certificate, error)); ok {
return rf(_a0, _a1, _a2)
}
if rf, ok := ret.Get(0).(func(context.Context, nebula.HostName, nebula.EncryptingPublicKey) nebula.Certificate); ok {
r0 = rf(_a0, _a1, _a2)
} else {
r0 = ret.Get(0).(nebula.Certificate)
}
if rf, ok := ret.Get(1).(func(context.Context, nebula.HostName, nebula.EncryptingPublicKey) error); ok {
r1 = rf(_a0, _a1, _a2)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// CreateNetwork provides a mock function with given fields: ctx, name, domain, ipNet, hostName
func (_m *MockRPC) CreateNetwork(ctx context.Context, name string, domain string, ipNet nebula.IPNet, hostName nebula.HostName) error {
ret := _m.Called(ctx, name, domain, ipNet, hostName)
if len(ret) == 0 {
panic("no return value specified for CreateNetwork")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, string, string, nebula.IPNet, nebula.HostName) error); ok {
r0 = rf(ctx, name, domain, ipNet, hostName)
} else {
r0 = ret.Error(0)
}
return r0
}
// GetConfig provides a mock function with given fields: _a0
func (_m *MockRPC) GetConfig(_a0 context.Context) (daecommon.NetworkConfig, error) {
ret := _m.Called(_a0)
if len(ret) == 0 {
panic("no return value specified for GetConfig")
}
var r0 daecommon.NetworkConfig
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) (daecommon.NetworkConfig, error)); ok {
return rf(_a0)
}
if rf, ok := ret.Get(0).(func(context.Context) daecommon.NetworkConfig); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(daecommon.NetworkConfig)
}
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetGarageClientParams provides a mock function with given fields: _a0
func (_m *MockRPC) GetGarageClientParams(_a0 context.Context) (network.GarageClientParams, error) {
ret := _m.Called(_a0)
if len(ret) == 0 {
panic("no return value specified for GetGarageClientParams")
}
var r0 network.GarageClientParams
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) (network.GarageClientParams, error)); ok {
return rf(_a0)
}
if rf, ok := ret.Get(0).(func(context.Context) network.GarageClientParams); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(network.GarageClientParams)
}
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetHosts provides a mock function with given fields: _a0
func (_m *MockRPC) GetHosts(_a0 context.Context) ([]bootstrap.Host, error) {
ret := _m.Called(_a0)
if len(ret) == 0 {
panic("no return value specified for GetHosts")
}
var r0 []bootstrap.Host
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) ([]bootstrap.Host, error)); ok {
return rf(_a0)
}
if rf, ok := ret.Get(0).(func(context.Context) []bootstrap.Host); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]bootstrap.Host)
}
}
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetNebulaCAPublicCredentials provides a mock function with given fields: _a0
func (_m *MockRPC) GetNebulaCAPublicCredentials(_a0 context.Context) (nebula.CAPublicCredentials, error) {
ret := _m.Called(_a0)
if len(ret) == 0 {
panic("no return value specified for GetNebulaCAPublicCredentials")
}
var r0 nebula.CAPublicCredentials
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) (nebula.CAPublicCredentials, error)); ok {
return rf(_a0)
}
if rf, ok := ret.Get(0).(func(context.Context) nebula.CAPublicCredentials); ok {
r0 = rf(_a0)
} else {
r0 = ret.Get(0).(nebula.CAPublicCredentials)
}
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// GetNetworks provides a mock function with given fields: _a0
func (_m *MockRPC) GetNetworks(_a0 context.Context) ([]bootstrap.CreationParams, error) {
ret := _m.Called(_a0)
if len(ret) == 0 {
panic("no return value specified for GetNetworks")
}
var r0 []bootstrap.CreationParams
var r1 error
if rf, ok := ret.Get(0).(func(context.Context) ([]bootstrap.CreationParams, error)); ok {
return rf(_a0)
}
if rf, ok := ret.Get(0).(func(context.Context) []bootstrap.CreationParams); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]bootstrap.CreationParams)
}
}
if rf, ok := ret.Get(1).(func(context.Context) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// JoinNetwork provides a mock function with given fields: _a0, _a1
func (_m *MockRPC) JoinNetwork(_a0 context.Context, _a1 network.JoiningBootstrap) error {
ret := _m.Called(_a0, _a1)
if len(ret) == 0 {
panic("no return value specified for JoinNetwork")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, network.JoiningBootstrap) error); ok {
r0 = rf(_a0, _a1)
} else {
r0 = ret.Error(0)
}
return r0
}
// RemoveHost provides a mock function with given fields: ctx, hostName
func (_m *MockRPC) RemoveHost(ctx context.Context, hostName nebula.HostName) error {
ret := _m.Called(ctx, hostName)
if len(ret) == 0 {
panic("no return value specified for RemoveHost")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, nebula.HostName) error); ok {
r0 = rf(ctx, hostName)
} else {
r0 = ret.Error(0)
}
return r0
}
// SetConfig provides a mock function with given fields: _a0, _a1
func (_m *MockRPC) SetConfig(_a0 context.Context, _a1 daecommon.NetworkConfig) error {
ret := _m.Called(_a0, _a1)
if len(ret) == 0 {
panic("no return value specified for SetConfig")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, daecommon.NetworkConfig) error); ok {
r0 = rf(_a0, _a1)
} else {
r0 = ret.Error(0)
}
return r0
}
// NewMockRPC creates a new instance of MockRPC. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockRPC(t interface {
mock.TestingT
Cleanup(func())
}) *MockRPC {
mock := &MockRPC{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}