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