Skip to content

Commit 73964f2

Browse files
committed
add hooks stdin test
Signed-off-by: Liang Chenye <[email protected]>
1 parent 216ebc7 commit 73964f2

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed

validation/hooks_stdin.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"io/ioutil"
7+
"os"
8+
"path/filepath"
9+
"reflect"
10+
"time"
11+
12+
tap "github.com/mndrix/tap-go"
13+
rspecs "github.com/opencontainers/runtime-spec/specs-go"
14+
"github.com/opencontainers/runtime-tools/specerror"
15+
"github.com/opencontainers/runtime-tools/validation/util"
16+
uuid "github.com/satori/go.uuid"
17+
)
18+
19+
func stdinStateCheck(outputDir, hookName string, expectedState rspecs.State) error {
20+
var state rspecs.State
21+
data, err := ioutil.ReadFile(filepath.Join(outputDir, hookName))
22+
if err != nil {
23+
return err
24+
}
25+
err = json.Unmarshal(data, &state)
26+
if err != nil {
27+
return err
28+
}
29+
30+
if state.ID != expectedState.ID {
31+
return fmt.Errorf("wrong container ID %q in the stdin of %s hook, expected %q", state.ID, hookName, expectedState.ID)
32+
}
33+
34+
if state.Bundle != expectedState.Bundle {
35+
return fmt.Errorf("wrong bundle directory %q in the stdin of %s hook, expected %q", state.Bundle, hookName, expectedState.Bundle)
36+
}
37+
38+
if hookName != "poststop" && state.Pid != expectedState.Pid {
39+
return fmt.Errorf("wrong container process ID %q in the stdin of %s hook, expected %q", state.Version, hookName, expectedState.Version)
40+
}
41+
42+
if !reflect.DeepEqual(state.Annotations, expectedState.Annotations) {
43+
return fmt.Errorf("wrong annotations \"%v\" in the stdin of %s hook, expected \"%v\"", state.Annotations, hookName, expectedState.Annotations)
44+
}
45+
return nil
46+
}
47+
48+
func main() {
49+
t := tap.New()
50+
t.Header(0)
51+
52+
bundleDir, err := util.PrepareBundle()
53+
if err != nil {
54+
util.Fatal(err)
55+
}
56+
containerID := uuid.NewV4().String()
57+
defer os.RemoveAll(bundleDir)
58+
59+
var containerPid int
60+
61+
annotationKey := "org.opencontainers.runtime-tools"
62+
annotationValue := "hook stdin test"
63+
g := util.GetDefaultGenerator()
64+
outputDir := filepath.Join(bundleDir, g.Spec().Root.Path)
65+
timeout := 1
66+
g.AddAnnotation(annotationKey, annotationValue)
67+
g.AddPreStartHook(rspecs.Hook{
68+
Path: filepath.Join(bundleDir, g.Spec().Root.Path, "/bin/sh"),
69+
Args: []string{
70+
"sh", "-c", fmt.Sprintf("cat > %s", filepath.Join(outputDir, "prestart")),
71+
},
72+
Timeout: &timeout,
73+
})
74+
g.AddPostStartHook(rspecs.Hook{
75+
Path: filepath.Join(bundleDir, g.Spec().Root.Path, "/bin/sh"),
76+
Args: []string{
77+
"sh", "-c", fmt.Sprintf("cat > %s", filepath.Join(outputDir, "poststart")),
78+
},
79+
Timeout: &timeout,
80+
})
81+
g.AddPostStopHook(rspecs.Hook{
82+
Path: filepath.Join(bundleDir, g.Spec().Root.Path, "/bin/sh"),
83+
Args: []string{
84+
"sh", "-c", fmt.Sprintf("cat > %s", filepath.Join(outputDir, "poststop")),
85+
},
86+
Timeout: &timeout,
87+
})
88+
g.SetProcessArgs([]string{"true"})
89+
config := util.LifecycleConfig{
90+
BundleDir: bundleDir,
91+
Config: g,
92+
Actions: util.LifecycleActionCreate | util.LifecycleActionStart | util.LifecycleActionDelete,
93+
PreCreate: func(r *util.Runtime) error {
94+
r.SetID(containerID)
95+
return nil
96+
},
97+
PreDelete: func(r *util.Runtime) error {
98+
state, err := r.State()
99+
if err != nil {
100+
return err
101+
}
102+
containerPid = state.Pid
103+
util.WaitingForStatus(*r, util.LifecycleStatusStopped, time.Second*10, time.Second)
104+
return nil
105+
},
106+
}
107+
108+
err = util.RuntimeLifecycleValidate(config)
109+
if err != nil {
110+
util.Fatal(err)
111+
}
112+
113+
expectedState := rspecs.State{
114+
Pid: containerPid,
115+
ID: containerID,
116+
Bundle: bundleDir,
117+
Annotations: map[string]string{annotationKey: annotationValue},
118+
}
119+
for _, file := range []string{"prestart", "poststart", "poststop"} {
120+
err := stdinStateCheck(outputDir, file, expectedState)
121+
util.SpecErrorOK(t, err == nil, specerror.NewError(specerror.PosixHooksStateToStdin, fmt.Errorf("the state of the container MUST be passed to %q hook over stdin", file), rspecs.Version), err)
122+
}
123+
124+
t.AutoPlan()
125+
}

0 commit comments

Comments
 (0)