Merge pull request #397 from yanxuean/trunc-for-list

Add truncindex for filter in List and Stat
This commit is contained in:
Lantao Liu 2017-11-07 00:41:03 -08:00 committed by GitHub
commit affc6e93a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 222 additions and 41 deletions

View File

@ -283,7 +283,30 @@ func TestContainerListStatsWithIdSandboxIdFilter(t *testing.T) {
return false, err return false, err
} }
if len(stats) != 1 { if len(stats) != 1 {
return false, fmt.Errorf("Unexpected stats length") return false, fmt.Errorf("unexpected stats length")
}
if stats[0].GetWritableLayer().GetUsedBytes().GetValue() != 0 &&
stats[0].GetWritableLayer().GetInodesUsed().GetValue() != 0 {
return true, nil
}
return false, nil
}, time.Second, 30*time.Second))
t.Logf("Verify container stats for sandbox %q and container %q filter", sb, id)
for _, s := range stats {
testStats(t, s, config)
}
}
t.Logf("Fetch container stats for sandbox truncID and container truncID filter ")
for id, config := range containerConfigMap {
require.NoError(t, Eventually(func() (bool, error) {
stats, err = runtimeService.ListContainerStats(
&runtime.ContainerStatsFilter{Id: id[:3], PodSandboxId: sb[:3]})
if err != nil {
return false, err
}
if len(stats) != 1 {
return false, fmt.Errorf("unexpected stats length")
} }
if stats[0].GetWritableLayer().GetUsedBytes().GetValue() != 0 && if stats[0].GetWritableLayer().GetUsedBytes().GetValue() != 0 &&
stats[0].GetWritableLayer().GetInodesUsed().GetValue() != 0 { stats[0].GetWritableLayer().GetInodesUsed().GetValue() != 0 {

View File

@ -54,12 +54,22 @@ func toCRIContainer(container containerstore.Container) *runtime.Container {
} }
} }
func (c *criContainerdService) normalizeContainerFilter(filter *runtime.ContainerFilter) {
if cntr, err := c.containerStore.Get(filter.GetId()); err == nil {
filter.Id = cntr.ID
}
if sb, err := c.sandboxStore.Get(filter.GetPodSandboxId()); err == nil {
filter.PodSandboxId = sb.ID
}
}
// filterCRIContainers filters CRIContainers. // filterCRIContainers filters CRIContainers.
func (c *criContainerdService) filterCRIContainers(containers []*runtime.Container, filter *runtime.ContainerFilter) []*runtime.Container { func (c *criContainerdService) filterCRIContainers(containers []*runtime.Container, filter *runtime.ContainerFilter) []*runtime.Container {
if filter == nil { if filter == nil {
return containers return containers
} }
c.normalizeContainerFilter(filter)
filtered := []*runtime.Container{} filtered := []*runtime.Container{}
for _, cntr := range containers { for _, cntr := range containers {
if filter.GetId() != "" && filter.GetId() != cntr.Id { if filter.GetId() != "" && filter.GetId() != cntr.Id {

View File

@ -26,6 +26,7 @@ import (
"k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime" "k8s.io/kubernetes/pkg/kubelet/apis/cri/v1alpha1/runtime"
containerstore "github.com/kubernetes-incubator/cri-containerd/pkg/store/container" containerstore "github.com/kubernetes-incubator/cri-containerd/pkg/store/container"
sandboxstore "github.com/kubernetes-incubator/cri-containerd/pkg/store/sandbox"
) )
func TestToCRIContainer(t *testing.T) { func TestToCRIContainer(t *testing.T) {
@ -168,25 +169,40 @@ func (c containerForTest) toContainer() (containerstore.Container, error) {
func TestListContainers(t *testing.T) { func TestListContainers(t *testing.T) {
c := newTestCRIContainerdService() c := newTestCRIContainerdService()
sandboxesInStore := []sandboxstore.Sandbox{
{
Metadata: sandboxstore.Metadata{
ID: "s-1abcdef1234",
Name: "sandboxname-1",
Config: &runtime.PodSandboxConfig{Metadata: &runtime.PodSandboxMetadata{Name: "podname-1"}},
},
},
{
Metadata: sandboxstore.Metadata{
ID: "s-2abcdef1234",
Name: "sandboxname-2",
Config: &runtime.PodSandboxConfig{Metadata: &runtime.PodSandboxMetadata{Name: "podname-2"}},
},
},
}
createdAt := time.Now().UnixNano() createdAt := time.Now().UnixNano()
startedAt := time.Now().UnixNano() startedAt := time.Now().UnixNano()
finishedAt := time.Now().UnixNano() finishedAt := time.Now().UnixNano()
containersInStore := []containerForTest{ containersInStore := []containerForTest{
{ {
metadata: containerstore.Metadata{ metadata: containerstore.Metadata{
ID: "1", ID: "c-1container",
Name: "name-1", Name: "name-1",
SandboxID: "s-1", SandboxID: "s-1abcdef1234",
Config: &runtime.ContainerConfig{Metadata: &runtime.ContainerMetadata{Name: "name-1"}}, Config: &runtime.ContainerConfig{Metadata: &runtime.ContainerMetadata{Name: "name-1"}},
}, },
status: containerstore.Status{CreatedAt: createdAt}, status: containerstore.Status{CreatedAt: createdAt},
}, },
{ {
metadata: containerstore.Metadata{ metadata: containerstore.Metadata{
ID: "2", ID: "c-2container",
Name: "name-2", Name: "name-2",
SandboxID: "s-1", SandboxID: "s-1abcdef1234",
Config: &runtime.ContainerConfig{Metadata: &runtime.ContainerMetadata{Name: "name-2"}}, Config: &runtime.ContainerConfig{Metadata: &runtime.ContainerMetadata{Name: "name-2"}},
}, },
status: containerstore.Status{ status: containerstore.Status{
@ -196,9 +212,9 @@ func TestListContainers(t *testing.T) {
}, },
{ {
metadata: containerstore.Metadata{ metadata: containerstore.Metadata{
ID: "3", ID: "c-3container",
Name: "name-3", Name: "name-3",
SandboxID: "s-1", SandboxID: "s-1abcdef1234",
Config: &runtime.ContainerConfig{Metadata: &runtime.ContainerMetadata{Name: "name-3"}}, Config: &runtime.ContainerConfig{Metadata: &runtime.ContainerMetadata{Name: "name-3"}},
}, },
status: containerstore.Status{ status: containerstore.Status{
@ -209,9 +225,9 @@ func TestListContainers(t *testing.T) {
}, },
{ {
metadata: containerstore.Metadata{ metadata: containerstore.Metadata{
ID: "4", ID: "c-4container",
Name: "name-4", Name: "name-4",
SandboxID: "s-2", SandboxID: "s-2abcdef1234",
Config: &runtime.ContainerConfig{Metadata: &runtime.ContainerMetadata{Name: "name-4"}}, Config: &runtime.ContainerConfig{Metadata: &runtime.ContainerMetadata{Name: "name-4"}},
}, },
status: containerstore.Status{ status: containerstore.Status{
@ -219,46 +235,105 @@ func TestListContainers(t *testing.T) {
}, },
}, },
} }
filter := &runtime.ContainerFilter{
PodSandboxId: "s-1", expectedContainers := []*runtime.Container{
}
expect := []*runtime.Container{
{ {
Id: "1", Id: "c-1container",
PodSandboxId: "s-1", PodSandboxId: "s-1abcdef1234",
Metadata: &runtime.ContainerMetadata{Name: "name-1"}, Metadata: &runtime.ContainerMetadata{Name: "name-1"},
State: runtime.ContainerState_CONTAINER_CREATED, State: runtime.ContainerState_CONTAINER_CREATED,
CreatedAt: createdAt, CreatedAt: createdAt,
}, },
{ {
Id: "2", Id: "c-2container",
PodSandboxId: "s-1", PodSandboxId: "s-1abcdef1234",
Metadata: &runtime.ContainerMetadata{Name: "name-2"}, Metadata: &runtime.ContainerMetadata{Name: "name-2"},
State: runtime.ContainerState_CONTAINER_RUNNING, State: runtime.ContainerState_CONTAINER_RUNNING,
CreatedAt: createdAt, CreatedAt: createdAt,
}, },
{ {
Id: "3", Id: "c-3container",
PodSandboxId: "s-1", PodSandboxId: "s-1abcdef1234",
Metadata: &runtime.ContainerMetadata{Name: "name-3"}, Metadata: &runtime.ContainerMetadata{Name: "name-3"},
State: runtime.ContainerState_CONTAINER_EXITED, State: runtime.ContainerState_CONTAINER_EXITED,
CreatedAt: createdAt, CreatedAt: createdAt,
}, },
{
Id: "c-4container",
PodSandboxId: "s-2abcdef1234",
Metadata: &runtime.ContainerMetadata{Name: "name-4"},
State: runtime.ContainerState_CONTAINER_CREATED,
CreatedAt: createdAt,
},
} }
// Inject test metadata // Inject test sandbox metadata
for _, sb := range sandboxesInStore {
assert.NoError(t, c.sandboxStore.Add(sb))
}
// Inject test container metadata
for _, cntr := range containersInStore { for _, cntr := range containersInStore {
container, err := cntr.toContainer() container, err := cntr.toContainer()
assert.NoError(t, err) assert.NoError(t, err)
assert.NoError(t, c.containerStore.Add(container)) assert.NoError(t, c.containerStore.Add(container))
} }
resp, err := c.ListContainers(context.Background(), &runtime.ListContainersRequest{Filter: filter}) for testdesc, testdata := range map[string]struct {
assert.NoError(t, err) filter *runtime.ContainerFilter
require.NotNil(t, resp) expect []*runtime.Container
containers := resp.GetContainers() }{
assert.Len(t, containers, len(expect)) "test without filter": {
for _, cntr := range expect { filter: &runtime.ContainerFilter{},
assert.Contains(t, containers, cntr) expect: expectedContainers,
},
"test filter by sandboxid": {
filter: &runtime.ContainerFilter{
PodSandboxId: "s-1abcdef1234",
},
expect: expectedContainers[:3],
},
"test filter by truncated sandboxid": {
filter: &runtime.ContainerFilter{
PodSandboxId: "s-1",
},
expect: expectedContainers[:3],
},
"test filter by containerid": {
filter: &runtime.ContainerFilter{
Id: "c-1container",
},
expect: expectedContainers[:1],
},
"test filter by truncated containerid": {
filter: &runtime.ContainerFilter{
Id: "c-1",
},
expect: expectedContainers[:1],
},
"test filter by containerid and sandboxid": {
filter: &runtime.ContainerFilter{
Id: "c-1container",
PodSandboxId: "s-1abcdef1234",
},
expect: expectedContainers[:1],
},
"test filter by truncated containerid and truncated sandboxid": {
filter: &runtime.ContainerFilter{
Id: "c-1",
PodSandboxId: "s-1",
},
expect: expectedContainers[:1],
},
} {
t.Logf("TestCase: %s", testdesc)
resp, err := c.ListContainers(context.Background(), &runtime.ListContainersRequest{Filter: testdata.filter})
assert.NoError(t, err)
require.NotNil(t, resp)
containers := resp.GetContainers()
assert.Len(t, containers, len(testdata.expect))
for _, cntr := range testdata.expect {
assert.Contains(t, containers, cntr)
}
} }
} }

View File

@ -119,6 +119,15 @@ func (c *criContainerdService) getContainerMetrics(
return &cs, nil return &cs, nil
} }
func (c *criContainerdService) normalizeContainerStatsFilter(filter *runtime.ContainerStatsFilter) {
if cntr, err := c.containerStore.Get(filter.GetId()); err == nil {
filter.Id = cntr.ID
}
if sb, err := c.sandboxStore.Get(filter.GetPodSandboxId()); err == nil {
filter.PodSandboxId = sb.ID
}
}
// buildTaskMetricsRequest constructs a tasks.MetricsRequest based on // buildTaskMetricsRequest constructs a tasks.MetricsRequest based on
// the information in the stats request and the containerStore // the information in the stats request and the containerStore
func (c *criContainerdService) buildTaskMetricsRequest( func (c *criContainerdService) buildTaskMetricsRequest(
@ -128,6 +137,7 @@ func (c *criContainerdService) buildTaskMetricsRequest(
if r.GetFilter() == nil { if r.GetFilter() == nil {
return req, nil, nil return req, nil, nil
} }
c.normalizeContainerStatsFilter(r.GetFilter())
var containers []containerstore.Container var containers []containerstore.Container
for _, cntr := range c.containerStore.List() { for _, cntr := range c.containerStore.List() {
if r.GetFilter().GetId() != "" && cntr.ID != r.GetFilter().GetId() { if r.GetFilter().GetId() != "" && cntr.ID != r.GetFilter().GetId() {

View File

@ -84,12 +84,19 @@ func toCRISandbox(meta sandboxstore.Metadata, state runtime.PodSandboxState, cre
} }
} }
func (c *criContainerdService) normalizePodSandboxFilter(filter *runtime.PodSandboxFilter) {
if sb, err := c.sandboxStore.Get(filter.GetId()); err == nil {
filter.Id = sb.ID
}
}
// filterCRISandboxes filters CRISandboxes. // filterCRISandboxes filters CRISandboxes.
func (c *criContainerdService) filterCRISandboxes(sandboxes []*runtime.PodSandbox, filter *runtime.PodSandboxFilter) []*runtime.PodSandbox { func (c *criContainerdService) filterCRISandboxes(sandboxes []*runtime.PodSandbox, filter *runtime.PodSandboxFilter) []*runtime.PodSandbox {
if filter == nil { if filter == nil {
return sandboxes return sandboxes
} }
c.normalizePodSandboxFilter(filter)
filtered := []*runtime.PodSandbox{} filtered := []*runtime.PodSandbox{}
for _, s := range sandboxes { for _, s := range sandboxes {
// Filter by id // Filter by id

View File

@ -59,26 +59,77 @@ func TestToCRISandbox(t *testing.T) {
func TestFilterSandboxes(t *testing.T) { func TestFilterSandboxes(t *testing.T) {
c := newTestCRIContainerdService() c := newTestCRIContainerdService()
sandboxes := []struct {
testSandboxes := []*runtime.PodSandbox{ sandbox sandboxstore.Sandbox
state runtime.PodSandboxState
}{
{ {
Id: "1", sandbox: sandboxstore.Sandbox{
Metadata: &runtime.PodSandboxMetadata{Name: "name-1", Uid: "uid-1", Namespace: "ns-1", Attempt: 1}, Metadata: sandboxstore.Metadata{
State: runtime.PodSandboxState_SANDBOX_READY, ID: "1abcdef",
Name: "sandboxname-1",
Config: &runtime.PodSandboxConfig{
Metadata: &runtime.PodSandboxMetadata{
Name: "podname-1",
Uid: "uid-1",
Namespace: "ns-1",
Attempt: 1,
},
},
},
},
state: runtime.PodSandboxState_SANDBOX_READY,
}, },
{ {
Id: "2", sandbox: sandboxstore.Sandbox{
Metadata: &runtime.PodSandboxMetadata{Name: "name-2", Uid: "uid-2", Namespace: "ns-2", Attempt: 2}, Metadata: sandboxstore.Metadata{
State: runtime.PodSandboxState_SANDBOX_NOTREADY, ID: "2abcdef",
Labels: map[string]string{"a": "b"}, Name: "sandboxname-2",
Config: &runtime.PodSandboxConfig{
Metadata: &runtime.PodSandboxMetadata{
Name: "podname-2",
Uid: "uid-2",
Namespace: "ns-2",
Attempt: 2,
},
Labels: map[string]string{"a": "b"},
},
},
},
state: runtime.PodSandboxState_SANDBOX_NOTREADY,
}, },
{ {
Id: "3", sandbox: sandboxstore.Sandbox{
Metadata: &runtime.PodSandboxMetadata{Name: "name-2", Uid: "uid-2", Namespace: "ns-2", Attempt: 2}, Metadata: sandboxstore.Metadata{
State: runtime.PodSandboxState_SANDBOX_READY, ID: "3abcdef",
Labels: map[string]string{"c": "d"}, Name: "sandboxname-3",
Config: &runtime.PodSandboxConfig{
Metadata: &runtime.PodSandboxMetadata{
Name: "podname-2",
Uid: "uid-2",
Namespace: "ns-2",
Attempt: 2,
},
Labels: map[string]string{"c": "d"},
},
},
},
state: runtime.PodSandboxState_SANDBOX_READY,
}, },
} }
// Create PodSandbox
testSandboxes := []*runtime.PodSandbox{}
createdAt := time.Now()
for _, sb := range sandboxes {
testSandboxes = append(testSandboxes, toCRISandbox(sb.sandbox.Metadata, sb.state, createdAt))
}
// Inject test sandbox metadata
for _, sb := range sandboxes {
assert.NoError(t, c.sandboxStore.Add(sb.sandbox))
}
for desc, test := range map[string]struct { for desc, test := range map[string]struct {
filter *runtime.PodSandboxFilter filter *runtime.PodSandboxFilter
expect []*runtime.PodSandbox expect []*runtime.PodSandbox
@ -87,6 +138,10 @@ func TestFilterSandboxes(t *testing.T) {
expect: testSandboxes, expect: testSandboxes,
}, },
"id filter": { "id filter": {
filter: &runtime.PodSandboxFilter{Id: "2abcdef"},
expect: []*runtime.PodSandbox{testSandboxes[1]},
},
"truncid filter": {
filter: &runtime.PodSandboxFilter{Id: "2"}, filter: &runtime.PodSandboxFilter{Id: "2"},
expect: []*runtime.PodSandbox{testSandboxes[1]}, expect: []*runtime.PodSandbox{testSandboxes[1]},
}, },
@ -121,6 +176,7 @@ func TestFilterSandboxes(t *testing.T) {
expect: []*runtime.PodSandbox{testSandboxes[2]}, expect: []*runtime.PodSandbox{testSandboxes[2]},
}, },
} { } {
t.Logf("TestCase: %s", desc)
filtered := c.filterCRISandboxes(testSandboxes, test.filter) filtered := c.filterCRISandboxes(testSandboxes, test.filter)
assert.Equal(t, test.expect, filtered, desc) assert.Equal(t, test.expect, filtered, desc)
} }