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