github.com/ranjib/nomad@v0.1.1-0.20160225204057-97751b02f70b/client/driver/raw_exec_test.go (about) 1 package driver 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "net/http" 7 "net/http/httptest" 8 "path/filepath" 9 "reflect" 10 "testing" 11 "time" 12 13 "github.com/hashicorp/nomad/client/config" 14 "github.com/hashicorp/nomad/client/driver/env" 15 "github.com/hashicorp/nomad/helper/testtask" 16 "github.com/hashicorp/nomad/nomad/structs" 17 "github.com/hashicorp/nomad/testutil" 18 ) 19 20 func TestRawExecDriver_Fingerprint(t *testing.T) { 21 t.Parallel() 22 driverCtx, _ := testDriverContexts(&structs.Task{Name: "foo"}) 23 d := NewRawExecDriver(driverCtx) 24 node := &structs.Node{ 25 Attributes: make(map[string]string), 26 } 27 28 // Disable raw exec. 29 cfg := &config.Config{Options: map[string]string{rawExecConfigOption: "false"}} 30 31 apply, err := d.Fingerprint(cfg, node) 32 if err != nil { 33 t.Fatalf("err: %v", err) 34 } 35 if apply { 36 t.Fatalf("should not apply") 37 } 38 if node.Attributes["driver.raw_exec"] != "" { 39 t.Fatalf("driver incorrectly enabled") 40 } 41 42 // Enable raw exec. 43 cfg.Options[rawExecConfigOption] = "true" 44 apply, err = d.Fingerprint(cfg, node) 45 if err != nil { 46 t.Fatalf("err: %v", err) 47 } 48 if !apply { 49 t.Fatalf("should apply") 50 } 51 if node.Attributes["driver.raw_exec"] != "1" { 52 t.Fatalf("driver not enabled") 53 } 54 } 55 56 func TestRawExecDriver_StartOpen_Wait(t *testing.T) { 57 t.Parallel() 58 task := &structs.Task{ 59 Name: "sleep", 60 Config: map[string]interface{}{ 61 "command": testtask.Path(), 62 "args": []string{"sleep", "1s"}, 63 }, 64 LogConfig: &structs.LogConfig{ 65 MaxFiles: 10, 66 MaxFileSizeMB: 10, 67 }, 68 Resources: basicResources, 69 } 70 testtask.SetTaskEnv(task) 71 driverCtx, execCtx := testDriverContexts(task) 72 defer execCtx.AllocDir.Destroy() 73 d := NewRawExecDriver(driverCtx) 74 75 handle, err := d.Start(execCtx, task) 76 if err != nil { 77 t.Fatalf("err: %v", err) 78 } 79 if handle == nil { 80 t.Fatalf("missing handle") 81 } 82 83 // Attempt to open 84 handle2, err := d.Open(execCtx, handle.ID()) 85 if err != nil { 86 t.Fatalf("err: %v", err) 87 } 88 if handle2 == nil { 89 t.Fatalf("missing handle") 90 } 91 92 // Task should terminate quickly 93 select { 94 case <-handle2.WaitCh(): 95 case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second): 96 t.Fatalf("timeout") 97 } 98 handle.Kill() 99 handle2.Kill() 100 } 101 102 func TestRawExecDriver_Start_Artifact_basic(t *testing.T) { 103 t.Parallel() 104 path := testtask.Path() 105 ts := httptest.NewServer(http.FileServer(http.Dir(filepath.Dir(path)))) 106 defer ts.Close() 107 108 file := filepath.Base(path) 109 task := &structs.Task{ 110 Name: "sleep", 111 Config: map[string]interface{}{ 112 "artifact_source": fmt.Sprintf("%s/%s", ts.URL, file), 113 "command": file, 114 "args": []string{"sleep", "1s"}, 115 }, 116 LogConfig: &structs.LogConfig{ 117 MaxFiles: 10, 118 MaxFileSizeMB: 10, 119 }, 120 Resources: basicResources, 121 } 122 testtask.SetTaskEnv(task) 123 124 driverCtx, execCtx := testDriverContexts(task) 125 defer execCtx.AllocDir.Destroy() 126 d := NewRawExecDriver(driverCtx) 127 128 handle, err := d.Start(execCtx, task) 129 if err != nil { 130 t.Fatalf("err: %v", err) 131 } 132 if handle == nil { 133 t.Fatalf("missing handle") 134 } 135 136 // Attempt to open 137 handle2, err := d.Open(execCtx, handle.ID()) 138 if err != nil { 139 t.Fatalf("err: %v", err) 140 } 141 if handle2 == nil { 142 t.Fatalf("missing handle") 143 } 144 145 // Task should terminate quickly 146 select { 147 case <-handle2.WaitCh(): 148 case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second): 149 t.Fatalf("timeout") 150 } 151 } 152 153 func TestRawExecDriver_Start_Wait(t *testing.T) { 154 t.Parallel() 155 task := &structs.Task{ 156 Name: "sleep", 157 Config: map[string]interface{}{ 158 "command": testtask.Path(), 159 "args": []string{"sleep", "1s"}, 160 }, 161 LogConfig: &structs.LogConfig{ 162 MaxFiles: 10, 163 MaxFileSizeMB: 10, 164 }, 165 Resources: basicResources, 166 } 167 testtask.SetTaskEnv(task) 168 driverCtx, execCtx := testDriverContexts(task) 169 defer execCtx.AllocDir.Destroy() 170 d := NewRawExecDriver(driverCtx) 171 172 handle, err := d.Start(execCtx, task) 173 if err != nil { 174 t.Fatalf("err: %v", err) 175 } 176 if handle == nil { 177 t.Fatalf("missing handle") 178 } 179 180 // Update should be a no-op 181 err = handle.Update(task) 182 if err != nil { 183 t.Fatalf("err: %v", err) 184 } 185 186 // Task should terminate quickly 187 select { 188 case res := <-handle.WaitCh(): 189 if !res.Successful() { 190 t.Fatalf("err: %v", res) 191 } 192 case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second): 193 t.Fatalf("timeout") 194 } 195 } 196 197 func TestRawExecDriver_Start_Wait_AllocDir(t *testing.T) { 198 t.Parallel() 199 exp := []byte{'w', 'i', 'n'} 200 file := "output.txt" 201 outPath := fmt.Sprintf(`${%s}/%s`, env.AllocDir, file) 202 task := &structs.Task{ 203 Name: "sleep", 204 Config: map[string]interface{}{ 205 "command": testtask.Path(), 206 "args": []string{ 207 "sleep", "1s", 208 "write", string(exp), outPath, 209 }, 210 }, 211 LogConfig: &structs.LogConfig{ 212 MaxFiles: 10, 213 MaxFileSizeMB: 10, 214 }, 215 Resources: basicResources, 216 } 217 testtask.SetTaskEnv(task) 218 219 driverCtx, execCtx := testDriverContexts(task) 220 defer execCtx.AllocDir.Destroy() 221 d := NewRawExecDriver(driverCtx) 222 223 handle, err := d.Start(execCtx, task) 224 if err != nil { 225 t.Fatalf("err: %v", err) 226 } 227 if handle == nil { 228 t.Fatalf("missing handle") 229 } 230 231 // Task should terminate quickly 232 select { 233 case res := <-handle.WaitCh(): 234 if !res.Successful() { 235 t.Fatalf("err: %v", res) 236 } 237 case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second): 238 t.Fatalf("timeout") 239 } 240 241 // Check that data was written to the shared alloc directory. 242 outputFile := filepath.Join(execCtx.AllocDir.SharedDir, file) 243 act, err := ioutil.ReadFile(outputFile) 244 if err != nil { 245 t.Fatalf("Couldn't read expected output: %v", err) 246 } 247 248 if !reflect.DeepEqual(act, exp) { 249 t.Fatalf("Command outputted %v; want %v", act, exp) 250 } 251 } 252 253 func TestRawExecDriver_Start_Kill_Wait(t *testing.T) { 254 t.Parallel() 255 task := &structs.Task{ 256 Name: "sleep", 257 Config: map[string]interface{}{ 258 "command": testtask.Path(), 259 "args": []string{"sleep", "45s"}, 260 }, 261 LogConfig: &structs.LogConfig{ 262 MaxFiles: 10, 263 MaxFileSizeMB: 10, 264 }, 265 Resources: basicResources, 266 } 267 testtask.SetTaskEnv(task) 268 269 driverCtx, execCtx := testDriverContexts(task) 270 defer execCtx.AllocDir.Destroy() 271 d := NewRawExecDriver(driverCtx) 272 273 handle, err := d.Start(execCtx, task) 274 if err != nil { 275 t.Fatalf("err: %v", err) 276 } 277 if handle == nil { 278 t.Fatalf("missing handle") 279 } 280 281 go func() { 282 time.Sleep(1 * time.Second) 283 err := handle.Kill() 284 285 // Can't rely on the ordering between wait and kill on travis... 286 if !testutil.IsTravis() && err != nil { 287 t.Fatalf("err: %v", err) 288 } 289 }() 290 291 // Task should terminate quickly 292 select { 293 case res := <-handle.WaitCh(): 294 if res.Successful() { 295 t.Fatal("should err") 296 } 297 case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second): 298 t.Fatalf("timeout") 299 } 300 }