Skip to content

Commit 0d595a2

Browse files
FedeDPpoiana
authored andcommitted
new(plugins/container): added fetcher tests.
Also, fixed a small bug in cri engine `get()` method. Signed-off-by: Federico Di Pierro <nierro92@gmail.com>
1 parent ecff28f commit 0d595a2

File tree

6 files changed

+148
-24
lines changed

6 files changed

+148
-24
lines changed

plugins/container/go-worker/pkg/container/containerd_test.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ package container
22

33
import (
44
"context"
5-
"github.com/falcosecurity/plugins/plugins/container/go-worker/pkg/event"
65
containerd "github.com/containerd/containerd/v2/client"
76
"github.com/containerd/containerd/v2/pkg/namespaces"
87
"github.com/containerd/containerd/v2/pkg/oci"
8+
"github.com/falcosecurity/plugins/plugins/container/go-worker/pkg/event"
99
"github.com/google/uuid"
1010
"github.com/opencontainers/runtime-spec/specs-go"
1111
"github.com/stretchr/testify/assert"
@@ -14,7 +14,7 @@ import (
1414
"testing"
1515
)
1616

17-
func TestContainerd(t *testing.T) {
17+
func testContainerd(t *testing.T, withFetcher bool) {
1818
usr, err := user.Current()
1919
assert.NoError(t, err)
2020
if usr.Uid != "0" {
@@ -70,9 +70,6 @@ func TestContainerd(t *testing.T) {
7070
oci.WithPrivileged))
7171
assert.NoError(t, err)
7272

73-
events, err := engine.List(context.Background())
74-
assert.NoError(t, err)
75-
7673
expectedEvent := event.Event{
7774
Info: event.Info{
7875
Container: event.Container{
@@ -103,6 +100,15 @@ func TestContainerd(t *testing.T) {
103100
IsCreate: true,
104101
}
105102

103+
if withFetcher {
104+
testFetcher(t, engine, expectedEvent.ID, expectedEvent)
105+
err = ctr.Delete(namespacedCtx)
106+
assert.NoError(t, err)
107+
return
108+
}
109+
110+
events, err := engine.List(context.Background())
111+
assert.NoError(t, err)
106112
found := false
107113
for _, evt := range events {
108114
if evt.FullID == ctr.ID() {
@@ -143,3 +149,7 @@ func TestContainerd(t *testing.T) {
143149
evt := waitOnChannelOrTimeout(t, listCh)
144150
assert.Equal(t, expectedEvent, evt)
145151
}
152+
153+
func TestContainerd(t *testing.T) {
154+
testContainerd(t, false)
155+
}

plugins/container/go-worker/pkg/container/cri.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ func (c *criEngine) ctrToInfo(ctx context.Context, ctr *v1.ContainerStatus, podS
380380
}
381381

382382
func (c *criEngine) get(ctx context.Context, containerId string) (*event.Event, error) {
383-
ctrs, err := c.client.ListContainers(ctx, &v1.ContainerFilter{State: &v1.ContainerStateValue{}, Id: containerId})
383+
ctrs, err := c.client.ListContainers(ctx, &v1.ContainerFilter{Id: containerId})
384384
if err != nil || len(ctrs) == 0 {
385385
return nil, err
386386
}

plugins/container/go-worker/pkg/container/cri_test.go

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ func TestCRIInfoMap(t *testing.T) {
200200
assert.NoError(t, err)
201201
}
202202

203-
func TestCRIFake(t *testing.T) {
203+
func testCRIFake(t *testing.T, withFetcher bool) {
204204
endpoint, err := fake.GenerateEndpoint()
205205
require.NoError(t, err)
206206

@@ -254,9 +254,6 @@ func TestCRIFake(t *testing.T) {
254254
})
255255
assert.NoError(t, err)
256256

257-
events, err := engine.List(context.Background())
258-
assert.NoError(t, err)
259-
260257
expectedEvent := event.Event{
261258
Info: event.Info{
262259
Container: event.Container{
@@ -285,6 +282,17 @@ func TestCRIFake(t *testing.T) {
285282
IsCreate: true,
286283
}
287284

285+
if withFetcher {
286+
// FakeRuntimeService ListContainers wants the fullID:
287+
// https://github.com/kubernetes/cri-api/blob/master/pkg/apis/testing/fake_runtime_service.go#L469
288+
testFetcher(t, engine, expectedEvent.FullID, expectedEvent)
289+
_, err = fakeRuntime.RemoveContainer(context.Background(), &v1.RemoveContainerRequest{ContainerId: ctr.ContainerId})
290+
assert.NoError(t, err)
291+
return
292+
}
293+
294+
events, err := engine.List(context.Background())
295+
assert.NoError(t, err)
288296
// We don't have this before creation
289297
found := false
290298
for _, evt := range events {
@@ -300,7 +308,11 @@ func TestCRIFake(t *testing.T) {
300308
// fakeruntime.GetContainerEvents() returns nil. Cannot be tested.
301309
}
302310

303-
func TestCRI(t *testing.T) {
311+
func TestCRIFake(t *testing.T) {
312+
testCRIFake(t, false)
313+
}
314+
315+
func testCRI(t *testing.T, withFetcher bool) {
304316
const criSocket = "/run/containerd/containerd.sock"
305317
client, err := remote.NewRemoteRuntimeService(criSocket, 5*time.Second, nil, nil)
306318
if err != nil {
@@ -358,9 +370,6 @@ func TestCRI(t *testing.T) {
358370
}, podSandboxConfig)
359371
assert.NoError(t, err)
360372

361-
events, err := engine.List(context.Background())
362-
assert.NoError(t, err)
363-
364373
expectedEvent := event.Event{
365374
Info: event.Info{
366375
Container: event.Container{
@@ -390,6 +399,21 @@ func TestCRI(t *testing.T) {
390399
IsCreate: true,
391400
}
392401

402+
if withFetcher {
403+
// RuntimeService wants the short ID:
404+
// https://github.com/cri-o/cri-o/blob/592e805f2423ba55054a16d3a7cc66499e2c0dac/server/container_list.go#L41
405+
testFetcher(t, engine, expectedEvent.ID, expectedEvent)
406+
407+
err = client.RemoveContainer(context.Background(), "test_sandbox_test_container_0")
408+
assert.NoError(t, err)
409+
410+
err = client.RemovePodSandbox(context.Background(), sandboxName)
411+
assert.NoError(t, err)
412+
return
413+
}
414+
415+
events, err := engine.List(context.Background())
416+
assert.NoError(t, err)
393417
found := false
394418
for _, evt := range events {
395419
if evt.FullID == ctr {
@@ -437,3 +461,7 @@ func TestCRI(t *testing.T) {
437461
}
438462
}
439463
}
464+
465+
func TestCRI(t *testing.T) {
466+
testCRI(t, false)
467+
}

plugins/container/go-worker/pkg/container/docker_test.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ package container
22

33
import (
44
"context"
5-
"github.com/falcosecurity/plugins/plugins/container/go-worker/pkg/event"
65
"github.com/docker/docker/api/types/container"
76
"github.com/docker/docker/api/types/image"
87
"github.com/docker/docker/client"
8+
"github.com/falcosecurity/plugins/plugins/container/go-worker/pkg/event"
99
"github.com/stretchr/testify/assert"
1010
"io"
1111
"runtime"
1212
"sync"
1313
"testing"
1414
)
1515

16-
func TestDocker(t *testing.T) {
16+
func testDocker(t *testing.T, withFetcher bool) {
1717
dockerClient, err := client.NewClientWithOpts(client.FromEnv,
1818
client.WithAPIVersionNegotiation())
1919
if err != nil {
@@ -49,9 +49,6 @@ func TestDocker(t *testing.T) {
4949
}, nil, nil, "test_container")
5050
assert.NoError(t, err)
5151

52-
events, err := engine.List(context.Background())
53-
assert.NoError(t, err)
54-
5552
imageId := "63b790fccc9078ab8bb913d94a5d869e19fca9b77712b315da3fa45bb8f14636"
5653
if runtime.GOARCH == "arm64" {
5754
imageId = "511a44083d3a23416fadc62847c45d14c25cbace86e7a72b2b350436978a0450"
@@ -88,6 +85,15 @@ func TestDocker(t *testing.T) {
8885
IsCreate: true,
8986
}
9087

88+
if withFetcher {
89+
testFetcher(t, engine, expectedEvent.ID, expectedEvent)
90+
err = dockerClient.ContainerRemove(context.Background(), ctr.ID, container.RemoveOptions{})
91+
assert.NoError(t, err)
92+
return
93+
}
94+
95+
events, err := engine.List(context.Background())
96+
assert.NoError(t, err)
9197
found := false
9298
for _, evt := range events {
9399
if evt.FullID == ctr.ID {
@@ -126,3 +132,7 @@ func TestDocker(t *testing.T) {
126132
evt := waitOnChannelOrTimeout(t, listCh)
127133
assert.Equal(t, expectedEvent, evt)
128134
}
135+
136+
func TestDocker(t *testing.T) {
137+
testDocker(t, false)
138+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package container
2+
3+
import (
4+
"context"
5+
"github.com/falcosecurity/plugins/plugins/container/go-worker/pkg/event"
6+
"github.com/stretchr/testify/assert"
7+
"sync"
8+
"testing"
9+
"time"
10+
)
11+
12+
func TestDockerFetcher(t *testing.T) {
13+
testDocker(t, true)
14+
}
15+
16+
func TestContainerdFetcher(t *testing.T) {
17+
testContainerd(t, true)
18+
}
19+
20+
func TestPodmanFetcher(t *testing.T) {
21+
testPodman(t, true)
22+
}
23+
24+
func TestCRIFakeFetcher(t *testing.T) {
25+
testCRIFake(t, true)
26+
}
27+
28+
func TestCRIFetcher(t *testing.T) {
29+
testCRI(t, true)
30+
}
31+
32+
func testFetcher(t *testing.T, containerEngine Engine, containerId string, expectedEvent event.Event) {
33+
// Create the fetcher engine with the docker engine as the only container engine
34+
containerEngines := []Engine{containerEngine}
35+
f := NewFetcherEngine(context.Background(), containerEngines)
36+
assert.NotNil(t, f)
37+
38+
// Check that fetcher is able to fetch the container
39+
wg := sync.WaitGroup{}
40+
cancelCtx, cancel := context.WithCancel(context.Background())
41+
t.Cleanup(func() {
42+
cancel()
43+
wg.Wait()
44+
})
45+
46+
listCh, err := f.Listen(cancelCtx, &wg)
47+
assert.NoError(t, err)
48+
49+
// Send the container ID to the fetcher channel to request its info to be loaded
50+
ch := GetFetcherChan()
51+
assert.NotNil(t, ch)
52+
go func() {
53+
time.Sleep(1 * time.Second)
54+
ch <- containerId
55+
}()
56+
57+
evt := waitOnChannelOrTimeout(t, listCh)
58+
// This needs to be updated on the fly
59+
expectedEvent.CreatedTime = evt.CreatedTime
60+
// In some cases, the env ordering might differ thus we manually check it and then copy it
61+
for _, env := range expectedEvent.Env {
62+
assert.Contains(t, evt.Env, env)
63+
}
64+
expectedEvent.Env = evt.Env
65+
assert.Equal(t, expectedEvent, evt)
66+
}

plugins/container/go-worker/pkg/container/podman_test.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ package container
55
import (
66
"context"
77
"fmt"
8-
"github.com/falcosecurity/plugins/plugins/container/go-worker/pkg/event"
98
"github.com/containers/image/v5/manifest"
109
"github.com/containers/podman/v5/pkg/bindings"
1110
"github.com/containers/podman/v5/pkg/bindings/containers"
1211
"github.com/containers/podman/v5/pkg/bindings/images"
1312
"github.com/containers/podman/v5/pkg/specgen"
13+
"github.com/falcosecurity/plugins/plugins/container/go-worker/pkg/event"
1414
"github.com/opencontainers/runtime-spec/specs-go"
1515
"github.com/stretchr/testify/assert"
1616
"os/user"
@@ -30,7 +30,7 @@ func waitOnChannelOrTimeout(t *testing.T, ch <-chan event.Event) event.Event {
3030
return event.Event{}
3131
}
3232

33-
func TestPodman(t *testing.T) {
33+
func testPodman(t *testing.T, withFetcher bool) {
3434
usr, err := user.Current()
3535
assert.NoError(t, err)
3636

@@ -85,9 +85,6 @@ func TestPodman(t *testing.T) {
8585
}, nil)
8686
assert.NoError(t, err)
8787

88-
events, err := engine.List(context.Background())
89-
assert.NoError(t, err)
90-
9188
imageId := "63b790fccc9078ab8bb913d94a5d869e19fca9b77712b315da3fa45bb8f14636"
9289
if runtime.GOARCH == "arm64" {
9390
imageId = "511a44083d3a23416fadc62847c45d14c25cbace86e7a72b2b350436978a0450"
@@ -123,6 +120,15 @@ func TestPodman(t *testing.T) {
123120
IsCreate: true,
124121
}
125122

123+
if withFetcher {
124+
testFetcher(t, engine, expectedEvent.ID, expectedEvent)
125+
_, err = containers.Remove(podmanCtx, ctr.ID, nil)
126+
assert.NoError(t, err)
127+
return
128+
}
129+
130+
events, err := engine.List(context.Background())
131+
assert.NoError(t, err)
126132
found := false
127133
for _, evt := range events {
128134
if evt.FullID == ctr.ID {
@@ -165,3 +171,7 @@ func TestPodman(t *testing.T) {
165171
evt := waitOnChannelOrTimeout(t, listCh)
166172
assert.Equal(t, expectedEvent, evt)
167173
}
174+
175+
func TestPodman(t *testing.T) {
176+
testPodman(t, false)
177+
}

0 commit comments

Comments
 (0)