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 "bytes"
5 "context"
6 "errors"
7 "os"
8 "path/filepath"
9 "strings"
10 "testing"
11 "time"
12
13 "github.com/carlosframework/platform/internal/activator"
14)
15
16func TestScheduleTokenFencePreservesEnvironment(t *testing.T) {
17 for _, content := range []string{"", "APP_SETTING=retained\n", "APP_SETTING=retained\nCARLOS_ADMIN_TOKEN=" + strings.Repeat("a", 64) + "\n"} {
18 name := "missing-file"
19 if content != "" {
20 name = "existing-without-token"
21 }
22 if strings.Contains(content, "CARLOS_ADMIN_TOKEN") {
23 name = "existing-token"
24 }
25 t.Run(name, func(t *testing.T) {
26 dd := t.TempDir()
27 const host = "fenced.example.com"
28 path := filepath.Join(dd, host+".env")
29 if content != "" {
30 if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
31 t.Fatal(err)
32 }
33 if err := os.Chmod(path, 0o644); err != nil {
34 t.Fatal(err)
35 }
36 }
37 svc := &activator.Service{}
38 ctx, cancel := context.WithTimeout(context.Background(), time.Second)
39 defer cancel()
40 if _, err := svc.FenceAndStop(ctx, host, 1); !errors.Is(err, activator.ErrStopUnproven) {
41 t.Fatal(err)
42 }
43 // Exercise the actual runner wiring, including the nil-store arm.
44 sd := newScheduleDeps(nil, nil, svc, nil, dd)
45 if token, err := sd.runner.Token(host); token != "" || !errors.Is(err, activator.ErrFenced) {
46 t.Fatalf("fenced token: present=%v err=%v", token != "", err)
47 }
48 raw, err := os.ReadFile(path)
49 if content == "" {
50 if !os.IsNotExist(err) {
51 t.Fatalf("fence created env: %v", err)
52 }
53 return
54 }
55 if err != nil || !bytes.Equal(raw, []byte(content)) {
56 t.Fatalf("fence changed bytes: %v", err)
57 }
58 fi, err := os.Stat(path)
59 if err != nil {
60 t.Fatal(err)
61 }
62 if fi.Mode().Perm() != 0o644 {
63 t.Fatalf("fence changed mode: %o", fi.Mode().Perm())
64 }
65 })
66 }
67}
68
69func TestScheduleTokenUnfencedManagedPreparation(t *testing.T) {
70 dd := t.TempDir()
71 const host = "ordinary.example.com"
72 path := filepath.Join(dd, host+".env")
73 if err := os.WriteFile(path, []byte("APP_SETTING=retained\n"), 0o644); err != nil {
74 t.Fatal(err)
75 }
76 sd := newScheduleDeps(nil, nil, &activator.Service{}, nil, dd)
77 first, err := sd.runner.Token(host)
78 if err != nil || len(first) != 64 {
79 t.Fatalf("mint: present=%v err=%v", first != "", err)
80 }
81 if err := os.Chmod(path, 0o644); err != nil {
82 t.Fatal(err)
83 }
84 second, err := sd.runner.Token(host)
85 if err != nil || first != second {
86 t.Fatalf("retained token: %v", err)
87 }
88 raw, err := os.ReadFile(path)
89 if err != nil {
90 t.Fatal(err)
91 }
92 if !bytes.HasPrefix(raw, []byte("APP_SETTING=retained\n")) || bytes.Count(raw, []byte("CARLOS_ADMIN_TOKEN=")) != 1 {
93 t.Fatal("ordinary token preparation lost environment or duplicated token")
94 }
95 fi, err := os.Stat(path)
96 if err != nil {
97 t.Fatal(err)
98 }
99 if fi.Mode().Perm() != 0o600 {
100 t.Fatalf("ordinary mode: %o", fi.Mode().Perm())
101 }
102}
103