github.com/kardianos/nomad@v0.1.3-0.20151022182107-b13df73ee850/client/driver/raw_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  
    16  func TestRawExecDriver_Fingerprint(t *testing.T) {
    17  	d := NewRawExecDriver(testDriverContext(""))
    18  	node := &structs.Node{
    19  		Attributes: make(map[string]string),
    20  	}
    21  
    22  	// Disable raw exec.
    23  	cfg := &config.Config{Options: map[string]string{rawExecConfigOption: "false"}}
    24  
    25  	apply, err := d.Fingerprint(cfg, node)
    26  	if err != nil {
    27  		t.Fatalf("err: %v", err)
    28  	}
    29  	if apply {
    30  		t.Fatalf("should not apply")
    31  	}
    32  	if node.Attributes["driver.raw_exec"] != "" {
    33  		t.Fatalf("driver incorrectly enabled")
    34  	}
    35  
    36  	// Enable raw exec.
    37  	cfg.Options[rawExecConfigOption] = "true"
    38  	apply, err = d.Fingerprint(cfg, node)
    39  	if err != nil {
    40  		t.Fatalf("err: %v", err)
    41  	}
    42  	if !apply {
    43  		t.Fatalf("should apply")
    44  	}
    45  	if node.Attributes["driver.raw_exec"] != "1" {
    46  		t.Fatalf("driver not enabled")
    47  	}
    48  }
    49  
    50  func TestRawExecDriver_StartOpen_Wait(t *testing.T) {
    51  	task := &structs.Task{
    52  		Name: "sleep",
    53  		Config: map[string]string{
    54  			"command": "/bin/sleep",
    55  			"args":    "1",
    56  		},
    57  	}
    58  	driverCtx := testDriverContext(task.Name)
    59  	ctx := testDriverExecContext(task, driverCtx)
    60  	defer ctx.AllocDir.Destroy()
    61  
    62  	d := NewRawExecDriver(driverCtx)
    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  	// Task should terminate quickly
    81  	select {
    82  	case <-handle2.WaitCh():
    83  	case <-time.After(2 * time.Second):
    84  		t.Fatalf("timeout")
    85  	}
    86  
    87  	// Check they are both tracking the same PID.
    88  	pid1 := handle.(*rawExecHandle).proc.Pid
    89  	pid2 := handle2.(*rawExecHandle).proc.Pid
    90  	if pid1 != pid2 {
    91  		t.Fatalf("tracking incorrect Pid; %v != %v", pid1, pid2)
    92  	}
    93  }
    94  
    95  func TestRawExecDriver_Start_Wait(t *testing.T) {
    96  	task := &structs.Task{
    97  		Name: "sleep",
    98  		Config: map[string]string{
    99  			"command": "/bin/sleep",
   100  			"args":    "1",
   101  		},
   102  	}
   103  
   104  	driverCtx := testDriverContext(task.Name)
   105  	ctx := testDriverExecContext(task, driverCtx)
   106  	defer ctx.AllocDir.Destroy()
   107  
   108  	d := NewRawExecDriver(driverCtx)
   109  	handle, err := d.Start(ctx, task)
   110  	if err != nil {
   111  		t.Fatalf("err: %v", err)
   112  	}
   113  	if handle == nil {
   114  		t.Fatalf("missing handle")
   115  	}
   116  
   117  	// Update should be a no-op
   118  	err = handle.Update(task)
   119  	if err != nil {
   120  		t.Fatalf("err: %v", err)
   121  	}
   122  
   123  	// Task should terminate quickly
   124  	select {
   125  	case err := <-handle.WaitCh():
   126  		if err != nil {
   127  			t.Fatalf("err: %v", err)
   128  		}
   129  	case <-time.After(2 * time.Second):
   130  		t.Fatalf("timeout")
   131  	}
   132  }
   133  
   134  func TestRawExecDriver_Start_Wait_AllocDir(t *testing.T) {
   135  	exp := []byte{'w', 'i', 'n'}
   136  	file := "output.txt"
   137  	task := &structs.Task{
   138  		Name: "sleep",
   139  		Config: map[string]string{
   140  			"command": "/bin/bash",
   141  			"args":    fmt.Sprintf(`-c "sleep 1; echo -n %s > $%s/%s"`, string(exp), environment.AllocDir, file),
   142  		},
   143  	}
   144  
   145  	driverCtx := testDriverContext(task.Name)
   146  	ctx := testDriverExecContext(task, driverCtx)
   147  	defer ctx.AllocDir.Destroy()
   148  
   149  	d := NewRawExecDriver(driverCtx)
   150  	handle, err := d.Start(ctx, task)
   151  	if err != nil {
   152  		t.Fatalf("err: %v", err)
   153  	}
   154  	if handle == nil {
   155  		t.Fatalf("missing handle")
   156  	}
   157  
   158  	// Task should terminate quickly
   159  	select {
   160  	case err := <-handle.WaitCh():
   161  		if err != nil {
   162  			t.Fatalf("err: %v", err)
   163  		}
   164  	case <-time.After(2 * time.Second):
   165  		t.Fatalf("timeout")
   166  	}
   167  
   168  	// Check that data was written to the shared alloc directory.
   169  	outputFile := filepath.Join(ctx.AllocDir.SharedDir, file)
   170  	act, err := ioutil.ReadFile(outputFile)
   171  	if err != nil {
   172  		t.Fatalf("Couldn't read expected output: %v", err)
   173  	}
   174  
   175  	if !reflect.DeepEqual(act, exp) {
   176  		t.Fatalf("Command outputted %v; want %v", act, exp)
   177  	}
   178  }
   179  
   180  func TestRawExecDriver_Start_Kill_Wait(t *testing.T) {
   181  	task := &structs.Task{
   182  		Name: "sleep",
   183  		Config: map[string]string{
   184  			"command": "/bin/sleep",
   185  			"args":    "1",
   186  		},
   187  	}
   188  
   189  	driverCtx := testDriverContext(task.Name)
   190  	ctx := testDriverExecContext(task, driverCtx)
   191  	defer ctx.AllocDir.Destroy()
   192  
   193  	d := NewRawExecDriver(driverCtx)
   194  	handle, err := d.Start(ctx, 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 err := <-handle.WaitCh():
   213  		if err == nil {
   214  			t.Fatal("should err")
   215  		}
   216  	case <-time.After(2 * time.Second):
   217  		t.Fatalf("timeout")
   218  	}
   219  }