github.com/dkerwin/nomad@v0.3.3-0.20160525181927-74554135514b/client/driver/rkt_test.go (about) 1 package driver 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "path/filepath" 7 "reflect" 8 "strings" 9 "testing" 10 "time" 11 12 "github.com/hashicorp/nomad/client/config" 13 "github.com/hashicorp/nomad/client/driver/env" 14 "github.com/hashicorp/nomad/nomad/structs" 15 "github.com/hashicorp/nomad/testutil" 16 17 ctestutils "github.com/hashicorp/nomad/client/testutil" 18 ) 19 20 func TestRktVersionRegex(t *testing.T) { 21 input_rkt := "rkt version 0.8.1" 22 input_appc := "appc version 1.2.0" 23 expected_rkt := "0.8.1" 24 expected_appc := "1.2.0" 25 rktMatches := reRktVersion.FindStringSubmatch(input_rkt) 26 appcMatches := reAppcVersion.FindStringSubmatch(input_appc) 27 if rktMatches[1] != expected_rkt { 28 fmt.Printf("Test failed; got %q; want %q\n", rktMatches[1], expected_rkt) 29 } 30 if appcMatches[1] != expected_appc { 31 fmt.Printf("Test failed; got %q; want %q\n", appcMatches[1], expected_appc) 32 } 33 } 34 35 // The fingerprinter test should always pass, even if rkt is not installed. 36 func TestRktDriver_Fingerprint(t *testing.T) { 37 ctestutils.RktCompatible(t) 38 driverCtx, _ := testDriverContexts(&structs.Task{Name: "foo"}) 39 d := NewRktDriver(driverCtx) 40 node := &structs.Node{ 41 Attributes: make(map[string]string), 42 } 43 apply, err := d.Fingerprint(&config.Config{}, node) 44 if err != nil { 45 t.Fatalf("err: %v", err) 46 } 47 if !apply { 48 t.Fatalf("should apply") 49 } 50 if node.Attributes["driver.rkt"] != "1" { 51 t.Fatalf("Missing Rkt driver") 52 } 53 if node.Attributes["driver.rkt.version"] == "" { 54 t.Fatalf("Missing Rkt driver version") 55 } 56 if node.Attributes["driver.rkt.appc.version"] == "" { 57 t.Fatalf("Missing appc version for the Rkt driver") 58 } 59 } 60 61 func TestRktDriver_Start_DNS(t *testing.T) { 62 ctestutils.RktCompatible(t) 63 // TODO: use test server to load from a fixture 64 task := &structs.Task{ 65 Name: "etcd", 66 Config: map[string]interface{}{ 67 "trust_prefix": "coreos.com/etcd", 68 "image": "coreos.com/etcd:v2.0.4", 69 "command": "/etcd", 70 "dns_servers": []string{"8.8.8.8", "8.8.4.4"}, 71 "dns_search_domains": []string{"example.com", "example.org", "example.net"}, 72 }, 73 LogConfig: &structs.LogConfig{ 74 MaxFiles: 10, 75 MaxFileSizeMB: 10, 76 }, 77 Resources: &structs.Resources{ 78 MemoryMB: 128, 79 CPU: 100, 80 }, 81 } 82 83 driverCtx, execCtx := testDriverContexts(task) 84 defer execCtx.AllocDir.Destroy() 85 86 d := NewRktDriver(driverCtx) 87 88 handle, err := d.Start(execCtx, task) 89 if err != nil { 90 t.Fatalf("err: %v", err) 91 } 92 if handle == nil { 93 t.Fatalf("missing handle") 94 } 95 defer handle.Kill() 96 97 // Attempt to open 98 handle2, err := d.Open(execCtx, handle.ID()) 99 if err != nil { 100 t.Fatalf("err: %v", err) 101 } 102 if handle2 == nil { 103 t.Fatalf("missing handle") 104 } 105 } 106 107 func TestRktDriver_Start_Wait(t *testing.T) { 108 ctestutils.RktCompatible(t) 109 task := &structs.Task{ 110 Name: "etcd", 111 Config: map[string]interface{}{ 112 "trust_prefix": "coreos.com/etcd", 113 "image": "coreos.com/etcd:v2.0.4", 114 "command": "/etcd", 115 "args": []string{"--version"}, 116 }, 117 LogConfig: &structs.LogConfig{ 118 MaxFiles: 10, 119 MaxFileSizeMB: 10, 120 }, 121 Resources: &structs.Resources{ 122 MemoryMB: 128, 123 CPU: 100, 124 }, 125 } 126 127 driverCtx, execCtx := testDriverContexts(task) 128 defer execCtx.AllocDir.Destroy() 129 d := NewRktDriver(driverCtx) 130 131 handle, err := d.Start(execCtx, task) 132 if err != nil { 133 t.Fatalf("err: %v", err) 134 } 135 if handle == nil { 136 t.Fatalf("missing handle") 137 } 138 defer handle.Kill() 139 140 // Update should be a no-op 141 err = handle.Update(task) 142 if err != nil { 143 t.Fatalf("err: %v", err) 144 } 145 146 select { 147 case res := <-handle.WaitCh(): 148 if !res.Successful() { 149 t.Fatalf("err: %v", res) 150 } 151 case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second): 152 t.Fatalf("timeout") 153 } 154 } 155 156 func TestRktDriver_Start_Wait_Skip_Trust(t *testing.T) { 157 ctestutils.RktCompatible(t) 158 task := &structs.Task{ 159 Name: "etcd", 160 Config: map[string]interface{}{ 161 "image": "coreos.com/etcd:v2.0.4", 162 "command": "/etcd", 163 "args": []string{"--version"}, 164 }, 165 LogConfig: &structs.LogConfig{ 166 MaxFiles: 10, 167 MaxFileSizeMB: 10, 168 }, 169 Resources: &structs.Resources{ 170 MemoryMB: 128, 171 CPU: 100, 172 }, 173 } 174 175 driverCtx, execCtx := testDriverContexts(task) 176 defer execCtx.AllocDir.Destroy() 177 d := NewRktDriver(driverCtx) 178 179 handle, err := d.Start(execCtx, task) 180 if err != nil { 181 t.Fatalf("err: %v", err) 182 } 183 if handle == nil { 184 t.Fatalf("missing handle") 185 } 186 defer handle.Kill() 187 188 // Update should be a no-op 189 err = handle.Update(task) 190 if err != nil { 191 t.Fatalf("err: %v", err) 192 } 193 194 select { 195 case res := <-handle.WaitCh(): 196 if !res.Successful() { 197 t.Fatalf("err: %v", res) 198 } 199 case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second): 200 t.Fatalf("timeout") 201 } 202 } 203 204 func TestRktDriver_Start_Wait_AllocDir(t *testing.T) { 205 ctestutils.RktCompatible(t) 206 207 exp := []byte{'w', 'i', 'n'} 208 file := "output.txt" 209 210 task := &structs.Task{ 211 Name: "alpine", 212 Config: map[string]interface{}{ 213 "image": "docker://alpine", 214 "command": "/bin/sh", 215 "args": []string{ 216 "-c", 217 fmt.Sprintf(`echo -n %s > ${%s}/%s`, string(exp), env.AllocDir, file), 218 }, 219 }, 220 LogConfig: &structs.LogConfig{ 221 MaxFiles: 10, 222 MaxFileSizeMB: 10, 223 }, 224 Resources: &structs.Resources{ 225 MemoryMB: 128, 226 CPU: 100, 227 }, 228 } 229 230 driverCtx, execCtx := testDriverContexts(task) 231 defer execCtx.AllocDir.Destroy() 232 d := NewRktDriver(driverCtx) 233 234 handle, err := d.Start(execCtx, task) 235 if err != nil { 236 t.Fatalf("err: %v", err) 237 } 238 if handle == nil { 239 t.Fatalf("missing handle") 240 } 241 defer handle.Kill() 242 243 select { 244 case res := <-handle.WaitCh(): 245 if !res.Successful() { 246 t.Fatalf("err: %v", res) 247 } 248 case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second): 249 t.Fatalf("timeout") 250 } 251 252 // Check that data was written to the shared alloc directory. 253 outputFile := filepath.Join(execCtx.AllocDir.SharedDir, file) 254 act, err := ioutil.ReadFile(outputFile) 255 if err != nil { 256 t.Fatalf("Couldn't read expected output: %v", err) 257 } 258 259 if !reflect.DeepEqual(act, exp) { 260 t.Fatalf("Command output is %v; expected %v", act, exp) 261 } 262 } 263 264 func TestRktDriverUser(t *testing.T) { 265 ctestutils.RktCompatible(t) 266 task := &structs.Task{ 267 Name: "etcd", 268 User: "alice", 269 Config: map[string]interface{}{ 270 "trust_prefix": "coreos.com/etcd", 271 "image": "coreos.com/etcd:v2.0.4", 272 "command": "/etcd", 273 "args": []string{"--version"}, 274 }, 275 LogConfig: &structs.LogConfig{ 276 MaxFiles: 10, 277 MaxFileSizeMB: 10, 278 }, 279 Resources: &structs.Resources{ 280 MemoryMB: 128, 281 CPU: 100, 282 }, 283 } 284 285 driverCtx, execCtx := testDriverContexts(task) 286 defer execCtx.AllocDir.Destroy() 287 d := NewRktDriver(driverCtx) 288 289 handle, err := d.Start(execCtx, task) 290 if err == nil { 291 handle.Kill() 292 t.Fatalf("Should've failed") 293 } 294 msg := "unknown user alice" 295 if !strings.Contains(err.Error(), msg) { 296 t.Fatalf("Expecting '%v' in '%v'", msg, err) 297 } 298 }