Repository navigation
Expand file tree
/
Copy pathchatv3_host_automations_test.go
More file actions
126 lines (119 loc) · 5.17 KB
/
Copy pathchatv3_host_automations_test.go
File metadata and controls
126 lines (119 loc) · 5.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package main
import (
"os"
"path/filepath"
"reflect"
"testing"
"time"
"github.com/Agent-Field/codeaf/internal/automation"
"github.com/Agent-Field/codeaf/internal/home"
"github.com/Agent-Field/codeaf/internal/remote"
)
// THE HOST DOOR HANDS THE WINDOW THE FAR MACHINE'S AUTOMATIONS, AND NOTHING WHEN
// THE FAR ENGINE HAS NONE. The engine below keeps a store of the test's own in a
// zone that is nobody's local one: the seam hostOptions builds reads that store
// over the wire, carries that zone, and claims a run's notification once; an
// engine whose welcome does not say it has the doors hands the zero seam, which
// the surface reads as automations absent — never this laptop's store.
func TestTheHostDoorReadsTheFarMachinesAutomations(t *testing.T) {
t.Setenv("HOME", t.TempDir())
store, err := automation.Open(t.TempDir())
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _ = store.Close() })
loop, err := remote.Loopback(remote.Hello{Version: remote.Version, Workspace: "/srv/app"}, remote.Options{
Boot: func(remote.Hello) (*remote.Engine, error) {
return &remote.Engine{Agent: &quietAgent{}, Workspace: "/srv/app", SessionFile: "/srv/app/j.jsonl",
Automations: &remote.EngineAutomations{Store: store, Zone: "Pacific/Chatham"}}, nil
},
})
if err != nil {
t.Fatalf("dial the loopback: %v", err)
}
t.Cleanup(func() { _ = loop.Close() })
fleet := onePipeFleet("devbox", loop.Client)
t.Cleanup(fleet.closeAll)
options, _ := hostOptions(fleet, loop.Client.Welcome(), false)
seam := options.Automations
if seam.List == nil || seam.Changes == nil || seam.Claim == nil || seam.Active == nil {
t.Fatal("the door hands a window over --host no automations seam, so it can draw none of that machine's automations")
}
if seam.Zone != "Pacific/Chatham" {
t.Fatalf("a rhythm typed over --host is read in %q, want the far machine's own zone", seam.Zone)
}
made, err := store.Create(automation.Automation{
Title: "leave", Workspace: "/srv/app",
Schedule: automation.Schedule{At: time.Now().Add(time.Hour)},
Action: automation.Action{Say: "time to leave"},
})
if err != nil {
t.Fatal(err)
}
list, err := seam.List()
if err != nil || len(list) != 1 || list[0].ID != made.ID {
t.Fatalf("the window's list of the far machine answered %+v, %v", list, err)
}
run, err := store.QueueNow(made.ID)
if err != nil {
t.Fatal(err)
}
if !seam.Claim(run.ID) {
t.Fatal("the first window to claim a run's notification was refused it")
}
if seam.Claim(run.ID) {
t.Fatal("a run's notification was claimed twice")
}
// A FOLDER UNDER ~ CROSSES AS ~ AND IS READ ON THE FAR MACHINE. The line is
// typed on the laptop, whose home is not the home of the machine that keeps
// and runs the automation, so the window sends it unexpanded and the far
// store reads it there.
far, err := seam.Create(automation.Automation{
Title: "plants", Workspace: "~/app",
Schedule: automation.Schedule{At: time.Now().Add(time.Hour)},
Action: automation.Action{Say: "water the plants"},
})
if err != nil {
t.Fatal(err)
}
house, _ := os.UserHomeDir()
if far.Workspace != filepath.Join(house, "app") {
t.Fatalf("a ~ folder typed over --host was kept as %q, want the engine machine's %q", far.Workspace, filepath.Join(house, "app"))
}
bareFleet := onePipeFleet("devbox", hostedClient(t))
t.Cleanup(bareFleet.closeAll)
bare, _ := hostOptions(bareFleet, remote.Welcome{Version: remote.Version, Workspace: "/srv/app"}, false)
if !reflect.ValueOf(bare.Automations).IsZero() {
t.Fatalf("an engine without the automations doors was handed a seam: %+v", bare.Automations)
}
}
// THE ENGINE HANDS THE WIRE THIS MACHINE'S AUTOMATIONS, AND A WINDOW HELD
// THROUGH IT IS A WINDOW THIS MACHINE'S CLOCK COUNTS. The hook carries the store
// and the zone this process opened once, and its HoldWindow is the very door a
// local window holds presence through — so a window attached from another
// machine is counted in the folder the clock reads, and stops being counted the
// moment it is let go.
func TestTheEngineHandsTheWireThisMachinesAutomations(t *testing.T) {
// THE STORE IS OPENED ONCE PER PROCESS, under the home this test binary
// already moved to a throwaway folder (testenv_test.go) — the same place
// every test that builds a conversation's config opens it. Only the window
// held below goes to a folder this test owns, so the count starts at zero.
autos, hook := v3Automations(), engineAutomations()
if autos == nil || hook == nil {
t.Fatalf("this process opened automations %v and handed the wire %v; both must be there under a writable home", autos, hook)
}
if hook.Store != autos.Store || hook.Zone != autos.Zone || hook.HoldWindow == nil {
t.Fatalf("the wire was handed %+v, not this process's own store %p in %q", hook, autos.Store, autos.Zone)
}
t.Setenv(home.EnvVar, t.TempDir())
presence := automation.NewPresence(automationsRoot())
release := hook.HoldWindow("attached from laptop")
if open, err := presence.Count(); err != nil || open != 1 {
release()
t.Fatalf("a window held through the engine counts %d, %v", open, err)
}
release()
if open, err := presence.Count(); err != nil || open != 0 {
t.Fatalf("a window the engine let go is still counted: %d, %v", open, err)
}
}