github.com/ryanslade/nomad@v0.2.4-0.20160128061903-fc95782f2089/client/driver/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/env"
    13  	"github.com/hashicorp/nomad/nomad/structs"
    14  	"github.com/hashicorp/nomad/testutil"
    15  
    16  	ctestutils "github.com/hashicorp/nomad/client/testutil"
    17  )
    18  
    19  func TestExecDriver_Fingerprint(t *testing.T) {
    20  	t.Parallel()
    21  	ctestutils.ExecCompatible(t)
    22  	driverCtx, _ := testDriverContexts(&structs.Task{Name: "foo"})
    23  	d := NewExecDriver(driverCtx)
    24  	node := &structs.Node{
    25  		Attributes: make(map[string]string),
    26  	}
    27  	apply, err := d.Fingerprint(&config.Config{}, node)
    28  	if err != nil {
    29  		t.Fatalf("err: %v", err)
    30  	}
    31  	if !apply {
    32  		t.Fatalf("should apply")
    33  	}
    34  	if node.Attributes["driver.exec"] == "" {
    35  		t.Fatalf("missing driver")
    36  	}
    37  }
    38  
    39  func TestExecDriver_StartOpen_Wait(t *testing.T) {
    40  	t.Parallel()
    41  	ctestutils.ExecCompatible(t)
    42  	task := &structs.Task{
    43  		Name: "sleep",
    44  		Config: map[string]interface{}{
    45  			"command": "/bin/sleep",
    46  			"args":    []string{"5"},
    47  		},
    48  		Resources: basicResources,
    49  	}
    50  
    51  	driverCtx, execCtx := testDriverContexts(task)
    52  	defer execCtx.AllocDir.Destroy()
    53  	d := NewExecDriver(driverCtx)
    54  
    55  	handle, err := d.Start(execCtx, task)
    56  	if err != nil {
    57  		t.Fatalf("err: %v", err)
    58  	}
    59  	if handle == nil {
    60  		t.Fatalf("missing handle")
    61  	}
    62  
    63  	// Attempt to open
    64  	handle2, err := d.Open(execCtx, handle.ID())
    65  	if err != nil {
    66  		t.Fatalf("err: %v", err)
    67  	}
    68  	if handle2 == nil {
    69  		t.Fatalf("missing handle")
    70  	}
    71  }
    72  
    73  func TestExecDriver_Start_Wait(t *testing.T) {
    74  	t.Parallel()
    75  	ctestutils.ExecCompatible(t)
    76  	task := &structs.Task{
    77  		Name: "sleep",
    78  		Config: map[string]interface{}{
    79  			"command": "/bin/sleep",
    80  			"args":    []string{"2"},
    81  		},
    82  		Resources: basicResources,
    83  	}
    84  
    85  	driverCtx, execCtx := testDriverContexts(task)
    86  	defer execCtx.AllocDir.Destroy()
    87  	d := NewExecDriver(driverCtx)
    88  
    89  	handle, err := d.Start(execCtx, task)
    90  	if err != nil {
    91  		t.Fatalf("err: %v", err)
    92  	}
    93  	if handle == nil {
    94  		t.Fatalf("missing handle")
    95  	}
    96  
    97  	// Update should be a no-op
    98  	err = handle.Update(task)
    99  	if err != nil {
   100  		t.Fatalf("err: %v", err)
   101  	}
   102  
   103  	// Task should terminate quickly
   104  	select {
   105  	case res := <-handle.WaitCh():
   106  		if !res.Successful() {
   107  			t.Fatalf("err: %v", res)
   108  		}
   109  	case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second):
   110  		t.Fatalf("timeout")
   111  	}
   112  }
   113  
   114  func TestExecDriver_Start_Artifact_basic(t *testing.T) {
   115  	t.Parallel()
   116  	ctestutils.ExecCompatible(t)
   117  	file := "hi_linux_amd64"
   118  	checksum := "sha256:6f99b4c5184726e601ecb062500aeb9537862434dfe1898dbe5c68d9f50c179c"
   119  
   120  	task := &structs.Task{
   121  		Name: "sleep",
   122  		Config: map[string]interface{}{
   123  			"artifact_source": fmt.Sprintf("https://dl.dropboxusercontent.com/u/47675/jar_thing/%s?checksum=%s", file, checksum),
   124  			"command":         filepath.Join("$NOMAD_TASK_DIR", file),
   125  		},
   126  		Resources: basicResources,
   127  	}
   128  
   129  	driverCtx, execCtx := testDriverContexts(task)
   130  	defer execCtx.AllocDir.Destroy()
   131  	d := NewExecDriver(driverCtx)
   132  
   133  	handle, err := d.Start(execCtx, task)
   134  	if err != nil {
   135  		t.Fatalf("err: %v", err)
   136  	}
   137  	if handle == nil {
   138  		t.Fatalf("missing handle")
   139  	}
   140  
   141  	// Update should be a no-op
   142  	err = handle.Update(task)
   143  	if err != nil {
   144  		t.Fatalf("err: %v", err)
   145  	}
   146  
   147  	// Task should terminate quickly
   148  	select {
   149  	case res := <-handle.WaitCh():
   150  		if !res.Successful() {
   151  			t.Fatalf("err: %v", res)
   152  		}
   153  	case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second):
   154  		t.Fatalf("timeout")
   155  	}
   156  }
   157  
   158  func TestExecDriver_Start_Artifact_expanded(t *testing.T) {
   159  	t.Parallel()
   160  	ctestutils.ExecCompatible(t)
   161  	file := "hi_linux_amd64"
   162  
   163  	task := &structs.Task{
   164  		Name: "sleep",
   165  		Config: map[string]interface{}{
   166  			"artifact_source": fmt.Sprintf("https://dl.dropboxusercontent.com/u/47675/jar_thing/%s", file),
   167  			"command":         "/bin/bash",
   168  			"args": []string{
   169  				"-c",
   170  				fmt.Sprintf(`/bin/sleep 1 && %s`, filepath.Join("$NOMAD_TASK_DIR", file)),
   171  			},
   172  		},
   173  		Resources: basicResources,
   174  	}
   175  
   176  	driverCtx, execCtx := testDriverContexts(task)
   177  	defer execCtx.AllocDir.Destroy()
   178  	d := NewExecDriver(driverCtx)
   179  
   180  	handle, err := d.Start(execCtx, task)
   181  	if err != nil {
   182  		t.Fatalf("err: %v", err)
   183  	}
   184  	if handle == nil {
   185  		t.Fatalf("missing handle")
   186  	}
   187  
   188  	// Update should be a no-op
   189  	err = handle.Update(task)
   190  	if err != nil {
   191  		t.Fatalf("err: %v", err)
   192  	}
   193  
   194  	// Task should terminate quickly
   195  	select {
   196  	case res := <-handle.WaitCh():
   197  		if !res.Successful() {
   198  			t.Fatalf("err: %v", res)
   199  		}
   200  	case <-time.After(time.Duration(testutil.TestMultiplier()*15) * time.Second):
   201  		t.Fatalf("timeout")
   202  	}
   203  }
   204  func TestExecDriver_Start_Wait_AllocDir(t *testing.T) {
   205  	t.Parallel()
   206  	ctestutils.ExecCompatible(t)
   207  
   208  	exp := []byte{'w', 'i', 'n'}
   209  	file := "output.txt"
   210  	task := &structs.Task{
   211  		Name: "sleep",
   212  		Config: map[string]interface{}{
   213  			"command": "/bin/bash",
   214  			"args": []string{
   215  				"-c",
   216  				fmt.Sprintf(`sleep 1; echo -n %s > $%s/%s`, string(exp), env.AllocDir, file),
   217  			},
   218  		},
   219  		Resources: basicResources,
   220  	}
   221  
   222  	driverCtx, execCtx := testDriverContexts(task)
   223  	defer execCtx.AllocDir.Destroy()
   224  	d := NewExecDriver(driverCtx)
   225  
   226  	handle, err := d.Start(execCtx, task)
   227  	if err != nil {
   228  		t.Fatalf("err: %v", err)
   229  	}
   230  	if handle == nil {
   231  		t.Fatalf("missing handle")
   232  	}
   233  
   234  	// Task should terminate quickly
   235  	select {
   236  	case res := <-handle.WaitCh():
   237  		if !res.Successful() {
   238  			t.Fatalf("err: %v", res)
   239  		}
   240  	case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second):
   241  		t.Fatalf("timeout")
   242  	}
   243  
   244  	// Check that data was written to the shared alloc directory.
   245  	outputFile := filepath.Join(execCtx.AllocDir.SharedDir, file)
   246  	act, err := ioutil.ReadFile(outputFile)
   247  	if err != nil {
   248  		t.Fatalf("Couldn't read expected output: %v", err)
   249  	}
   250  
   251  	if !reflect.DeepEqual(act, exp) {
   252  		t.Fatalf("Command outputted %v; want %v", act, exp)
   253  	}
   254  }
   255  
   256  func TestExecDriver_Start_Kill_Wait(t *testing.T) {
   257  	t.Parallel()
   258  	ctestutils.ExecCompatible(t)
   259  	task := &structs.Task{
   260  		Name: "sleep",
   261  		Config: map[string]interface{}{
   262  			"command": "/bin/sleep",
   263  			"args":    []string{"1"},
   264  		},
   265  		Resources: basicResources,
   266  	}
   267  
   268  	driverCtx, execCtx := testDriverContexts(task)
   269  	defer execCtx.AllocDir.Destroy()
   270  	d := NewExecDriver(driverCtx)
   271  
   272  	handle, err := d.Start(execCtx, task)
   273  	if err != nil {
   274  		t.Fatalf("err: %v", err)
   275  	}
   276  	if handle == nil {
   277  		t.Fatalf("missing handle")
   278  	}
   279  
   280  	go func() {
   281  		time.Sleep(100 * time.Millisecond)
   282  		err := handle.Kill()
   283  		if err != nil {
   284  			t.Fatalf("err: %v", err)
   285  		}
   286  	}()
   287  
   288  	// Task should terminate quickly
   289  	select {
   290  	case res := <-handle.WaitCh():
   291  		if res.Successful() {
   292  			t.Fatal("should err")
   293  		}
   294  	case <-time.After(time.Duration(testutil.TestMultiplier()*10) * time.Second):
   295  		t.Fatalf("timeout")
   296  	}
   297  }