github.com/maier/nomad@v0.4.1-0.20161110003312-a9e3d0b8549d/client/driver/java_test.go (about) 1 package driver 2 3 import ( 4 "os" 5 "os/exec" 6 "path/filepath" 7 "runtime" 8 "strings" 9 "syscall" 10 "testing" 11 "time" 12 13 "github.com/hashicorp/nomad/client/config" 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 var ( 21 osJavaDriverSupport = map[string]bool{ 22 "linux": true, 23 } 24 ) 25 26 // javaLocated checks whether java is installed so we can run java stuff. 27 func javaLocated() bool { 28 _, err := exec.Command("java", "-version").CombinedOutput() 29 return err == nil 30 } 31 32 // The fingerprinter test should always pass, even if Java is not installed. 33 func TestJavaDriver_Fingerprint(t *testing.T) { 34 ctestutils.JavaCompatible(t) 35 task := &structs.Task{ 36 Name: "foo", 37 Resources: structs.DefaultResources(), 38 } 39 driverCtx, execCtx := testDriverContexts(task) 40 defer execCtx.AllocDir.Destroy() 41 d := NewJavaDriver(driverCtx) 42 node := &structs.Node{ 43 Attributes: map[string]string{ 44 "unique.cgroup.mountpoint": "/sys/fs/cgroups", 45 }, 46 } 47 apply, err := d.Fingerprint(&config.Config{}, node) 48 if err != nil { 49 t.Fatalf("err: %v", err) 50 } 51 if apply != javaLocated() { 52 t.Fatalf("Fingerprinter should detect Java when it is installed") 53 } 54 if node.Attributes["driver.java"] != "1" { 55 if v, ok := osJavaDriverSupport[runtime.GOOS]; v && ok { 56 t.Fatalf("missing java driver") 57 } else { 58 t.Skipf("missing java driver, no OS support") 59 } 60 } 61 for _, key := range []string{"driver.java.version", "driver.java.runtime", "driver.java.vm"} { 62 if node.Attributes[key] == "" { 63 t.Fatalf("missing driver key (%s)", key) 64 } 65 } 66 } 67 68 func TestJavaDriver_StartOpen_Wait(t *testing.T) { 69 if !javaLocated() { 70 t.Skip("Java not found; skipping") 71 } 72 73 ctestutils.JavaCompatible(t) 74 task := &structs.Task{ 75 Name: "demo-app", 76 Config: map[string]interface{}{ 77 "jar_path": "demoapp.jar", 78 "jvm_options": []string{"-Xmx64m", "-Xms32m"}, 79 }, 80 LogConfig: &structs.LogConfig{ 81 MaxFiles: 10, 82 MaxFileSizeMB: 10, 83 }, 84 Resources: basicResources, 85 } 86 87 driverCtx, execCtx := testDriverContexts(task) 88 defer execCtx.AllocDir.Destroy() 89 d := NewJavaDriver(driverCtx) 90 91 // Copy the test jar into the task's directory 92 dst, _ := execCtx.AllocDir.TaskDirs[task.Name] 93 copyFile("./test-resources/java/demoapp.jar", filepath.Join(dst, "demoapp.jar"), t) 94 95 handle, err := d.Start(execCtx, task) 96 if err != nil { 97 t.Fatalf("err: %v", err) 98 } 99 if handle == nil { 100 t.Fatalf("missing handle") 101 } 102 103 // Attempt to open 104 handle2, err := d.Open(execCtx, handle.ID()) 105 if err != nil { 106 t.Fatalf("err: %v", err) 107 } 108 if handle2 == nil { 109 t.Fatalf("missing handle") 110 } 111 112 time.Sleep(2 * time.Second) 113 114 // There is a race condition between the handle waiting and killing. One 115 // will return an error. 116 handle.Kill() 117 handle2.Kill() 118 } 119 120 func TestJavaDriver_Start_Wait(t *testing.T) { 121 if !javaLocated() { 122 t.Skip("Java not found; skipping") 123 } 124 125 ctestutils.JavaCompatible(t) 126 task := &structs.Task{ 127 Name: "demo-app", 128 Config: map[string]interface{}{ 129 "jar_path": "demoapp.jar", 130 }, 131 LogConfig: &structs.LogConfig{ 132 MaxFiles: 10, 133 MaxFileSizeMB: 10, 134 }, 135 Resources: basicResources, 136 } 137 138 driverCtx, execCtx := testDriverContexts(task) 139 d := NewJavaDriver(driverCtx) 140 141 // Copy the test jar into the task's directory 142 dst, _ := execCtx.AllocDir.TaskDirs[task.Name] 143 copyFile("./test-resources/java/demoapp.jar", filepath.Join(dst, "demoapp.jar"), t) 144 145 handle, err := d.Start(execCtx, task) 146 if err != nil { 147 t.Fatalf("err: %v", err) 148 } 149 if handle == nil { 150 t.Fatalf("missing handle") 151 } 152 153 // Task should terminate quickly 154 select { 155 case res := <-handle.WaitCh(): 156 if !res.Successful() { 157 t.Fatalf("err: %v", res) 158 } 159 case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second): 160 // expect the timeout b/c it's a long lived process 161 break 162 } 163 164 // Get the stdout of the process and assrt that it's not empty 165 stdout := filepath.Join(execCtx.AllocDir.LogDir(), "demo-app.stdout.0") 166 fInfo, err := os.Stat(stdout) 167 if err != nil { 168 t.Fatalf("failed to get stdout of process: %v", err) 169 } 170 if fInfo.Size() == 0 { 171 t.Fatalf("stdout of process is empty") 172 } 173 174 // need to kill long lived process 175 err = handle.Kill() 176 if err != nil { 177 t.Fatalf("Error: %s", err) 178 } 179 } 180 181 func TestJavaDriver_Start_Kill_Wait(t *testing.T) { 182 if !javaLocated() { 183 t.Skip("Java not found; skipping") 184 } 185 186 ctestutils.JavaCompatible(t) 187 task := &structs.Task{ 188 Name: "demo-app", 189 Config: map[string]interface{}{ 190 "jar_path": "demoapp.jar", 191 }, 192 LogConfig: &structs.LogConfig{ 193 MaxFiles: 10, 194 MaxFileSizeMB: 10, 195 }, 196 Resources: basicResources, 197 } 198 199 driverCtx, execCtx := testDriverContexts(task) 200 defer execCtx.AllocDir.Destroy() 201 d := NewJavaDriver(driverCtx) 202 203 // Copy the test jar into the task's directory 204 dst, _ := execCtx.AllocDir.TaskDirs[task.Name] 205 copyFile("./test-resources/java/demoapp.jar", filepath.Join(dst, "demoapp.jar"), t) 206 207 handle, err := d.Start(execCtx, task) 208 if err != nil { 209 t.Fatalf("err: %v", err) 210 } 211 if handle == nil { 212 t.Fatalf("missing handle") 213 } 214 215 go func() { 216 time.Sleep(100 * time.Millisecond) 217 err := handle.Kill() 218 if err != nil { 219 t.Fatalf("err: %v", err) 220 } 221 }() 222 223 // Task should terminate quickly 224 select { 225 case res := <-handle.WaitCh(): 226 if res.Successful() { 227 t.Fatal("should err") 228 } 229 case <-time.After(time.Duration(testutil.TestMultiplier()*10) * time.Second): 230 t.Fatalf("timeout") 231 232 // Need to kill long lived process 233 if err = handle.Kill(); err != nil { 234 t.Fatalf("Error: %s", err) 235 } 236 } 237 } 238 239 func TestJavaDriver_Signal(t *testing.T) { 240 if !javaLocated() { 241 t.Skip("Java not found; skipping") 242 } 243 244 ctestutils.JavaCompatible(t) 245 task := &structs.Task{ 246 Name: "demo-app", 247 Config: map[string]interface{}{ 248 "jar_path": "demoapp.jar", 249 }, 250 LogConfig: &structs.LogConfig{ 251 MaxFiles: 10, 252 MaxFileSizeMB: 10, 253 }, 254 Resources: basicResources, 255 } 256 257 driverCtx, execCtx := testDriverContexts(task) 258 defer execCtx.AllocDir.Destroy() 259 d := NewJavaDriver(driverCtx) 260 261 // Copy the test jar into the task's directory 262 dst, _ := execCtx.AllocDir.TaskDirs[task.Name] 263 copyFile("./test-resources/java/demoapp.jar", filepath.Join(dst, "demoapp.jar"), t) 264 265 handle, err := d.Start(execCtx, task) 266 if err != nil { 267 t.Fatalf("err: %v", err) 268 } 269 if handle == nil { 270 t.Fatalf("missing handle") 271 } 272 273 go func() { 274 time.Sleep(100 * time.Millisecond) 275 err := handle.Signal(syscall.SIGHUP) 276 if err != nil { 277 t.Fatalf("err: %v", err) 278 } 279 }() 280 281 // Task should terminate quickly 282 select { 283 case res := <-handle.WaitCh(): 284 if res.Successful() { 285 t.Fatal("should err") 286 } 287 case <-time.After(time.Duration(testutil.TestMultiplier()*10) * time.Second): 288 t.Fatalf("timeout") 289 290 // Need to kill long lived process 291 if err = handle.Kill(); err != nil { 292 t.Fatalf("Error: %s", err) 293 } 294 } 295 } 296 297 func TestJavaDriverUser(t *testing.T) { 298 if !javaLocated() { 299 t.Skip("Java not found; skipping") 300 } 301 302 ctestutils.JavaCompatible(t) 303 task := &structs.Task{ 304 Name: "demo-app", 305 User: "alice", 306 Config: map[string]interface{}{ 307 "jar_path": "demoapp.jar", 308 }, 309 LogConfig: &structs.LogConfig{ 310 MaxFiles: 10, 311 MaxFileSizeMB: 10, 312 }, 313 Resources: basicResources, 314 } 315 316 driverCtx, execCtx := testDriverContexts(task) 317 defer execCtx.AllocDir.Destroy() 318 d := NewJavaDriver(driverCtx) 319 320 handle, err := d.Start(execCtx, task) 321 if err == nil { 322 handle.Kill() 323 t.Fatalf("Should've failed") 324 } 325 msg := "user alice" 326 if !strings.Contains(err.Error(), msg) { 327 t.Fatalf("Expecting '%v' in '%v'", msg, err) 328 } 329 }