github.com/kardianos/nomad@v0.1.3-0.20151022182107-b13df73ee850/client/executor/exec_linux_test.go (about)

     1  package executor
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/hashicorp/nomad/client/allocdir"
    12  	"github.com/hashicorp/nomad/nomad/mock"
    13  	"github.com/hashicorp/nomad/nomad/structs"
    14  
    15  	ctestutil "github.com/hashicorp/nomad/client/testutil"
    16  )
    17  
    18  var (
    19  	constraint = &structs.Resources{
    20  		CPU:      250,
    21  		MemoryMB: 256,
    22  		Networks: []*structs.NetworkResource{
    23  			&structs.NetworkResource{
    24  				MBits:        50,
    25  				DynamicPorts: []string{"http"},
    26  			},
    27  		},
    28  	}
    29  )
    30  
    31  func mockAllocDir(t *testing.T) (string, *allocdir.AllocDir) {
    32  	alloc := mock.Alloc()
    33  	task := alloc.Job.TaskGroups[0].Tasks[0]
    34  
    35  	allocDir := allocdir.NewAllocDir(filepath.Join(os.TempDir(), alloc.ID))
    36  	if err := allocDir.Build([]*structs.Task{task}); err != nil {
    37  		t.Fatalf("allocDir.Build() failed: %v", err)
    38  	}
    39  
    40  	return task.Name, allocDir
    41  }
    42  
    43  func TestExecutorLinux_Start_Invalid(t *testing.T) {
    44  	ctestutil.ExecCompatible(t)
    45  	invalid := "/bin/foobar"
    46  	e := Command(invalid, "1")
    47  
    48  	if err := e.Limit(constraint); err != nil {
    49  		t.Fatalf("Limit() failed: %v", err)
    50  	}
    51  
    52  	task, alloc := mockAllocDir(t)
    53  	defer alloc.Destroy()
    54  	if err := e.ConfigureTaskDir(task, alloc); err != nil {
    55  		t.Fatalf("ConfigureTaskDir(%v, %v) failed: %v", task, alloc, err)
    56  	}
    57  
    58  	if err := e.Start(); err == nil {
    59  		t.Fatalf("Start(%v) should have failed", invalid)
    60  	}
    61  }
    62  
    63  func TestExecutorLinux_Start_Wait_Failure_Code(t *testing.T) {
    64  	ctestutil.ExecCompatible(t)
    65  	e := Command("/bin/date", "-invalid")
    66  
    67  	if err := e.Limit(constraint); err != nil {
    68  		t.Fatalf("Limit() failed: %v", err)
    69  	}
    70  
    71  	task, alloc := mockAllocDir(t)
    72  	defer alloc.Destroy()
    73  	if err := e.ConfigureTaskDir(task, alloc); err != nil {
    74  		t.Fatalf("ConfigureTaskDir(%v, %v) failed: %v", task, alloc, err)
    75  	}
    76  
    77  	if err := e.Start(); err != nil {
    78  		t.Fatalf("Start() failed: %v", err)
    79  	}
    80  
    81  	if err := e.Wait(); err == nil {
    82  		t.Fatalf("Wait() should have failed")
    83  	}
    84  }
    85  
    86  func TestExecutorLinux_Start_Wait(t *testing.T) {
    87  	ctestutil.ExecCompatible(t)
    88  	task, alloc := mockAllocDir(t)
    89  	defer alloc.Destroy()
    90  
    91  	taskDir, ok := alloc.TaskDirs[task]
    92  	if !ok {
    93  		t.Fatalf("No task directory found for task %v", task)
    94  	}
    95  
    96  	expected := "hello world"
    97  	file := filepath.Join(allocdir.TaskLocal, "output.txt")
    98  	absFilePath := filepath.Join(taskDir, file)
    99  	cmd := fmt.Sprintf(`"%v \"%v\" > %v"`, "/bin/sleep 1 ; echo -n", expected, file)
   100  	e := Command("/bin/bash", "-c", cmd)
   101  
   102  	if err := e.Limit(constraint); err != nil {
   103  		t.Fatalf("Limit() failed: %v", err)
   104  	}
   105  
   106  	if err := e.ConfigureTaskDir(task, alloc); err != nil {
   107  		t.Fatalf("ConfigureTaskDir(%v, %v) failed: %v", task, alloc, err)
   108  	}
   109  
   110  	if err := e.Start(); err != nil {
   111  		t.Fatalf("Start() failed: %v", err)
   112  	}
   113  
   114  	if err := e.Wait(); err != nil {
   115  		t.Fatalf("Wait() failed: %v", err)
   116  	}
   117  
   118  	output, err := ioutil.ReadFile(absFilePath)
   119  	if err != nil {
   120  		t.Fatalf("Couldn't read file %v", absFilePath)
   121  	}
   122  
   123  	act := string(output)
   124  	if act != expected {
   125  		t.Fatalf("Command output incorrectly: want %v; got %v", expected, act)
   126  	}
   127  }
   128  
   129  func TestExecutorLinux_Start_Kill(t *testing.T) {
   130  	ctestutil.ExecCompatible(t)
   131  	task, alloc := mockAllocDir(t)
   132  	defer alloc.Destroy()
   133  
   134  	taskDir, ok := alloc.TaskDirs[task]
   135  	if !ok {
   136  		t.Fatalf("No task directory found for task %v", task)
   137  	}
   138  
   139  	filePath := filepath.Join(taskDir, "output")
   140  	e := Command("/bin/bash", "-c", "sleep 1 ; echo \"failure\" > "+filePath)
   141  
   142  	// This test can only be run if cgroups are enabled.
   143  	if !e.(*LinuxExecutor).cgroupEnabled {
   144  		t.SkipNow()
   145  	}
   146  
   147  	if err := e.Limit(constraint); err != nil {
   148  		t.Fatalf("Limit() failed: %v", err)
   149  	}
   150  
   151  	if err := e.ConfigureTaskDir(task, alloc); err != nil {
   152  		t.Fatalf("ConfigureTaskDir(%v, %v) failed: %v", task, alloc, err)
   153  	}
   154  
   155  	if err := e.Start(); err != nil {
   156  		t.Fatalf("Start() failed: %v", err)
   157  	}
   158  
   159  	if err := e.Shutdown(); err != nil {
   160  		t.Fatalf("Shutdown() failed: %v", err)
   161  	}
   162  
   163  	time.Sleep(1500 * time.Millisecond)
   164  
   165  	// Check that the file doesn't exist.
   166  	if _, err := os.Stat(filePath); err == nil {
   167  		t.Fatalf("Stat(%v) should have failed: task not killed", filePath)
   168  	}
   169  }
   170  
   171  func TestExecutorLinux_Open(t *testing.T) {
   172  	ctestutil.ExecCompatible(t)
   173  	task, alloc := mockAllocDir(t)
   174  	defer alloc.Destroy()
   175  
   176  	taskDir, ok := alloc.TaskDirs[task]
   177  	if !ok {
   178  		t.Fatalf("No task directory found for task %v", task)
   179  	}
   180  
   181  	filePath := filepath.Join(taskDir, "output")
   182  	e := Command("/bin/bash", "-c", "sleep 1 ; echo \"failure\" > "+filePath)
   183  
   184  	// This test can only be run if cgroups are enabled.
   185  	if !e.(*LinuxExecutor).cgroupEnabled {
   186  		t.SkipNow()
   187  	}
   188  
   189  	if err := e.Limit(constraint); err != nil {
   190  		t.Fatalf("Limit() failed: %v", err)
   191  	}
   192  
   193  	if err := e.ConfigureTaskDir(task, alloc); err != nil {
   194  		t.Fatalf("ConfigureTaskDir(%v, %v) failed: %v", task, alloc, err)
   195  	}
   196  
   197  	if err := e.Start(); err != nil {
   198  		t.Fatalf("Start() failed: %v", err)
   199  	}
   200  
   201  	id, err := e.ID()
   202  	if err != nil {
   203  		t.Fatalf("ID() failed: %v", err)
   204  	}
   205  
   206  	if _, err := OpenId(id); err == nil {
   207  		t.Fatalf("Open(%v) should have failed", id)
   208  	}
   209  
   210  	time.Sleep(1500 * time.Millisecond)
   211  
   212  	// Check that the file doesn't exist, open should have killed the process.
   213  	if _, err := os.Stat(filePath); err == nil {
   214  		t.Fatalf("Stat(%v) should have failed: task not killed", filePath)
   215  	}
   216  }