From 4ff0757d44e500caee9ad4ce68bb0a7d84a3bfec Mon Sep 17 00:00:00 2001 From: Josh Bleecher Snyder Date: Wed, 18 Aug 2021 14:20:40 -0700 Subject: [PATCH] cmd/testcontrol: add test control server This is useful for manual performance testing of networks with many nodes. I imagine it'll grow more knobs over time. Signed-off-by: Josh Bleecher Snyder --- cmd/testcontrol/testcontrol.go | 98 +++++++++++++++++++ tstest/integration/testcontrol/testcontrol.go | 28 ++++++ 2 files changed, 126 insertions(+) create mode 100644 cmd/testcontrol/testcontrol.go diff --git a/cmd/testcontrol/testcontrol.go b/cmd/testcontrol/testcontrol.go new file mode 100644 index 000000000..116badd24 --- /dev/null +++ b/cmd/testcontrol/testcontrol.go @@ -0,0 +1,98 @@ +// Copyright (c) 2021 Tailscale Inc & AUTHORS All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Program testcontrol runs a simple test control server. +package main + +import ( + "flag" + "log" + "net/http" + "testing" + + "tailscale.com/tstest/integration" + "tailscale.com/tstest/integration/testcontrol" + "tailscale.com/types/logger" +) + +var ( + flagNFake = flag.Int("nfake", 0, "number of fake nodes to add to network") +) + +func main() { + flag.Parse() + + var t fakeTB + derpMap := integration.RunDERPAndSTUN(t, logger.Discard, "127.0.0.1") + + control := &testcontrol.Server{ + DERPMap: derpMap, + ExplicitBaseURL: "http://127.0.0.1:9911", + } + for i := 0; i < *flagNFake; i++ { + control.AddFakeNode() + } + mux := http.NewServeMux() + mux.Handle("/", control) + addr := "127.0.0.1:9911" + log.Printf("listening on %s", addr) + err := http.ListenAndServe(addr, mux) + log.Fatal(err) +} + +type fakeTB struct { + *testing.T +} + +func (t fakeTB) Cleanup(_ func()) {} +func (t fakeTB) Error(args ...interface{}) { + t.Fatal(args...) +} +func (t fakeTB) Errorf(format string, args ...interface{}) { + t.Fatalf(format, args...) +} +func (t fakeTB) Fail() { + t.Fatal("failed") +} +func (t fakeTB) FailNow() { + t.Fatal("failed") +} +func (t fakeTB) Failed() bool { + return false +} +func (t fakeTB) Fatal(args ...interface{}) { + log.Fatal(args...) +} +func (t fakeTB) Fatalf(format string, args ...interface{}) { + log.Fatalf(format, args...) +} +func (t fakeTB) Helper() {} +func (t fakeTB) Log(args ...interface{}) { + log.Print(args...) +} +func (t fakeTB) Logf(format string, args ...interface{}) { + log.Printf(format, args...) +} +func (t fakeTB) Name() string { + return "faketest" +} +func (t fakeTB) Setenv(key string, value string) { + panic("not implemented") +} +func (t fakeTB) Skip(args ...interface{}) { + t.Fatal("skipped") +} +func (t fakeTB) SkipNow() { + t.Fatal("skipnow") +} +func (t fakeTB) Skipf(format string, args ...interface{}) { + t.Logf(format, args...) + t.Fatal("skipped") +} +func (t fakeTB) Skipped() bool { + return false +} +func (t fakeTB) TempDir() string { + panic("not implemented") +} diff --git a/tstest/integration/testcontrol/testcontrol.go b/tstest/integration/testcontrol/testcontrol.go index 9454df298..32427ceec 100644 --- a/tstest/integration/testcontrol/testcontrol.go +++ b/tstest/integration/testcontrol/testcontrol.go @@ -31,6 +31,7 @@ import ( "tailscale.com/net/tsaddr" "tailscale.com/smallzstd" "tailscale.com/tailcfg" + "tailscale.com/types/key" "tailscale.com/types/logger" "tailscale.com/types/wgkey" ) @@ -269,6 +270,33 @@ func (s *Server) nodeLocked(nodeKey tailcfg.NodeKey) *tailcfg.Node { return s.nodes[nodeKey].Clone() } +// AddFakeNode injects a fake node into the server. +func (s *Server) AddFakeNode() { + s.mu.Lock() + defer s.mu.Unlock() + if s.nodes == nil { + s.nodes = make(map[tailcfg.NodeKey]*tailcfg.Node) + } + nk := tailcfg.NodeKey(key.NewPrivate().Public()) + mk := tailcfg.MachineKey(key.NewPrivate().Public()) + dk := tailcfg.DiscoKey(key.NewPrivate().Public()) + id := int64(binary.LittleEndian.Uint64(nk[:])) + ip := netaddr.IPv4(nk[0], nk[1], nk[2], nk[3]) + addr := netaddr.IPPrefixFrom(ip, 32) + s.nodes[nk] = &tailcfg.Node{ + ID: tailcfg.NodeID(id), + StableID: tailcfg.StableNodeID(fmt.Sprintf("TESTCTRL%08x", id)), + User: tailcfg.UserID(id), + Machine: mk, + Key: nk, + MachineAuthorized: true, + DiscoKey: dk, + Addresses: []netaddr.IPPrefix{addr}, + AllowedIPs: []netaddr.IPPrefix{addr}, + } + // TODO: send updates to other (non-fake?) nodes +} + func (s *Server) AllNodes() (nodes []*tailcfg.Node) { s.mu.Lock() defer s.mu.Unlock()