From 70bcdca2c27a39e2fb529d9567d9edfbfcc38c5b Mon Sep 17 00:00:00 2001 From: Ulysses Souza Date: Tue, 19 May 2020 19:45:03 +0200 Subject: [PATCH] Add tests to volume convertion Signed-off-by: Ulysses Souza --- azure/convert/volume.go | 10 ++- azure/convert/volume_test.go | 134 +++++++++++++++++++++++++++++++++++ errdefs/errors.go | 5 ++ 3 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 azure/convert/volume_test.go diff --git a/azure/convert/volume.go b/azure/convert/volume.go index 24d630531..0acafdf68 100644 --- a/azure/convert/volume.go +++ b/azure/convert/volume.go @@ -55,10 +55,16 @@ type volumeInput struct { func escapeKeySlashes(rawURL string) (string, error) { urlSplit := strings.Split(rawURL, "@") if len(urlSplit) < 1 { - return "", errors.New("invalid url format " + rawURL) + return "", errors.Wrap(errdefs.ErrParsingFailed, "invalid url format "+rawURL) } userPasswd := strings.ReplaceAll(urlSplit[0], "/", "_") - scaped := userPasswd + rawURL[strings.Index(rawURL, "@"):] + + atIndex := strings.Index(rawURL, "@") + if atIndex < 0 { + return "", errors.Wrap(errdefs.ErrParsingFailed, "no share specified in "+rawURL) + } + + scaped := userPasswd + rawURL[atIndex:] return scaped, nil } diff --git a/azure/convert/volume_test.go b/azure/convert/volume_test.go new file mode 100644 index 000000000..ff7adf39d --- /dev/null +++ b/azure/convert/volume_test.go @@ -0,0 +1,134 @@ +/* + Copyright (c) 2020 Docker Inc. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, + INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH + THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +package convert + +import ( + "testing" + + "github.com/compose-spec/compose-go/types" + "gotest.tools/assert" + + "github.com/docker/api/errdefs" +) + +const ( + storageAccountNameKey = "storage_account_name" + storageAccountKeyKey = "storage_account_key" + shareNameKey = "share_name" +) + +func TestGetRunVolumes(t *testing.T) { + volumeStrings := []string{ + "myuser1:mykey1@myshare1/my/path/to/target1", + "myuser2:mykey2@myshare2/my/path/to/target2", + "myuser3:mykey3@mydefaultsharename", // Use default placement at '/run/volumes/' + } + var goldenVolumeConfigs = map[string]types.VolumeConfig{ + "volume-0": { + Name: "volume-0", + Driver: "azure_file", + DriverOpts: map[string]string{ + storageAccountNameKey: "myuser1", + storageAccountKeyKey: "mykey1", + shareNameKey: "myshare1", + }, + }, + "volume-1": { + Name: "volume-1", + Driver: "azure_file", + DriverOpts: map[string]string{ + storageAccountNameKey: "myuser2", + storageAccountKeyKey: "mykey2", + shareNameKey: "myshare2", + }, + }, + "volume-2": { + Name: "volume-2", + Driver: "azure_file", + DriverOpts: map[string]string{ + storageAccountNameKey: "myuser3", + storageAccountKeyKey: "mykey3", + shareNameKey: "mydefaultsharename", + }, + }, + } + goldenServiceVolumeConfigs := []types.ServiceVolumeConfig{ + { + Type: "azure_file", + Source: "volume-0", + Target: "/my/path/to/target1", + }, + { + Type: "azure_file", + Source: "volume-1", + Target: "/my/path/to/target2", + }, + { + Type: "azure_file", + Source: "volume-2", + Target: "/run/volumes/mydefaultsharename", + }, + } + + volumeConfigs, serviceVolumeConfigs, err := GetRunVolumes(volumeStrings) + assert.NilError(t, err) + for k, v := range volumeConfigs { + assert.DeepEqual(t, goldenVolumeConfigs[k], v) + } + for i, v := range serviceVolumeConfigs { + assert.DeepEqual(t, goldenServiceVolumeConfigs[i], v) + } +} + +func TestGetRunVolumesMissingFileShare(t *testing.T) { + _, _, err := GetRunVolumes([]string{"myuser:mykey@"}) + assert.Equal(t, true, errdefs.IsErrParsingFailed(err)) + assert.ErrorContains(t, err, "does not include a storage file share") +} + +func TestGetRunVolumesMissingUser(t *testing.T) { + _, _, err := GetRunVolumes([]string{":mykey@myshare"}) + assert.Equal(t, true, errdefs.IsErrParsingFailed(err)) + assert.ErrorContains(t, err, "does not include a storage username") +} + +func TestGetRunVolumesMissingKey(t *testing.T) { + _, _, err := GetRunVolumes([]string{"userwithnokey:@myshare"}) + assert.Equal(t, true, errdefs.IsErrParsingFailed(err)) + assert.ErrorContains(t, err, "does not include a storage key") + + _, _, err = GetRunVolumes([]string{"userwithnokeytoo@myshare"}) + assert.Equal(t, true, errdefs.IsErrParsingFailed(err)) + assert.ErrorContains(t, err, "does not include a storage key") +} + +func TestGetRunVolumesNoShare(t *testing.T) { + _, _, err := GetRunVolumes([]string{"noshare"}) + assert.Equal(t, true, errdefs.IsErrParsingFailed(err)) + assert.ErrorContains(t, err, "no share specified") +} diff --git a/errdefs/errors.go b/errdefs/errors.go index 6fae1e8f3..436377e7f 100644 --- a/errdefs/errors.go +++ b/errdefs/errors.go @@ -73,3 +73,8 @@ func IsUnknownError(err error) bool { func IsErrNotImplemented(err error) bool { return errors.Is(err, ErrNotImplemented) } + +// IsErrParseFail returns true if the unwrapped error is ErrParsingFailed +func IsErrParsingFailed(err error) bool { + return errors.Is(err, ErrParsingFailed) +}