package glm import ( "isle/daemon/daecommon" "os" "path/filepath" "regexp" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func Test_validateTargetAllocs(t *testing.T) { t.Parallel() tests := []struct { label string mkDir, mkFile string activeAllocs, targetAllocs []daecommon.ConfigStorageAllocation wantErr string }{ { label: "empty/empty", }, { label: "empty/single", targetAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "A2", Capacity: 1, RPCPort: 3900}, }, }, { label: "empty/multiple", targetAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "A2", Capacity: 1, RPCPort: 3900}, {DataPath: "B1", MetaPath: "B2", Capacity: 1, RPCPort: 3901}, }, }, { label: "no change", activeAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "B1", MetaPath: "B2", Capacity: 1, RPCPort: 3901}, {DataPath: "A1", MetaPath: "A2", Capacity: 1, RPCPort: 3900}, }, targetAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "A2", Capacity: 1, RPCPort: 3900}, {DataPath: "B1", MetaPath: "B2", Capacity: 1, RPCPort: 3901}, }, }, { label: "change capacity and add alloc", activeAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "A2", Capacity: 1, RPCPort: 3900}, }, targetAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "A2", Capacity: 2, RPCPort: 3900}, {DataPath: "B1", MetaPath: "B2", Capacity: 1, RPCPort: 3901}, }, }, { label: "change rpc port", activeAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "A2", Capacity: 1, RPCPort: 3900}, }, targetAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "B1", MetaPath: "B2", Capacity: 1, RPCPort: 3902}, {DataPath: "A1", MetaPath: "A2", Capacity: 2, RPCPort: 3901}, }, wantErr: `Data path ".+/A1" is already being used`, }, { label: "change data path", activeAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "A2", Capacity: 1, RPCPort: 3900}, }, targetAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "B1", MetaPath: "B2", Capacity: 1, RPCPort: 3901}, {DataPath: "Aa", MetaPath: "A2", Capacity: 2, RPCPort: 3900}, }, wantErr: `RPC port 3900 is already being used`, }, { label: "change meta path", activeAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "A2", Capacity: 1, RPCPort: 3900}, }, targetAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "B1", MetaPath: "B2", Capacity: 1, RPCPort: 3901}, {DataPath: "A1", MetaPath: "Aa", Capacity: 2, RPCPort: 3900}, }, wantErr: `RPC port 3900 is already being used`, }, { label: "conflict rpc port", activeAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "A2", Capacity: 1, RPCPort: 3900}, }, targetAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "B1", MetaPath: "B2", Capacity: 1, RPCPort: 3900}, }, wantErr: `RPC port 3900 is already being used`, }, { label: "conflict data path", activeAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "A2", Capacity: 1, RPCPort: 3900}, }, targetAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "B2", Capacity: 1, RPCPort: 3901}, }, wantErr: `Data path ".+/A1" is already being used`, }, { label: "conflict meta path", activeAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "A2", Capacity: 1, RPCPort: 3900}, }, targetAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "B1", MetaPath: "A2", Capacity: 1, RPCPort: 3901}, }, wantErr: `Meta path ".+/A2" is already being used`, }, { label: "directory/empty", mkDir: "A1", targetAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "A2", Capacity: 1, RPCPort: 3900}, }, }, { label: "directory/with file", mkFile: "A1/some file", targetAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "A2", Capacity: 1, RPCPort: 3900}, }, wantErr: `directory ".+/A1" is already being used`, }, { label: "directory/active alloc with file", mkFile: "A1/some file", activeAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "A2", Capacity: 1, RPCPort: 3900}, }, targetAllocs: []daecommon.ConfigStorageAllocation{ {DataPath: "A1", MetaPath: "A2", Capacity: 1, RPCPort: 3900}, }, }, } for _, test := range tests { t.Run(test.label, func(t *testing.T) { dir := t.TempDir() joinRoot := func(allocs []daecommon.ConfigStorageAllocation) { for i := range allocs { allocs[i].DataPath = filepath.Join(dir, allocs[i].DataPath) allocs[i].MetaPath = filepath.Join(dir, allocs[i].MetaPath) } } joinRoot(test.activeAllocs) joinRoot(test.targetAllocs) if test.mkDir != "" { path := filepath.Join(dir, test.mkDir) require.NoError(t, os.MkdirAll(path, 0755)) } if test.mkFile != "" { path := filepath.Join(dir, test.mkFile) dirPath := filepath.Dir(path) require.NoError(t, os.MkdirAll(dirPath, 0755)) require.NoError(t, os.WriteFile(path, []byte("HI"), 0644)) } err := validateTargetAllocs(test.activeAllocs, test.targetAllocs) if test.wantErr == "" { assert.NoError(t, err) } else { wantErrRegexp := regexp.MustCompile(test.wantErr) assert.True( t, wantErrRegexp.MatchString(err.Error()), "wantErr: %s\nerr:%s", test.wantErr, err, ) } }) } }