fix(relays): the generic HTTP board never sent its URLs; cluster filters start off
buildDeviceDriver had no case for "httpgen", so the generic board fell through
to the WebSwitch driver: it polled an address it had never been given, reported
itself offline, greyed out every relay button, and sent none of the configured
URLs. Nothing in the interface said so — the board was configured, saved and
listed, and simply did nothing. deviceKey did not cover the URLs either, so once
that is fixed, correcting a typo in one would still have handed back the cached
driver holding the old address until a restart.
Two shapes of home-made switch could not be described at all:
- a bit-mask board whose four URLs differ by one character
(/Set0/1, /Set0/2, /Set0/4, /Set0/8) — {value} in the pattern now takes the
number from the per-relay box, keeping the address in one place;
- a board numbering its channels from zero — {relay-1}, since giving up the
pattern for eight hand-typed URLs was the only alternative.
The pattern decides what the per-relay boxes hold, and the grid says which as
soon as {value} is typed: guessing per box ("does this look like a URL?") would
change meaning on a typo, which is not a thing to do to something wired to an
antenna. A URL typed without a scheme gets http:// like the named boards get
from relayBase; https:// is passed through untouched.
Host and the connection test are gone for this type. It has no address of its
own — its relays may each live on a different box — and no status to read, so a
test could only ever answer "OK, 4 relays". Save was greyed out without a host,
which made a complete configuration of four full URLs impossible to store.
Cluster filters no longer persist across launches. A band lock set weeks earlier
is invisible to whoever set it: the counter reads 76 spots live, the grid is
empty, and the search goes to the cluster instead. Nobody loses work by
re-ticking a chip. Grouping and the panel state still persist — they change how
spots look, never whether they appear.
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// The generic HTTP board must actually be built from its URLs.
|
||||
//
|
||||
// It was not: buildDeviceDriver had no case for it, so it fell through to the
|
||||
// WebSwitch driver. The board was configured, saved, listed — and every command
|
||||
// went to a WebSwitch address that did not exist, which also left the device
|
||||
// reported as offline and every relay button on the panel greyed out. Nothing in
|
||||
// the UI said so; the URLs were simply never sent.
|
||||
func TestGenericHTTPBoardSendsItsConfiguredURL(t *testing.T) {
|
||||
hit := make(chan string, 4)
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
hit <- r.URL.Path
|
||||
}))
|
||||
defer srv.Close()
|
||||
|
||||
// Host deliberately empty — this board's whole address is in the URLs.
|
||||
d := StationDevice{
|
||||
Type: "httpgen",
|
||||
Channels: 2,
|
||||
OnURLs: []string{srv.URL + "/relay1/on", srv.URL + "/relay2/on"},
|
||||
OffURLs: []string{srv.URL + "/relay1/off", srv.URL + "/relay2/off"},
|
||||
}
|
||||
if err := buildDeviceDriver(d).Set(context.Background(), 2, true); err != nil {
|
||||
t.Fatalf("Set: %v", err)
|
||||
}
|
||||
select {
|
||||
case got := <-hit:
|
||||
if got != "/relay2/on" {
|
||||
t.Errorf("board was asked for %q, want /relay2/on", got)
|
||||
}
|
||||
case <-time.After(3 * time.Second):
|
||||
t.Fatal("the configured URL was never requested — the board is not using its own driver")
|
||||
}
|
||||
}
|
||||
|
||||
// Editing a URL must rebuild the driver. The cached one is keyed by the device's
|
||||
// configuration, and the URLs used not to be part of that key: correcting a typo
|
||||
// handed back the driver still holding the old address, so the fix looked like it
|
||||
// had done nothing until OpsLog was restarted.
|
||||
func TestGenericHTTPBoardKeyCoversItsURLs(t *testing.T) {
|
||||
a := StationDevice{Type: "httpgen", Channels: 2, OnURLs: []string{"http://box/a"}}
|
||||
b := StationDevice{Type: "httpgen", Channels: 2, OnURLs: []string{"http://box/b"}}
|
||||
if deviceKey(a) == deviceKey(b) {
|
||||
t.Error("two boards with different URLs share a cache key — an edited URL would not take effect")
|
||||
}
|
||||
c := a
|
||||
c.OnPat = "http://box/{relay}"
|
||||
if deviceKey(a) == deviceKey(c) {
|
||||
t.Error("changing the ON pattern left the cache key unchanged")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user