mirror of
https://github.com/tailscale/tailscale.git
synced 2025-08-19 17:37:32 +00:00
ipn/ipn{server,test}: extract the LocalAPI test client and server into ipntest
In this PR, we extract the in-process LocalAPI client/server implementation from ipn/ipnserver/server_test.go into a new ipntest package to be used in high‑level black‑box tests, such as those for the tailscale CLI. Updates #15575 Signed-off-by: Nick Khyl <nickk@tailscale.com>
This commit is contained in:
80
ipn/lapitest/example_test.go
Normal file
80
ipn/lapitest/example_test.go
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright (c) Tailscale Inc & AUTHORS
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
package lapitest
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"tailscale.com/ipn"
|
||||
)
|
||||
|
||||
func TestClientServer(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctx := context.Background()
|
||||
|
||||
// Create a server and two clients.
|
||||
// Both clients represent the same user to make this work across platforms.
|
||||
// On Windows we've been restricting the API usage to a single user at a time.
|
||||
// While we're planning on changing this once a better permission model is in place,
|
||||
// this test is currently limited to a single user (but more than one client is fine).
|
||||
// Alternatively, we could override GOOS via envknobs to test as if we're
|
||||
// on a different platform, but that would make the test depend on global state, etc.
|
||||
s := NewServer(t, WithLogging(false))
|
||||
c1 := s.ClientWithName("User-A")
|
||||
c2 := s.ClientWithName("User-A")
|
||||
|
||||
// Start watching the IPN bus as the second client.
|
||||
w2, _ := c2.WatchIPNBus(context.Background(), ipn.NotifyInitialPrefs)
|
||||
|
||||
// We're supposed to get a notification about the initial prefs,
|
||||
// and WantRunning should be false.
|
||||
n, err := w2.Next()
|
||||
for ; err == nil; n, err = w2.Next() {
|
||||
if n.Prefs == nil {
|
||||
// Ignore non-prefs notifications.
|
||||
continue
|
||||
}
|
||||
if n.Prefs.WantRunning() {
|
||||
t.Errorf("WantRunning(initial): got %v, want false", n.Prefs.WantRunning())
|
||||
}
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("IPNBusWatcher.Next failed: %v", err)
|
||||
}
|
||||
|
||||
// Now send an EditPrefs request from the first client to set WantRunning to true.
|
||||
change := &ipn.MaskedPrefs{Prefs: ipn.Prefs{WantRunning: true}, WantRunningSet: true}
|
||||
gotPrefs, err := c1.EditPrefs(ctx, change)
|
||||
if err != nil {
|
||||
t.Fatalf("EditPrefs failed: %v", err)
|
||||
}
|
||||
if !gotPrefs.WantRunning {
|
||||
t.Fatalf("EditPrefs.WantRunning: got %v, want true", gotPrefs.WantRunning)
|
||||
}
|
||||
|
||||
// We can check the backend directly to see if the prefs were set correctly.
|
||||
if gotWantRunning := s.Backend().Prefs().WantRunning(); !gotWantRunning {
|
||||
t.Fatalf("Backend.Prefs.WantRunning: got %v, want true", gotWantRunning)
|
||||
}
|
||||
|
||||
// And can also wait for the second client with an IPN bus watcher to receive the notification
|
||||
// about the prefs change.
|
||||
n, err = w2.Next()
|
||||
for ; err == nil; n, err = w2.Next() {
|
||||
if n.Prefs == nil {
|
||||
// Ignore non-prefs notifications.
|
||||
continue
|
||||
}
|
||||
if !n.Prefs.WantRunning() {
|
||||
t.Fatalf("WantRunning(changed): got %v, want true", n.Prefs.WantRunning())
|
||||
}
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("IPNBusWatcher.Next failed: %v", err)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user