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