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 }