github.com/dkerwin/nomad@v0.3.3-0.20160525181927-74554135514b/client/driver/rkt_test.go (about)

     1  package driver
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"path/filepath"
     7  	"reflect"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/hashicorp/nomad/client/config"
    13  	"github.com/hashicorp/nomad/client/driver/env"
    14  	"github.com/hashicorp/nomad/nomad/structs"
    15  	"github.com/hashicorp/nomad/testutil"
    16  
    17  	ctestutils "github.com/hashicorp/nomad/client/testutil"
    18  )
    19  
    20  func TestRktVersionRegex(t *testing.T) {
    21  	input_rkt := "rkt version 0.8.1"
    22  	input_appc := "appc version 1.2.0"
    23  	expected_rkt := "0.8.1"
    24  	expected_appc := "1.2.0"
    25  	rktMatches := reRktVersion.FindStringSubmatch(input_rkt)
    26  	appcMatches := reAppcVersion.FindStringSubmatch(input_appc)
    27  	if rktMatches[1] != expected_rkt {
    28  		fmt.Printf("Test failed; got %q; want %q\n", rktMatches[1], expected_rkt)
    29  	}
    30  	if appcMatches[1] != expected_appc {
    31  		fmt.Printf("Test failed; got %q; want %q\n", appcMatches[1], expected_appc)
    32  	}
    33  }
    34  
    35  // The fingerprinter test should always pass, even if rkt is not installed.
    36  func TestRktDriver_Fingerprint(t *testing.T) {
    37  	ctestutils.RktCompatible(t)
    38  	driverCtx, _ := testDriverContexts(&structs.Task{Name: "foo"})
    39  	d := NewRktDriver(driverCtx)
    40  	node := &structs.Node{
    41  		Attributes: make(map[string]string),
    42  	}
    43  	apply, err := d.Fingerprint(&config.Config{}, node)
    44  	if err != nil {
    45  		t.Fatalf("err: %v", err)
    46  	}
    47  	if !apply {
    48  		t.Fatalf("should apply")
    49  	}
    50  	if node.Attributes["driver.rkt"] != "1" {
    51  		t.Fatalf("Missing Rkt driver")
    52  	}
    53  	if node.Attributes["driver.rkt.version"] == "" {
    54  		t.Fatalf("Missing Rkt driver version")
    55  	}
    56  	if node.Attributes["driver.rkt.appc.version"] == "" {
    57  		t.Fatalf("Missing appc version for the Rkt driver")
    58  	}
    59  }
    60  
    61  func TestRktDriver_Start_DNS(t *testing.T) {
    62  	ctestutils.RktCompatible(t)
    63  	// TODO: use test server to load from a fixture
    64  	task := &structs.Task{
    65  		Name: "etcd",
    66  		Config: map[string]interface{}{
    67  			"trust_prefix":       "coreos.com/etcd",
    68  			"image":              "coreos.com/etcd:v2.0.4",
    69  			"command":            "/etcd",
    70  			"dns_servers":        []string{"8.8.8.8", "8.8.4.4"},
    71  			"dns_search_domains": []string{"example.com", "example.org", "example.net"},
    72  		},
    73  		LogConfig: &structs.LogConfig{
    74  			MaxFiles:      10,
    75  			MaxFileSizeMB: 10,
    76  		},
    77  		Resources: &structs.Resources{
    78  			MemoryMB: 128,
    79  			CPU:      100,
    80  		},
    81  	}
    82  
    83  	driverCtx, execCtx := testDriverContexts(task)
    84  	defer execCtx.AllocDir.Destroy()
    85  
    86  	d := NewRktDriver(driverCtx)
    87  
    88  	handle, err := d.Start(execCtx, task)
    89  	if err != nil {
    90  		t.Fatalf("err: %v", err)
    91  	}
    92  	if handle == nil {
    93  		t.Fatalf("missing handle")
    94  	}
    95  	defer handle.Kill()
    96  
    97  	// Attempt to open
    98  	handle2, err := d.Open(execCtx, handle.ID())
    99  	if err != nil {
   100  		t.Fatalf("err: %v", err)
   101  	}
   102  	if handle2 == nil {
   103  		t.Fatalf("missing handle")
   104  	}
   105  }
   106  
   107  func TestRktDriver_Start_Wait(t *testing.T) {
   108  	ctestutils.RktCompatible(t)
   109  	task := &structs.Task{
   110  		Name: "etcd",
   111  		Config: map[string]interface{}{
   112  			"trust_prefix": "coreos.com/etcd",
   113  			"image":        "coreos.com/etcd:v2.0.4",
   114  			"command":      "/etcd",
   115  			"args":         []string{"--version"},
   116  		},
   117  		LogConfig: &structs.LogConfig{
   118  			MaxFiles:      10,
   119  			MaxFileSizeMB: 10,
   120  		},
   121  		Resources: &structs.Resources{
   122  			MemoryMB: 128,
   123  			CPU:      100,
   124  		},
   125  	}
   126  
   127  	driverCtx, execCtx := testDriverContexts(task)
   128  	defer execCtx.AllocDir.Destroy()
   129  	d := NewRktDriver(driverCtx)
   130  
   131  	handle, err := d.Start(execCtx, task)
   132  	if err != nil {
   133  		t.Fatalf("err: %v", err)
   134  	}
   135  	if handle == nil {
   136  		t.Fatalf("missing handle")
   137  	}
   138  	defer handle.Kill()
   139  
   140  	// Update should be a no-op
   141  	err = handle.Update(task)
   142  	if err != nil {
   143  		t.Fatalf("err: %v", err)
   144  	}
   145  
   146  	select {
   147  	case res := <-handle.WaitCh():
   148  		if !res.Successful() {
   149  			t.Fatalf("err: %v", res)
   150  		}
   151  	case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second):
   152  		t.Fatalf("timeout")
   153  	}
   154  }
   155  
   156  func TestRktDriver_Start_Wait_Skip_Trust(t *testing.T) {
   157  	ctestutils.RktCompatible(t)
   158  	task := &structs.Task{
   159  		Name: "etcd",
   160  		Config: map[string]interface{}{
   161  			"image":   "coreos.com/etcd:v2.0.4",
   162  			"command": "/etcd",
   163  			"args":    []string{"--version"},
   164  		},
   165  		LogConfig: &structs.LogConfig{
   166  			MaxFiles:      10,
   167  			MaxFileSizeMB: 10,
   168  		},
   169  		Resources: &structs.Resources{
   170  			MemoryMB: 128,
   171  			CPU:      100,
   172  		},
   173  	}
   174  
   175  	driverCtx, execCtx := testDriverContexts(task)
   176  	defer execCtx.AllocDir.Destroy()
   177  	d := NewRktDriver(driverCtx)
   178  
   179  	handle, err := d.Start(execCtx, task)
   180  	if err != nil {
   181  		t.Fatalf("err: %v", err)
   182  	}
   183  	if handle == nil {
   184  		t.Fatalf("missing handle")
   185  	}
   186  	defer handle.Kill()
   187  
   188  	// Update should be a no-op
   189  	err = handle.Update(task)
   190  	if err != nil {
   191  		t.Fatalf("err: %v", err)
   192  	}
   193  
   194  	select {
   195  	case res := <-handle.WaitCh():
   196  		if !res.Successful() {
   197  			t.Fatalf("err: %v", res)
   198  		}
   199  	case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second):
   200  		t.Fatalf("timeout")
   201  	}
   202  }
   203  
   204  func TestRktDriver_Start_Wait_AllocDir(t *testing.T) {
   205  	ctestutils.RktCompatible(t)
   206  
   207  	exp := []byte{'w', 'i', 'n'}
   208  	file := "output.txt"
   209  
   210  	task := &structs.Task{
   211  		Name: "alpine",
   212  		Config: map[string]interface{}{
   213  			"image":   "docker://alpine",
   214  			"command": "/bin/sh",
   215  			"args": []string{
   216  				"-c",
   217  				fmt.Sprintf(`echo -n %s > ${%s}/%s`, string(exp), env.AllocDir, file),
   218  			},
   219  		},
   220  		LogConfig: &structs.LogConfig{
   221  			MaxFiles:      10,
   222  			MaxFileSizeMB: 10,
   223  		},
   224  		Resources: &structs.Resources{
   225  			MemoryMB: 128,
   226  			CPU:      100,
   227  		},
   228  	}
   229  
   230  	driverCtx, execCtx := testDriverContexts(task)
   231  	defer execCtx.AllocDir.Destroy()
   232  	d := NewRktDriver(driverCtx)
   233  
   234  	handle, err := d.Start(execCtx, task)
   235  	if err != nil {
   236  		t.Fatalf("err: %v", err)
   237  	}
   238  	if handle == nil {
   239  		t.Fatalf("missing handle")
   240  	}
   241  	defer handle.Kill()
   242  
   243  	select {
   244  	case res := <-handle.WaitCh():
   245  		if !res.Successful() {
   246  			t.Fatalf("err: %v", res)
   247  		}
   248  	case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second):
   249  		t.Fatalf("timeout")
   250  	}
   251  
   252  	// Check that data was written to the shared alloc directory.
   253  	outputFile := filepath.Join(execCtx.AllocDir.SharedDir, file)
   254  	act, err := ioutil.ReadFile(outputFile)
   255  	if err != nil {
   256  		t.Fatalf("Couldn't read expected output: %v", err)
   257  	}
   258  
   259  	if !reflect.DeepEqual(act, exp) {
   260  		t.Fatalf("Command output is %v; expected %v", act, exp)
   261  	}
   262  }
   263  
   264  func TestRktDriverUser(t *testing.T) {
   265  	ctestutils.RktCompatible(t)
   266  	task := &structs.Task{
   267  		Name: "etcd",
   268  		User: "alice",
   269  		Config: map[string]interface{}{
   270  			"trust_prefix": "coreos.com/etcd",
   271  			"image":        "coreos.com/etcd:v2.0.4",
   272  			"command":      "/etcd",
   273  			"args":         []string{"--version"},
   274  		},
   275  		LogConfig: &structs.LogConfig{
   276  			MaxFiles:      10,
   277  			MaxFileSizeMB: 10,
   278  		},
   279  		Resources: &structs.Resources{
   280  			MemoryMB: 128,
   281  			CPU:      100,
   282  		},
   283  	}
   284  
   285  	driverCtx, execCtx := testDriverContexts(task)
   286  	defer execCtx.AllocDir.Destroy()
   287  	d := NewRktDriver(driverCtx)
   288  
   289  	handle, err := d.Start(execCtx, task)
   290  	if err == nil {
   291  		handle.Kill()
   292  		t.Fatalf("Should've failed")
   293  	}
   294  	msg := "unknown user alice"
   295  	if !strings.Contains(err.Error(), msg) {
   296  		t.Fatalf("Expecting '%v' in '%v'", msg, err)
   297  	}
   298  }