open-nomad/client/driver/lxc_test.go

200 lines
4.2 KiB
Go
Raw Normal View History

//+build linux,lxc
2016-09-12 02:33:09 +00:00
package driver
import (
"fmt"
2016-10-13 19:45:33 +00:00
"os"
"path/filepath"
2016-09-12 02:33:09 +00:00
"testing"
"time"
"github.com/hashicorp/nomad/client/config"
"github.com/hashicorp/nomad/nomad/structs"
"github.com/hashicorp/nomad/testutil"
lxc "gopkg.in/lxc/go-lxc.v2"
)
func TestLxcDriver_Fingerprint(t *testing.T) {
2017-07-21 19:06:39 +00:00
t.Parallel()
2016-09-12 02:33:09 +00:00
if !lxcPresent(t) {
t.Skip("lxc not present")
}
task := &structs.Task{
Name: "foo",
Driver: "lxc",
2016-09-12 02:33:09 +00:00
Resources: structs.DefaultResources(),
}
ctx := testDriverContexts(t, task)
defer ctx.AllocDir.Destroy()
d := NewLxcDriver(ctx.DriverCtx)
2016-09-12 02:33:09 +00:00
node := &structs.Node{
Attributes: map[string]string{},
}
apply, err := d.Fingerprint(&config.Config{}, node)
if err != nil {
t.Fatalf("err: %v", err)
}
if !apply {
t.Fatalf("should apply by default")
2016-10-13 20:22:12 +00:00
}
apply, err = d.Fingerprint(&config.Config{Options: map[string]string{lxcConfigOption: "0"}}, node)
2016-10-13 20:22:12 +00:00
if err != nil {
t.Fatalf("err: %v", err)
}
2016-11-01 21:35:09 +00:00
if apply {
t.Fatalf("should not apply with config")
2016-09-12 02:33:09 +00:00
}
if node.Attributes["driver.lxc"] == "" {
t.Fatalf("missing driver")
}
}
func TestLxcDriver_Start_Wait(t *testing.T) {
2017-07-23 04:01:22 +00:00
if !testutil.IsTravis() {
t.Parallel()
}
2016-09-12 02:33:09 +00:00
if !lxcPresent(t) {
t.Skip("lxc not present")
}
task := &structs.Task{
Name: "foo",
Driver: "lxc",
2016-09-12 02:33:09 +00:00
Config: map[string]interface{}{
"template": "/usr/share/lxc/templates/lxc-busybox",
},
KillTimeout: 10 * time.Second,
Resources: structs.DefaultResources(),
}
ctx := testDriverContexts(t, task)
defer ctx.AllocDir.Destroy()
d := NewLxcDriver(ctx.DriverCtx)
2016-09-12 02:33:09 +00:00
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
2017-06-20 20:21:55 +00:00
sresp, err := d.Start(ctx.ExecCtx, task)
2016-09-12 02:33:09 +00:00
if err != nil {
t.Fatalf("err: %v", err)
}
2017-06-20 20:21:55 +00:00
lxcHandle, _ := sresp.Handle.(*lxcDriverHandle)
2016-09-12 02:33:09 +00:00
// Destroy the container after the test
defer func() {
lxcHandle.container.Stop()
lxcHandle.container.Destroy()
}()
testutil.WaitForResult(func() (bool, error) {
state := lxcHandle.container.State()
if state == lxc.RUNNING {
return true, nil
}
return false, fmt.Errorf("container in state: %v", state)
}, func(err error) {
t.Fatalf("err: %v", err)
})
2016-10-13 19:45:33 +00:00
// Look for mounted directories in their proper location
containerName := fmt.Sprintf("%s-%s", task.Name, ctx.DriverCtx.allocID)
for _, mnt := range []string{"alloc", "local", "secrets"} {
2016-10-13 19:45:33 +00:00
fullpath := filepath.Join(lxcHandle.lxcPath, containerName, "rootfs", mnt)
stat, err := os.Stat(fullpath)
if err != nil {
t.Fatalf("err %v", err)
}
if !stat.IsDir() {
t.Fatalf("expected %q to be a dir", fullpath)
}
}
2016-09-12 02:33:09 +00:00
// Desroy the container
2017-06-20 20:21:55 +00:00
if err := sresp.Handle.Kill(); err != nil {
2016-09-12 02:33:09 +00:00
t.Fatalf("err: %v", err)
}
select {
2017-06-20 20:21:55 +00:00
case res := <-sresp.Handle.WaitCh():
2016-09-12 02:33:09 +00:00
if !res.Successful() {
t.Fatalf("err: %v", res)
}
case <-time.After(time.Duration(testutil.TestMultiplier()*5) * time.Second):
t.Fatalf("timeout")
}
}
func TestLxcDriver_Open_Wait(t *testing.T) {
2017-07-23 04:01:22 +00:00
if !testutil.IsTravis() {
t.Parallel()
}
2016-09-12 02:33:09 +00:00
if !lxcPresent(t) {
t.Skip("lxc not present")
}
task := &structs.Task{
Name: "foo",
Driver: "lxc",
2016-09-12 02:33:09 +00:00
Config: map[string]interface{}{
"template": "/usr/share/lxc/templates/lxc-busybox",
},
KillTimeout: 10 * time.Second,
Resources: structs.DefaultResources(),
}
ctx := testDriverContexts(t, task)
defer ctx.AllocDir.Destroy()
d := NewLxcDriver(ctx.DriverCtx)
2016-09-12 02:33:09 +00:00
if _, err := d.Prestart(ctx.ExecCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
2017-06-20 20:21:55 +00:00
sresp, err := d.Start(ctx.ExecCtx, task)
2016-09-12 02:33:09 +00:00
if err != nil {
t.Fatalf("err: %v", err)
}
// Destroy the container after the test
2017-06-20 20:21:55 +00:00
lh := sresp.Handle.(*lxcDriverHandle)
defer func() {
lh.container.Stop()
lh.container.Destroy()
}()
2016-09-12 02:33:09 +00:00
2017-06-20 20:21:55 +00:00
handle2, err := d.Open(ctx.ExecCtx, lh.ID())
2016-09-12 02:33:09 +00:00
if err != nil {
t.Fatalf("err: %v", err)
}
if handle2 == nil {
t.Fatalf("missing handle on open")
}
lxcHandle, _ := handle2.(*lxcDriverHandle)
testutil.WaitForResult(func() (bool, error) {
state := lxcHandle.container.State()
if state == lxc.RUNNING {
return true, nil
}
return false, fmt.Errorf("container in state: %v", state)
}, func(err error) {
t.Fatalf("err: %v", err)
})
// Desroy the container
if err := handle2.Kill(); err != nil {
t.Fatalf("err: %v", err)
}
}
func lxcPresent(t *testing.T) bool {
return lxc.Version() != ""
}