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

     1  //+build linux,lxc
     2  
     3  package driver
     4  
     5  import (
     6  	"fmt"
     7  	"os"
     8  	"path/filepath"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/hashicorp/nomad/client/config"
    13  	"github.com/hashicorp/nomad/nomad/structs"
    14  	"github.com/hashicorp/nomad/testutil"
    15  	lxc "gopkg.in/lxc/go-lxc.v2"
    16  )
    17  
    18  func TestLxcDriver_Fingerprint(t *testing.T) {
    19  	if !lxcPresent(t) {
    20  		t.Skip("lxc not present")
    21  	}
    22  
    23  	task := &structs.Task{
    24  		Name:      "foo",
    25  		Resources: structs.DefaultResources(),
    26  	}
    27  
    28  	driverCtx, execCtx := testDriverContexts(task)
    29  	defer execCtx.AllocDir.Destroy()
    30  	d := NewLxcDriver(driverCtx)
    31  	node := &structs.Node{
    32  		Attributes: map[string]string{},
    33  	}
    34  	apply, err := d.Fingerprint(&config.Config{}, node)
    35  	if err != nil {
    36  		t.Fatalf("err: %v", err)
    37  	}
    38  	if !apply {
    39  		t.Fatalf("should apply by default")
    40  	}
    41  
    42  	apply, err = d.Fingerprint(&config.Config{Options: map[string]string{lxcConfigOption: "0"}}, node)
    43  	if err != nil {
    44  		t.Fatalf("err: %v", err)
    45  	}
    46  	if apply {
    47  		t.Fatalf("should not apply with config")
    48  	}
    49  	if node.Attributes["driver.lxc"] == "" {
    50  		t.Fatalf("missing driver")
    51  	}
    52  }
    53  
    54  func TestLxcDriver_Start_Wait(t *testing.T) {
    55  	if !lxcPresent(t) {
    56  		t.Skip("lxc not present")
    57  	}
    58  
    59  	task := &structs.Task{
    60  		Name: "foo",
    61  		Config: map[string]interface{}{
    62  			"template": "/usr/share/lxc/templates/lxc-busybox",
    63  		},
    64  		KillTimeout: 10 * time.Second,
    65  		Resources:   structs.DefaultResources(),
    66  	}
    67  
    68  	driverCtx, execCtx := testDriverContexts(task)
    69  	defer execCtx.AllocDir.Destroy()
    70  	d := NewLxcDriver(driverCtx)
    71  
    72  	handle, err := d.Start(execCtx, task)
    73  	if err != nil {
    74  		t.Fatalf("err: %v", err)
    75  	}
    76  	if handle == nil {
    77  		t.Fatalf("missing handle")
    78  	}
    79  
    80  	lxcHandle, _ := handle.(*lxcDriverHandle)
    81  
    82  	// Destroy the container after the test
    83  	defer func() {
    84  		lxcHandle.container.Stop()
    85  		lxcHandle.container.Destroy()
    86  	}()
    87  
    88  	testutil.WaitForResult(func() (bool, error) {
    89  		state := lxcHandle.container.State()
    90  		if state == lxc.RUNNING {
    91  			return true, nil
    92  		}
    93  		return false, fmt.Errorf("container in state: %v", state)
    94  	}, func(err error) {
    95  		t.Fatalf("err: %v", err)
    96  	})
    97  
    98  	// Look for mounted directories in their proper location
    99  	containerName := fmt.Sprintf("%s-%s", task.Name, execCtx.AllocID)
   100  	for _, mnt := range []string{"alloc", "local", "secret"} {
   101  		fullpath := filepath.Join(lxcHandle.lxcPath, containerName, "rootfs", mnt)
   102  		stat, err := os.Stat(fullpath)
   103  		if err != nil {
   104  			t.Fatalf("err %v", err)
   105  		}
   106  		if !stat.IsDir() {
   107  			t.Fatalf("expected %q to be a dir", fullpath)
   108  		}
   109  	}
   110  
   111  	// Desroy the container
   112  	if err := handle.Kill(); err != nil {
   113  		t.Fatalf("err: %v", err)
   114  	}
   115  
   116  	select {
   117  	case res := <-handle.WaitCh():
   118  		if !res.Successful() {
   119  			t.Fatalf("err: %v", res)
   120  		}
   121  	case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second):
   122  		t.Fatalf("timeout")
   123  	}
   124  }
   125  
   126  func TestLxcDriver_Open_Wait(t *testing.T) {
   127  	if !lxcPresent(t) {
   128  		t.Skip("lxc not present")
   129  	}
   130  
   131  	task := &structs.Task{
   132  		Name: "foo",
   133  		Config: map[string]interface{}{
   134  			"template": "/usr/share/lxc/templates/lxc-busybox",
   135  		},
   136  		KillTimeout: 10 * time.Second,
   137  		Resources:   structs.DefaultResources(),
   138  	}
   139  
   140  	driverCtx, execCtx := testDriverContexts(task)
   141  	defer execCtx.AllocDir.Destroy()
   142  	d := NewLxcDriver(driverCtx)
   143  
   144  	handle, err := d.Start(execCtx, task)
   145  	if err != nil {
   146  		t.Fatalf("err: %v", err)
   147  	}
   148  	if handle == nil {
   149  		t.Fatalf("missing handle")
   150  	}
   151  
   152  	// Destroy the container after the test
   153  	if lh, ok := handle.(*lxcDriverHandle); ok {
   154  		defer func() {
   155  			lh.container.Stop()
   156  			lh.container.Destroy()
   157  		}()
   158  	}
   159  
   160  	handle2, err := d.Open(execCtx, handle.ID())
   161  	if err != nil {
   162  		t.Fatalf("err: %v", err)
   163  	}
   164  
   165  	if handle2 == nil {
   166  		t.Fatalf("missing handle on open")
   167  	}
   168  
   169  	lxcHandle, _ := handle2.(*lxcDriverHandle)
   170  
   171  	testutil.WaitForResult(func() (bool, error) {
   172  		state := lxcHandle.container.State()
   173  		if state == lxc.RUNNING {
   174  			return true, nil
   175  		}
   176  		return false, fmt.Errorf("container in state: %v", state)
   177  	}, func(err error) {
   178  		t.Fatalf("err: %v", err)
   179  	})
   180  
   181  	// Desroy the container
   182  	if err := handle2.Kill(); err != nil {
   183  		t.Fatalf("err: %v", err)
   184  	}
   185  }
   186  
   187  func lxcPresent(t *testing.T) bool {
   188  	return lxc.Version() != ""
   189  }