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 "os"
6 "strings"
7 "testing"
8
9 "github.com/carlosframework/platform/internal/hostguard"
10 "github.com/carlosframework/platform/internal/rootstate"
11)
12
13func TestPlan14UnitRetirementExactOwner(t *testing.T) {
14 for _, attack := range []string{"none", "successor", "running", "lost replace", "lost final write"} {
15 t.Run(attack, func(t *testing.T) {
16 b, in, shape := plan14UnitBindingFixture(t, "console.service", "", "")
17 shape.Program = strings.Repeat("a", 64)
18 b.canonical = func(context.Context, string) (claimUnitShape, error) { return shape, nil }
19 captured, err := b.establish(t.Context(), in.Host)
20 if err != nil {
21 t.Fatal(err)
22 }
23 files := &plan14UnitFiles{}
24 ms := &plan14UnitBindingFault{Store: &rollbackMemory{files: map[string][]byte{}}}
25 material := claimUnitMaterializer{idle: func(string) error { return nil }, state: ms, read: files.read, create: files.create, replace: files.replace}
26 if err = material.install(t.Context(), captured); err != nil {
27 t.Fatal(err)
28 }
29 target := hostguard.FenceTarget{Host: in.Host, Incarnation: in.Incarnation, Stamp: in.Stamp, Box: in.Box, Enrollment: in.Enrollment}
30 if attack == "successor" {
31 target.Stamp++
32 }
33 gone := func(context.Context, string, string) error {
34 if attack == "running" {
35 return os.ErrPermission
36 }
37 return nil
38 }
39 original := material.replace
40 material.replace = func(unit string, id rootstate.FileIdentity, body []byte) error {
41 if err := original(unit, id, body); err != nil {
42 return err
43 }
44 if attack == "lost replace" {
45 return os.ErrInvalid
46 }
47 if attack == "lost final write" {
48 ms.fail = true
49 }
50 return nil
51 }
52 err = retireClaimBoundUnit(t.Context(), target, b, material, gone)
53 if attack == "none" {
54 if err != nil {
55 t.Fatal(err)
56 }
57 } else if err == nil {
58 t.Fatal("attack accepted")
59 }
60 if attack == "successor" || attack == "running" {
61 if files.retires != 0 {
62 t.Fatal("foreign or running retired")
63 }
64 return
65 }
66 material.replace = original
67 ms.fail = false
68 if err = retireClaimBoundUnit(t.Context(), target, b, material, gone); err != nil {
69 t.Fatal("recover", err)
70 }
71 retired, err := b.read(in.Host)
72 if err != nil || !retired.Retired || files.retires != 1 {
73 t.Fatal(retired, err, files.retires)
74 }
75 })
76 }
77}
78