github.com/kardianos/nomad@v0.1.3-0.20151022182107-b13df73ee850/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/environment"
    13  	"github.com/hashicorp/nomad/nomad/structs"
    14  
    15  	ctestutils "github.com/hashicorp/nomad/client/testutil"
    16  )
    17  
    18  func TestExecDriver_Fingerprint(t *testing.T) {
    19  	ctestutils.ExecCompatible(t)
    20  	d := NewExecDriver(testDriverContext(""))
    21  	node := &structs.Node{
    22  		Attributes: make(map[string]string),
    23  	}
    24  	apply, err := d.Fingerprint(&config.Config{}, node)
    25  	if err != nil {
    26  		t.Fatalf("err: %v", err)
    27  	}
    28  	if !apply {
    29  		t.Fatalf("should apply")
    30  	}
    31  	if node.Attributes["driver.exec"] == "" {
    32  		t.Fatalf("missing driver")
    33  	}
    34  }
    35  
    36  /*
    37  TODO: This test is disabled til a follow-up api changes the restore state interface.
    38  The driver/executor interface will be changed from Open to Cleanup, in which
    39  clean-up tears down previous allocs.
    40  
    41  func TestExecDriver_StartOpen_Wait(t *testing.T) {
    42  	ctestutils.ExecCompatible(t)
    43  	task := &structs.Task{
    44  		Name: "sleep",
    45  		Config: map[string]string{
    46  			"command": "/bin/sleep",
    47  			"args":    "5",
    48  		},
    49  		Resources: basicResources,
    50  	}
    51  
    52  	driverCtx := testDriverContext(task.Name)
    53  	ctx := testDriverExecContext(task, driverCtx)
    54  	defer ctx.AllocDir.Destroy()
    55  	d := NewExecDriver(driverCtx)
    56  
    57  	if task.Resources == nil {
    58  		task.Resources = &structs.Resources{}
    59  	}
    60  	task.Resources.CPU = 0.5
    61  	task.Resources.MemoryMB = 2
    62  
    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  */
    81  
    82  func TestExecDriver_Start_Wait(t *testing.T) {
    83  	ctestutils.ExecCompatible(t)
    84  	task := &structs.Task{
    85  		Name: "sleep",
    86  		Config: map[string]string{
    87  			"command": "/bin/sleep",
    88  			"args":    "2",
    89  		},
    90  		Resources: basicResources,
    91  	}
    92  
    93  	driverCtx := testDriverContext(task.Name)
    94  	ctx := testDriverExecContext(task, driverCtx)
    95  	defer ctx.AllocDir.Destroy()
    96  	d := NewExecDriver(driverCtx)
    97  
    98  	handle, err := d.Start(ctx, task)
    99  	if err != nil {
   100  		t.Fatalf("err: %v", err)
   101  	}
   102  	if handle == nil {
   103  		t.Fatalf("missing handle")
   104  	}
   105  
   106  	// Update should be a no-op
   107  	err = handle.Update(task)
   108  	if err != nil {
   109  		t.Fatalf("err: %v", err)
   110  	}
   111  
   112  	// Task should terminate quickly
   113  	select {
   114  	case err := <-handle.WaitCh():
   115  		if err != nil {
   116  			t.Fatalf("err: %v", err)
   117  		}
   118  	case <-time.After(4 * time.Second):
   119  		t.Fatalf("timeout")
   120  	}
   121  }
   122  
   123  func TestExecDriver_Start_Wait_AllocDir(t *testing.T) {
   124  	ctestutils.ExecCompatible(t)
   125  
   126  	exp := []byte{'w', 'i', 'n'}
   127  	file := "output.txt"
   128  	task := &structs.Task{
   129  		Name: "sleep",
   130  		Config: map[string]string{
   131  			"command": "/bin/bash",
   132  			"args":    fmt.Sprintf("-c \"sleep 1; echo -n %s > $%s/%s\"", string(exp), environment.AllocDir, file),
   133  		},
   134  		Resources: basicResources,
   135  	}
   136  
   137  	driverCtx := testDriverContext(task.Name)
   138  	ctx := testDriverExecContext(task, driverCtx)
   139  	defer ctx.AllocDir.Destroy()
   140  	d := NewExecDriver(driverCtx)
   141  
   142  	handle, err := d.Start(ctx, task)
   143  	if err != nil {
   144  		t.Fatalf("err: %v", err)
   145  	}
   146  	if handle == nil {
   147  		t.Fatalf("missing handle")
   148  	}
   149  
   150  	// Task should terminate quickly
   151  	select {
   152  	case err := <-handle.WaitCh():
   153  		if err != nil {
   154  			t.Fatalf("err: %v", err)
   155  		}
   156  	case <-time.After(2 * time.Second):
   157  		t.Fatalf("timeout")
   158  	}
   159  
   160  	// Check that data was written to the shared alloc directory.
   161  	outputFile := filepath.Join(ctx.AllocDir.SharedDir, file)
   162  	act, err := ioutil.ReadFile(outputFile)
   163  	if err != nil {
   164  		t.Fatalf("Couldn't read expected output: %v", err)
   165  	}
   166  
   167  	if !reflect.DeepEqual(act, exp) {
   168  		t.Fatalf("Command outputted %v; want %v", act, exp)
   169  	}
   170  }
   171  
   172  func TestExecDriver_Start_Kill_Wait(t *testing.T) {
   173  	ctestutils.ExecCompatible(t)
   174  	task := &structs.Task{
   175  		Name: "sleep",
   176  		Config: map[string]string{
   177  			"command": "/bin/sleep",
   178  			"args":    "1",
   179  		},
   180  		Resources: basicResources,
   181  	}
   182  
   183  	driverCtx := testDriverContext(task.Name)
   184  	ctx := testDriverExecContext(task, driverCtx)
   185  	defer ctx.AllocDir.Destroy()
   186  	d := NewExecDriver(driverCtx)
   187  
   188  	handle, err := d.Start(ctx, task)
   189  	if err != nil {
   190  		t.Fatalf("err: %v", err)
   191  	}
   192  	if handle == nil {
   193  		t.Fatalf("missing handle")
   194  	}
   195  
   196  	go func() {
   197  		time.Sleep(100 * time.Millisecond)
   198  		err := handle.Kill()
   199  		if err != nil {
   200  			t.Fatalf("err: %v", err)
   201  		}
   202  	}()
   203  
   204  	// Task should terminate quickly
   205  	select {
   206  	case err := <-handle.WaitCh():
   207  		if err == nil {
   208  			t.Fatal("should err")
   209  		}
   210  	case <-time.After(2 * time.Second):
   211  		t.Fatalf("timeout")
   212  	}
   213  }