github.com/huiliang/nomad@v0.2.1-0.20151124023127-7a8b664699ff/client/driver/exec_test.go (about) 1 package driver 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "path/filepath" 7 "reflect" 8 "testing" 9 "time" 10 11 "github.com/hashicorp/nomad/client/config" 12 "github.com/hashicorp/nomad/client/driver/environment" 13 "github.com/hashicorp/nomad/nomad/structs" 14 15 ctestutils "github.com/hashicorp/nomad/client/testutil" 16 ) 17 18 func TestExecDriver_Fingerprint(t *testing.T) { 19 ctestutils.ExecCompatible(t) 20 d := NewExecDriver(testDriverContext("")) 21 node := &structs.Node{ 22 Attributes: make(map[string]string), 23 } 24 apply, err := d.Fingerprint(&config.Config{}, node) 25 if err != nil { 26 t.Fatalf("err: %v", err) 27 } 28 if !apply { 29 t.Fatalf("should apply") 30 } 31 if node.Attributes["driver.exec"] == "" { 32 t.Fatalf("missing driver") 33 } 34 } 35 36 func TestExecDriver_StartOpen_Wait(t *testing.T) { 37 ctestutils.ExecCompatible(t) 38 task := &structs.Task{ 39 Name: "sleep", 40 Config: map[string]interface{}{ 41 "command": "/bin/sleep", 42 "args": []string{"5"}, 43 }, 44 Resources: basicResources, 45 } 46 47 driverCtx := testDriverContext(task.Name) 48 ctx := testDriverExecContext(task, driverCtx) 49 defer ctx.AllocDir.Destroy() 50 d := NewExecDriver(driverCtx) 51 52 handle, err := d.Start(ctx, task) 53 if err != nil { 54 t.Fatalf("err: %v", err) 55 } 56 if handle == nil { 57 t.Fatalf("missing handle") 58 } 59 60 // Attempt to open 61 handle2, err := d.Open(ctx, handle.ID()) 62 if err != nil { 63 t.Fatalf("err: %v", err) 64 } 65 if handle2 == nil { 66 t.Fatalf("missing handle") 67 } 68 } 69 70 func TestExecDriver_Start_Wait(t *testing.T) { 71 ctestutils.ExecCompatible(t) 72 task := &structs.Task{ 73 Name: "sleep", 74 Config: map[string]interface{}{ 75 "command": "/bin/sleep", 76 "args": []string{"2"}, 77 }, 78 Resources: basicResources, 79 } 80 81 driverCtx := testDriverContext(task.Name) 82 ctx := testDriverExecContext(task, driverCtx) 83 defer ctx.AllocDir.Destroy() 84 d := NewExecDriver(driverCtx) 85 86 handle, err := d.Start(ctx, task) 87 if err != nil { 88 t.Fatalf("err: %v", err) 89 } 90 if handle == nil { 91 t.Fatalf("missing handle") 92 } 93 94 // Update should be a no-op 95 err = handle.Update(task) 96 if err != nil { 97 t.Fatalf("err: %v", err) 98 } 99 100 // Task should terminate quickly 101 select { 102 case res := <-handle.WaitCh(): 103 if !res.Successful() { 104 t.Fatalf("err: %v", res) 105 } 106 case <-time.After(4 * time.Second): 107 t.Fatalf("timeout") 108 } 109 } 110 111 func TestExecDriver_Start_Artifact_basic(t *testing.T) { 112 ctestutils.ExecCompatible(t) 113 file := "hi_linux_amd64" 114 checksum := "sha256:6f99b4c5184726e601ecb062500aeb9537862434dfe1898dbe5c68d9f50c179c" 115 116 task := &structs.Task{ 117 Name: "sleep", 118 Config: map[string]interface{}{ 119 "artifact_source": fmt.Sprintf("https://dl.dropboxusercontent.com/u/47675/jar_thing/%s?checksum=%s", file, checksum), 120 "command": filepath.Join("$NOMAD_TASK_DIR", file), 121 }, 122 Resources: basicResources, 123 } 124 125 driverCtx := testDriverContext(task.Name) 126 ctx := testDriverExecContext(task, driverCtx) 127 defer ctx.AllocDir.Destroy() 128 d := NewExecDriver(driverCtx) 129 130 handle, err := d.Start(ctx, task) 131 if err != nil { 132 t.Fatalf("err: %v", err) 133 } 134 if handle == nil { 135 t.Fatalf("missing handle") 136 } 137 138 // Update should be a no-op 139 err = handle.Update(task) 140 if err != nil { 141 t.Fatalf("err: %v", err) 142 } 143 144 // Task should terminate quickly 145 select { 146 case res := <-handle.WaitCh(): 147 if !res.Successful() { 148 t.Fatalf("err: %v", res) 149 } 150 case <-time.After(5 * time.Second): 151 t.Fatalf("timeout") 152 } 153 } 154 155 func TestExecDriver_Start_Artifact_expanded(t *testing.T) { 156 ctestutils.ExecCompatible(t) 157 file := "hi_linux_amd64" 158 159 task := &structs.Task{ 160 Name: "sleep", 161 Config: map[string]interface{}{ 162 "artifact_source": fmt.Sprintf("https://dl.dropboxusercontent.com/u/47675/jar_thing/%s", file), 163 "command": "/bin/bash", 164 "args": []string{ 165 "-c", 166 fmt.Sprintf(`/bin/sleep 1 && %s`, filepath.Join("$NOMAD_TASK_DIR", file)), 167 }, 168 }, 169 Resources: basicResources, 170 } 171 172 driverCtx := testDriverContext(task.Name) 173 ctx := testDriverExecContext(task, driverCtx) 174 defer ctx.AllocDir.Destroy() 175 d := NewExecDriver(driverCtx) 176 177 handle, err := d.Start(ctx, task) 178 if err != nil { 179 t.Fatalf("err: %v", err) 180 } 181 if handle == nil { 182 t.Fatalf("missing handle") 183 } 184 185 // Update should be a no-op 186 err = handle.Update(task) 187 if err != nil { 188 t.Fatalf("err: %v", err) 189 } 190 191 // Task should terminate quickly 192 select { 193 case res := <-handle.WaitCh(): 194 if !res.Successful() { 195 t.Fatalf("err: %v", res) 196 } 197 case <-time.After(5 * time.Second): 198 t.Fatalf("timeout") 199 } 200 } 201 func TestExecDriver_Start_Wait_AllocDir(t *testing.T) { 202 ctestutils.ExecCompatible(t) 203 204 exp := []byte{'w', 'i', 'n'} 205 file := "output.txt" 206 task := &structs.Task{ 207 Name: "sleep", 208 Config: map[string]interface{}{ 209 "command": "/bin/bash", 210 "args": []string{ 211 "-c", 212 fmt.Sprintf(`sleep 1; echo -n %s > $%s/%s`, string(exp), environment.AllocDir, file), 213 }, 214 }, 215 Resources: basicResources, 216 } 217 218 driverCtx := testDriverContext(task.Name) 219 ctx := testDriverExecContext(task, driverCtx) 220 defer ctx.AllocDir.Destroy() 221 d := NewExecDriver(driverCtx) 222 223 handle, err := d.Start(ctx, 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(2 * time.Second): 238 t.Fatalf("timeout") 239 } 240 241 // Check that data was written to the shared alloc directory. 242 outputFile := filepath.Join(ctx.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 TestExecDriver_Start_Kill_Wait(t *testing.T) { 254 ctestutils.ExecCompatible(t) 255 task := &structs.Task{ 256 Name: "sleep", 257 Config: map[string]interface{}{ 258 "command": "/bin/sleep", 259 "args": []string{"1"}, 260 }, 261 Resources: basicResources, 262 } 263 264 driverCtx := testDriverContext(task.Name) 265 ctx := testDriverExecContext(task, driverCtx) 266 defer ctx.AllocDir.Destroy() 267 d := NewExecDriver(driverCtx) 268 269 handle, err := d.Start(ctx, task) 270 if err != nil { 271 t.Fatalf("err: %v", err) 272 } 273 if handle == nil { 274 t.Fatalf("missing handle") 275 } 276 277 go func() { 278 time.Sleep(100 * time.Millisecond) 279 err := handle.Kill() 280 if err != nil { 281 t.Fatalf("err: %v", err) 282 } 283 }() 284 285 // Task should terminate quickly 286 select { 287 case res := <-handle.WaitCh(): 288 if res.Successful() { 289 t.Fatal("should err") 290 } 291 case <-time.After(8 * time.Second): 292 t.Fatalf("timeout") 293 } 294 }