@@ -2,203 +2,99 @@ package cmdguard
22
33import (
44 "os/exec"
5- "reflect"
6- "testing"
7- )
8-
9- /*
10- Copyright 2024 The Fluid Authors.
11-
12- Licensed under the Apache License, Version 2.0 (the "License");
13- you may not use this file except in compliance with the License.
14- You may obtain a copy of the License at
155
16- http://www.apache.org/licenses/LICENSE-2.0
17-
18- Unless required by applicable law or agreed to in writing, software
19- distributed under the License is distributed on an "AS IS" BASIS,
20- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21- See the License for the specific language governing permissions and
22- limitations under the License.
23- */
24-
25- func TestValidateShellPipeString (t * testing.T ) {
26- type args struct {
27- command string
28- }
29- tests := []struct {
30- name string
31- args args
32- wantErr bool
33- }{
34- {name : "valid command with grep" , args : args {command : "echo hello world | grep hello" }, wantErr : true },
35- {name : "valid command with wc -l" , args : args {command : "ls file | wc -l" }, wantErr : false },
36- {name : "invalid command with xyz" , args : args {command : "echo hello world | xyz" }, wantErr : true },
37- {name : "invalid command with kubectl" , args : args {command : "kubectl hello world | xyz" }, wantErr : true },
38- {name : "illegal sequence in command with &" , args : args {command : "echo hello world & echo y" }, wantErr : true },
39- {name : "illegal sequence in command with ;" , args : args {command : "ls ; echo y" }, wantErr : true },
40- {name : "command with $" , args : args {command : "ls $HOME" }, wantErr : true },
41- {name : "command with absolute path" , args : args {command : "ls /etc" }, wantErr : false },
42- }
6+ . "github.com/onsi/ginkgo/v2"
7+ . "github.com/onsi/gomega"
8+ )
439
44- for _ , tt := range tests {
45- t .Run (tt .name , func (t * testing.T ) {
46- if err := validateShellPipeString (tt .args .command ); (err != nil ) != tt .wantErr {
47- t .Errorf ("Testcase '%s' ValidateShellPipeString() error = %v, wantErr %v" , tt .name , err , tt .wantErr )
48- }
49- })
50- }
51- }
10+ var _ = Describe ("cmdguard pipes" , func () {
11+ Describe ("validateShellPipeString" , func () {
12+ DescribeTable ("pipe string validation" ,
13+ func (command string , wantErr bool ) {
14+ err := validateShellPipeString (command )
15+ if wantErr {
16+ Expect (err ).To (HaveOccurred ())
17+ } else {
18+ Expect (err ).NotTo (HaveOccurred ())
19+ }
20+ },
21+ Entry ("valid command with grep" , "echo hello world | grep hello" , true ),
22+ Entry ("valid command with wc -l" , "ls file | wc -l" , false ),
23+ Entry ("invalid command with xyz" , "echo hello world | xyz" , true ),
24+ Entry ("invalid command with kubectl" , "kubectl hello world | xyz" , true ),
25+ Entry ("illegal sequence in command with &" , "echo hello world & echo y" , true ),
26+ Entry ("illegal sequence in command with ;" , "ls ; echo y" , true ),
27+ Entry ("command with $" , "ls $HOME" , true ),
28+ Entry ("command with absolute path" , "ls /etc" , false ),
29+ )
30+ })
5231
53- func TestShellCommand (t * testing.T ) {
54- type args struct {
55- name string
56- arg []string
57- }
58- tests := []struct {
59- name string
60- args args
61- wantCmd * exec.Cmd
62- wantErr bool
63- }{
64- {name : "valid simple command" , args : args {name : "bash" , arg : []string {"-c" , "ls" }}, wantCmd : exec .Command ("bash" , "-c" , "ls" ), wantErr : false },
65- {name : "insufficient arguments" , args : args {name : "bash" , arg : []string {"-c" }}, wantCmd : nil , wantErr : true },
66- {name : "unknown shell command" , args : args {name : "zsh" , arg : []string {"-c" , "ls" }}, wantCmd : nil , wantErr : true },
67- {name : "valid piped command" , args : args {name : "bash" , arg : []string {"-c" , "ls | grep something" }}, wantCmd : exec .Command ("bash" , "-c" , "ls | grep something" ), wantErr : false },
68- {name : "invalid piped command" , args : args {name : "bash" , arg : []string {"-c" , "ls | random-command" }}, wantCmd : nil , wantErr : true },
69- }
70- for _ , tt := range tests {
71- t .Run (tt .name , func (t * testing.T ) {
72- gotCmd , err := ShellCommand (tt .args .name , tt .args .arg ... )
73- if (err != nil ) != tt .wantErr {
74- t .Errorf ("Testcase '%s': PipeCommand() error = %v, wantErr %v" , tt .name , err , tt .wantErr )
75- return
76- }
77- if gotCmd != nil && ! reflect .DeepEqual (gotCmd .Path , tt .wantCmd .Path ) {
78- t .Errorf ("Testcase '%s': PipeCommand() = %v, want %v" , tt .name , gotCmd , tt .wantCmd )
79- }
80- if gotCmd != nil && ! reflect .DeepEqual (gotCmd .Args , tt .wantCmd .Args ) {
81- t .Errorf ("Testcase '%s': PipeCommand() = %v, want %v" , tt .name , gotCmd , tt .wantCmd )
82- }
83- })
84- }
85- }
32+ Describe ("ShellCommand" , func () {
33+ DescribeTable ("shell command creation" ,
34+ func (name string , arg []string , wantCmd * exec.Cmd , wantErr bool ) {
35+ gotCmd , err := ShellCommand (name , arg ... )
36+ if wantErr {
37+ Expect (err ).To (HaveOccurred ())
38+ Expect (gotCmd ).To (BeNil ())
39+ } else {
40+ Expect (err ).NotTo (HaveOccurred ())
41+ Expect (gotCmd ).NotTo (BeNil ())
42+ Expect (gotCmd .Path ).To (Equal (wantCmd .Path ))
43+ Expect (gotCmd .Args ).To (Equal (wantCmd .Args ))
44+ }
45+ },
46+ Entry ("valid simple command" , "bash" , []string {"-c" , "ls" }, exec .Command ("bash" , "-c" , "ls" ), false ),
47+ Entry ("insufficient arguments" , "bash" , []string {"-c" }, nil , true ),
48+ Entry ("unknown shell command" , "zsh" , []string {"-c" , "ls" }, nil , true ),
49+ Entry ("valid piped command" , "bash" , []string {"-c" , "ls | grep something" }, exec .Command ("bash" , "-c" , "ls | grep something" ), false ),
50+ Entry ("invalid piped command" , "bash" , []string {"-c" , "ls | random-command" }, nil , true ),
51+ )
52+ })
8653
87- func TestIsValidCommand (t * testing.T ) {
88- type args struct {
89- cmd string
90- allowedCommands map [string ]CommandValidater
91- }
92- tests := []struct {
93- name string
94- args args
95- want bool
96- }{
97- {name : "valid bash command" , args : args {cmd : "bash" , allowedCommands : map [string ]CommandValidater {"bash" : ExactMatch }}, want : true },
98- {name : "valid sh command" , args : args {cmd : "sh" , allowedCommands : map [string ]CommandValidater {"bash" : ExactMatch , "sh" : ExactMatch }}, want : true },
99- {name : "invalid zsh command" , args : args {cmd : "zsh" , allowedCommands : map [string ]CommandValidater {"bash" : ExactMatch }}, want : false },
100- }
101- for _ , tt := range tests {
102- t .Run (tt .name , func (t * testing.T ) {
103- if got := isValidCommand (tt .args .cmd , tt .args .allowedCommands ); got != tt .want {
104- t .Errorf ("Testcase '%s': isValidCommand() = %v, want %v" , tt .name , got , tt .want )
105- }
106- })
107- }
108- }
54+ Describe ("isValidCommand" , func () {
55+ DescribeTable ("command validity" ,
56+ func (cmd string , allowedCommands map [string ]CommandValidater , want bool ) {
57+ Expect (isValidCommand (cmd , allowedCommands )).To (Equal (want ))
58+ },
59+ Entry ("valid bash command" , "bash" , map [string ]CommandValidater {"bash" : ExactMatch }, true ),
60+ Entry ("valid sh command" , "sh" , map [string ]CommandValidater {"bash" : ExactMatch , "sh" : ExactMatch }, true ),
61+ Entry ("invalid zsh command" , "zsh" , map [string ]CommandValidater {"bash" : ExactMatch }, false ),
62+ )
63+ })
10964
110- func Test_splitShellCommand (t * testing.T ) {
111- type args struct {
112- shellCommandSlice []string
113- }
114- tests := []struct {
115- name string
116- args args
117- wantShellCommand string
118- wantPipedCommands string
119- wantErr bool
120- }{
121- {
122- name : "valid shell command" ,
123- args : args {shellCommandSlice : []string {" bash " , " -c" , "echo foobar | grep foo" }},
124- wantShellCommand : "bash -c" ,
125- wantPipedCommands : "echo foobar | grep foo" ,
126- wantErr : false ,
127- },
128- {
129- name : "empty shell command" ,
130- args : args {shellCommandSlice : []string {}},
131- wantShellCommand : "" ,
132- wantPipedCommands : "" ,
133- wantErr : true ,
134- },
135- {
136- name : "invalid command without shell" ,
137- args : args {shellCommandSlice : []string {"echo foobar | grep foo" }},
138- wantShellCommand : "" ,
139- wantPipedCommands : "" ,
140- wantErr : true ,
141- },
142- {
143- name : "valid command without shell" ,
144- args : args {shellCommandSlice : []string {"test" , "hello" , "--help" }},
145- wantShellCommand : "test hello" ,
146- wantPipedCommands : "--help" ,
147- wantErr : false ,
148- },
149- }
150- for _ , tt := range tests {
151- t .Run (tt .name , func (t * testing.T ) {
152- gotShellCommand , gotPipedCommands , err := splitShellCommand (tt .args .shellCommandSlice )
153- if (err != nil ) != tt .wantErr {
154- t .Errorf ("splitShellCommand() error = %v, wantErr %v" , err , tt .wantErr )
155- return
156- }
157- if gotShellCommand != tt .wantShellCommand {
158- t .Errorf ("splitShellCommand() gotShellCommand = %v, want %v" , gotShellCommand , tt .wantShellCommand )
159- }
160- if gotPipedCommands != tt .wantPipedCommands {
161- t .Errorf ("splitShellCommand() gotPipedCommands = %v, want %v" , gotPipedCommands , tt .wantPipedCommands )
162- }
163- })
164- }
165- }
65+ Describe ("splitShellCommand" , func () {
66+ DescribeTable ("splitting shell command" ,
67+ func (shellCommandSlice []string , wantShellCommand , wantPipedCommands string , wantErr bool ) {
68+ gotShellCommand , gotPipedCommands , err := splitShellCommand (shellCommandSlice )
69+ if wantErr {
70+ Expect (err ).To (HaveOccurred ())
71+ } else {
72+ Expect (err ).NotTo (HaveOccurred ())
73+ Expect (gotShellCommand ).To (Equal (wantShellCommand ))
74+ Expect (gotPipedCommands ).To (Equal (wantPipedCommands ))
75+ }
76+ },
77+ Entry ("valid shell command" , []string {" bash " , " -c" , "echo foobar | grep foo" }, "bash -c" , "echo foobar | grep foo" , false ),
78+ Entry ("empty shell command" , []string {}, "" , "" , true ),
79+ Entry ("invalid command without shell" , []string {"echo foobar | grep foo" }, "" , "" , true ),
80+ Entry ("valid command without shell" , []string {"test" , "hello" , "--help" }, "test hello" , "--help" , false ),
81+ )
82+ })
16683
167- func Test_validateShellCommand (t * testing.T ) {
168- type args struct {
169- shellCommand string
170- }
171- tests := []struct {
172- name string
173- args args
174- wantErr bool
175- }{
176- {
177- name : "bash shell" ,
178- args : args {shellCommand : "bash -c" },
179- wantErr : false ,
180- },
181- {
182- name : "sh shell" ,
183- args : args {shellCommand : "sh -c" },
184- wantErr : false ,
185- },
186- {
187- name : "zsh shell(invalid)" ,
188- args : args {shellCommand : "zsh -c" },
189- wantErr : true ,
190- },
191- {
192- name : "bash command" ,
193- args : args {shellCommand : "bash -s" },
194- wantErr : true ,
195- },
196- }
197- for _ , tt := range tests {
198- t .Run (tt .name , func (t * testing.T ) {
199- if err := validateShellCommand (tt .args .shellCommand ); (err != nil ) != tt .wantErr {
200- t .Errorf ("validateShellCommand() error = %v, wantErr %v" , err , tt .wantErr )
201- }
202- })
203- }
204- }
84+ Describe ("validateShellCommand" , func () {
85+ DescribeTable ("shell command validation" ,
86+ func (shellCommand string , wantErr bool ) {
87+ err := validateShellCommand (shellCommand )
88+ if wantErr {
89+ Expect (err ).To (HaveOccurred ())
90+ } else {
91+ Expect (err ).NotTo (HaveOccurred ())
92+ }
93+ },
94+ Entry ("bash shell" , "bash -c" , false ),
95+ Entry ("sh shell" , "sh -c" , false ),
96+ Entry ("zsh shell(invalid)" , "zsh -c" , true ),
97+ Entry ("bash command" , "bash -s" , true ),
98+ )
99+ })
100+ })
0 commit comments