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