Skip to content

Commit a259dda

Browse files
author
Ma Shimiao
committed
split runtimevalidate into inside and outside validaiton
Signed-off-by: Ma Shimiao <[email protected]>
1 parent bbf9886 commit a259dda

File tree

2 files changed

+155
-33
lines changed

2 files changed

+155
-33
lines changed

Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ $(RUNTIME_TOOLS_LINK):
3939
localvalidation:
4040
RUNTIME=$(RUNTIME) go test -tags "$(BUILDTAGS)" ${TESTFLAGS} -v github.com/opencontainers/runtime-tools/validation
4141

42-
4342
.PHONY: test .gofmt .govet .golint
4443

4544
test: .gofmt .govet .golint

validation/validation_test.go

Lines changed: 155 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
package validation
22

33
import (
4+
"encoding/json"
45
"fmt"
56
"io/ioutil"
67
"os"
78
"os/exec"
89
"path/filepath"
10+
"strings"
911
"testing"
1012

13+
"github.com/hashicorp/go-multierror"
14+
"github.com/mndrix/tap-go"
1115
"github.com/mrunalp/fileutils"
16+
rspec "github.com/opencontainers/runtime-spec/specs-go"
1217
"github.com/opencontainers/runtime-tools/generate"
1318
"github.com/satori/go.uuid"
1419
)
@@ -17,51 +22,90 @@ var (
1722
runtime = "runc"
1823
)
1924

25+
type validation struct {
26+
test func(string, string, *rspec.Spec) error
27+
description string
28+
}
29+
2030
func init() {
2131
runtime = os.Getenv("RUNTIME")
2232
}
2333

