open-nomad/client/driver/lxc_test.go

196 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) {
if !lxcPresent(t) {
t.Skip("lxc not present")
}
task := &structs.Task{
Name: "foo",
Resources: structs.DefaultResources(),
}
driverCtx, execCtx := testDriverContexts(task)
defer execCtx.AllocDir.Destroy()
d := NewLxcDriver(driverCtx)
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) {
if !lxcPresent(t) {
t.Skip("lxc not present")
}
task := &structs.Task{
Name: "foo",
Config: map[string]interface{}{
"template": "/usr/share/lxc/templates/lxc-busybox",
},
KillTimeout: 10 * time.Second,
Resources: structs.DefaultResources(),
}
driverCtx, execCtx := testDriverContexts(task)
defer execCtx.AllocDir.Destroy()
d := NewLxcDriver(driverCtx)
if err := d.Prestart(execCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
2016-09-12 02:33:09 +00:00
handle, err := d.Start(execCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
lxcHandle, _ := handle.(*lxcDriverHandle)
// 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, execCtx.AllocID)
for _, mnt := range []string{"alloc", "local", "secret"} {
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
if err := handle.Kill(); err != nil {
t.Fatalf("err: %v", err)
}
select {
case res := <-handle.WaitCh():
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) {
if !lxcPresent(t) {
t.Skip("lxc not present")
}
task := &structs.Task{
Name: "foo",
Config: map[string]interface{}{
"template": "/usr/share/lxc/templates/lxc-busybox",
},
KillTimeout: 10 * time.Second,
Resources: structs.DefaultResources(),
}
driverCtx, execCtx := testDriverContexts(task)
defer execCtx.AllocDir.Destroy()
d := NewLxcDriver(driverCtx)
if err := d.Prestart(execCtx, task); err != nil {
t.Fatalf("prestart err: %v", err)
}
2016-09-12 02:33:09 +00:00
handle, err := d.Start(execCtx, task)
if err != nil {
t.Fatalf("err: %v", err)
}
if handle == nil {
t.Fatalf("missing handle")
}
// Destroy the container after the test
if lh, ok := handle.(*lxcDriverHandle); ok {
defer func() {
lh.container.Stop()
lh.container.Destroy()
}()
}
handle2, err := d.Open(execCtx, handle.ID())
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() != ""
}