Skip to content
This repository was archived by the owner on Aug 26, 2022. It is now read-only.

Commit e1dee79

Browse files
aneeshkpryandgoulding
authored andcommitted
Adding testcases for contaner certification test
Add first container cnf test case
1 parent b22ad8f commit e1dee79

File tree

15 files changed

+664
-4
lines changed

15 files changed

+664
-4
lines changed

Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,17 @@ cnf-tests: build build-cnf-tests run-cnf-tests
3434

3535
operator-cnf-tests: build build-cnf-operator-tests run-operator-tests
3636

37+
container-cnf-tests: build build-cnf-container-tests run-container-tests
38+
3739
build-cnf-tests:
3840
PATH=${PATH}:${GOBIN} ginkgo build ./test-network-function
3941

4042
build-cnf-operator-tests:
4143
PATH=${PATH}:${GOBIN} ginkgo build ./test-network-function/operator-test --tags operator_suite
4244

45+
build-cnf-container-tests:
46+
PATH=${PATH}:${GOBIN} ginkgo build ./test-network-function/container-test --tags container_suite
47+
4348
run-generic-cnf-tests:
4449
cd ./test-network-function && ./test-network-function.test -ginkgo.focus="generic" ${COMMON_GINKGO_ARGS}
4550

@@ -49,6 +54,9 @@ run-cnf-tests:
4954
run-operator-tests:
5055
cd ./test-network-function/operator-test && ./operator-test.test $COMMON_GINKGO_ARGS
5156

57+
run-container-tests:
58+
cd ./test-network-function/container-test && ./container-test.test $COMMON_GINKGO_ARGS
59+
5260
deps-update:
5361
go mod tidy && \
5462
go mod vendor
@@ -71,6 +79,8 @@ clean:
7179
rm -f ./test-network-function/cnf-certification-tests_junit.xml
7280
rm -f ./test-network-function/operator-test/operator-test.test
7381
rm -f ./test-network-function/operator-test/cnf-operator-certification-tests_junit.xml
82+
rm -f ./test-network-function/container-test/container-test.test
83+
rm -f ./test-network-function/container-test/cnf-container-certification-tests_junit.xml
7484

7585
dependencies:
7686
go get github.com/onsi/ginkgo/ginkgo

