github.com/maier/nomad@v0.4.1-0.20161110003312-a9e3d0b8549d/client/driver/executor/executor_linux_test.go (about)

     1  package executor
     2  
     3  import (
     4  	"io/ioutil"
     5  	"log"
     6  	"os"
     7  	"path/filepath"
     8  	"strconv"
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/hashicorp/nomad/client/driver/env"
    13  	cstructs "github.com/hashicorp/nomad/client/driver/structs"
    14  	"github.com/hashicorp/nomad/client/testutil"
    15  	"github.com/hashicorp/nomad/nomad/mock"
    16  )
    17  
    18  func testExecutorContextWithChroot(t *testing.T) *ExecutorContext {
    19  	taskEnv := env.NewTaskEnvironment(mock.Node())
    20  	task, allocDir := mockAllocDir(t)
    21  	ctx := &ExecutorContext{
    22  		TaskEnv:  taskEnv,
    23  		Task:     task,
    24  		AllocDir: allocDir,
    25  		ChrootEnv: map[string]string{
    26  			"/etc/ld.so.cache":  "/etc/ld.so.cache",
    27  			"/etc/ld.so.conf":   "/etc/ld.so.conf",
    28  			"/etc/ld.so.conf.d": "/etc/ld.so.conf.d",
    29  			"/lib":              "/lib",
    30  			"/lib64":            "/lib64",
    31  			"/usr/lib":          "/usr/lib",
    32  			"/bin/ls":           "/bin/ls",
    33  			"/foobar":           "/does/not/exist",
    34  		},
    35  	}
    36  	return ctx
    37  }
    38  
    39  func TestExecutor_IsolationAndConstraints(t *testing.T) {
    40  	testutil.ExecCompatible(t)
    41  
    42  	execCmd := ExecCommand{Cmd: "/bin/ls", Args: []string{"-F", "/", "/etc/"}}
    43  	ctx := testExecutorContextWithChroot(t)
    44  	defer ctx.AllocDir.Destroy()
    45  
    46  	execCmd.FSIsolation = true
    47  	execCmd.ResourceLimits = true
    48  	execCmd.User = cstructs.DefaultUnpriviledgedUser
    49  
    50  	executor := NewExecutor(log.New(os.Stdout, "", log.LstdFlags))
    51  
    52  	if err := executor.SetContext(ctx); err != nil {
    53  		t.Fatalf("Unexpected error")
    54  	}
    55  
    56  	ps, err := executor.LaunchCmd(&execCmd)
    57  	if err != nil {
    58  		t.Fatalf("error in launching command: %v", err)
    59  	}
    60  	if ps.Pid == 0 {
    61  		t.Fatalf("expected process to start and have non zero pid")
    62  	}
    63  	_, err = executor.Wait()
    64  	if err != nil {
    65  		t.Fatalf("error in waiting for command: %v", err)
    66  	}
    67  
    68  	// Check if the resource contraints were applied
    69  	memLimits := filepath.Join(ps.IsolationConfig.CgroupPaths["memory"], "memory.limit_in_bytes")
    70  	data, err := ioutil.ReadFile(memLimits)
    71  	if err != nil {
    72  		t.Fatalf("err: %v", err)
    73  	}
    74  	expectedMemLim := strconv.Itoa(ctx.Task.Resources.MemoryMB * 1024 * 1024)
    75  	actualMemLim := strings.TrimSpace(string(data))
    76  	if actualMemLim != expectedMemLim {
    77  		t.Fatalf("actual mem limit: %v, expected: %v", string(data), expectedMemLim)
    78  	}
    79  
    80  	if err := executor.Exit(); err != nil {
    81  		t.Fatalf("error: %v", err)
    82  	}
    83  
    84  	// Check if Nomad has actually removed the cgroups
    85  	if _, err := os.Stat(memLimits); err == nil {
    86  		t.Fatalf("file %v hasn't been removed", memLimits)
    87  	}
    88  
    89  	expected := `/:
    90  alloc/
    91  bin/
    92  dev/
    93  etc/
    94  lib/
    95  lib64/
    96  local/
    97  proc/
    98  secrets/
    99  tmp/
   100  usr/
   101  
   102  /etc/:
   103  ld.so.cache
   104  ld.so.conf
   105  ld.so.conf.d/`
   106  	file := filepath.Join(ctx.AllocDir.LogDir(), "web.stdout.0")
   107  	output, err := ioutil.ReadFile(file)
   108  	if err != nil {
   109  		t.Fatalf("Couldn't read file %v", file)
   110  	}
   111  
   112  	act := strings.TrimSpace(string(output))
   113  	if act != expected {
   114  		t.Fatalf("Command output incorrectly: want %v; got %v", expected, act)
   115  	}
   116  }