github.com/dkerwin/nomad@v0.3.3-0.20160525181927-74554135514b/client/driver/java_test.go (about)

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