diff --git a/pkg/proto/v0/settings.pb.micro_test.go b/pkg/proto/v0/settings.pb.micro_test.go index 2c4963522..8be2c5591 100644 --- a/pkg/proto/v0/settings.pb.micro_test.go +++ b/pkg/proto/v0/settings.pb.micro_test.go @@ -279,6 +279,7 @@ func TestSaveGetSettingsBundleWithNoSettings(t *testing.T) { cresponse, err := cl.SaveSettingsBundle(context.Background(), &createRequest) if err != nil || (CustomError{} != testCase.expectedError) { + assert.Error(t, err) var errorData CustomError _ = json.Unmarshal([]byte(err.Error()), &errorData) assert.Equal(t, testCase.expectedError.ID, errorData.ID) @@ -625,7 +626,7 @@ func TestGetSettingsBundleCreatesFolder(t *testing.T) { getRequest := proto.GetSettingsBundleRequest{Identifier: &identifier} _, _ = cl.GetSettingsBundle(context.Background(), &getRequest) - assert.DirExists(t, "ocis-settings-store/bundles/not-existing-extension") + assert.NoDirExists(t, "ocis-settings-store/bundles/not-existing-extension") assert.NoFileExists(t, "ocis-settings-store/bundles/not-existing-extension/not-existing-bundle.json") _ = os.RemoveAll("ocis-settings-store") } @@ -901,7 +902,7 @@ func TestListSettingsBundlesOfNonExistingExtension(t *testing.T) { response, err := cl.ListSettingsBundles(context.Background(), &listRequest) assert.NoError(t, err) assert.Empty(t, response.String()) - assert.DirExists(t, "ocis-settings-store/bundles") + assert.NoDirExists(t, "ocis-settings-store/bundles") assert.NoDirExists(t, "ocis-settings-store/bundles/does-not-exist") } diff --git a/pkg/store/filesystem/bundles.go b/pkg/store/filesystem/bundles.go index d73c4d538..89a98a3dd 100644 --- a/pkg/store/filesystem/bundles.go +++ b/pkg/store/filesystem/bundles.go @@ -10,11 +10,11 @@ import ( // ListBundles returns all bundles in the mountPath folder belonging to the given extension func (s Store) ListBundles(identifier *proto.Identifier) ([]*proto.SettingsBundle, error) { - bundlesFolder := s.buildFolderPathBundles() + var records []*proto.SettingsBundle + bundlesFolder := s.buildFolderPathBundles(false) extensionFolders, err := ioutil.ReadDir(bundlesFolder) if err != nil { - s.Logger.Err(err).Msgf("error reading %v", bundlesFolder) - return nil, err + return records, nil } if len(identifier.Extension) < 1 { @@ -22,7 +22,6 @@ func (s Store) ListBundles(identifier *proto.Identifier) ([]*proto.SettingsBundl } else { s.Logger.Info().Msgf("listing bundles by extension %v", identifier.Extension) } - var records []*proto.SettingsBundle for _, extensionFolder := range extensionFolders { extensionPath := path.Join(bundlesFolder, extensionFolder.Name()) bundleFiles, err := ioutil.ReadDir(extensionPath) @@ -50,7 +49,7 @@ func (s Store) ListBundles(identifier *proto.Identifier) ([]*proto.SettingsBundl // ReadBundle tries to find a bundle by the given identifier within the mountPath. // Extension and BundleKey within the identifier are required. func (s Store) ReadBundle(identifier *proto.Identifier) (*proto.SettingsBundle, error) { - filePath := s.buildFilePathFromBundleArgs(identifier.Extension, identifier.BundleKey) + filePath := s.buildFilePathFromBundleArgs(identifier.Extension, identifier.BundleKey, false) record := proto.SettingsBundle{} if err := s.parseRecordFromFile(&record, filePath); err != nil { return nil, err @@ -63,7 +62,7 @@ func (s Store) ReadBundle(identifier *proto.Identifier) (*proto.SettingsBundle, // WriteBundle writes the given record into a file within the mountPath // Extension and BundleKey within the record identifier are required. func (s Store) WriteBundle(record *proto.SettingsBundle) (*proto.SettingsBundle, error) { - filePath := s.buildFilePathFromBundle(record) + filePath := s.buildFilePathFromBundle(record, true) if err := s.writeRecordToFile(record, filePath); err != nil { return nil, err } diff --git a/pkg/store/filesystem/paths.go b/pkg/store/filesystem/paths.go index 5cc30d704..9bb1c5475 100644 --- a/pkg/store/filesystem/paths.go +++ b/pkg/store/filesystem/paths.go @@ -10,41 +10,40 @@ import ( const folderNameBundles = "bundles" const folderNameValues = "values" -// Builds the folder path for storing settings bundles -func (s Store) buildFolderPathBundles() string { +// Builds the folder path for storing settings bundles. If mkdir is true, folders in the path will be created if necessary. +func (s Store) buildFolderPathBundles(mkdir bool) string { folderPath := path.Join(s.mountPath, folderNameBundles) - s.ensureFolderExists(folderPath) + if mkdir { + s.ensureFolderExists(folderPath) + } return folderPath } -// Builds a unique file name from the given settings bundle -func (s Store) buildFilePathFromBundle(bundle *proto.SettingsBundle) string { - return s.buildFilePathFromBundleArgs(bundle.Identifier.Extension, bundle.Identifier.BundleKey) +// Builds a unique file name from the given settings bundle. If mkdir is true, folders in the path will be created if necessary. +func (s Store) buildFilePathFromBundle(bundle *proto.SettingsBundle, mkdir bool) string { + return s.buildFilePathFromBundleArgs(bundle.Identifier.Extension, bundle.Identifier.BundleKey, mkdir) } -// Builds a unique file name from the given params -func (s Store) buildFilePathFromBundleArgs(extension string, bundleKey string) string { +// Builds a unique file name from the given params. If mkdir is true, folders in the path will be created if necessary. +func (s Store) buildFilePathFromBundleArgs(extension string, bundleKey string, mkdir bool) string { extensionFolder := path.Join(s.mountPath, folderNameBundles, extension) - s.ensureFolderExists(extensionFolder) + if mkdir { + s.ensureFolderExists(extensionFolder) + } return path.Join(extensionFolder, bundleKey+".json") } -// // Builds the folder path for storing settings values -// func (s Store) buildFolderPathValues() string { -// folderPath := path.Join(s.mountPath, folderNameValues) -// s.ensureFolderExists(folderPath) -// return folderPath -// } - -// Builds a unique file name from the given settings value -func (s Store) buildFilePathFromValue(value *proto.SettingsValue) string { - return s.buildFilePathFromValueArgs(value.Identifier.AccountUuid, value.Identifier.Extension, value.Identifier.BundleKey) +// Builds a unique file name from the given settings value. If mkdir is true, folders in the path will be created if necessary. +func (s Store) buildFilePathFromValue(value *proto.SettingsValue, mkdir bool) string { + return s.buildFilePathFromValueArgs(value.Identifier.AccountUuid, value.Identifier.Extension, value.Identifier.BundleKey, mkdir) } -// Builds a unique file name from the given params -func (s Store) buildFilePathFromValueArgs(accountUUID string, extension string, bundleKey string) string { +// Builds a unique file name from the given params. If mkdir is true, folders in the path will be created if necessary. +func (s Store) buildFilePathFromValueArgs(accountUUID string, extension string, bundleKey string, mkdir bool) string { extensionFolder := path.Join(s.mountPath, folderNameValues, accountUUID, extension) - s.ensureFolderExists(extensionFolder) + if mkdir { + s.ensureFolderExists(extensionFolder) + } return path.Join(extensionFolder, bundleKey+".json") } diff --git a/pkg/store/filesystem/values.go b/pkg/store/filesystem/values.go index d322ca0d1..04828fae1 100644 --- a/pkg/store/filesystem/values.go +++ b/pkg/store/filesystem/values.go @@ -14,7 +14,7 @@ import ( // ReadValue tries to find a value by the given identifier attributes within the mountPath // All identifier fields are required. func (s Store) ReadValue(identifier *proto.Identifier) (*proto.SettingsValue, error) { - filePath := s.buildFilePathFromValueArgs(identifier.AccountUuid, identifier.Extension, identifier.BundleKey) + filePath := s.buildFilePathFromValueArgs(identifier.AccountUuid, identifier.Extension, identifier.BundleKey, false) values, err := s.readValuesMapFromFile(filePath) if err != nil { return nil, err @@ -29,7 +29,7 @@ func (s Store) ReadValue(identifier *proto.Identifier) (*proto.SettingsValue, er // WriteValue writes the given SettingsValue into a file within the mountPath // All identifier fields within the value are required. func (s Store) WriteValue(value *proto.SettingsValue) (*proto.SettingsValue, error) { - filePath := s.buildFilePathFromValue(value) + filePath := s.buildFilePathFromValue(value, true) values, err := s.readValuesMapFromFile(filePath) if err != nil { return nil, err @@ -50,7 +50,6 @@ func (s Store) ListValues(identifier *proto.Identifier) ([]*proto.SettingsValue, return values, nil } - // TODO: might be a good idea to do this non-hierarchical. i.e. allowing all fragments in the identifier being set or not. // depending on the set values in the identifier arg, collect all SettingValues files for the account var valueFilePaths []string if len(identifier.Extension) < 1 { @@ -62,7 +61,7 @@ func (s Store) ListValues(identifier *proto.Identifier) ([]*proto.SettingsValue, return nil }); err != nil { s.Logger.Err(err).Msgf("error reading %v", accountFolderPath) - return nil, err + return values, nil } } else if len(identifier.BundleKey) < 1 { extensionPath := path.Join(accountFolderPath, identifier.Extension) @@ -74,7 +73,7 @@ func (s Store) ListValues(identifier *proto.Identifier) ([]*proto.SettingsValue, return nil }); err != nil { s.Logger.Err(err).Msgf("error reading %v", extensionPath) - return nil, err + return values, nil } } else { bundlePath := path.Join(accountFolderPath, identifier.Extension, identifier.BundleKey+".json")