Skip to content

Commit 8d5cb3a

Browse files
committed
add CheckSemVer unit test
Signed-off-by: liang chenye <[email protected]>
1 parent 66950fa commit 8d5cb3a

File tree

3 files changed

+100
-55
lines changed

3 files changed

+100
-55
lines changed

cmd/ocitools/validate.go

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
package main
22

33
import (
4-
"encoding/json"
54
"fmt"
6-
"io/ioutil"
7-
"os"
8-
"path"
95
"strings"
10-
"unicode/utf8"
116

12-
rspec "github.com/opencontainers/runtime-spec/specs-go"
137
"github.com/urfave/cli"
148

15-
"github.com/opencontainers/ocitools/validate"
9+
"github.com/opencontainers/runtime-tools/validate"
1610
)
1711

1812
var bundleValidateFlags = []cli.Flag{
@@ -26,37 +20,12 @@ var bundleValidateCommand = cli.Command{
2620
Before: before,
2721
Action: func(context *cli.Context) error {
2822
inputPath := context.String("path")
29-
if inputPath == "" {
30-
return fmt.Errorf("Bundle path shouldn't be empty")
31-
}
32-
33-
if _, err := os.Stat(inputPath); err != nil {
34-
return err
35-
}
36-
37-
configPath := path.Join(inputPath, "config.json")
38-
content, err := ioutil.ReadFile(configPath)
23+
hostSpecific := context.GlobalBool("host-specific")
24+
v, err := validate.NewValidatorFromPath(inputPath, hostSpecific)
3925
if err != nil {
4026
return err
4127
}
42-
if !utf8.Valid(content) {
43-
return fmt.Errorf("%q is not encoded in UTF-8", configPath)
44-
}
45-
var spec rspec.Spec
46-
if err = json.Unmarshal(content, &spec); err != nil {
47-
return err
48-
}
49-
50-
rootfsPath := path.Join(inputPath, spec.Root.Path)
51-
if fi, err := os.Stat(rootfsPath); err != nil {
52-
return fmt.Errorf("Cannot find the root path %q", rootfsPath)
53-
} else if !fi.IsDir() {
54-
return fmt.Errorf("The root path %q is not a directory.", rootfsPath)
55-
}
56-
57-
hostSpecific := context.GlobalBool("host-specific")
5828

59-
v := validate.NewValidator(spec, rootfsPath, hostSpecific)
6029
errMsgs := v.CheckAll()
6130
if len(errMsgs) > 0 {
6231
return fmt.Errorf("%d Errors detected:\n%s", len(errMsgs), strings.Join(errMsgs, "\n"))

validate/validate.go

Lines changed: 64 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ package validate
22

33
import (
44
"bufio"
5+
"encoding/json"
56
"fmt"
7+
"io/ioutil"
68
"os"
79
"path"
810
"path/filepath"
911
"reflect"
1012
"strings"
1113
"unicode"
14+
"unicode/utf8"
1215

1316
"github.com/Sirupsen/logrus"
1417
"github.com/blang/semver"
@@ -53,16 +56,42 @@ var (
5356
)
5457

5558
type Validator struct {
56-
spec rspec.Spec
57-
rootfs string
58-
hostSpecific bool
59+
spec *rspec.Spec
60+
bundlePath string
61+
HostSpecific bool
5962
}
6063

61-
func NewValidator(spec rspec.Spec, rootfs string, hostSpecific bool) Validator {
62-
return Validator{spec: spec, rootfs: rootfs, hostSpecific: hostSpecific}
64+
func NewValidator(spec *rspec.Spec, bundlePath string, hostSpecific bool) Validator {
65+
return Validator{spec: spec, bundlePath: bundlePath, HostSpecific: hostSpecific}
66+
}
67+
68+
func NewValidatorFromPath(bundlePath string, hostSpecific bool) (Validator, error) {
69+
if bundlePath == "" {
70+
return Validator{}, fmt.Errorf("Bundle path shouldn't be empty")
71+
}
72+
73+
if _, err := os.Stat(bundlePath); err != nil {
74+
return Validator{}, err
75+
}
76+
77+
configPath := path.Join(bundlePath, "config.json")
78+
content, err := ioutil.ReadFile(configPath)
79+
if err != nil {
80+
return Validator{}, err
81+
}
82+
if !utf8.Valid(content) {
83+
return Validator{}, fmt.Errorf("%q is not encoded in UTF-8", configPath)
84+
}
85+
var spec rspec.Spec
86+
if err = json.Unmarshal(content, &spec); err != nil {
87+
return Validator{}, err
88+
}
89+
90+
return NewValidator(&spec, bundlePath, hostSpecific), nil
6391
}
6492

6593
func (v *Validator) CheckAll() (msgs []string) {
94+
msgs = append(msgs, v.CheckRootfsPath()...)
6695
msgs = append(msgs, v.CheckMandatoryFields()...)
6796
msgs = append(msgs, v.CheckSemVer()...)
6897
msgs = append(msgs, v.CheckMounts()...)
@@ -74,6 +103,19 @@ func (v *Validator) CheckAll() (msgs []string) {
74103
return
75104
}
76105

106+
func (v *Validator) CheckRootfsPath() (msgs []string) {
107+
logrus.Debugf("check rootfs path")
108+
109+
rootfsPath := path.Join(v.bundlePath, v.spec.Root.Path)
110+
if fi, err := os.Stat(rootfsPath); err != nil {
111+
msgs = append(msgs, fmt.Sprintf("Cannot find the root path %q", rootfsPath))
112+
} else if !fi.IsDir() {
113+
msgs = append(msgs, fmt.Sprintf("The root path %q is not a directory.", rootfsPath))
114+
}
115+
116+
return
117+
118+
}
77119
func (v *Validator) CheckSemVer() (msgs []string) {
78120
logrus.Debugf("check semver")
79121

@@ -118,6 +160,16 @@ func (v *Validator) CheckPlatform() (msgs []string) {
118160
return
119161
}
120162

163+
func (v *Validator) CheckHooks() (msgs []string) {
164+
logrus.Debugf("check hooks")
165+
166+
msgs = append(msgs, checkEventHooks("pre-start", v.spec.Hooks.Prestart, v.HostSpecific)...)
167+
msgs = append(msgs, checkEventHooks("post-start", v.spec.Hooks.Poststart, v.HostSpecific)...)
168+
msgs = append(msgs, checkEventHooks("post-stop", v.spec.Hooks.Poststop, v.HostSpecific)...)
169+
170+
return
171+
}
172+
121173
func checkEventHooks(hookType string, hooks []rspec.Hook, hostSpecific bool) (msgs []string) {
122174
for _, hook := range hooks {
123175
if !filepath.IsAbs(hook.Path) {
@@ -143,15 +195,6 @@ func checkEventHooks(hookType string, hooks []rspec.Hook, hostSpecific bool) (ms
143195

144196
return
145197
}
146-
func (v *Validator) CheckHooks() (msgs []string) {
147-
logrus.Debugf("check hooks")
148-
149-
msgs = append(msgs, checkEventHooks("pre-start", v.spec.Hooks.Prestart, v.hostSpecific)...)
150-
msgs = append(msgs, checkEventHooks("post-start", v.spec.Hooks.Poststart, v.hostSpecific)...)
151-
msgs = append(msgs, checkEventHooks("post-stop", v.spec.Hooks.Poststop, v.hostSpecific)...)
152-
153-
return
154-
}
155198

156199
func (v *Validator) CheckProcess() (msgs []string) {
157200
logrus.Debugf("check process")
@@ -181,7 +224,7 @@ func (v *Validator) CheckProcess() (msgs []string) {
181224
}
182225

183226
if len(process.ApparmorProfile) > 0 {
184-
profilePath := filepath.Join(v.rootfs, "/etc/apparmor.d", process.ApparmorProfile)
227+
profilePath := filepath.Join(v.bundlePath, v.spec.Root.Path, "/etc/apparmor.d", process.ApparmorProfile)
185228
_, err := os.Stat(profilePath)
186229
if err != nil {
187230
msgs = append(msgs, err.Error())
@@ -195,7 +238,7 @@ func supportedMountTypes(OS string, hostSpecific bool) (map[string]bool, error)
195238
supportedTypes := make(map[string]bool)
196239

197240
if OS != "linux" && OS != "windows" {
198-
logrus.Warnf("%v is not supported to (v *Validator) Check mount type", OS)
241+
logrus.Warnf("%v is not supported to check mount type", OS)
199242
return nil, nil
200243
} else if OS == "windows" {
201244
supportedTypes["ntfs"] = true
@@ -235,7 +278,7 @@ func supportedMountTypes(OS string, hostSpecific bool) (map[string]bool, error)
235278
func (v *Validator) CheckMounts() (msgs []string) {
236279
logrus.Debugf("check mounts")
237280

238-
supportedTypes, err := supportedMountTypes(v.spec.Platform.OS, v.hostSpecific)
281+
supportedTypes, err := supportedMountTypes(v.spec.Platform.OS, v.HostSpecific)
239282
if err != nil {
240283
msgs = append(msgs, err.Error())
241284
return
@@ -310,12 +353,12 @@ func (v *Validator) CheckLinux() (msgs []string) {
310353
}
311354

312355
if v.spec.Linux.Resources != nil {
313-
ms := v.checkLinuxResources()
356+
ms := v.CheckLinuxResources()
314357
msgs = append(msgs, ms...)
315358
}
316359

317360
if v.spec.Linux.Seccomp != nil {
318-
ms := v.checkSeccomp()
361+
ms := v.CheckSeccomp()
319362
msgs = append(msgs, ms...)
320363
}
321364

@@ -334,7 +377,7 @@ func (v *Validator) CheckLinux() (msgs []string) {
334377
return
335378
}
336379

337-
func (v *Validator) checkLinuxResources() (msgs []string) {
380+
func (v *Validator) CheckLinuxResources() (msgs []string) {
338381
logrus.Debugf("check linux resources")
339382

340383
r := v.spec.Linux.Resources
@@ -350,7 +393,7 @@ func (v *Validator) checkLinuxResources() (msgs []string) {
350393
return
351394
}
352395

353-
func (v *Validator) checkSeccomp() (msgs []string) {
396+
func (v *Validator) CheckSeccomp() (msgs []string) {
354397
logrus.Debugf("check linux seccomp")
355398

356399
s := v.spec.Linux.Seccomp

validate/validate_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package validate
2+
3+
import (
4+
"strings"
5+
"testing"
6+
7+
rspec "github.com/opencontainers/runtime-spec/specs-go"
8+
)
9+
10+
func checkErrors(t *testing.T, title string, msgs []string, valid bool) {
11+
if valid && len(msgs) > 0 {
12+
t.Fatalf("%s: expected not to get error, but get %d errors:\n%s", title, len(msgs), strings.Join(msgs, "\n"))
13+
} else if !valid && len(msgs) == 0 {
14+
t.Fatalf("%s: expected to get error, but actually not", title)
15+
}
16+
}
17+
18+
func TestCheckSemVer(t *testing.T) {
19+
cases := []struct {
20+
val string
21+
expected bool
22+
}{
23+
{rspec.Version, true},
24+
//FIXME: validate currently only handles rpsec.Version
25+
{"0.0.1", false},
26+
{"invalid", false},
27+
}
28+
29+
for _, c := range cases {
30+
v := NewValidator(&rspec.Spec{Version: c.val}, "", false)
31+
checkErrors(t, "checkSemVer "+c.val, v.CheckSemVer(), c.expected)
32+
}
33+
}

0 commit comments

Comments
 (0)