carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package instancectl
2
3import (
4 "context"
5 "errors"
6 "os"
7 "path/filepath"
8 "strings"
9 "testing"
10)
11
12func TestPlan14BoundUnitPlacement(t *testing.T) {
13 for _, name := range []string{"console.service", "woodstar-atbridge.service", "carlos-app@shop.example.service"} {
14 t.Run(name, func(t *testing.T) {
15 u, ctl, in, _ := claimUnitFixture(t)
16 u.BoundHost, u.BoundUnit = in.Host, name
17 ctl.group = "/" + BoundClaimUnitControlGroup(in.Host, name)
18 ctl.events = filepath.Join(u.CgroupRoot, strings.TrimPrefix(ctl.group, "/"))
19 if err := os.MkdirAll(ctl.events, 0755); err != nil {
20 t.Fatal(err)
21 }
22 ctl.setPopulated(false)
23 // A bound unit must never be started by the unreserved entrypoint.
24 if _, err := u.Start(t.Context(), in); err == nil {
25 t.Fatal("unreserved named launch")
26 }
27 if strings.Contains(ctl.joined(), "start ") {
28 t.Fatal(ctl.joined())
29 }
30 if err := u.Gone(t.Context(), in.Host, ""); err != nil {
31 t.Fatal(err)
32 }
33 ctl.state, ctl.invocation = "active", "replacement"
34 ctl.setPopulated(true)
35 if err := u.Gone(t.Context(), in.Host, "old"); !errors.Is(err, ErrClaimUnitBusy) {
36 t.Fatalf("replacement with populated tree accepted: %v", err)
37 }
38 ctl.state = "inactive"
39 if err := u.Gone(t.Context(), in.Host, "old"); !errors.Is(err, ErrClaimUnitBusy) {
40 t.Fatalf("descendants accepted: %v", err)
41 }
42 ctl.setPopulated(false)
43 if err := u.Gone(t.Context(), in.Host, "old"); err != nil {
44 t.Fatal(err)
45 }
46 before := ctl.joined()
47 if err := u.Stop(context.Background(), "sibling.example"); err == nil {
48 t.Fatal("binding crossed hosts")
49 }
50 if ctl.joined() != before {
51 t.Fatal("foreign host reached systemd")
52 }
53 })
54 }
55}
56
57func TestPlan14BoundUnitNames(t *testing.T) {
58 for _, name := range []string{"../console.service", "console.service/child", "x\n.service", "x@.service", "x.socket", "--x.service", "carlos-instance-control.service"} {
59 u, ctl, in, _ := claimUnitFixture(t)
60 u.BoundHost, u.BoundUnit = in.Host, name
61 if err := u.Gone(t.Context(), in.Host, ""); err == nil {
62 t.Fatalf("accepted %q", name)
63 }
64 if ctl.joined() != "" {
65 t.Fatal("invalid binding reached systemd")
66 }
67 }
68}
69
70func TestPlan14BoundUnitExactStop(t *testing.T) {
71 u, ctl, in, _ := claimUnitFixture(t)
72 u.BoundHost, u.BoundUnit = in.Host, "console.service"
73 ctl.group = "/" + BoundClaimUnitControlGroup(in.Host, u.BoundUnit)
74 ctl.invocation, ctl.state = "replacement", "active"
75 if err := u.StopInvocation(t.Context(), in.Host, "old"); err == nil {
76 t.Fatal("stopped replacement")
77 }
78 if strings.Contains(ctl.joined(), "stop ") {
79 t.Fatal(ctl.joined())
80 }
81 if err := u.StopInvocation(t.Context(), in.Host, ""); err == nil {
82 t.Fatal("stopped unknown invocation")
83 }
84 ctl.invocation = "old"
85 if err := u.StopInvocation(t.Context(), in.Host, "old"); err != nil {
86 t.Fatal(err)
87 }
88 if !strings.Contains(ctl.joined(), "stop console.service") {
89 t.Fatal(ctl.joined())
90 }
91}
92
93func TestPlan14BoundStopReportsInvocationRace(t *testing.T) {
94 for _, changed := range []string{"invocation", "group"} {
95 t.Run(changed, func(t *testing.T) {
96 u, ctl, in, _ := claimUnitFixture(t)
97 u.BoundHost, u.BoundUnit = in.Host, "console.service"
98 ctl.group = "/" + BoundClaimUnitControlGroup(in.Host, u.BoundUnit)
99 ctl.invocation, ctl.state = "old", "active"
100 u.Systemctl = func(ctx context.Context, args ...string) (string, error) {
101 if args[0] == "stop" {
102 if changed == "invocation" {
103 ctl.invocation = "replacement"
104 } else {
105 ctl.group = "/sibling.slice/console.service"
106 }
107 }
108 return ctl.run(ctx, args...)
109 }
110 if err := u.StopInvocation(t.Context(), in.Host, "old"); !errors.Is(err, ErrClaimUnitBusy) {
111 t.Fatal("uncertain stop reported success", err)
112 }
113 })
114 }
115}
116