carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package host
2
3import (
4 "context"
5 "crypto/sha256"
6 "encoding/hex"
7 "encoding/json"
8 "testing"
9
10 "github.com/carlosframework/platform/internal/hostclaim"
11 "github.com/carlosframework/platform/internal/hostguard"
12)
13
14func TestPlan14BoundProgram(t *testing.T) {
15 f, _, _ := generationLaunchFixture(t)
16 b, _, _ := plan14UnitBindingFixture(t, "console.service", "", "")
17 in, err := f.root.Guard.Root.Installation(t.Context(), f.target.Host, hostguard.Captured{Incarnation: f.target.Incarnation, Stamp: f.target.Stamp})
18 if err != nil {
19 t.Fatal(err)
20 }
21 p := claimUnitProgram{Schema: 1, Host: in.Host, Args: []string{"console", "-listen", "127.0.0.1:8090"}, Env: []string{"CONSOLE_ORIGIN=https://shop.example"}}
22 raw, _ := json.Marshal(p)
23 sum := sha256.Sum256(raw)
24 s := claimUnitShape{Host: in.Host, Account: in.Account, App: in.App, Kind: "instance", Unit: "console.service", Addr: "127.0.0.1:8090", Program: hex.EncodeToString(sum[:])}
25 b.installation = func(context.Context, string) (hostguard.RootInstallation, error) { return in, nil }
26 b.canonical = func(context.Context, string) (claimUnitShape, error) { return s, nil }
27 if _, err := b.establish(t.Context(), in.Host); err != nil {
28 t.Fatal(err)
29 }
30 f.root.unitBindings = b
31 f.root.unitProgram = func(shape claimUnitShape) (claimUnitProgram, error) { return decodeClaimUnitProgram(raw, shape) }
32 f.root.Units = plan14NamedLaunchUnits{f.units, in.Host, s.Unit}
33 f.req.Spec.Args, f.req.Spec.Env = p.Args, p.Env
34 f.req.Spec.Identity.Config = s.Program
35 launch, err := f.root.launchSpec(f.req)
36 if err != nil || len(launch.Argv) != 4 || launch.Argv[1] != "console" {
37 t.Fatal(launch, err)
38 }
39 f.units.started.Unit, f.units.started.ControlGroup, _ = f.root.Units.(plan14NamedLaunchUnits).Placement(in.Host)
40 f.req.Reservation.Group.RelativePath = f.units.started.ControlGroup
41 inputs, err := f.req.Spec.Hash()
42 if err != nil {
43 t.Fatal(err)
44 }
45 f.req.Reservation.Inputs = inputs
46 f.claims.set(func(c *hostclaim.Claim) { c.Holder.WakeRetry.Attempt.LaunchInputs = inputs })
47 f.units.beforeCheck = func() { raw = append(raw, ' ') }
48 if _, err := f.root.Serve(t.Context(), f.peer, f.req); err == nil {
49 t.Fatal("changed program at exec accepted")
50 }
51 if n, _ := f.units.counts(); n != 0 {
52 t.Fatal("changed program executed")
53 }
54 raw, _ = json.Marshal(p)
55 f.req.Spec.Env = []string{"CONSOLE_ORIGIN=https://forged.example"}
56 if _, err := f.root.launchSpec(f.req); err == nil {
57 t.Fatal("service-selected environment accepted")
58 }
59 f.req.Spec.Env = p.Env
60 f.req.Spec.Identity.Config = "forged-config"
61 if _, err := f.root.launchSpec(f.req); err == nil {
62 t.Fatal("service-selected program identity accepted")
63 }
64 f.req.Spec.Identity.Config = s.Program
65 f.req.Spec.Args = []string{"shell"}
66 if _, err := f.root.launchSpec(f.req); err == nil {
67 t.Fatal("service-selected command accepted")
68 }
69 f.req.Spec.Args = p.Args
70 raw = append(raw, ' ')
71 if _, err := f.root.launchSpec(f.req); err == nil {
72 t.Fatal("changed canonical bytes accepted")
73 }
74 f.root.unitProgram = nil
75 if _, err := f.root.launchSpec(f.req); err == nil {
76 t.Fatal("missing program reader fell through")
77 }
78}
79
80func TestPlan14BoundProgramDecode(t *testing.T) {
81 for _, p := range []claimUnitProgram{
82 {Schema: 2, Host: "shop.example"},
83 {Schema: 1, Host: "sibling.example"},
84 {Schema: 1, Host: "shop.example", Args: []string{"bad\x00arg"}},
85 {Schema: 1, Host: "shop.example", Env: []string{"A=1", "A=2"}},
86 {Schema: 1, Host: "shop.example", Env: []string{"INVALID"}},
87 } {
88 raw, _ := json.Marshal(p)
89 sum := sha256.Sum256(raw)
90 if _, err := decodeClaimUnitProgram(raw, claimUnitShape{Host: "shop.example", Program: hex.EncodeToString(sum[:])}); err == nil {
91 t.Fatal("invalid program accepted", p)
92 }
93 }
94}
95