github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/hooks/hooks_test.go (about) 1 package hooks 2 3 import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 "path/filepath" 8 "runtime" 9 "testing" 10 11 current "github.com/hanks177/podman/v4/pkg/hooks/1.0.0" 12 rspec "github.com/opencontainers/runtime-spec/specs-go" 13 "github.com/stretchr/testify/assert" 14 ) 15 16 // path is the path to an example hook executable. 17 var path string 18 19 func TestGoodNew(t *testing.T) { 20 ctx := context.Background() 21 22 dir := t.TempDir() 23 24 for i, name := range []string{ 25 "01-my-hook.json", 26 "01-UPPERCASE.json", 27 "02-another-hook.json", 28 } { 29 jsonPath := filepath.Join(dir, name) 30 var extraStages string 31 if i == 0 { 32 extraStages = ", \"poststart\", \"poststop\"" 33 } 34 err := ioutil.WriteFile(jsonPath, []byte(fmt.Sprintf("{\"version\": \"1.0.0\", \"hook\": {\"path\": \"%s\", \"timeout\": %d}, \"when\": {\"always\": true}, \"stages\": [\"prestart\"%s]}", path, i+1, extraStages)), 0644) 35 if err != nil { 36 t.Fatal(err) 37 } 38 } 39 40 manager, err := New(ctx, []string{dir}, []string{}) 41 if err != nil { 42 t.Fatal(err) 43 } 44 45 config := &rspec.Spec{} 46 extensionStageHooks, err := manager.Hooks(config, map[string]string{}, false) 47 if err != nil { 48 t.Fatal(err) 49 } 50 51 one := 1 52 two := 2 53 three := 3 54 assert.Equal(t, &rspec.Hooks{ 55 Prestart: []rspec.Hook{ 56 { 57 Path: path, 58 Timeout: &one, 59 }, 60 { 61 Path: path, 62 Timeout: &two, 63 }, 64 { 65 Path: path, 66 Timeout: &three, 67 }, 68 }, 69 Poststart: []rspec.Hook{ 70 { 71 Path: path, 72 Timeout: &one, 73 }, 74 }, 75 Poststop: []rspec.Hook{ 76 { 77 Path: path, 78 Timeout: &one, 79 }, 80 }, 81 }, config.Hooks) 82 83 var nilExtensionStageHooks map[string][]rspec.Hook 84 assert.Equal(t, nilExtensionStageHooks, extensionStageHooks) 85 } 86 87 func TestBadNew(t *testing.T) { 88 ctx := context.Background() 89 90 dir := t.TempDir() 91 92 jsonPath := filepath.Join(dir, "a.json") 93 err := ioutil.WriteFile(jsonPath, []byte("{\"version\": \"-1\"}"), 0644) 94 if err != nil { 95 t.Fatal(err) 96 } 97 98 _, err = New(ctx, []string{dir}, []string{}) 99 if err == nil { 100 t.Fatal("unexpected success") 101 } 102 assert.Regexp(t, "^parsing hook \"[^\"]*a.json\": unrecognized hook version: \"-1\"$", err.Error()) 103 } 104 105 func TestBrokenMatch(t *testing.T) { 106 manager := Manager{ 107 hooks: map[string]*current.Hook{ 108 "a.json": { 109 Version: current.Version, 110 Hook: rspec.Hook{ 111 Path: "/a/b/c", 112 }, 113 When: current.When{ 114 Commands: []string{"["}, 115 }, 116 Stages: []string{"prestart"}, 117 }, 118 }, 119 } 120 config := &rspec.Spec{ 121 Process: &rspec.Process{ 122 Args: []string{"/bin/sh"}, 123 }, 124 } 125 extensionStageHooks, err := manager.Hooks(config, map[string]string{}, false) 126 if err == nil { 127 t.Fatal("unexpected success") 128 } 129 assert.Regexp(t, "^matching hook \"a\\.json\": command: error parsing regexp: .*", err.Error()) 130 131 var nilExtensionStageHooks map[string][]rspec.Hook 132 assert.Equal(t, nilExtensionStageHooks, extensionStageHooks) 133 } 134 135 func TestInvalidStage(t *testing.T) { 136 always := true 137 manager := Manager{ 138 hooks: map[string]*current.Hook{ 139 "a.json": { 140 Version: current.Version, 141 Hook: rspec.Hook{ 142 Path: "/a/b/c", 143 }, 144 When: current.When{ 145 Always: &always, 146 }, 147 Stages: []string{"does-not-exist"}, 148 }, 149 }, 150 } 151 extensionStageHooks, err := manager.Hooks(&rspec.Spec{}, map[string]string{}, false) 152 if err == nil { 153 t.Fatal("unexpected success") 154 } 155 assert.Regexp(t, "^hook \"a\\.json\": unknown stage \"does-not-exist\"$", err.Error()) 156 157 var nilExtensionStageHooks map[string][]rspec.Hook 158 assert.Equal(t, nilExtensionStageHooks, extensionStageHooks) 159 } 160 161 func TestExtensionStage(t *testing.T) { 162 always := true 163 manager := Manager{ 164 hooks: map[string]*current.Hook{ 165 "a.json": { 166 Version: current.Version, 167 Hook: rspec.Hook{ 168 Path: "/a/b/c", 169 }, 170 When: current.When{ 171 Always: &always, 172 }, 173 Stages: []string{"prestart", "poststop", "a", "b"}, 174 }, 175 }, 176 extensionStages: []string{"poststop", "a", "b", "c"}, 177 } 178 179 config := &rspec.Spec{} 180 extensionStageHooks, err := manager.Hooks(config, map[string]string{}, false) 181 if err != nil { 182 t.Fatal(err) 183 } 184 185 assert.Equal(t, &rspec.Hooks{ 186 Prestart: []rspec.Hook{ 187 { 188 Path: "/a/b/c", 189 }, 190 }, 191 }, config.Hooks) 192 193 assert.Equal(t, map[string][]rspec.Hook{ 194 "poststop": { 195 { 196 Path: "/a/b/c", 197 }, 198 }, 199 "a": { 200 { 201 Path: "/a/b/c", 202 }, 203 }, 204 "b": { 205 { 206 Path: "/a/b/c", 207 }, 208 }, 209 }, extensionStageHooks) 210 } 211 212 func init() { 213 if runtime.GOOS != "windows" { 214 path = "/bin/sh" 215 } else { 216 panic("we need a reliable executable path on Windows") 217 } 218 }