Add test for 'storage list-allocation(s)' command
This commit is contained in:
parent
190beba739
commit
8eb3b1d98f
58
go/cmd/entrypoint/main_test.go
Normal file
58
go/cmd/entrypoint/main_test.go
Normal 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())
|
||||||
|
}
|
85
go/cmd/entrypoint/storage_test.go
Normal file
85
go/cmd/entrypoint/storage_test.go
Normal 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
307
go/daemon/rpc_mock.go
Normal 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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user