github.com/huiliang/nomad@v0.2.1-0.20151124023127-7a8b664699ff/client/driver/raw_exec_test.go (about)

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