Skip to content

Commit 2bc8c77

Browse files
authored
Merge pull request #5068 from AkihiroSuda/restart-test
restart: add an integration test
2 parents 119fe70 + 36df282 commit 2bc8c77

1 file changed

Lines changed: 111 additions & 0 deletions

File tree

restart_monitor_linux_test.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
Copyright The containerd Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package containerd
18+
19+
import (
20+
"context"
21+
"fmt"
22+
"syscall"
23+
"testing"
24+
"time"
25+
26+
"github.com/containerd/containerd/containers"
27+
"github.com/containerd/containerd/oci"
28+
)
29+
30+
// TestRestartMonitor tests restarting containers
31+
// with the restart monitor service plugin
32+
func TestRestartMonitor(t *testing.T) {
33+
const (
34+
interval = 10 * time.Second
35+
epsilon = 1 * time.Second
36+
)
37+
configTOML := fmt.Sprintf(`
38+
version = 2
39+
[plugins]
40+
[plugins."io.containerd.internal.v1.restart"]
41+
interval = "%s"
42+
`, interval.String())
43+
client, _, cleanup := newDaemonWithConfig(t, configTOML)
44+
defer cleanup()
45+
46+
var (
47+
ctx, cancel = testContext(t)
48+
id = t.Name()
49+
)
50+
defer cancel()
51+
52+
image, err := client.Pull(ctx, testImage, WithPullUnpack)
53+
if err != nil {
54+
t.Fatal(err)
55+
}
56+
57+
container, err := client.NewContainer(ctx, id,
58+
WithNewSnapshot(id, image),
59+
WithNewSpec(
60+
oci.WithImageConfig(image),
61+
withProcessArgs("sleep", "infinity"),
62+
),
63+
withRestartStatus(Running),
64+
)
65+
if err != nil {
66+
t.Fatal(err)
67+
}
68+
defer container.Delete(ctx, WithSnapshotCleanup)
69+
70+
task, err := container.NewTask(ctx, empty())
71+
if err != nil {
72+
t.Fatal(err)
73+
}
74+
defer task.Delete(ctx, WithProcessKill)
75+
76+
if err := task.Start(ctx); err != nil {
77+
t.Fatal(err)
78+
}
79+
80+
task.Kill(ctx, syscall.SIGKILL)
81+
begin := time.Now()
82+
deadline := begin.Add(interval).Add(epsilon)
83+
for time.Now().Before(deadline) {
84+
status, err := task.Status(ctx)
85+
if err != nil {
86+
t.Fatal(err)
87+
}
88+
t.Logf("%v: status=%q", time.Now(), status)
89+
90+
if status.Status == Running {
91+
elapsed := time.Since(begin)
92+
t.Logf("the task was restarted after %s", elapsed.String())
93+
return
94+
}
95+
time.Sleep(epsilon)
96+
}
97+
t.Fatalf("the task was not restarted in %s + %s",
98+
interval.String(), epsilon.String())
99+
}
100+
101+
// withRestartStatus is a copy of "github.com/containerd/containerd/runtime/restart".WithStatus.
102+
// This copy is needed because `go test` refuses circular imports.
103+
func withRestartStatus(status ProcessStatus) func(context.Context, *Client, *containers.Container) error {
104+
return func(_ context.Context, _ *Client, c *containers.Container) error {
105+
if c.Labels == nil {
106+
c.Labels = make(map[string]string)
107+
}
108+
c.Labels["containerd.io/restart.status"] = string(status)
109+
return nil
110+
}
111+
}

0 commit comments

Comments
 (0)