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