github.com/ranjib/nomad@v0.1.1-0.20160225204057-97751b02f70b/client/driver/raw_exec_test.go (about)

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