|
|
|
|
@ -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()
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|