github.com/kardianos/nomad@v0.1.3-0.20151022182107-b13df73ee850/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 /* 37 TODO: This test is disabled til a follow-up api changes the restore state interface. 38 The driver/executor interface will be changed from Open to Cleanup, in which 39 clean-up tears down previous allocs. 40 41 func TestExecDriver_StartOpen_Wait(t *testing.T) { 42 ctestutils.ExecCompatible(t) 43 task := &structs.Task{ 44 Name: "sleep", 45 Config: map[string]string{ 46 "command": "/bin/sleep", 47 "args": "5", 48 }, 49 Resources: basicResources, 50 } 51 52 driverCtx := testDriverContext(task.Name) 53 ctx := testDriverExecContext(task, driverCtx) 54 defer ctx.AllocDir.Destroy() 55 d := NewExecDriver(driverCtx) 56 57 if task.Resources == nil { 58 task.Resources = &structs.Resources{} 59 } 60 task.Resources.CPU = 0.5 61 task.Resources.MemoryMB = 2 62 63 handle, err := d.Start(ctx, task) 64 if err != nil { 65 t.Fatalf("err: %v", err) 66 } 67 if handle == nil { 68 t.Fatalf("missing handle") 69 } 70 71 // Attempt to open 72 handle2, err := d.Open(ctx, handle.ID()) 73 if err != nil { 74 t.Fatalf("err: %v", err) 75 } 76 if handle2 == nil { 77 t.Fatalf("missing handle") 78 } 79 } 80 */ 81 82 func TestExecDriver_Start_Wait(t *testing.T) { 83 ctestutils.ExecCompatible(t) 84 task := &structs.Task{ 85 Name: "sleep", 86 Config: map[string]string{ 87 "command": "/bin/sleep", 88 "args": "2", 89 }, 90 Resources: basicResources, 91 } 92 93 driverCtx := testDriverContext(task.Name) 94 ctx := testDriverExecContext(task, driverCtx) 95 defer ctx.AllocDir.Destroy() 96 d := NewExecDriver(driverCtx) 97 98 handle, err := d.Start(ctx, task) 99 if err != nil { 100 t.Fatalf("err: %v", err) 101 } 102 if handle == nil { 103 t.Fatalf("missing handle") 104 } 105 106 // Update should be a no-op 107 err = handle.Update(task) 108 if err != nil { 109 t.Fatalf("err: %v", err) 110 } 111 112 // Task should terminate quickly 113 select { 114 case err := <-handle.WaitCh(): 115 if err != nil { 116 t.Fatalf("err: %v", err) 117 } 118 case <-time.After(4 * time.Second): 119 t.Fatalf("timeout") 120 } 121 } 122 123 func TestExecDriver_Start_Wait_AllocDir(t *testing.T) { 124 ctestutils.ExecCompatible(t) 125 126 exp := []byte{'w', 'i', 'n'} 127 file := "output.txt" 128 task := &structs.Task{ 129 Name: "sleep", 130 Config: map[string]string{ 131 "command": "/bin/bash", 132 "args": fmt.Sprintf("-c \"sleep 1; echo -n %s > $%s/%s\"", string(exp), environment.AllocDir, file), 133 }, 134 Resources: basicResources, 135 } 136 137 driverCtx := testDriverContext(task.Name) 138 ctx := testDriverExecContext(task, driverCtx) 139 defer ctx.AllocDir.Destroy() 140 d := NewExecDriver(driverCtx) 141 142 handle, err := d.Start(ctx, task) 143 if err != nil { 144 t.Fatalf("err: %v", err) 145 } 146 if handle == nil { 147 t.Fatalf("missing handle") 148 } 149 150 // Task should terminate quickly 151 select { 152 case err := <-handle.WaitCh(): 153 if err != nil { 154 t.Fatalf("err: %v", err) 155 } 156 case <-time.After(2 * time.Second): 157 t.Fatalf("timeout") 158 } 159 160 // Check that data was written to the shared alloc directory. 161 outputFile := filepath.Join(ctx.AllocDir.SharedDir, file) 162 act, err := ioutil.ReadFile(outputFile) 163 if err != nil { 164 t.Fatalf("Couldn't read expected output: %v", err) 165 } 166 167 if !reflect.DeepEqual(act, exp) { 168 t.Fatalf("Command outputted %v; want %v", act, exp) 169 } 170 } 171 172 func TestExecDriver_Start_Kill_Wait(t *testing.T) { 173 ctestutils.ExecCompatible(t) 174 task := &structs.Task{ 175 Name: "sleep", 176 Config: map[string]string{ 177 "command": "/bin/sleep", 178 "args": "1", 179 }, 180 Resources: basicResources, 181 } 182 183 driverCtx := testDriverContext(task.Name) 184 ctx := testDriverExecContext(task, driverCtx) 185 defer ctx.AllocDir.Destroy() 186 d := NewExecDriver(driverCtx) 187 188 handle, err := d.Start(ctx, task) 189 if err != nil { 190 t.Fatalf("err: %v", err) 191 } 192 if handle == nil { 193 t.Fatalf("missing handle") 194 } 195 196 go func() { 197 time.Sleep(100 * time.Millisecond) 198 err := handle.Kill() 199 if err != nil { 200 t.Fatalf("err: %v", err) 201 } 202 }() 203 204 // Task should terminate quickly 205 select { 206 case err := <-handle.WaitCh(): 207 if err == nil { 208 t.Fatal("should err") 209 } 210 case <-time.After(2 * time.Second): 211 t.Fatalf("timeout") 212 } 213 }