ipn: add watch opt to include actions in health messages
Updates tailscale/corp#27759 Signed-off-by: James Sanderson <jsanderson@tailscale.com>
This commit is contained in:
committed by
James 'zofrex' Sanderson
parent
1635ccca27
commit
5fde183754
+105
-1
@@ -5348,6 +5348,8 @@ func TestDisplayMessages(t *testing.T) {
|
||||
ht.SetIPNState("NeedsLogin", true)
|
||||
ht.GotStreamedMapResponse()
|
||||
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
b.setNetMapLocked(&netmap.NetworkMap{
|
||||
DisplayMessages: map[tailcfg.DisplayMessageID]tailcfg.DisplayMessage{
|
||||
"test-message": {
|
||||
@@ -5374,7 +5376,8 @@ func TestDisplayMessagesURLFilter(t *testing.T) {
|
||||
ht.SetIPNState("NeedsLogin", true)
|
||||
ht.GotStreamedMapResponse()
|
||||
|
||||
defer b.lockAndGetUnlock()()
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
b.setNetMapLocked(&netmap.NetworkMap{
|
||||
DisplayMessages: map[tailcfg.DisplayMessageID]tailcfg.DisplayMessage{
|
||||
"test-message": {
|
||||
@@ -5405,3 +5408,104 @@ func TestDisplayMessagesURLFilter(t *testing.T) {
|
||||
t.Errorf("Unexpected message content (-want/+got):\n%s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDisplayMessageIPNBus checks that we send health messages appropriately
|
||||
// based on whether the watcher has sent the [ipn.NotifyHealthActions] watch
|
||||
// option or not.
|
||||
func TestDisplayMessageIPNBus(t *testing.T) {
|
||||
type test struct {
|
||||
name string
|
||||
mask ipn.NotifyWatchOpt
|
||||
wantWarning health.UnhealthyState
|
||||
}
|
||||
|
||||
msgs := map[tailcfg.DisplayMessageID]tailcfg.DisplayMessage{
|
||||
"test-message": {
|
||||
Title: "Message title",
|
||||
Text: "Message text.",
|
||||
Severity: tailcfg.SeverityMedium,
|
||||
PrimaryAction: &tailcfg.DisplayMessageAction{
|
||||
URL: "https://example.com",
|
||||
Label: "Learn more",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range []test{
|
||||
{
|
||||
name: "older-client-no-actions",
|
||||
mask: 0,
|
||||
wantWarning: health.UnhealthyState{
|
||||
WarnableCode: "test-message",
|
||||
Severity: health.SeverityMedium,
|
||||
Title: "Message title",
|
||||
Text: "Message text. Learn more: https://example.com", // PrimaryAction appended to text
|
||||
PrimaryAction: nil, // PrimaryAction not included
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "new-client-with-actions",
|
||||
mask: ipn.NotifyHealthActions,
|
||||
wantWarning: health.UnhealthyState{
|
||||
WarnableCode: "test-message",
|
||||
Severity: health.SeverityMedium,
|
||||
Title: "Message title",
|
||||
Text: "Message text.",
|
||||
PrimaryAction: &health.UnhealthyStateAction{
|
||||
URL: "https://example.com",
|
||||
Label: "Learn more",
|
||||
},
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
lb := newLocalBackendWithTestControl(t, false, func(tb testing.TB, opts controlclient.Options) controlclient.Client {
|
||||
return newClient(tb, opts)
|
||||
})
|
||||
|
||||
ipnWatcher := newNotificationWatcher(t, lb, nil)
|
||||
ipnWatcher.watch(tt.mask, []wantedNotification{{
|
||||
name: "test",
|
||||
cond: func(_ testing.TB, _ ipnauth.Actor, n *ipn.Notify) bool {
|
||||
if n.Health == nil {
|
||||
return false
|
||||
}
|
||||
got, ok := n.Health.Warnings["test-message"]
|
||||
if ok {
|
||||
if diff := cmp.Diff(tt.wantWarning, got); diff != "" {
|
||||
t.Errorf("unexpected warning details (-want/+got):\n%s", diff)
|
||||
return true // we failed the test so tell the watcher we've seen what we need to to stop it waiting
|
||||
}
|
||||
}
|
||||
return ok
|
||||
},
|
||||
}})
|
||||
|
||||
lb.SetPrefsForTest(&ipn.Prefs{
|
||||
ControlURL: "https://localhost:1/",
|
||||
WantRunning: true,
|
||||
LoggedOut: false,
|
||||
})
|
||||
if err := lb.Start(ipn.Options{}); err != nil {
|
||||
t.Fatalf("(*LocalBackend).Start(): %v", err)
|
||||
}
|
||||
|
||||
cc := lb.cc.(*mockControl)
|
||||
|
||||
// Assert that we are logged in and authorized, and also send our DisplayMessages
|
||||
cc.send(nil, "", true, &netmap.NetworkMap{
|
||||
SelfNode: (&tailcfg.Node{MachineAuthorized: true}).View(),
|
||||
DisplayMessages: msgs,
|
||||
})
|
||||
|
||||
// Tell the health tracker that we are in a map poll because
|
||||
// mockControl doesn't tell it
|
||||
lb.HealthTracker().GotStreamedMapResponse()
|
||||
|
||||
// Assert that we got the expected notification
|
||||
ipnWatcher.check()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user