1
16
17 package exec
18
19 import (
20 "fmt"
21 "io"
22 "strings"
23 "testing"
24 "time"
25
26 utilfeature "k8s.io/apiserver/pkg/util/feature"
27 featuregatetesting "k8s.io/component-base/featuregate/testing"
28 "k8s.io/kubernetes/pkg/features"
29 "k8s.io/kubernetes/pkg/probe"
30 )
31
32 type FakeCmd struct {
33 out []byte
34 stdout []byte
35 err error
36 writer io.Writer
37 }
38
39 func (f *FakeCmd) Run() error {
40 return nil
41 }
42
43 func (f *FakeCmd) CombinedOutput() ([]byte, error) {
44 return f.out, f.err
45 }
46
47 func (f *FakeCmd) Output() ([]byte, error) {
48 return f.stdout, f.err
49 }
50
51 func (f *FakeCmd) SetDir(dir string) {}
52
53 func (f *FakeCmd) SetStdin(in io.Reader) {}
54
55 func (f *FakeCmd) SetStdout(out io.Writer) {
56 f.writer = out
57 }
58
59 func (f *FakeCmd) SetStderr(out io.Writer) {
60 f.writer = out
61 }
62
63 func (f *FakeCmd) SetEnv(env []string) {}
64
65 func (f *FakeCmd) Stop() {}
66
67 func (f *FakeCmd) Start() error {
68 if f.writer != nil {
69 f.writer.Write(f.out)
70 return f.err
71 }
72 return f.err
73 }
74
75 func (f *FakeCmd) Wait() error { return nil }
76
77 func (f *FakeCmd) StdoutPipe() (io.ReadCloser, error) {
78 return nil, nil
79 }
80
81 func (f *FakeCmd) StderrPipe() (io.ReadCloser, error) {
82 return nil, nil
83 }
84
85 type fakeExitError struct {
86 exited bool
87 statusCode int
88 }
89
90 func (f *fakeExitError) String() string {
91 return f.Error()
92 }
93
94 func (f *fakeExitError) Error() string {
95 return "fake exit"
96 }
97
98 func (f *fakeExitError) Exited() bool {
99 return f.exited
100 }
101
102 func (f *fakeExitError) ExitStatus() int {
103 return f.statusCode
104 }
105
106 func TestExec(t *testing.T) {
107 prober := New()
108
109 tenKilobyte := strings.Repeat("logs-123", 128*10)
110 elevenKilobyte := strings.Repeat("logs-123", 8*128*11)
111
112 tests := []struct {
113 expectedStatus probe.Result
114 expectError bool
115 execProbeTimeout bool
116 input string
117 output string
118 err error
119 }{
120
121 {probe.Success, false, true, "OK", "OK", nil},
122
123 {probe.Success, false, true, "OK", "OK", &fakeExitError{true, 0}},
124
125 {probe.Success, false, true, elevenKilobyte, tenKilobyte, nil},
126
127 {probe.Unknown, true, true, "", "", fmt.Errorf("test error")},
128
129 {probe.Failure, false, true, "Fail", "", &fakeExitError{true, 1}},
130
131 {probe.Failure, false, true, "", "command testcmd timed out", NewTimeoutError(fmt.Errorf("command testcmd timed out"), time.Second)},
132
133 {probe.Unknown, true, false, "", "", NewTimeoutError(fmt.Errorf("command testcmd timed out"), time.Second)},
134 }
135
136 for i, test := range tests {
137 defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExecProbeTimeout, test.execProbeTimeout)()
138 fake := FakeCmd{
139 out: []byte(test.output),
140 err: test.err,
141 }
142 status, output, err := prober.Probe(&fake)
143 if status != test.expectedStatus {
144 t.Errorf("[%d] expected %v, got %v", i, test.expectedStatus, status)
145 }
146 if err != nil && !test.expectError {
147 t.Errorf("[%d] unexpected error: %v", i, err)
148 }
149 if err == nil && test.expectError {
150 t.Errorf("[%d] unexpected non-error", i)
151 }
152 if test.output != output {
153 t.Errorf("[%d] expected %s, got %s", i, test.output, output)
154 }
155 }
156 }
157
View as plain text