github.com/dkerwin/nomad@v0.3.3-0.20160525181927-74554135514b/client/driver/raw_exec_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/helper/testtask"
    15  	"github.com/hashicorp/nomad/nomad/structs"
    16  	"github.com/hashicorp/nomad/testutil"
    17  )
    18  
    19  func TestRawExecDriver_Fingerprint(t *testing.T) {
    20  	t.Parallel()
    21  	driverCtx, _ := testDriverContexts(&structs.Task{Name: "foo"})
    22  	d := NewRawExecDriver(driverCtx)
    23  	node := &structs.Node{
    24  		Attributes: make(map[string]string),
    25  	}
    26  
    27  	// Disable raw exec.
    28  	cfg := &config.Config{Options: map[string]string{rawExecConfigOption: "false"}}
    29  
    30  	apply, err := d.Fingerprint(cfg, node)
    31  	if err != nil {
    32  		t.Fatalf("err: %v", err)
    33  	}
    34  	if apply {
    35  		t.Fatalf("should not apply")
    36  	}
    37  	if node.Attributes["driver.raw_exec"] != "" {
    38  		t.Fatalf("driver incorrectly enabled")
    39  	}
    40  
    41  	// Enable raw exec.
    42  	cfg.Options[rawExecConfigOption] = "true"
    43  	apply, err = d.Fingerprint(cfg, 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.raw_exec"] != "1" {
    51  		t.Fatalf("driver not enabled")
    52  	}
    53  }
    54  
    55  func TestRawExecDriver_StartOpen_Wait(t *testing.T) {
    56  	t.Parallel()
    57  	task := &structs.Task{
    58  		Name: "sleep",
    59  		Config: map[string]interface{}{
    60  			"command": testtask.Path(),
    61  			"args":    []string{"sleep", "1s"},
    62  		},
    63  		LogConfig: &structs.LogConfig{
    64  			MaxFiles:      10,
    65  			MaxFileSizeMB: 10,
    66  		},
    67  		Resources: basicResources,
    68  	}
    69  	testtask.SetTaskEnv(task)
    70  	driverCtx, execCtx := testDriverContexts(task)
    71  	defer execCtx.AllocDir.Destroy()
    72  	d := NewRawExecDriver(driverCtx)
    73  
    74  	handle, err := d.Start(execCtx, task)
    75  	if err != nil {
    76  		t.Fatalf("err: %v", err)
    77  	}
    78  	if handle == nil {
    79  		t.Fatalf("missing handle")
    80  	}
    81  
    82  	// Attempt to open
    83  	handle2, err := d.Open(execCtx, handle.ID())
    84  	if err != nil {
    85  		t.Fatalf("err: %v", err)
    86  	}
    87  	if handle2 == nil {
    88  		t.Fatalf("missing handle")
    89  	}
    90  
    91  	// Task should terminate quickly
    92  	select {
    93  	case <-handle2.WaitCh():
    94  	case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second):
    95  		t.Fatalf("timeout")
    96  	}
    97  	handle.Kill()
    98  	handle2.Kill()
    99  }
   100  
   101  func TestRawExecDriver_Start_Wait(t *testing.T) {
   102  	t.Parallel()
   103  	task := &structs.Task{
   104  		Name: "sleep",
   105  		Config: map[string]interface{}{
   106  			"command": testtask.Path(),
   107  			"args":    []string{"sleep", "1s"},
   108  		},
   109  		LogConfig: &structs.LogConfig{
   110  			MaxFiles:      10,
   111  			MaxFileSizeMB: 10,
   112  		},
   113  		Resources: basicResources,
   114  	}
   115  	testtask.SetTaskEnv(task)
   116  	driverCtx, execCtx := testDriverContexts(task)
   117  	defer execCtx.AllocDir.Destroy()
   118  	d := NewRawExecDriver(driverCtx)
   119  
   120  	handle, err := d.Start(execCtx, task)
   121  	if err != nil {
   122  		t.Fatalf("err: %v", err)
   123  	}
   124  	if handle == nil {
   125  		t.Fatalf("missing handle")
   126  	}
   127  
   128  	// Update should be a no-op
   129  	err = handle.Update(task)
   130  	if err != nil {
   131  		t.Fatalf("err: %v", err)
   132  	}
   133  
   134  	// Task should terminate quickly
   135  	select {
   136  	case res := <-handle.WaitCh():
   137  		if !res.Successful() {
   138  			t.Fatalf("err: %v", res)
   139  		}
   140  	case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second):
   141  		t.Fatalf("timeout")
   142  	}
   143  }
   144  
   145  func TestRawExecDriver_Start_Wait_AllocDir(t *testing.T) {
   146  	t.Parallel()
   147  	exp := []byte{'w', 'i', 'n'}
   148  	file := "output.txt"
   149  	outPath := fmt.Sprintf(`${%s}/%s`, env.AllocDir, file)
   150  	task := &structs.Task{
   151  		Name: "sleep",
   152  		Config: map[string]interface{}{
   153  			"command": testtask.Path(),
   154  			"args": []string{
   155  				"sleep", "1s",
   156  				"write", string(exp), outPath,
   157  			},
   158  		},
   159  		LogConfig: &structs.LogConfig{
   160  			MaxFiles:      10,
   161  			MaxFileSizeMB: 10,
   162  		},
   163  		Resources: basicResources,
   164  	}
   165  	testtask.SetTaskEnv(task)
   166  
   167  	driverCtx, execCtx := testDriverContexts(task)
   168  	defer execCtx.AllocDir.Destroy()
   169  	d := NewRawExecDriver(driverCtx)
   170  
   171  	handle, err := d.Start(execCtx, task)
   172  	if err != nil {
   173  		t.Fatalf("err: %v", err)
   174  	}
   175  	if handle == nil {
   176  		t.Fatalf("missing handle")
   177  	}
   178  
   179  	// Task should terminate quickly
   180  	select {
   181  	case res := <-handle.WaitCh():
   182  		if !res.Successful() {
   183  			t.Fatalf("err: %v", res)
   184  		}
   185  	case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second):
   186  		t.Fatalf("timeout")
   187  	}
   188  
   189  	// Check that data was written to the shared alloc directory.
   190  	outputFile := filepath.Join(execCtx.AllocDir.SharedDir, file)
   191  	act, err := ioutil.ReadFile(outputFile)
   192  	if err != nil {
   193  		t.Fatalf("Couldn't read expected output: %v", err)
   194  	}
   195  
   196  	if !reflect.DeepEqual(act, exp) {
   197  		t.Fatalf("Command outputted %v; want %v", act, exp)
   198  	}
   199  }
   200  
   201  func TestRawExecDriver_Start_Kill_Wait(t *testing.T) {
   202  	t.Parallel()
   203  	task := &structs.Task{
   204  		Name: "sleep",
   205  		Config: map[string]interface{}{
   206  			"command": testtask.Path(),
   207  			"args":    []string{"sleep", "45s"},
   208  		},
   209  		LogConfig: &structs.LogConfig{
   210  			MaxFiles:      10,
   211  			MaxFileSizeMB: 10,
   212  		},
   213  		Resources: basicResources,
   214  	}
   215  	testtask.SetTaskEnv(task)
   216  
   217  	driverCtx, execCtx := testDriverContexts(task)
   218  	defer execCtx.AllocDir.Destroy()
   219  	d := NewRawExecDriver(driverCtx)
   220  
   221  	handle, err := d.Start(execCtx, task)
   222  	if err != nil {
   223  		t.Fatalf("err: %v", err)
   224  	}
   225  	if handle == nil {
   226  		t.Fatalf("missing handle")
   227  	}
   228  
   229  	go func() {
   230  		time.Sleep(1 * time.Second)
   231  		err := handle.Kill()
   232  
   233  		// Can't rely on the ordering between wait and kill on travis...
   234  		if !testutil.IsTravis() && err != nil {
   235  			t.Fatalf("err: %v", err)
   236  		}
   237  	}()
   238  
   239  	// Task should terminate quickly
   240  	select {
   241  	case res := <-handle.WaitCh():
   242  		if res.Successful() {
   243  			t.Fatal("should err")
   244  		}
   245  	case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second):
   246  		t.Fatalf("timeout")
   247  	}
   248  }
   249  
   250  func TestRawExecDriverUser(t *testing.T) {
   251  	t.Parallel()
   252  	task := &structs.Task{
   253  		Name: "sleep",
   254  		User: "alice",
   255  		Config: map[string]interface{}{
   256  			"command": testtask.Path(),
   257  			"args":    []string{"sleep", "45s"},
   258  		},
   259  		LogConfig: &structs.LogConfig{
   260  			MaxFiles:      10,
   261  			MaxFileSizeMB: 10,
   262  		},
   263  		Resources: basicResources,
   264  	}
   265  	testtask.SetTaskEnv(task)
   266  
   267  	driverCtx, execCtx := testDriverContexts(task)
   268  	defer execCtx.AllocDir.Destroy()
   269  	d := NewRawExecDriver(driverCtx)
   270  
   271  	handle, err := d.Start(execCtx, task)
   272  	if err == nil {
   273  		handle.Kill()
   274  		t.Fatalf("Should've failed")
   275  	}
   276  	msg := "unknown user alice"
   277  	if !strings.Contains(err.Error(), msg) {
   278  		t.Fatalf("Expecting '%v' in '%v'", msg, err)
   279  	}
   280  }