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:
Nick Khyl
2025-04-16 16:32:10 -05:00
committed by Nick Khyl
parent 0f4f808e70
commit f0a27066c4
9 changed files with 846 additions and 335 deletions
+42
View File
@@ -0,0 +1,42 @@
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
package ipnserver
import (
"context"
"net/http"
"tailscale.com/ipn/ipnauth"
)
// BlockWhileInUseByOtherForTest blocks while the actor can't connect to the server because
// the server is in use by a different actor. It is used in tests only.
func (s *Server) BlockWhileInUseByOtherForTest(ctx context.Context, actor ipnauth.Actor) error {
return s.blockWhileIdentityInUse(ctx, actor)
}
// BlockWhileInUseForTest blocks until the server becomes idle (no active requests),
// or the specified context is done. It returns the context's error if it is done.
// It is used in tests only.
func (s *Server) BlockWhileInUseForTest(ctx context.Context) error {
ready, cleanup := s.zeroReqWaiter.add(&s.mu, ctx)
s.mu.Lock()
busy := len(s.activeReqs) != 0
s.mu.Unlock()
if busy {
<-ready
}
cleanup()
return ctx.Err()
}
// ServeHTTPForTest responds to a single LocalAPI HTTP request.
// The request's context carries the actor that made the request
// and can be created with [NewContextWithActorForTest].
// It is used in tests only.
func (s *Server) ServeHTTPForTest(w http.ResponseWriter, r *http.Request) {
s.serveHTTP(w, r)
}