carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1//go:build linux && rootrunner
2
3package host
4
5import (
6 "bytes"
7 "context"
8 "os"
9 "testing"
10
11 "github.com/carlosframework/platform/internal/instancectl"
12 "github.com/carlosframework/platform/internal/rootstate"
13)
14
15func plan14ProductionStartupDefersReplacement(t *testing.T, original *ClaimLaunchRoot, material *claimUnitMaterializer, binding claimUnitBinding, ctl func(context.Context, ...string) (string, error)) {
16 t.Helper()
17 launch := *original
18 before, id, err := material.read(binding.Shape.Unit)
19 if err != nil {
20 t.Fatal(err)
21 }
22 invocation, err := ctl(t.Context(), "show", binding.Shape.Unit, "-p", "InvocationID", "--value")
23 if err != nil || invocation == "" {
24 t.Fatal("missing live predecessor", err)
25 }
26 oldOpen, oldMaterials, oldShapes := openClaimUnitBindings, openClaimUnitMaterializations, productionClaimUnitShapes
27 defer func() {
28 openClaimUnitBindings, openClaimUnitMaterializations, productionClaimUnitShapes = oldOpen, oldMaterials, oldShapes
29 }()
30 openClaimUnitBindings = func() (rootstate.Store, error) { return launch.unitBindings.state, nil }
31 openClaimUnitMaterializations = func() (rootstate.Store, error) { return material.state, nil }
32 productionClaimUnitShapes = func() (map[string]claimUnitShape, error) {
33 return map[string]claimUnitShape{binding.Shape.Host: binding.Shape}, nil
34 }
35 base := launch.Units.(instancectl.ClaimUnits)
36 base.BoundHost, base.BoundUnit = "", ""
37 for _, retained := range []bool{true, false} {
38 if !retained {
39 if err := launch.unitBindings.state.Remove(binding.Shape.Host + ".json"); err != nil {
40 t.Fatal(err)
41 }
42 }
43 launch.Units = base
44 wrapped := ClaimRootWithLaunch{Launch: &launch}
45 wrapped.Root.Stop.Coordinator.Kernel = claimUnitStopKernel{Units: base}
46 assembly := &ClaimAssembly{}
47 if err := bindProductionClaimUnits(t.Context(), &wrapped, assembly); err != nil {
48 t.Fatal("named unit blocked control startup", err)
49 }
50 after, afterID, err := material.read(binding.Shape.Unit)
51 if err != nil || !bytes.Equal(before, after) || !id.Same(afterID) {
52 t.Fatal("startup replaced named unit before reserved startup works", err)
53 }
54 afterInvocation, err := ctl(t.Context(), "show", binding.Shape.Unit, "-p", "InvocationID", "--value")
55 if err != nil || afterInvocation != invocation {
56 t.Fatal("startup stopped live predecessor", err)
57 }
58 if _, err := material.load(binding.Shape.Host); !os.IsNotExist(err) {
59 t.Fatal("startup retained named replacement intent", err)
60 }
61 if !retained {
62 if _, err := launch.unitBindings.read(binding.Shape.Host); !os.IsNotExist(err) {
63 t.Fatal("startup established named authority before startup works", err)
64 }
65 }
66 }
67}
68