From: Timo Tietavainen Date: Mon, 15 Nov 2021 19:33:15 +0000 (+0200) Subject: Implement SDL CLI 'remove' -command X-Git-Tag: v0.9.0~8 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=b1cc9affa891649332fb034f648e44514624a956;p=ric-plt%2Fsdlgo.git Implement SDL CLI 'remove' -command Implement a new 'remove' -command for 'sdlcli' -tool. With this command single or many keys under given namespace can be removed from SDL DB. Command syntax is: sdlcli remove [... ] [flags] For the time being only -h and --help flags are supported with the 'remove' -command. Issue-Id: RIC-113 Signed-off-by: Timo Tietavainen Change-Id: I4b68689ae9ec388372298f0445f714a5bdb23f3b --- diff --git a/internal/cli/cli_private_fn_test.go b/internal/cli/cli_private_fn_test.go index 95bc579..2dacf4d 100644 --- a/internal/cli/cli_private_fn_test.go +++ b/internal/cli/cli_private_fn_test.go @@ -23,9 +23,10 @@ package cli var ( - NewRootCmd = newRootCmd - NewHealthCheckCmd = newHealthCheckCmd - NewKeysCmdForTest = newKeysCmd - NewGetCmdForTest = newGetCmd - NewSetCmdForTest = newSetCmd + NewRootCmd = newRootCmd + NewHealthCheckCmd = newHealthCheckCmd + NewKeysCmdForTest = newKeysCmd + NewGetCmdForTest = newGetCmd + NewSetCmdForTest = newSetCmd + NewRemoveCmdForTest = newRemoveCmd ) diff --git a/internal/cli/remove.go b/internal/cli/remove.go new file mode 100644 index 0000000..35fef03 --- /dev/null +++ b/internal/cli/remove.go @@ -0,0 +1,69 @@ +/* + Copyright (c) 2021 AT&T Intellectual Property. + Copyright (c) 2018-2021 Nokia. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + * This source code is part of the near-RT RIC (RAN Intelligent Controller) + * platform project (RICP). + */ + +package cli + +import ( + "bytes" + "gerrit.o-ran-sc.org/r/ric-plt/sdlgo" + "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/sdlgoredis" + "github.com/spf13/cobra" + "os" +) + +const removeLongHelp = "Remove key(s) under given namespace from SDL DB.\n" + + "Multiple keys to remove can be given in a single command,\n" + + "each key is separated from the one next to it by a space." + +func init() { + rootCmd.AddCommand(newRemoveCmd(func() ISyncStorage { + return sdlgo.NewSyncStorage() + })) +} + +func newRemoveCmd(sdlCreateCb SyncStorageCreateCb) *cobra.Command { + cmd := &cobra.Command{ + Use: "remove [... ]", + Short: "Remove key(s) under given namespace from SDL DB", + Long: removeLongHelp, + Args: cobra.MinimumNArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + var buf bytes.Buffer + sdlgoredis.SetDbLogger(&buf) + err := runRemove(sdlCreateCb, args) + if err != nil { + cmd.PrintErrf("%s\n", buf.String()) + } + return err + }, + } + cmd.SetOut(os.Stdout) + return cmd +} + +func runRemove(sdlCreateCb SyncStorageCreateCb, args []string) error { + sdl := sdlCreateCb() + if err := sdl.Remove(args[0], args[1:]); err != nil { + return err + } + return nil +} diff --git a/internal/cli/remove_test.go b/internal/cli/remove_test.go new file mode 100644 index 0000000..180499d --- /dev/null +++ b/internal/cli/remove_test.go @@ -0,0 +1,131 @@ +/* + Copyright (c) 2021 AT&T Intellectual Property. + Copyright (c) 2018-2021 Nokia. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + * This source code is part of the near-RT RIC (RAN Intelligent Controller) + * platform project (RICP). + */ + +package cli_test + +import ( + "bytes" + "fmt" + "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/cli" + "gerrit.o-ran-sc.org/r/ric-plt/sdlgo/internal/mocks" + "github.com/stretchr/testify/assert" + "testing" +) + +var removeMocks *RemoveMocks + +type RemoveMocks struct { + sdlIface *mocks.MockSdlApi + ns string + keys []string + ret error +} + +func setupRemoveCliMock(ns string, keys []string, ret error) { + removeMocks = new(RemoveMocks) + removeMocks.ns = ns + removeMocks.keys = keys + removeMocks.ret = ret +} + +func newMockSdlRemoveApi() cli.ISyncStorage { + removeMocks.sdlIface = new(mocks.MockSdlApi) + removeMocks.sdlIface.On("Remove", removeMocks.ns, removeMocks.keys).Return(removeMocks.ret) + return removeMocks.sdlIface +} + +func runRemoveCli() (string, string, error) { + bufStdout := new(bytes.Buffer) + bufStderr := new(bytes.Buffer) + cmd := cli.NewRemoveCmdForTest(newMockSdlRemoveApi) + cmd.SetOut(bufStdout) + cmd.SetErr(bufStderr) + args := []string{removeMocks.ns} + args = append(args, removeMocks.keys...) + cmd.SetArgs(args) + err := cmd.Execute() + + return bufStdout.String(), bufStderr.String(), err +} + +func TestCliRemoveCanShowHelp(t *testing.T) { + var expOkErr error + expHelp := "Usage:\n " + "remove [... ] [flags]" + expFlagErr := fmt.Errorf("unknown flag: --some-unknown-flag") + expArgCntLtErr := fmt.Errorf("requires at least 2 arg(s), only received 1") + tests := []struct { + args []string + expErr error + expOutput string + }{ + {args: []string{"-h"}, expErr: expOkErr, expOutput: expHelp}, + {args: []string{"--help"}, expErr: expOkErr, expOutput: expHelp}, + {args: []string{"--some-unknown-flag"}, expErr: expFlagErr, expOutput: expHelp}, + {args: []string{"some-ns"}, expErr: expArgCntLtErr, expOutput: expHelp}, + } + + for _, test := range tests { + buf := new(bytes.Buffer) + cmd := cli.NewRemoveCmdForTest(newMockSdlRemoveApi) + cmd.SetOut(buf) + cmd.SetArgs(test.args) + + err := cmd.Execute() + + stdout := buf.String() + assert.Equal(t, test.expErr, err) + assert.Contains(t, stdout, test.expOutput) + } +} + +func TestCliRemoveCommandWithOneKeySuccess(t *testing.T) { + setupRemoveCliMock("some-ns", []string{"some-key"}, nil) + + stdout, stderr, err := runRemoveCli() + + assert.Nil(t, err) + assert.Equal(t, "", stdout) + assert.Equal(t, "", stderr) + removeMocks.sdlIface.AssertExpectations(t) +} + +func TestCliRemoveCommandWithMultipleKeysSuccess(t *testing.T) { + setupRemoveCliMock("some-ns", []string{"some-key-1", "some-key-1", "some-key-3"}, nil) + + stdout, stderr, err := runRemoveCli() + + assert.Nil(t, err) + assert.Equal(t, "", stdout) + assert.Equal(t, "", stderr) + removeMocks.sdlIface.AssertExpectations(t) +} + +func TestCliRemoveCommandFailure(t *testing.T) { + expErr := fmt.Errorf("some-error") + setupRemoveCliMock("some-ns", []string{"some-key"}, expErr) + + _, stderr, err := runRemoveCli() + + assert.Equal(t, expErr, err) + assert.Contains(t, stderr, expErr.Error()) + removeMocks.sdlIface.AssertExpectations(t) +} diff --git a/internal/cli/types.go b/internal/cli/types.go index 448515c..dbe410b 100644 --- a/internal/cli/types.go +++ b/internal/cli/types.go @@ -43,6 +43,7 @@ type DbCreateCb func() *Database type ISyncStorage interface { ListKeys(ns string, pattern string) ([]string, error) Set(ns string, pairs ...interface{}) error + Remove(ns string, keys []string) error } //SyncStorageCreateCb callback function type to create a new SyncStorageInterface diff --git a/internal/mocks/db_mocks_private_testing.go b/internal/mocks/db_mocks_private_testing.go index 45fbb78..06927cb 100644 --- a/internal/mocks/db_mocks_private_testing.go +++ b/internal/mocks/db_mocks_private_testing.go @@ -54,3 +54,8 @@ func (m *MockSdlApi) Set(ns string, pairs ...interface{}) error { a := m.Called(ns, pairs) return a.Error(0) } + +func (m *MockSdlApi) Remove(ns string, keys []string) error { + a := m.Called(ns, keys) + return a.Error(0) +}