1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
12 "git.curoverse.com/arvados.git/lib/cloud"
13 "git.curoverse.com/arvados.git/lib/dispatchcloud/test"
14 "git.curoverse.com/arvados.git/sdk/go/arvados"
15 check "gopkg.in/check.v1"
18 var _ = check.Suite(&WorkerSuite{})
20 type WorkerSuite struct{}
22 func (suite *WorkerSuite) TestProbeAndUpdate(c *check.C) {
23 logger := test.Logger()
24 bootTimeout := time.Minute
25 probeTimeout := time.Second
27 is, err := (&test.StubDriver{}).InstanceSet(nil, "", logger)
28 c.Assert(err, check.IsNil)
29 inst, err := is.Create(arvados.InstanceType{}, "", nil, nil)
30 c.Assert(err, check.IsNil)
33 testCaseComment string // displayed in test output to help identify failure case
38 respBoot stubResp // zero value is success
39 respRun stubResp // zero value is success + nothing running
44 errFail := errors.New("failed")
45 respFail := stubResp{"", "command failed\n", errFail}
46 respContainerRunning := stubResp{"zzzzz-dz642-abcdefghijklmno\n", "", nil}
47 for _, trial := range []trialT{
49 testCaseComment: "Unknown, probes fail",
53 expectState: StateUnknown,
56 testCaseComment: "Unknown, boot probe fails, but one container is running",
59 respRun: respContainerRunning,
60 expectState: StateUnknown,
64 testCaseComment: "Unknown, boot probe fails, previously running container has exited",
68 expectState: StateUnknown,
72 testCaseComment: "Unknown, boot timeout exceeded, boot probe fails",
74 age: bootTimeout + time.Second,
77 expectState: StateShutdown,
80 testCaseComment: "Unknown, boot timeout exceeded, boot probe succeeds but crunch-run fails",
84 expectState: StateShutdown,
87 testCaseComment: "Unknown, boot timeout exceeded, boot probe fails but crunch-run succeeds",
91 expectState: StateShutdown,
94 testCaseComment: "Unknown, boot timeout exceeded, boot probe fails but container is running",
98 respRun: respContainerRunning,
99 expectState: StateUnknown,
103 testCaseComment: "Booting, boot probe fails, run probe fails",
107 expectState: StateBooting,
110 testCaseComment: "Booting, boot probe fails, run probe succeeds (but isn't expected to be called)",
113 expectState: StateBooting,
116 testCaseComment: "Booting, boot probe succeeds, run probe fails",
119 expectState: StateBooting,
122 testCaseComment: "Booting, boot probe succeeds, run probe succeeds",
124 expectState: StateIdle,
127 testCaseComment: "Booting, boot probe succeeds, run probe succeeds, container is running",
129 respRun: respContainerRunning,
130 expectState: StateRunning,
134 testCaseComment: "Booting, boot timeout exceeded",
136 age: bootTimeout * 2,
138 expectState: StateShutdown,
141 testCaseComment: "Idle, probe timeout exceeded, one container running",
143 age: probeTimeout * 2,
144 respRun: respContainerRunning,
145 expectState: StateRunning,
149 testCaseComment: "Idle, probe timeout exceeded, one container running, probe fails",
151 age: probeTimeout * 2,
154 expectState: StateShutdown,
158 testCaseComment: "Idle, probe timeout exceeded, nothing running, probe fails",
160 age: probeTimeout * 2,
162 expectState: StateShutdown,
165 testCaseComment: "Running, one container still running",
168 respRun: respContainerRunning,
169 expectState: StateRunning,
173 testCaseComment: "Running, container has exited",
176 expectState: StateIdle,
180 testCaseComment: "Running, probe timeout exceeded, nothing running, new container being started",
182 age: probeTimeout * 2,
184 expectState: StateRunning,
187 c.Logf("------- %#v", trial)
188 ctime := time.Now().Add(-trial.age)
190 "bootprobe": trial.respBoot,
191 "crunch-run --list": trial.respRun,
194 newExecutor: func(cloud.Instance) Executor { return exr },
195 bootProbeCommand: "bootprobe",
196 timeoutBooting: bootTimeout,
197 timeoutProbe: probeTimeout,
198 exited: map[string]time.Time{},
212 if trial.running > 0 {
213 wkr.running = map[string]struct{}{"zzzzz-dz642-abcdefghijklmno": struct{}{}}
215 if trial.starting > 0 {
216 wkr.starting = map[string]struct{}{"zzzzz-dz642-abcdefghijklmno": struct{}{}}
219 c.Check(wkr.state, check.Equals, trial.expectState)
220 c.Check(len(wkr.running), check.Equals, trial.expectRunning)
224 type stubResp struct {
229 type stubExecutor map[string]stubResp
231 func (se stubExecutor) SetTarget(cloud.ExecutorTarget) {}
232 func (se stubExecutor) Close() {}
233 func (se stubExecutor) Execute(env map[string]string, cmd string, stdin io.Reader) (stdout, stderr []byte, err error) {
236 return nil, []byte("command not found\n"), errors.New("command not found")
238 return []byte(resp.stdout), []byte(resp.stderr), resp.err