github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/hooks/1.0.0/when_test.go (about) 1 package hook 2 3 import ( 4 "fmt" 5 "testing" 6 7 rspec "github.com/opencontainers/runtime-spec/specs-go" 8 "github.com/stretchr/testify/assert" 9 ) 10 11 func TestNoMatch(t *testing.T) { 12 config := &rspec.Spec{} 13 for _, o := range []bool{true, false} { 14 or := o 15 t.Run(fmt.Sprintf("or %t", or), func(t *testing.T) { 16 when := When{Or: or} 17 match, err := when.Match(config, map[string]string{}, false) 18 if err != nil { 19 t.Fatal(err) 20 } 21 assert.Equal(t, false, match) 22 }) 23 } 24 } 25 26 func TestAlways(t *testing.T) { 27 config := &rspec.Spec{} 28 processStruct := &rspec.Process{ 29 Args: []string{"/bin/sh", "a", "b"}, 30 } 31 for _, a := range []bool{true, false} { 32 always := a 33 for _, o := range []bool{true, false} { 34 or := o 35 for _, p := range []*rspec.Process{processStruct, nil} { 36 process := p 37 t.Run(fmt.Sprintf("always %t, or %t, has process %t", always, or, process != nil), func(t *testing.T) { 38 config.Process = process 39 when := When{Always: &always, Or: or} 40 match, err := when.Match(config, map[string]string{}, false) 41 if err != nil { 42 t.Fatal(err) 43 } 44 assert.Equal(t, always, match) 45 }) 46 } 47 } 48 } 49 } 50 51 func TestHasBindMountsAnd(t *testing.T) { 52 hasBindMounts := true 53 when := When{HasBindMounts: &hasBindMounts} 54 config := &rspec.Spec{} 55 for _, b := range []bool{false, true} { 56 containerHasBindMounts := b 57 t.Run(fmt.Sprintf("%t", containerHasBindMounts), func(t *testing.T) { 58 match, err := when.Match(config, map[string]string{}, containerHasBindMounts) 59 if err != nil { 60 t.Fatal(err) 61 } 62 assert.Equal(t, containerHasBindMounts, match) 63 }) 64 } 65 } 66 67 func TestHasBindMountsOr(t *testing.T) { 68 hasBindMounts := true 69 when := When{HasBindMounts: &hasBindMounts, Or: true} 70 config := &rspec.Spec{} 71 for _, b := range []bool{false, true} { 72 containerHasBindMounts := b 73 t.Run(fmt.Sprintf("%t", containerHasBindMounts), func(t *testing.T) { 74 match, err := when.Match(config, map[string]string{}, containerHasBindMounts) 75 if err != nil { 76 t.Fatal(err) 77 } 78 assert.Equal(t, containerHasBindMounts, match) 79 }) 80 } 81 } 82 83 func TestAnnotations(t *testing.T) { 84 when := When{ 85 Annotations: map[string]string{ 86 "^a$": "^b$", 87 "^c$": "^d$", 88 }, 89 } 90 config := &rspec.Spec{} 91 for _, tt := range []struct { 92 name string 93 annotations map[string]string 94 or bool 95 match bool 96 }{ 97 { 98 name: "matching both, and", 99 annotations: map[string]string{ 100 "a": "b", 101 "c": "d", 102 "e": "f", 103 }, 104 or: false, 105 match: true, 106 }, 107 { 108 name: "matching one, and", 109 annotations: map[string]string{ 110 "a": "b", 111 }, 112 or: false, 113 match: false, 114 }, 115 { 116 name: "matching one, or", 117 annotations: map[string]string{ 118 "a": "b", 119 }, 120 or: true, 121 match: true, 122 }, 123 { 124 name: "key-only, or", 125 annotations: map[string]string{ 126 "a": "bc", 127 }, 128 or: true, 129 match: false, 130 }, 131 { 132 name: "value-only, or", 133 annotations: map[string]string{ 134 "ac": "b", 135 }, 136 or: true, 137 match: false, 138 }, 139 } { 140 test := tt 141 t.Run(test.name, func(t *testing.T) { 142 when.Or = test.or 143 match, err := when.Match(config, test.annotations, false) 144 if err != nil { 145 t.Fatal(err) 146 } 147 assert.Equal(t, test.match, match) 148 }) 149 } 150 } 151 152 func TestCommands(t *testing.T) { 153 when := When{ 154 Commands: []string{ 155 "^/bin/sh$", 156 }, 157 } 158 config := &rspec.Spec{} 159 for _, tt := range []struct { 160 name string 161 process *rspec.Process 162 match bool 163 }{ 164 { 165 name: "good", 166 process: &rspec.Process{ 167 Args: []string{"/bin/sh", "a", "b"}, 168 }, 169 match: true, 170 }, 171 { 172 name: "extra characters", 173 process: &rspec.Process{ 174 Args: []string{"/bin/shell", "a", "b"}, 175 }, 176 match: false, 177 }, 178 { 179 name: "process unset", 180 match: false, 181 }, 182 } { 183 test := tt 184 t.Run(test.name, func(t *testing.T) { 185 config.Process = test.process 186 match, err := when.Match(config, map[string]string{}, false) 187 if err != nil { 188 t.Fatal(err) 189 } 190 assert.Equal(t, test.match, match) 191 }) 192 } 193 } 194 195 func TestCommandsEmptyProcessArgs(t *testing.T) { 196 when := When{ 197 Commands: []string{ 198 "^/bin/sh$", 199 }, 200 } 201 config := &rspec.Spec{ 202 Process: &rspec.Process{}, 203 } 204 _, err := when.Match(config, map[string]string{}, false) 205 if err == nil { 206 t.Fatal("unexpected success") 207 } 208 assert.Regexp(t, "^process\\.args must have at least one entry$", err.Error()) 209 } 210 211 func TestHasBindMountsAndCommands(t *testing.T) { 212 hasBindMounts := true 213 when := When{ 214 HasBindMounts: &hasBindMounts, 215 Commands: []string{ 216 "^/bin/sh$", 217 }, 218 } 219 config := &rspec.Spec{Process: &rspec.Process{}} 220 for _, tt := range []struct { 221 name string 222 command string 223 hasBindMounts bool 224 or bool 225 match bool 226 }{ 227 { 228 name: "both, and", 229 command: "/bin/sh", 230 hasBindMounts: true, 231 or: false, 232 match: true, 233 }, 234 { 235 name: "both, or", 236 command: "/bin/sh", 237 hasBindMounts: true, 238 or: true, 239 match: true, 240 }, 241 { 242 name: "bind, and", 243 command: "/bin/shell", 244 hasBindMounts: true, 245 or: false, 246 match: false, 247 }, 248 { 249 name: "bind, or", 250 command: "/bin/shell", 251 hasBindMounts: true, 252 or: true, 253 match: true, 254 }, 255 { 256 name: "command, and", 257 command: "/bin/sh", 258 hasBindMounts: false, 259 or: false, 260 match: false, 261 }, 262 { 263 name: "command, or", 264 command: "/bin/sh", 265 hasBindMounts: false, 266 or: true, 267 match: true, 268 }, 269 { 270 name: "neither, and", 271 command: "/bin/shell", 272 hasBindMounts: false, 273 or: false, 274 match: false, 275 }, 276 { 277 name: "neither, or", 278 command: "/bin/shell", 279 hasBindMounts: false, 280 or: true, 281 match: false, 282 }, 283 } { 284 test := tt 285 t.Run(test.name, func(t *testing.T) { 286 config.Process.Args = []string{test.command} 287 when.Or = test.or 288 match, err := when.Match(config, map[string]string{}, test.hasBindMounts) 289 if err != nil { 290 t.Fatal(err) 291 } 292 assert.Equal(t, test.match, match) 293 }) 294 } 295 } 296 297 func TestInvalidRegexp(t *testing.T) { 298 config := &rspec.Spec{Process: &rspec.Process{Args: []string{"/bin/sh"}}} 299 for _, tt := range []struct { 300 name string 301 when When 302 expected string 303 }{ 304 { 305 name: "invalid-annotation-key", 306 when: When{Annotations: map[string]string{"[": "a"}}, 307 expected: "^annotation key: error parsing regexp: .*", 308 }, 309 { 310 name: "invalid-annotation-value", 311 when: When{Annotations: map[string]string{"a": "["}}, 312 expected: "^annotation value: error parsing regexp: .*", 313 }, 314 { 315 name: "invalid-command", 316 when: When{Commands: []string{"["}}, 317 expected: "^command: error parsing regexp: .*", 318 }, 319 } { 320 test := tt 321 t.Run(test.name, func(t *testing.T) { 322 _, err := test.when.Match(config, map[string]string{"a": "b"}, false) 323 if err == nil { 324 t.Fatal("unexpected success") 325 } 326 assert.Regexp(t, test.expected, err.Error()) 327 }) 328 } 329 }