cli: Optimize container research

This commit will allow for better performance regarding the time spent
to retrieve the sandbox ID related to a container ID.

The way it works is by relying on a specific mapping between container
IDs and sanbox IDs, meaning it allows to retrieve directly the sandbox
ID related to a container ID from the CLI. This lowers complexity from
O(n²) to O(1), because we don't need to call into ListPod() which was
parsing all the pods and all the containers on the system everytime
the CLI need to retrieve this mapping.

This commit also updates the whole unit tests as a consequence. This
is involving most of them since they were all relying on ListPod()
before.

Fixes #212

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf
2018-04-20 12:26:02 -07:00
parent f92d7dd1c1
commit e6f066b828
14 changed files with 837 additions and 695 deletions

View File

@@ -7,6 +7,8 @@ package main
import (
"flag"
"io/ioutil"
"os"
"testing"
vc "github.com/kata-containers/runtime/virtcontainers"
@@ -24,20 +26,21 @@ func TestStartInvalidArgs(t *testing.T) {
assert.Error(err)
assert.False(vcmock.IsMockError(err))
// Mock Listsandbox error
path, err := createTempContainerIDMapping(testContainerID, testSandboxID)
assert.NoError(err)
defer os.RemoveAll(path)
// Mock StatusContainer error
_, err = start(testContainerID)
assert.Error(err)
assert.True(vcmock.IsMockError(err))
testingImpl.ListSandboxFunc = func() ([]vc.SandboxStatus, error) {
return []vc.SandboxStatus{}, nil
}
path, err = ioutil.TempDir("", "containers-mapping")
assert.NoError(err)
defer os.RemoveAll(path)
ctrsMapTreePath = path
defer func() {
testingImpl.ListSandboxFunc = nil
}()
// Container missing in ListSandbox
// Container missing in container mapping
_, err = start(testContainerID)
assert.Error(err)
assert.False(vcmock.IsMockError(err))
@@ -50,27 +53,24 @@ func TestStartSandbox(t *testing.T) {
MockID: testSandboxID,
}
testingImpl.ListSandboxFunc = func() ([]vc.SandboxStatus, error) {
return []vc.SandboxStatus{
{
ID: sandbox.ID(),
ContainersStatus: []vc.ContainerStatus{
{
ID: sandbox.ID(),
Annotations: map[string]string{
vcAnnotations.ContainerTypeKey: string(vc.PodSandbox),
},
},
},
path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID())
assert.NoError(err)
defer os.RemoveAll(path)
testingImpl.StatusContainerFunc = func(sandboxID, containerID string) (vc.ContainerStatus, error) {
return vc.ContainerStatus{
ID: sandbox.ID(),
Annotations: map[string]string{
vcAnnotations.ContainerTypeKey: string(vc.PodSandbox),
},
}, nil
}
defer func() {
testingImpl.ListSandboxFunc = nil
testingImpl.StatusContainerFunc = nil
}()
_, err := start(sandbox.ID())
_, err = start(sandbox.ID())
assert.Error(err)
assert.True(vcmock.IsMockError(err))
@@ -93,25 +93,22 @@ func TestStartMissingAnnotation(t *testing.T) {
MockID: testSandboxID,
}
testingImpl.ListSandboxFunc = func() ([]vc.SandboxStatus, error) {
return []vc.SandboxStatus{
{
ID: sandbox.ID(),
ContainersStatus: []vc.ContainerStatus{
{
ID: sandbox.ID(),
Annotations: map[string]string{},
},
},
},
path, err := createTempContainerIDMapping(sandbox.ID(), sandbox.ID())
assert.NoError(err)
defer os.RemoveAll(path)
testingImpl.StatusContainerFunc = func(sandboxID, containerID string) (vc.ContainerStatus, error) {
return vc.ContainerStatus{
ID: sandbox.ID(),
Annotations: map[string]string{},
}, nil
}
defer func() {
testingImpl.ListSandboxFunc = nil
testingImpl.StatusContainerFunc = nil
}()
_, err := start(sandbox.ID())
_, err = start(sandbox.ID())
assert.Error(err)
assert.False(vcmock.IsMockError(err))
}
@@ -130,27 +127,24 @@ func TestStartContainerSucessFailure(t *testing.T) {
},
}
testingImpl.ListSandboxFunc = func() ([]vc.SandboxStatus, error) {
return []vc.SandboxStatus{
{
ID: sandbox.ID(),
ContainersStatus: []vc.ContainerStatus{
{
ID: testContainerID,
Annotations: map[string]string{
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
},
},
},
path, err := createTempContainerIDMapping(testContainerID, sandbox.ID())
assert.NoError(err)
defer os.RemoveAll(path)
testingImpl.StatusContainerFunc = func(sandboxID, containerID string) (vc.ContainerStatus, error) {
return vc.ContainerStatus{
ID: testContainerID,
Annotations: map[string]string{
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
},
}, nil
}
defer func() {
testingImpl.ListSandboxFunc = nil
testingImpl.StatusContainerFunc = nil
}()
_, err := start(testContainerID)
_, err = start(testContainerID)
assert.Error(err)
assert.True(vcmock.IsMockError(err))
@@ -182,6 +176,10 @@ func TestStartCLIFunction(t *testing.T) {
assert.Error(err)
assert.False(vcmock.IsMockError(err))
path, err := createTempContainerIDMapping("xyz", "xyz")
assert.NoError(err)
defer os.RemoveAll(path)
flagSet = flag.NewFlagSet("container-id", flag.ContinueOnError)
flagSet.Parse([]string{"xyz"})
ctx = cli.NewContext(app, flagSet, nil)
@@ -205,18 +203,15 @@ func TestStartCLIFunctionSuccess(t *testing.T) {
},
}
testingImpl.ListSandboxFunc = func() ([]vc.SandboxStatus, error) {
return []vc.SandboxStatus{
{
ID: sandbox.ID(),
ContainersStatus: []vc.ContainerStatus{
{
ID: testContainerID,
Annotations: map[string]string{
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
},
},
},
path, err := createTempContainerIDMapping(testContainerID, testSandboxID)
assert.NoError(err)
defer os.RemoveAll(path)
testingImpl.StatusContainerFunc = func(sandboxID, containerID string) (vc.ContainerStatus, error) {
return vc.ContainerStatus{
ID: testContainerID,
Annotations: map[string]string{
vcAnnotations.ContainerTypeKey: string(vc.PodContainer),
},
}, nil
}
@@ -226,7 +221,7 @@ func TestStartCLIFunctionSuccess(t *testing.T) {
}
defer func() {
testingImpl.ListSandboxFunc = nil
testingImpl.StatusContainerFunc = nil
testingImpl.StartContainerFunc = nil
}()
@@ -240,6 +235,6 @@ func TestStartCLIFunctionSuccess(t *testing.T) {
ctx := cli.NewContext(app, flagSet, nil)
assert.NotNil(ctx)
err := fn(ctx)
err = fn(ctx)
assert.NoError(err)
}