github.com/huiliang/nomad@v0.2.1-0.20151124023127-7a8b664699ff/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  func TestExecDriver_StartOpen_Wait(t *testing.T) {
    37  	ctestutils.ExecCompatible(t)
    38  	task := &structs.Task{
    39  		Name: "sleep",
    40  		Config: map[string]interface{}{
    41  			"command": "/bin/sleep",
    42  			"args":    []string{"5"},
    43  		},
    44  		Resources: basicResources,
    45  	}
    46  
    47  	driverCtx := testDriverContext(task.Name)
    48  	ctx := testDriverExecContext(task, driverCtx)
    49  	defer ctx.AllocDir.Destroy()
    50  	d := NewExecDriver(driverCtx)
    51  
    52  	handle, err := d.Start(ctx, task)
    53  	if err != nil {
    54  		t.Fatalf("err: %v", err)
    55  	}
    56  	if handle == nil {
    57  		t.Fatalf("missing handle")
    58  	}
    59  
    60  	// Attempt to open
    61  	handle2, err := d.Open(ctx, handle.ID())
    62  	if err != nil {
    63  		t.Fatalf("err: %v", err)
    64  	}
    65  	if handle2 == nil {
    66  		t.Fatalf("missing handle")
    67  	}
    68  }
    69  
    70  func TestExecDriver_Start_Wait(t *testing.T) {
    71  	ctestutils.ExecCompatible(t)
    72  	task := &structs.Task{
    73  		Name: "sleep",
    74  		Config: map[string]interface{}{
    75  			"command": "/bin/sleep",
    76  			"args":    []string{"2"},
    77  		},
    78  		Resources: basicResources,
    79  	}
    80  
    81  	driverCtx := testDriverContext(task.Name)
    82  	ctx := testDriverExecContext(task, driverCtx)
    83  	defer ctx.AllocDir.Destroy()
    84  	d := NewExecDriver(driverCtx)
    85  
    86  	handle, err := d.Start(ctx, task)
    87  	if err != nil {
    88  		t.Fatalf("err: %v", err)
    89  	}
    90  	if handle == nil {
    91  		t.Fatalf("missing handle")
    92  	}
    93  
    94  	// Update should be a no-op
    95  	err = handle.Update(task)
    96  	if err != nil {
    97  		t.Fatalf("err: %v", err)
    98  	}
    99  
   100  	// Task should terminate quickly
   101  	select {
   102  	case res := <-handle.WaitCh():
   103  		if !res.Successful() {
   104  			t.Fatalf("err: %v", res)
   105  		}
   106  	case <-time.After(4 * time.Second):
   107  		t.Fatalf("timeout")
   108  	}
   109  }
   110  
   111  func TestExecDriver_Start_Artifact_basic(t *testing.T) {
   112  	ctestutils.ExecCompatible(t)
   113  	file := "hi_linux_amd64"
   114  	checksum := "sha256:6f99b4c5184726e601ecb062500aeb9537862434dfe1898dbe5c68d9f50c179c"
   115  
   116  	task := &structs.Task{
   117  		Name: "sleep",
   118  		Config: map[string]interface{}{
   119  			"artifact_source": fmt.Sprintf("https://dl.dropboxusercontent.com/u/47675/jar_thing/%s?checksum=%s", file, checksum),
   120  			"command":         filepath.Join("$NOMAD_TASK_DIR", file),
   121  		},
   122  		Resources: basicResources,
   123  	}
   124  
   125  	driverCtx := testDriverContext(task.Name)
   126  	ctx := testDriverExecContext(task, driverCtx)
   127  	defer ctx.AllocDir.Destroy()
   128  	d := NewExecDriver(driverCtx)
   129  
   130  	handle, err := d.Start(ctx, task)
   131  	if err != nil {
   132  		t.Fatalf("err: %v", err)
   133  	}
   134  	if handle == nil {
   135  		t.Fatalf("missing handle")
   136  	}
   137  
   138  	// Update should be a no-op
   139  	err = handle.Update(task)
   140  	if err != nil {
   141  		t.Fatalf("err: %v", err)
   142  	}
   143  
   144  	// Task should terminate quickly
   145  	select {
   146  	case res := <-handle.WaitCh():
   147  		if !res.Successful() {
   148  			t.Fatalf("err: %v", res)
   149  		}
   150  	case <-time.After(5 * time.Second):
   151  		t.Fatalf("timeout")
   152  	}
   153  }
   154  
   155  func TestExecDriver_Start_Artifact_expanded(t *testing.T) {
   156  	ctestutils.ExecCompatible(t)
   157  	file := "hi_linux_amd64"
   158  
   159  	task := &structs.Task{
   160  		Name: "sleep",
   161  		Config: map[string]interface{}{
   162  			"artifact_source": fmt.Sprintf("https://dl.dropboxusercontent.com/u/47675/jar_thing/%s", file),
   163  			"command":         "/bin/bash",
   164  			"args": []string{
   165  				"-c",
   166  				fmt.Sprintf(`/bin/sleep 1 && %s`, filepath.Join("$NOMAD_TASK_DIR", file)),
   167  			},
   168  		},
   169  		Resources: basicResources,
   170  	}
   171  
   172  	driverCtx := testDriverContext(task.Name)
   173  	ctx := testDriverExecContext(task, driverCtx)
   174  	defer ctx.AllocDir.Destroy()
   175  	d := NewExecDriver(driverCtx)
   176  
   177  	handle, err := d.Start(ctx, task)
   178  	if err != nil {
   179  		t.Fatalf("err: %v", err)
   180  	}
   181  	if handle == nil {
   182  		t.Fatalf("missing handle")
   183  	}
   184  
   185  	// Update should be a no-op
   186  	err = handle.Update(task)
   187  	if err != nil {
   188  		t.Fatalf("err: %v", err)
   189  	}
   190  
   191  	// Task should terminate quickly
   192  	select {
   193  	case res := <-handle.WaitCh():
   194  		if !res.Successful() {
   195  			t.Fatalf("err: %v", res)
   196  		}
   197  	case <-time.After(5 * time.Second):
   198  		t.Fatalf("timeout")
   199  	}
   200  }
   201  func TestExecDriver_Start_Wait_AllocDir(t *testing.T) {
   202  	ctestutils.ExecCompatible(t)
   203  
   204  	exp := []byte{'w', 'i', 'n'}
   205  	file := "output.txt"
   206  	task := &structs.Task{
   207  		Name: "sleep",
   208  		Config: map[string]interface{}{
   209  			"command": "/bin/bash",
   210  			"args": []string{
   211  				"-c",
   212  				fmt.Sprintf(`sleep 1; echo -n %s > $%s/%s`, string(exp), environment.AllocDir, file),
   213  			},
   214  		},
   215  		Resources: basicResources,
   216  	}
   217  
   218  	driverCtx := testDriverContext(task.Name)
   219  	ctx := testDriverExecContext(task, driverCtx)
   220  	defer ctx.AllocDir.Destroy()
   221  	d := NewExecDriver(driverCtx)
   222  
   223  	handle, err := d.Start(ctx, 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(2 * time.Second):
   238  		t.Fatalf("timeout")
   239  	}
   240  
   241  	// Check that data was written to the shared alloc directory.
   242  	outputFile := filepath.Join(ctx.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 TestExecDriver_Start_Kill_Wait(t *testing.T) {
   254  	ctestutils.ExecCompatible(t)
   255  	task := &structs.Task{
   256  		Name: "sleep",
   257  		Config: map[string]interface{}{
   258  			"command": "/bin/sleep",
   259  			"args":    []string{"1"},
   260  		},
   261  		Resources: basicResources,
   262  	}
   263  
   264  	driverCtx := testDriverContext(task.Name)
   265  	ctx := testDriverExecContext(task, driverCtx)
   266  	defer ctx.AllocDir.Destroy()
   267  	d := NewExecDriver(driverCtx)
   268  
   269  	handle, err := d.Start(ctx, task)
   270  	if err != nil {
   271  		t.Fatalf("err: %v", err)
   272  	}
   273  	if handle == nil {
   274  		t.Fatalf("missing handle")
   275  	}
   276  
   277  	go func() {
   278  		time.Sleep(100 * time.Millisecond)
   279  		err := handle.Kill()
   280  		if err != nil {
   281  			t.Fatalf("err: %v", err)
   282  		}
   283  	}()
   284  
   285  	// Task should terminate quickly
   286  	select {
   287  	case res := <-handle.WaitCh():
   288  		if res.Successful() {
   289  			t.Fatal("should err")
   290  		}
   291  	case <-time.After(8 * time.Second):
   292  		t.Fatalf("timeout")
   293  	}
   294  }