README.md

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ In order to run an operator test suite, `operator-test` for example, issue the f
281281
282282
```shell script
283283
make build build-cnf-operator-tests
284-
cd ./test-network-function/operator-test && ./operator-test.test -ginkgo.v -ginkgo.focus="operatr_test" -junit . -report .
284+
cd ./test-network-function/operator-test && ./operator-test.test -ginkgo.v -ginkgo.focus="operator_test" -junit . -report .
285285
```
286286
287287
Test Configuration
@@ -298,9 +298,67 @@ Sample config.yml
298298
status: "Succeeded"
299299
300300
```
301-
cd ./test-network-function/operator-test && ./operator-test.test -config=config.yml -ginkgo.v -ginkgo.focus="operatr_test" -junit . -report .
301+
cd ./test-network-function/operator-test && ./operator-test.test -config=config.yml -ginkgo.v -ginkgo.focus="operator_test" -junit . -report .
302302
```
303303
304304
305305
A JUnit report containing results is created at `test-network-function/operator-test/cnf-operator-certification-tests_junit.xml`.
306306
307+
### Run an Container Test Suite
308+
309+
In order to run an container test suite, `container-test` for example, issue the following command:
310+
311+
```shell script
312+
make build build-cnf-container-tests
313+
cd ./test-network-function/container-test && ./container-test.test -ginkgo.v -ginkgo.focus="container_test" -junit . -report .
314+
```
315+
316+
Test Configuration
317+
318+
You can either edit the provided config at `test-network-function/container-test/config.yml`
319+
or you can pass config with `-config` flag to the test suite
320+
321+
Sample config.yml
322+
---
323+
pod:
324+
- name: "nginx"
325+
namespace: "default"
326+
status: "Running"
327+
tests:
328+
- "PRIVILEGED_POD"
329+
330+
```shell script
331+
make build build-cnf-container-tests
332+
cd ./test-network-function/container-test && ./container-test.test -config=config.yml -ginkgo.v -ginkgo.focus="container_test" -junit . -report .
333+
```
334+
335+
Configuring test cases
336+
337+
By default the test suite will run all the default test cases defined by the suite,
338+
but you can override those test cases by creating a folder named`testcases` and adding test steps under that folder.
339+
The filenames and contents should match as shown below.
340+
341+
Example:
342+
```
343+
./testcases/
344+
privileged.yml
345+
```
346+
347+
You can delete or comment the test step for bypassing the tests.
348+
For an example, if you remove `"HOST_PATH_CHECK"` from the privileged.yml then that test will be skipped.
349+
1. privileged.yml
350+
```
351+
---
352+
testconfigured:
353+
- "HOST_NETWORK_CHECK"
354+
- "HOST_PORT_CHECK"
355+
- "HOST_PATH_CHECK"
356+
- "HOST_IPC_CHECK"
357+
- "HOST_PID_CHECK"
358+
- "CAPABILITY_CHECK"
359+
- "ROOT_CHECK"
360+
- "PRIVILEGE_ESCALATION"`
361+
```
362+
363+
A JUnit report containing results is created at `test-network-function/container-test/cnf-operator-certification-tests_junit.xml`.
364+

pkg/tnf/handlers/container/doc.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
//Package container provides functionality to test pod and container level checks
2+
package container

pkg/tnf/handlers/container/pod.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
package container
2+
3+
import (
4+
"fmt"
5+
"github.com/redhat-nfvpe/test-network-function/internal/reel"
6+
"github.com/redhat-nfvpe/test-network-function/pkg/tnf"
7+
"github.com/redhat-nfvpe/test-network-function/pkg/tnf/handlers/container/testcases"
8+
"regexp"
9+
"strings"
10+
"time"
11+
)
12+
13+
//Pod that is under test.
14+
type Pod struct {
15+
result int
16+
timeout time.Duration
17+
args []string
18+
status string
19+
Command string
20+
Name string
21+
Namespace string
22+
ExpectStatus []string
23+
Action string
24+
ResultType string
25+
FailOn string
26+
}
27+
28+
// Args returns the command line args for the test.
29+
func (p *Pod) Args() []string {
30+
return p.args
31+
}
32+
33+
// Timeout return the timeout for the test.
34+
func (p *Pod) Timeout() time.Duration {
35+
return p.timeout
36+
}
37+
38+
// Result returns the test result.
39+
func (p *Pod) Result() int {
40+
return p.result
41+
}
42+
43+
// ReelFirst returns a step which expects an pod status for the given pod.
44+
func (p *Pod) ReelFirst() *reel.Step {
45+
return &reel.Step{
46+
Expect: []string{testcases.GetOutRegExp("ALLOW_ALL")},
47+
Timeout: p.timeout,
48+
}
49+
}
50+
51+
func contains(arr []string, str string) (found bool) {
52+
found = false
53+
for _, a := range arr {
54+
if a == str {
55+
found = true
56+
break
57+
}
58+
}
59+
return
60+
}
61+
62+
// ReelMatch parses the pod status output and set the test result on match.
63+
// Returns no step; the test is complete.
64+
func (p *Pod) ReelMatch(_ string, _ string, match string) *reel.Step {
65+
//for type: array ,should match for any expected status or fail on any expected status
66+
//based on the action type allow (default)|deny
67+
if p.ResultType == "array" {
68+
69+
replacer := strings.NewReplacer(`[`, ``, "\"", ``, `]`, ``, `, `, `,`)
70+
match = replacer.Replace(match)
71+
matchSlice := strings.Split(match, ",")
72+
for _, status := range matchSlice {
73+
if contains(p.ExpectStatus, status) {
74+
if p.Action == "deny" { //Single deny match is failure.
75+
return nil
76+
}
77+
} else if p.Action == "allow" {
78+
return nil //should be in allowed list
79+
}
80+
}
81+
} else {
82+
for _, status := range p.ExpectStatus {
83+
re := regexp.MustCompile(testcases.GetOutRegExp(status))
84+
matched := re.MatchString(match)
85+
if !matched {
86+
return nil
87+
}
88+
}
89+
}
90+
91+
p.result = tnf.SUCCESS
92+
return nil
93+
}
94+
95+
// ReelTimeout does nothing;
96+
func (p *Pod) ReelTimeout() *reel.Step {
97+
return nil
98+
}
99+
100+
// ReelEOF does nothing.
101+
func (p *Pod) ReelEOF() {
102+
}
103+
104+
// NewPod creates a `Container` test on the configured test cases.
105+
func NewPod(command, name, namespace string, expectedStatus []string, resultType string, action string, timeout time.Duration) *Pod {
106+
args := strings.Split(fmt.Sprintf(command, name, namespace), " ")
107+
return &Pod{
108+
Name: name,
109+
Namespace: namespace,
110+
ExpectStatus: expectedStatus,
111+
Action: action,
112+
ResultType: resultType,
113+
result: tnf.ERROR,
114+
timeout: timeout,
115+
args: args,
116+
}
117+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package container_test
2+
3+
import (
4+
"fmt"
5+
"github.com/redhat-nfvpe/test-network-function/pkg/tnf"
6+
"github.com/redhat-nfvpe/test-network-function/pkg/tnf/handlers/container"
7+
"github.com/redhat-nfvpe/test-network-function/pkg/tnf/handlers/container/testcases"
8+
"github.com/stretchr/testify/assert"
9+
"strings"
10+
"testing"
11+
"time"
12+
)
13+
14+
const (
15+
testTimeoutDuration = time.Second * 2
16+
name = "HOST_NETWORK_CHECK"
17+
namespace = "test"
18+
command = "oc get pod %s -n %s -o json | jq -r '.spec.hostNetwork'"
19+
actionAllow = "allow"
20+
actionDeny = "deny"
21+
)
22+
23+
var (
24+
stringExpectedStatus = []string{"NULL_FALSE"}
25+
sliceExpectedStatus = []string{"NET_ADMIN", "SYS_TIME"}
26+
)
27+
28+
func TestPod_Args(t *testing.T) {
29+
c := container.NewPod(command, name, namespace, stringExpectedStatus, actionAllow, "string", testTimeoutDuration)
30+
args := strings.Split(fmt.Sprintf(command, c.Name, c.Namespace), " ")
31+
assert.Equal(t, args, c.Args())
32+
}
33+
34+
func TestPod_ReelFirst(t *testing.T) {
35+
c := container.NewPod(command, name, namespace, stringExpectedStatus, actionAllow, "string", testTimeoutDuration)
36+
step := c.ReelFirst()
37+
assert.Equal(t, "", step.Execute)
38+
assert.Equal(t, []string{testcases.GetOutRegExp("ALLOW_ALL")}, step.Expect)
39+
assert.Equal(t, testTimeoutDuration, step.Timeout)
40+
}
41+
42+
func TestPod_ReelEof(t *testing.T) {
43+
c := container.NewPod(command, name, namespace, stringExpectedStatus, "string", actionAllow, testTimeoutDuration)
44+
// just ensures lack of panic
45+
c.ReelEOF()
46+
}
47+
48+
func TestPod_ReelTimeout(t *testing.T) {
49+
c := container.NewPod(command, name, namespace, stringExpectedStatus, "string", actionAllow, testTimeoutDuration)
50+
step := c.ReelTimeout()
51+
assert.Nil(t, step)
52+
}
53+
func TestPodTest_ReelMatchString(t *testing.T) {
54+
c := container.NewPod(command, name, namespace, stringExpectedStatus, "string", actionAllow, testTimeoutDuration)
55+
step := c.ReelMatch("", "", "null")
56+
assert.Nil(t, step)
57+
assert.Equal(t, tnf.SUCCESS, c.Result())
58+
}
59+
60+
func TestPodTest_ReelMatchStringNoFound(t *testing.T) {
61+
c := container.NewPod(command, name, namespace, stringExpectedStatus, "string", actionAllow, testTimeoutDuration)
62+
step := c.ReelMatch("", "", "not_null")
63+
assert.Nil(t, step)
64+
assert.Equal(t, tnf.ERROR, c.Result())
65+
}
66+
67+
func TestPodTest_ReelMatchArray_Allow_Match(t *testing.T) {
68+
c := container.NewPod(command, name, namespace, sliceExpectedStatus, "array", actionAllow, testTimeoutDuration)
69+
step := c.ReelMatch("", "", `["NET_ADMIN", "SYS_TIME"]`)
70+
assert.Nil(t, step)
71+
assert.Equal(t, tnf.SUCCESS, c.Result())
72+
}
73+
74+
func TestPodTest_ReelMatchArray_Allow_NoMatch(t *testing.T) {
75+
c := container.NewPod(command, name, namespace, sliceExpectedStatus, "array", actionAllow, testTimeoutDuration)
76+
step := c.ReelMatch("", "", `["NET_ADMIN", "NO_SYS_TIME"]`)
77+
assert.Nil(t, step)
78+
assert.Equal(t, tnf.ERROR, c.Result())
79+
}
80+
func TestPodTest_ReelMatchArray_Deny_Match(t *testing.T) {
81+
c := container.NewPod(command, name, namespace, sliceExpectedStatus, "array", actionDeny, testTimeoutDuration)
82+
step := c.ReelMatch("", "", `["NET_ADMIN", "SYS_TIME"]`)
83+
assert.Nil(t, step)
84+
assert.Equal(t, tnf.ERROR, c.Result())
85+
}
86+
func TestPodTest_ReelMatchArray_Deny_NotMatch(t *testing.T) {
87+
c := container.NewPod(command, name, namespace, sliceExpectedStatus, "array", actionDeny, testTimeoutDuration)
88+
step := c.ReelMatch("", "", `["NOT_NET_ADMIN", "NOT_SYS_TIME"]`)
89+
assert.Nil(t, step)
90+
assert.Equal(t, tnf.SUCCESS, c.Result())
91+
}
92+
func TestNewPod(t *testing.T) {
93+
c := container.NewPod(command, name, namespace, stringExpectedStatus, "string", actionAllow, testTimeoutDuration)
94+
assert.Equal(t, tnf.ERROR, c.Result())
95+
assert.Equal(t, testTimeoutDuration, c.Timeout())
96+
}

0 commit comments

Comments
 (0)