24-
func runtimeValidate(runtime string, g *generate.Generator) error {
34+
func TestValidateRuntimeInside(t *testing.T) {
35+
g, err := getDefaultGenerator()
36+
if err != nil {
37+
t.Errorf("%s failed validation: %v", runtime, err)
38+
}
39+
g.SetProcessArgs([]string{"/runtimetest"})
40+
41+
if err := runtimeInsideValidate(runtime, g); err != nil {
42+
t.Errorf("%s failed validation: %v", runtime, err)
43+
}
44+
}
45+
46+
func TestValidateRuntimeOutside(t *testing.T) {
47+
g, err := getDefaultGenerator()
48+
if err != nil {
49+
t.Errorf("%s failed validation: %v", runtime, err)
50+
}
51+
g.SetProcessArgs([]string{"sleep", "50"})
52+
53+
if err := runtimeOutsideValidate(runtime, g); err != nil {
54+
t.Errorf("%s failed validation: %v", runtime, err)
55+
}
56+
}
57+
58+
func runtimeInsideValidate(runtime string, g *generate.Generator) error {
2559
// Find the runtime binary in the PATH
2660
runtimePath, err := exec.LookPath(runtime)
2761
if err != nil {
2862
return err
2963
}
3064

31-
// Setup a temporary test directory
32-
tmpDir, err := ioutil.TempDir("", "ocitest")
65+
bundleDir, rootfsDir, err := prepareBundle(g)
3366
if err != nil {
3467
return err
3568
}
36-
defer os.RemoveAll(tmpDir)
69+
defer os.RemoveAll(bundleDir)
3770

38-
// Create bundle directory for the test container
39-
bundleDir := tmpDir + "/busybox"
40-
if err := os.MkdirAll(bundleDir, 0755); err != nil {
71+
// Copy the runtimetest binary to the rootfs
72+
err = fileutils.CopyFile("../runtimetest", filepath.Join(rootfsDir, "runtimetest"))
73+
if err != nil {
4174
return err
4275
}
4376

44-
// Untar the root fs
45-
untarCmd := exec.Command("tar", "-xf", "../rootfs.tar.gz", "-C", bundleDir)
46-
output, err := untarCmd.CombinedOutput()
47-
if err != nil {
48-
fmt.Println(string(output))
77+
// TODO: Use a library to split run into create/start
78+
// Launch the OCI runtime
79+
containerID := uuid.NewV4()
80+
runtimeCmd := exec.Command(runtimePath, "run", containerID.String())
81+
runtimeCmd.Dir = bundleDir
82+
runtimeCmd.Stdin = os.Stdin
83+
runtimeCmd.Stdout = os.Stdout
84+
runtimeCmd.Stderr = os.Stderr
85+
if err = runtimeCmd.Run(); err != nil {
4986
return err
5087
}
5188

52-
// Copy the runtimetest binary to the rootfs
53-
err = fileutils.CopyFile("../runtimetest", filepath.Join(bundleDir, "runtimetest"))
89+
return nil
90+
}
5491

55-
// Generate test configuration
56-
err = g.SaveToFile(filepath.Join(bundleDir, "config.json"), generate.ExportOptions{})
92+
func runtimeOutsideValidate(runtime string, g *generate.Generator) error {
93+
// Find the runtime binary in the PATH
94+
runtimePath, err := exec.LookPath(runtime)
95+
if err != nil {
96+
return err
97+
}
98+
99+
bundleDir, _, err := prepareBundle(g)
57100
if err != nil {
58101
return err
59102
}
103+
// defer os.RemoveAll(bundleDir)
60104

61105
// TODO: Use a library to split run into create/start
62106
// Launch the OCI runtime
63107
containerID := uuid.NewV4()
64-
runtimeCmd := exec.Command(runtimePath, "run", containerID.String())
108+
runtimeCmd := exec.Command(runtimePath, "create", containerID.String())
65109
runtimeCmd.Dir = bundleDir
66110
runtimeCmd.Stdin = os.Stdin
67111
runtimeCmd.Stdout = os.Stdout
@@ -70,29 +114,108 @@ func runtimeValidate(runtime string, g *generate.Generator) error {
70114
return err
71115
}
72116

73-
return nil
117+
outsideValidations := []validation{
118+
{
119+
test: validateLabels,
120+
description: "labels",
121+
},
122+
// Add more container outside validation
123+
}
124+
125+
t := tap.New()
126+
t.Header(0)
127+
128+
var validationErrors error
129+
for _, v := range outsideValidations {
130+
err := v.test(runtimePath, containerID.String(), g.Spec())
131+
t.Ok(err == nil, v.description)
132+
if err != nil {
133+
validationErrors = multierror.Append(validationErrors, err)
134+
}
135+
}
136+
t.AutoPlan()
137+
138+
return validationErrors
74139
}
75140

76-
func getDefaultGenerator() *generate.Generator {
77-
g := generate.New()
78-
g.SetRootPath(".")
79-
g.SetProcessArgs([]string{"/runtimetest"})
80-
return &g
141+
func validateLabels(runtimePath, id string, spec *rspec.Spec) error {
142+
runtimeCmd := exec.Command(runtimePath, "state", id)
143+
output, err := runtimeCmd.Output()
144+
if err != nil {
145+
return err
146+
}
147+
148+
var state rspec.State
149+
if err := json.NewDecoder(strings.NewReader(string(output))).Decode(&state); err != nil {
150+
return err
151+
}
152+
for key, value := range spec.Annotations {
153+
if state.Annotations[key] == value {
154+
continue
155+
}
156+
return fmt.Errorf("Expected annotation %s:%s not set", key, value)
157+
}
158+
return nil
81159
}
82160

83-
func TestValidateBasic(t *testing.T) {
84-
g := getDefaultGenerator()
161+
func prepareBundle(g *generate.Generator) (string, string, error) {
162+
// Setup a temporary test directory
163+
tmpDir, err := ioutil.TempDir("", "ocitest")
164+
if err != nil {
165+
return "", "", err
166+
}
85167

86-
if err := runtimeValidate(runtime, g); err != nil {
87-
t.Errorf("%s failed validation: %v", runtime, err)
168+
// Create bundle directory for the test container
169+
bundleDir := tmpDir
170+
if err := os.MkdirAll(bundleDir, 0755); err != nil {
171+
return "", "", err
88172
}
173+
174+
// Create rootfs directory for the test container
175+
rootfsDir := bundleDir + "/rootfs"
176+
if err := os.MkdirAll(rootfsDir, 0755); err != nil {
177+
return "", "", err
178+
}
179+
180+
// Untar the root fs
181+
untarCmd := exec.Command("tar", "-xf", "../rootfs.tar.gz", "-C", rootfsDir)
182+
output, err := untarCmd.CombinedOutput()
183+
if err != nil {
184+
fmt.Println(string(output))
185+
return "", "", err
186+
}
187+
188+
// Generate test configuration
189+
err = g.SaveToFile(filepath.Join(bundleDir, "config.json"), generate.ExportOptions{})
190+
if err != nil {
191+
return "", "", err
192+
}
193+
194+
// Copy the configuration file to the rootfs
195+
err = fileutils.CopyFile(filepath.Join(bundleDir, "config.json"), filepath.Join(rootfsDir, "config.json"))
196+
if err != nil {
197+
return "", "", err
198+
}
199+
200+
return bundleDir, rootfsDir, nil
89201
}
90202

91-
func TestValidateSysctls(t *testing.T) {
92-
g := getDefaultGenerator()
93-
g.AddLinuxSysctl("net.ipv4.ip_forward", "1")
203+
func getDefaultGenerator() (*generate.Generator, error) {
204+
// Generate testcase template
205+
generateCmd := exec.Command("oci-runtime-tool", "generate", "--bind=/tmp:/volume/testing:rw", "--cgroups-path=/tmp/testcgroup", "--device-add=c:80:500:/dev/test:fileMode=438", "--disable-oom-kill=true", "--env=testvar=vartest", "--hostname=localvalidation", "--label=testlabel=nonevar", "--linux-cpu-shares=1024", "--output", "/tmp/config.json")
206+
output, err := generateCmd.CombinedOutput()
207+
if err != nil {
208+
fmt.Println(string(output))
209+
return nil, err
210+
}
94211

95-
if err := runtimeValidate(runtime, g); err != nil {
96-
t.Errorf("%s failed validation: %v", runtime, err)
212+
// Get testcase configuration
213+
g, err := generate.NewFromFile("/tmp/config.json")
214+
if err != nil {
215+
return nil, err
97216
}
217+
218+
g.SetRootPath("rootfs")
219+
220+
return &g, nil
98221
}

0 commit comments

Comments
 (0)