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 "strings"
5 "testing"
6
7 "github.com/carlosframework/platform/internal/provision"
8)
9
10// Escape follows systemd-escape(1) for unit instance names. The cases are
11// the ones our identifiers can produce (hosts are [a-z0-9.-]; a hashed
12// identifier adds a leading underscore), plus the general rules so a
13// surprise character can never yield an unloadable unit name.
14func TestEscapeFollowsSystemd(t *testing.T) {
15 cases := map[string]string{
16 "bill.go.tito.io": "bill.go.tito.io",
17 "bill-2.example.com": `bill\x2d2.example.com`,
18 "_aaaa-1234abcd": `_aaaa\x2d1234abcd`,
19 "a/b": "a-b",
20 ".hidden": `\x2ehidden`,
21 "x y": `x\x20y`,
22 "": "",
23 "UPPER_ok:1": "UPPER_ok:1",
24 }
25 for in, want := range cases {
26 if got := Escape(in); got != want {
27 t.Errorf("Escape(%q) = %q, want %q", in, got, want)
28 }
29 }
30}
31
32func TestUnitAndSliceNamesAreKeyedByEscapedInstanceID(t *testing.T) {
33 host := "bill-2.example.com"
34 esc := `bill\x2d2.example.com`
35 if got := UnitName(RoleRun, host); got != "carlos-instance@"+esc+".service" {
36 t.Errorf("run unit = %q", got)
37 }
38 if got := UnitName(RoleSeed, host); got != "carlos-instance-seed@"+esc+".service" {
39 t.Errorf("seed unit = %q", got)
40 }
41 if got := UnitName(RoleSidecar, host); got != "carlos-instance-sidecar@"+esc+".service" {
42 t.Errorf("sidecar unit = %q", got)
43 }
44 if got := SliceName(host); got != "carlos-instances-"+esc+".slice" {
45 t.Errorf("slice = %q", got)
46 }
47 long := strings.Repeat("a", 60) + ".example.com"
48 if got := UnitName(RoleRun, long); !strings.HasPrefix(got, "carlos-instance@_") || !strings.HasSuffix(got, ".service") {
49 t.Errorf("long host unit = %q, want the hashed identifier", got)
50 }
51 if got, want := UnitName(RoleRun, long), "carlos-instance@"+Escape(provision.InstanceID(long))+".service"; got != want {
52 t.Errorf("long host unit = %q, want %q", got, want)
53 }
54}
55
56func TestParseUnitNameRoundTrips(t *testing.T) {
57 for _, role := range []Role{RoleRun, RoleSeed, RoleSidecar, RoleCmd} {
58 u := UnitName(role, "bill-2.example.com")
59 gotRole, esc, ok := ParseUnitName(u)
60 if !ok || gotRole != role || esc != `bill\x2d2.example.com` {
61 t.Errorf("ParseUnitName(%q) = %q %q %v", u, gotRole, esc, ok)
62 }
63 }
64 if got := UnitName(RoleCmd, "bill-2.example.com"); got != `carlos-instance-cmd@bill\x2d2.example.com.service` {
65 t.Errorf("cmd unit = %q", got)
66 }
67 for _, bad := range []string{"carlos-edge.service", "carlos-app@x.service", "carlos-instance@x.socket", "carlos-instance@.service", "carlos-instance-cmd@.service", "carlos-instances-x.slice"} {
68 if _, _, ok := ParseUnitName(bad); ok {
69 t.Errorf("ParseUnitName(%q) accepted", bad)
70 }
71 }
72}
73
74func TestParseRole(t *testing.T) {
75 for _, s := range []string{"run", "seed", "sidecar", "cmd"} {
76 if r, ok := ParseRole(s); !ok || string(r) != s {
77 t.Errorf("ParseRole(%q) = %q %v", s, r, ok)
78 }
79 }
80 for _, s := range []string{"", "Run", "exec", "run ", "Cmd", "cmd-err"} {
81 if _, ok := ParseRole(s); ok {
82 t.Errorf("ParseRole(%q) accepted", s)
83 }
84 }
85}
86
87func TestFileNames(t *testing.T) {
88 if got := LaunchFileName(RoleSidecar); got != "launch.sidecar.json" {
89 t.Errorf("LaunchFileName = %q", got)
90 }
91 if got := ExitRecordName(RoleRun, "abc123"); got != "exit.run.abc123.json" {
92 t.Errorf("ExitRecordName = %q", got)
93 }
94 if provision.ValidHostShape(ProbeDirName) {
95 t.Errorf("ProbeDirName %q is a valid host; it must never collide with one", ProbeDirName)
96 }
97}
98