package main import ( "context" "isle/daemon" "isle/daemon/daecommon" "isle/toolkit" "testing" "github.com/stretchr/testify/assert" ) func TestStorageAllocationAdd(t *testing.T) { t.Parallel() tests := []struct { name string args []string setExpectations func(*daemon.MockRPC) wantAlloc daecommon.ConfigStorageAllocation }{ { name: "success/no ports", args: []string{ "--data-path", "foo", "--meta-path=bar", "--capacity", "1", }, wantAlloc: daecommon.ConfigStorageAllocation{ DataPath: "foo", MetaPath: "bar", Capacity: 1, }, }, { name: "success/all ports", args: []string{ "--data-path", "foo", "--meta-path=bar", "--capacity", "1", "--s3-api-port", "1000", "--rpc-port=2000", "--admin-port", "3000", }, wantAlloc: daecommon.ConfigStorageAllocation{ DataPath: "foo", MetaPath: "bar", Capacity: 1, S3APIPort: 1000, RPCPort: 2000, AdminPort: 3000, }, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { var ( h = newRunHarness(t) config = daecommon.NewNetworkConfig(nil) ) h.daemonRPC. On("GetConfig", toolkit.MockArg[context.Context]()). Return(config, nil). Once() config.Storage.Allocations = append( config.Storage.Allocations, test.wantAlloc, ) h.daemonRPC. On( "SetConfig", toolkit.MockArg[context.Context](), config, ). Return(nil). Once() args := []string{"storage", "allocation", "add"} args = append(args, test.args...) assert.NoError(t, h.run(t, args...)) }) } } 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", "allocation", "list") }) } } func TestStorageAllocationRemove(t *testing.T) { t.Parallel() config := func(rpcPorts ...int) daecommon.NetworkConfig { return daecommon.NewNetworkConfig(func(c *daecommon.NetworkConfig) { for _, rpcPort := range rpcPorts { c.Storage.Allocations = append( c.Storage.Allocations, daecommon.ConfigStorageAllocation{RPCPort: rpcPort}, ) } }) } tests := []struct { name string args []string setExpectations func(*daemon.MockRPC) wantErr string }{ { name: "error/no indexes", args: nil, wantErr: "At least one --index must be specified", }, { name: "error/unknown index", args: []string{"--index", "1"}, setExpectations: func(daemonRPC *daemon.MockRPC) { daemonRPC. On("GetConfig", toolkit.MockArg[context.Context]()). Return(config(1000), nil). Once() }, wantErr: "Index 1 not found", }, { name: "success/remove single", args: []string{"--index", "0"}, setExpectations: func(daemonRPC *daemon.MockRPC) { config := config(1000, 2000) daemonRPC. On("GetConfig", toolkit.MockArg[context.Context]()). Return(config, nil). Once() config.Storage.Allocations = config.Storage.Allocations[1:] daemonRPC. On( "SetConfig", toolkit.MockArg[context.Context](), config, ). Return(nil). Once() }, }, { name: "success/remove multiple", args: []string{"--index", "0", "--index", "2"}, setExpectations: func(daemonRPC *daemon.MockRPC) { config := config(1000, 2000, 3000) daemonRPC. On("GetConfig", toolkit.MockArg[context.Context]()). Return(config, nil). Once() config.Storage.Allocations = config.Storage.Allocations[1:2] daemonRPC. On( "SetConfig", toolkit.MockArg[context.Context](), config, ). Return(nil). Once() }, }, { name: "success/remove all", args: []string{"--index", "0", "--index", "1"}, setExpectations: func(daemonRPC *daemon.MockRPC) { config := config(1000, 2000) daemonRPC. On("GetConfig", toolkit.MockArg[context.Context]()). Return(config, nil). Once() config.Storage.Allocations = config.Storage.Allocations[:0] daemonRPC. On( "SetConfig", toolkit.MockArg[context.Context](), config, ). Return(nil). Once() }, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { h := newRunHarness(t) if test.setExpectations != nil { test.setExpectations(h.daemonRPC) } args := []string{"storage", "allocation", "remove"} args = append(args, test.args...) err := h.run(t, args...) if test.wantErr == "" { assert.NoError(t, err) } else { assert.Contains(t, err.Error(), test.wantErr) } }) } }