2017-11-20 20:43:56 +00:00
|
|
|
package libpod
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"io/ioutil"
|
2018-01-15 16:21:30 +00:00
|
|
|
"net"
|
2017-11-20 20:43:56 +00:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"reflect"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
2017-11-29 19:37:35 +00:00
|
|
|
"github.com/containers/storage"
|
2018-01-15 16:21:30 +00:00
|
|
|
"github.com/cri-o/ocicni/pkg/ocicni"
|
2017-11-20 20:43:56 +00:00
|
|
|
"github.com/opencontainers/runtime-tools/generate"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
)
|
|
|
|
|
2017-11-24 18:39:29 +00:00
|
|
|
func getTestContainer(id, name, locksDir string) (*Container, error) {
|
2017-11-20 20:43:56 +00:00
|
|
|
ctr := &Container{
|
2017-11-22 17:21:53 +00:00
|
|
|
config: &ContainerConfig{
|
2017-11-20 20:43:56 +00:00
|
|
|
ID: id,
|
|
|
|
Name: name,
|
|
|
|
RootfsImageID: id,
|
|
|
|
RootfsImageName: "testimg",
|
2018-01-10 18:49:38 +00:00
|
|
|
ImageVolumes: true,
|
|
|
|
ReadOnly: true,
|
2017-11-20 20:43:56 +00:00
|
|
|
StaticDir: "/does/not/exist/",
|
|
|
|
Stdin: true,
|
|
|
|
Labels: make(map[string]string),
|
|
|
|
StopSignal: 0,
|
2017-12-19 20:42:30 +00:00
|
|
|
StopTimeout: 0,
|
2017-11-20 20:43:56 +00:00
|
|
|
CreatedTime: time.Now(),
|
2018-01-15 16:21:30 +00:00
|
|
|
Privileged: true,
|
|
|
|
Mounts: []string{"/does/not/exist"},
|
|
|
|
DNSServer: []net.IP{net.ParseIP("192.168.1.1"), net.ParseIP("192.168.2.2")},
|
|
|
|
DNSSearch: []string{"example.com", "example.example.com"},
|
|
|
|
PortMappings: []ocicni.PortMapping{
|
|
|
|
{
|
|
|
|
HostPort: 80,
|
|
|
|
ContainerPort: 90,
|
|
|
|
Protocol: "tcp",
|
|
|
|
HostIP: "192.168.3.3",
|
|
|
|
},
|
|
|
|
{
|
|
|
|
HostPort: 100,
|
|
|
|
ContainerPort: 110,
|
|
|
|
Protocol: "udp",
|
|
|
|
HostIP: "192.168.4.4",
|
|
|
|
},
|
|
|
|
},
|
2017-11-20 20:43:56 +00:00
|
|
|
},
|
|
|
|
state: &containerRuntimeInfo{
|
|
|
|
State: ContainerStateRunning,
|
|
|
|
ConfigPath: "/does/not/exist/specs/" + id,
|
|
|
|
RunDir: "/does/not/exist/tmp/",
|
|
|
|
Mounted: true,
|
|
|
|
Mountpoint: "/does/not/exist/tmp/" + id,
|
2017-11-21 18:58:53 +00:00
|
|
|
PID: 1234,
|
2017-11-20 20:43:56 +00:00
|
|
|
},
|
|
|
|
valid: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
g := generate.New()
|
|
|
|
ctr.config.Spec = g.Spec()
|
|
|
|
|
|
|
|
ctr.config.Labels["test"] = "testing"
|
|
|
|
|
2017-11-24 18:39:29 +00:00
|
|
|
// Must make lockfile or container will error on being retrieved from DB
|
|
|
|
lockPath := filepath.Join(locksDir, id)
|
|
|
|
lock, err := storage.GetLockfile(lockPath)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
ctr.lock = lock
|
|
|
|
|
|
|
|
return ctr, nil
|
2017-11-20 20:43:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// This horrible hack tests if containers are equal in a way that should handle
|
|
|
|
// empty arrays being dropped to nil pointers in the spec JSON
|
|
|
|
func testContainersEqual(a, b *Container) bool {
|
|
|
|
if a == nil && b == nil {
|
|
|
|
return true
|
|
|
|
} else if a == nil || b == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
if a.valid != b.valid {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
aConfigJSON, err := json.Marshal(a.config)
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
bConfigJSON, err := json.Marshal(b.config)
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(aConfigJSON, bConfigJSON) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
aStateJSON, err := json.Marshal(a.state)
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
bStateJSON, err := json.Marshal(b.state)
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return reflect.DeepEqual(aStateJSON, bStateJSON)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get an empty state for use in tests
|
|
|
|
// An empty Runtime is provided
|
2017-11-27 19:07:41 +00:00
|
|
|
func getEmptyState() (s State, p string, p2 string, err error) {
|
2017-11-20 20:43:56 +00:00
|
|
|
tmpDir, err := ioutil.TempDir("", "libpod_state_test_")
|
|
|
|
if err != nil {
|
2017-11-27 19:07:41 +00:00
|
|
|
return nil, "", "", err
|
2017-11-20 20:43:56 +00:00
|
|
|
}
|
|
|
|
defer func() {
|
|
|
|
if err != nil {
|
|
|
|
os.RemoveAll(tmpDir)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
dbPath := filepath.Join(tmpDir, "db.sql")
|
2017-11-27 19:07:41 +00:00
|
|
|
specsDir := filepath.Join(tmpDir, "specs")
|
|
|
|
lockDir := filepath.Join(tmpDir, "locks")
|
2017-11-20 20:43:56 +00:00
|
|
|
|
2017-11-29 19:37:35 +00:00
|
|
|
runtime := new(Runtime)
|
|
|
|
runtime.config = new(RuntimeConfig)
|
|
|
|
runtime.config.StorageConfig = storage.StoreOptions{}
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
state, err := NewSQLState(dbPath, specsDir, lockDir, runtime)
|
2017-11-20 20:43:56 +00:00
|
|
|
if err != nil {
|
2017-11-27 19:07:41 +00:00
|
|
|
return nil, "", "", err
|
2017-11-20 20:43:56 +00:00
|
|
|
}
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
return state, tmpDir, lockDir, nil
|
2017-11-20 20:43:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestAddAndGetContainer(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr, err := getTestContainer("0123456789ABCDEF0123456789ABCDEF", "test", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.AddContainer(testCtr)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
retrievedCtr, err := state.Container(testCtr.ID())
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
// Use assert.EqualValues if the test fails to pretty print diff
|
|
|
|
// between actual and expected
|
|
|
|
if !testContainersEqual(testCtr, retrievedCtr) {
|
|
|
|
assert.EqualValues(t, testCtr, retrievedCtr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAddAndGetContainerFromMultiple(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr1, err := getTestContainer("11111111111111111111111111111111", "test1", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr2, err := getTestContainer("22222222222222222222222222222222", "test2", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.AddContainer(testCtr1)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = state.AddContainer(testCtr2)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
retrievedCtr, err := state.Container(testCtr1.ID())
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
// Use assert.EqualValues if the test fails to pretty print diff
|
|
|
|
// between actual and expected
|
|
|
|
if !testContainersEqual(testCtr1, retrievedCtr) {
|
|
|
|
assert.EqualValues(t, testCtr1, retrievedCtr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAddInvalidContainerFails(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, _, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
|
|
|
err = state.AddContainer(&Container{})
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAddDuplicateIDFails(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr1, err := getTestContainer("11111111111111111111111111111111", "test1", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr2, err := getTestContainer(testCtr1.ID(), "test2", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.AddContainer(testCtr1)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = state.AddContainer(testCtr2)
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAddDuplicateNameFails(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr1, err := getTestContainer("11111111111111111111111111111111", "test1", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr2, err := getTestContainer("22222222222222222222222222222222", testCtr1.Name(), lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.AddContainer(testCtr1)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = state.AddContainer(testCtr2)
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetNonexistantContainerFails(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, _, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
|
|
|
_, err = state.Container("does not exist")
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetContainerWithEmptyIDFails(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, _, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
|
|
|
_, err = state.Container("")
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLookupContainerWithEmptyIDFails(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, _, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
|
|
|
_, err = state.LookupContainer("")
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLookupNonexistantContainerFails(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, _, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
|
|
|
|
_, err = state.LookupContainer("does not exist")
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLookupContainerByFullID(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr, err := getTestContainer("0123456789ABCDEF0123456789ABCDEF", "test", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.AddContainer(testCtr)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
retrievedCtr, err := state.LookupContainer(testCtr.ID())
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
// Use assert.EqualValues if the test fails to pretty print diff
|
|
|
|
// between actual and expected
|
|
|
|
if !testContainersEqual(testCtr, retrievedCtr) {
|
|
|
|
assert.EqualValues(t, testCtr, retrievedCtr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLookupContainerByUniquePartialID(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr, err := getTestContainer("0123456789ABCDEF0123456789ABCDEF", "test", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.AddContainer(testCtr)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
retrievedCtr, err := state.LookupContainer(testCtr.ID()[0:8])
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
// Use assert.EqualValues if the test fails to pretty print diff
|
|
|
|
// between actual and expected
|
|
|
|
if !testContainersEqual(testCtr, retrievedCtr) {
|
|
|
|
assert.EqualValues(t, testCtr, retrievedCtr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLookupContainerByNonUniquePartialIDFails(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr1, err := getTestContainer("00000000000000000000000000000000", "test1", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr2, err := getTestContainer("00000000000000000000000000000001", "test2", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.AddContainer(testCtr1)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = state.AddContainer(testCtr2)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
_, err = state.LookupContainer(testCtr1.ID()[0:8])
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLookupContainerByName(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr, err := getTestContainer("0123456789ABCDEF0123456789ABCDEF", "test", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.AddContainer(testCtr)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
retrievedCtr, err := state.LookupContainer(testCtr.Name())
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
// Use assert.EqualValues if the test fails to pretty print diff
|
|
|
|
// between actual and expected
|
|
|
|
if !testContainersEqual(testCtr, retrievedCtr) {
|
|
|
|
assert.EqualValues(t, testCtr, retrievedCtr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestHasContainerEmptyIDFails(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, _, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
|
|
|
_, err = state.HasContainer("")
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestHasContainerNoSuchContainerReturnsFalse(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, _, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
|
|
|
exists, err := state.HasContainer("does not exist")
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.False(t, exists)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestHasContainerFindsContainer(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr, err := getTestContainer("0123456789ABCDEF0123456789ABCDEF", "test", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.AddContainer(testCtr)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
exists, err := state.HasContainer(testCtr.ID())
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.True(t, exists)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSaveAndUpdateContainer(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr, err := getTestContainer("0123456789ABCDEF0123456789ABCDEF", "test", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.AddContainer(testCtr)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
retrievedCtr, err := state.Container(testCtr.ID())
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
retrievedCtr.state.State = ContainerStateStopped
|
|
|
|
retrievedCtr.state.ExitCode = 127
|
|
|
|
retrievedCtr.state.FinishedTime = time.Now()
|
|
|
|
|
|
|
|
err = state.SaveContainer(retrievedCtr)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = state.UpdateContainer(testCtr)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
// Use assert.EqualValues if the test fails to pretty print diff
|
|
|
|
// between actual and expected
|
|
|
|
if !testContainersEqual(testCtr, retrievedCtr) {
|
|
|
|
assert.EqualValues(t, testCtr, retrievedCtr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUpdateContainerNotInDatabaseReturnsError(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr, err := getTestContainer("0123456789ABCDEF0123456789ABCDEF", "test", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.UpdateContainer(testCtr)
|
|
|
|
assert.Error(t, err)
|
|
|
|
assert.False(t, testCtr.valid)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestUpdateInvalidContainerReturnsError(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, _, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
|
|
|
err = state.UpdateContainer(&Container{})
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSaveInvalidContainerReturnsError(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, _, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
|
|
|
err = state.SaveContainer(&Container{})
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSaveContainerNotInStateReturnsError(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr, err := getTestContainer("0123456789ABCDEF0123456789ABCDEF", "test", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.SaveContainer(testCtr)
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRemoveContainer(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr, err := getTestContainer("0123456789ABCDEF0123456789ABCDEF", "test", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.AddContainer(testCtr)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
ctrs, err := state.AllContainers()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, 1, len(ctrs))
|
|
|
|
|
|
|
|
err = state.RemoveContainer(testCtr)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
ctrs2, err := state.AllContainers()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, 0, len(ctrs2))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRemoveNonexistantContainerFails(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr, err := getTestContainer("0123456789ABCDEF0123456789ABCDEF", "test", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.RemoveContainer(testCtr)
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetAllContainersOnNewStateIsEmpty(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, _, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
|
|
|
ctrs, err := state.AllContainers()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, 0, len(ctrs))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetAllContainersWithOneContainer(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr, err := getTestContainer("0123456789ABCDEF0123456789ABCDEF", "test", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.AddContainer(testCtr)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
ctrs, err := state.AllContainers()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, 1, len(ctrs))
|
|
|
|
|
|
|
|
// Use assert.EqualValues if the test fails to pretty print diff
|
|
|
|
// between actual and expected
|
|
|
|
if !testContainersEqual(testCtr, ctrs[0]) {
|
|
|
|
assert.EqualValues(t, testCtr, ctrs[0])
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestGetAllContainersTwoContainers(t *testing.T) {
|
2017-11-27 19:07:41 +00:00
|
|
|
state, path, lockPath, err := getEmptyState()
|
2017-11-20 20:43:56 +00:00
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr1, err := getTestContainer("11111111111111111111111111111111", "test1", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-27 19:07:41 +00:00
|
|
|
testCtr2, err := getTestContainer("22222222222222222222222222222222", "test2", lockPath)
|
2017-11-24 18:39:29 +00:00
|
|
|
assert.NoError(t, err)
|
2017-11-20 20:43:56 +00:00
|
|
|
|
|
|
|
err = state.AddContainer(testCtr1)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = state.AddContainer(testCtr2)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
ctrs, err := state.AllContainers()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, 2, len(ctrs))
|
2017-11-22 17:21:53 +00:00
|
|
|
|
|
|
|
// Containers should be ordered by creation time
|
|
|
|
|
|
|
|
// Use assert.EqualValues if the test fails to pretty print diff
|
|
|
|
// between actual and expected
|
|
|
|
if !testContainersEqual(testCtr2, ctrs[0]) {
|
|
|
|
assert.EqualValues(t, testCtr2, ctrs[0])
|
|
|
|
}
|
|
|
|
if !testContainersEqual(testCtr1, ctrs[1]) {
|
|
|
|
assert.EqualValues(t, testCtr1, ctrs[1])
|
|
|
|
}
|
2017-11-20 20:43:56 +00:00
|
|
|
}
|
2018-01-12 17:41:10 +00:00
|
|
|
|
|
|
|
func TestContainerInUseInvalidContainer(t *testing.T) {
|
|
|
|
state, path, _, err := getEmptyState()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
|
|
|
_, err = state.ContainerInUse(&Container{})
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestContainerInUseOneContainer(t *testing.T) {
|
|
|
|
state, path, lockPath, err := getEmptyState()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
|
|
|
testCtr1, err := getTestContainer("11111111111111111111111111111111", "test1", lockPath)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
testCtr2, err := getTestContainer("22222222222222222222222222222222", "test2", lockPath)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
testCtr2.config.UserNsCtr = testCtr1.config.ID
|
|
|
|
|
|
|
|
err = state.AddContainer(testCtr1)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = state.AddContainer(testCtr2)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
ids, err := state.ContainerInUse(testCtr1)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, 1, len(ids))
|
|
|
|
assert.Equal(t, testCtr2.config.ID, ids[0])
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestContainerInUseTwoContainers(t *testing.T) {
|
|
|
|
state, path, lockPath, err := getEmptyState()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
|
|
|
testCtr1, err := getTestContainer("11111111111111111111111111111111", "test1", lockPath)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
testCtr2, err := getTestContainer("22222222222222222222222222222222", "test2", lockPath)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
testCtr3, err := getTestContainer("33333333333333333333333333333333", "test3", lockPath)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
testCtr2.config.UserNsCtr = testCtr1.config.ID
|
|
|
|
testCtr3.config.IPCNsCtr = testCtr1.config.ID
|
|
|
|
|
|
|
|
err = state.AddContainer(testCtr1)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = state.AddContainer(testCtr2)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = state.AddContainer(testCtr3)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
ids, err := state.ContainerInUse(testCtr1)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
assert.Equal(t, 2, len(ids))
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCannotRemoveContainerWithDependency(t *testing.T) {
|
|
|
|
state, path, lockPath, err := getEmptyState()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
|
|
|
testCtr1, err := getTestContainer("11111111111111111111111111111111", "test1", lockPath)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
testCtr2, err := getTestContainer("22222222222222222222222222222222", "test2", lockPath)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
testCtr2.config.UserNsCtr = testCtr1.config.ID
|
|
|
|
|
|
|
|
err = state.AddContainer(testCtr1)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = state.AddContainer(testCtr2)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = state.RemoveContainer(testCtr1)
|
|
|
|
assert.Error(t, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCanRemoveContainerAfterDependencyRemoved(t *testing.T) {
|
|
|
|
state, path, lockPath, err := getEmptyState()
|
|
|
|
assert.NoError(t, err)
|
|
|
|
defer os.RemoveAll(path)
|
|
|
|
defer state.Close()
|
|
|
|
|
|
|
|
testCtr1, err := getTestContainer("11111111111111111111111111111111", "test1", lockPath)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
testCtr2, err := getTestContainer("22222222222222222222222222222222", "test2", lockPath)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
testCtr2.config.UserNsCtr = testCtr1.config.ID
|
|
|
|
|
|
|
|
err = state.AddContainer(testCtr1)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = state.AddContainer(testCtr2)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = state.RemoveContainer(testCtr2)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
|
|
|
|
err = state.RemoveContainer(testCtr1)
|
|
|
|
assert.NoError(t, err)
|
|
|
|
}
|