A new package can also later record/report which knobs are checked and
set. It also makes the code cleaner & easier to grep for env knobs.
Change-Id: Id8a123ab7539f1fadbd27e0cbeac79c2e4f09751
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
testNodes have a reference to a testing.TB via their env.
Use it instead of making the caller pass theirs.
We did this in some methods but not others; finish the job.
This simplifies the call sites.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
magicsock was hanging onto its netmap on logout,
which caused tailscale status to display partial
information about a bunch of zombie peers.
After logout, there should be no peers.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
If you're using -verbose-tailscaled, you're doing in-the-weeds debugging,
so you probably want the verbose output.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
And it updates the build tag style on a couple files.
Change-Id: I84478d822c8de3f84b56fa1176c99d2ea5083237
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
The existing code relied on the Go build cache to avoid
needless work when obtaining the tailscale binaries.
For non-obvious reasons, the binaries were getting re-linked
every time, which added 600ms or so on my machine to every test.
Instead, build the binaries exactly once, on demand.
This reduces the time to run 'go test -count=5' from 34s to 10s
on my machine.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
fee2d9fad added support for cmd/tailscale to connect to IPNExtension.
It came in two parts: If no socket was provided, dial IPNExtension first,
and also, if dialing the socket failed, fall back to IPNExtension.
The second half of that support caused the integration tests to fail
when run on a machine that was also running IPNExtension.
The integration tests want to wait until the tailscaled instances
that they spun up are listening. They do that by dialing the new
instance. But when that dial failed, it was falling back to IPNExtension,
so it appeared (incorrectly) that tailscaled was running.
Hilarity predictably ensued.
If a user (or a test) explicitly provides a socket to dial,
it is a reasonable assumption that they have a specific tailscaled
in mind and don't want to fall back to IPNExtension.
It is certainly true of the integration tests.
Instead of adding a bool to Connect, split out the notion of a
connection strategy. For now, the implementation remains the same,
but with the details hidden a bit. Later, we can improve that.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
Not done yet, but this move more of the outbound dial special casing
from random packages into tsdial, which aspires to be the one unified
place for all outbound dialing shenanigans.
Then this plumbs it all around, so everybody is ultimately
holding on to the same dialer.
As of this commit, macOS/iOS using an exit node should be able to
reach to the exit node's DoH DNS proxy over peerapi, doing the sockopt
to stay within the Network Extension.
A number of steps remain, including but limited to:
* move a bunch more random dialing stuff
* make netstack-mode tailscaled be able to use exit node's DNS proxy,
teaching tsdial's resolver to use it when an exit node is in use.
Updates #1713
Change-Id: I1e8ee378f125421c2b816f47bc2c6d913ddcd2f5
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
For now this just deletes the net/socks5/tssocks implementation (and
the DNSMap stuff from wgengine/netstack) and moves it into net/tsdial.
Then initialize a Dialer early in tailscaled, currently only use for the
outbound and SOCKS5 proxies. It will be plumbed more later. Notably, it
needs to get down into the DNS forwarder for exit node DNS forwading
in netstack mode. But it will also absorb all the peerapi setsockopt
and netns Dial and tlsdial complexity too.
Updates #1713
Change-Id: Ibc6d56ae21a22655b2fa1002d8fc3f2b2ae8b6df
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
And annotate magicsock as a start.
And add localapi and debug handlers with the Prometheus-format
exporter.
Updates #3307
Change-Id: I47c5d535fe54424741df143d052760387248f8d3
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
github.com/go-multierror/multierror served us well.
But we need a few feature from it (implement Is),
and it's not worth maintaining a fork of such a small module.
Instead, I did a clean room implementation inspired by its API.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
testing.AllocsPerRun measures the total allocations performed
by the entire program while repeatedly executing a function f.
If some unrelated part of the rest of the program happens to
allocate a lot during that period, you end up with a test failure.
Ideally, the rest of the program would be silent while
testing.AllocsPerRun executes.
Realistically, that is often unachievable.
AllocsPerRun attempts to mitigate this by setting GOMAXPROCS to 1,
but that doesn't prevent other code from running;
it only makes it less likely.
You can also mitigate this by passing a large iteration count to
AllocsPerRun, but that is unreliable and needlessly expensive.
Unlike most of package testing, AllocsPerRun doesn't use any
toolchain magic, so we can just write a replacement.
One wild idea is to change how we count mallocs.
Instead of using runtime.MemStats, turn on memory profiling with a
memprofilerate of 1. Discard all samples from the profile whose stack
does not contain testing.AllocsPerRun. Count the remaining samples to
determine the number of mallocs.
That's fun, but overkill.
Instead, this change adds a simple API that attempts to get f to
run at least once with a target number of allocations.
This is useful when you know that f should allocate consistently.
We can then assume that any iterations with too many allocations
are probably due to one-time costs or background noise.
This suits most uses of AllocsPerRun.
Ratcheting tests tend to be significantly less flaky,
because they are biased towards success.
They can also be faster, because they can exit early,
once success has been reached.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
For the service, all we need to do is handle the `svc.SessionChange` command.
Upon receipt of a `windows.WTS_SESSION_UNLOCK` event, we fire off a goroutine to flush the DNS cache.
(Windows expects responses to service requests to be quick, so we don't want to do that synchronously.)
This is gated on an integral registry value named `FlushDNSOnSessionUnlock`,
whose value we obtain during service initialization.
(See [this link](https://docs.microsoft.com/en-us/windows/win32/api/winsvc/nc-winsvc-lphandler_function_ex) for information re: handling `SERVICE_CONTROL_SESSIONCHANGE`.)
Fixes#2956
Signed-off-by: Aaron Klotz <aaron@tailscale.com>
This adds support for tailscaled to be an HTTP proxy server.
It shares the same backend dialing code as the SOCK5 server, but the
client protocol is HTTP (including CONNECT), rather than SOCKS.
Fixes#2289
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
Updates #2781 (might even fix it, but its real issue is that
SetPrivateKey starts a ReSTUN goroutines which then logs, and
that bug and data race existed prior to MemLogger existing)
* Revert "Revert "types/key: add MachinePrivate and MachinePublic.""
This reverts commit 61c3b98a24.
Signed-off-by: David Anderson <danderson@tailscale.com>
* types/key: add ControlPrivate, with custom serialization.
ControlPrivate is just a MachinePrivate that serializes differently
in JSON, to be compatible with how the Tailscale control plane
historically serialized its private key.
Signed-off-by: David Anderson <danderson@tailscale.com>
Plumb throughout the codebase as a replacement for the mixed use of
tailcfg.MachineKey and wgkey.Private/Public.
Signed-off-by: David Anderson <danderson@tailscale.com>
I have seen this once in the VM test (caused by an EOF, I believe on
shutdown) that didn't need to cause the test to fail.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
The tests build fine on other Unix's, they just can't run there.
But there is already a t.Skip by default, so `go test` ends up
working fine elsewhere and checks the code compiles.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
This uses a neat little tool to dump the output of DNS queries to
standard out. This is the first end-to-end test of DNS that runs against
actual linux systems. The /etc/resolv.conf test may look superflous,
however this will help for correlating system state if one of the DNS
tests fails.
Signed-off-by: Christine Dodrill <xe@tailscale.com>
Fix a few test printing issues when tests fail.
Qemu console output is super useful when something is wrong in the
harness and we cannot even bring up the tests.
Also useful for figuring out where all the time goes in tests.
A little noisy, but not too noisy as long as you're only running one VM
as part of the tests, which is my plan.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
Also remove extra distros for now.
We can bring them back later if useful.
Though our most important distros are these two Ubuntu, debian stable,
and Raspbian (not currently supported).
And before doing more Linux, we should do Windows.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
The VM test has two tailscaled instances running and interleaves the
logs. Without a prefix it is impossible to figure out what is going on.
It might be even better to include the [ABCD] node prefix here as well.
Unfortunately lots of interesting logs happen before tailscaled has a
node key, so it wouldn't be a replacement for a short ID.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
By default httptest listens only on the loopback adapter.
Instead, listen on the IP the user asked for.
The VM test needs this, as it wants to start DERP and STUN
servers on the host that can be reached by guest VMs.
Signed-off-by: David Crawshaw <crawshaw@tailscale.com>
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 <josh@tailscale.com>
This prevents centos tests from timing out because sshd does reverse dns
lookups on every session being established instead of doing it once on
the acutal ssh connection being established. This is odd. Appending this
to the sshd config and restarting it seems to fix it though.
Signed-off-by: Christine Dodrill <xe@tailscale.com>
Filch doesn't like having multiple processes competing
for the same log files (#937).
Parallel integration tests were all using the same log files.
Add a TS_LOGS_DIR env var that the integration test can use
to use separate log files per test.
Fixes#2269
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
The maximum unix domain socket path length on darwin is 104 bytes,
including the trailing NUL.
On my machine, the path created by some newly added tests (6eecf3c9)
was too long, resulting in cryptic test failures.
Shorten the names of the tests, and add a check to make
the diagnosis easier next time.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
With this, I can now:
* install Tailscale
* stop the GUI
* net stop Tailscale
* net start Tailscale
* tailscale up --unattended
(where the middle three steps simulate what would happen on a Windows
Server Core machine without a GUI)
Fixes#2137
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
We have different deps depending on the platform.
If we pick a privileged platform, we'll miss some deps.
If we use the union of all platforms, the integration test
won't compile on some platforms, because it'll import
packages that don't compile on that platform.
Give in to the madness and give each platform its own deps file.
Signed-off-by: Josh Bleecher Snyder <josh@tailscale.com>
This moves the distribution definitions into a maintainable hujson file
instead of just existing as constants in `distros.go`. Comments are
maintained from the inline definitions.
This uses jennifer[1] for hygenic source tree creation. This allows us
to generate a unique top-level test for each VM run. This should
hopefully help make the output of `go test` easier to read.
This also separates each test out into its own top-level test so that we
can better track the time that each distro takes. I really wish there
was a way to have the `test_codegen.go` file _always_ run as a part of
the compile process instead of having to rely on people remembering to
run `go generate`, but I am limited by my tools.
This will let us remove the `-distro-regex` flag and use `go test -run`
to pick which distros are run.
Signed-off-by: Christine Dodrill <xe@tailscale.com>
Add in UPnP portmapping, using goupnp library in order to get the UPnP client and run the
portmapping functions. This rips out anywhere where UPnP used to be in portmapping, and has a
flow separate from PMP and PCP.
RELNOTE=portmapper now supports UPnP mappings
Fixes#682
Updates #2109
Signed-off-by: julianknodt <julianknodt@gmail.com>
Apparently this test was flaking because I critically misunderstood how
the kernel buffers UDP packets for senders. I'm trying to send more UDP
packets and will see if that helps.
Signed-off-by: Christine Dodrill <xe@tailscale.com>
This test used to try to run this only once, but this variant of the
test attempts to run `tailscale status` up to 6 times in a loop with
exponential backoff.
This fixes the flakiness found in previous instances of this test.
Signed-off-by: Christine Dodrill <xe@tailscale.com>
Regression from 6d10655dc3, which added
UpdatePrefs but didn't write it out to disk.
I'd planned on adding tests to state_test.go which is why I'd earlier
added 46896a9311 to prepare for making
such persistence tests easier to write, but turns out state_test.go
didn't even test UpdatePrefs, so I'm staying out of there.
Instead, this is tested using integration tests.
Fixes#2321
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
My spatial memory functions poorly with large files and the vms_test.go
file recently surpassed the point where it functions adequately. This
patch splits up vms_test.go into more files to make my spatial memory
function like I need it to.
Signed-off-by: Christine Dodrill <xe@tailscale.com>
Split from https://github.com/tailscale/tailscale/pull/2376.
This adds IPv6 support to testcontrol so each member of the tailscale
network gets an IPv6 address too.
Signed-off-by: Christine Dodrill <xe@tailscale.com>
The DERPTestPort int meant two things before: which port to use, and
whether to disable TLS verification. Users would like to set the port
without disabling TLS, so break it into two options.
Updates #1264
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
To avoid the generated nixos disk images from becoming immune from the
GC, I delete the symlink to the nix store at the end of tests.
`t.Cleanup` runs at the end of a test. I changed this part of the code
to have a separate timer for how long it takes to run NixOS builds, but
I did that by using a subtest. This means that it was creating the NixOS
image, deleting its symlink and then trying to use that symlink to find
the resulting disk image, making the whole thing ineffectual.
This was a mistake. I am reverting this change made in
https://github.com/tailscale/tailscale/pull/2360 to remove this layer of
subtesting.
Signed-off-by: Christine Dodrill <xe@tailscale.com>
This tests incoming and outgoing UDP traffic. It would test incoming UDP
traffic however our socks server doesn't seem to allow for connecting to
destinations over UDP. When the socks server gets that support the
incoming test should pass without issue.
Signed-off-by: Christine Dodrill <xe@tailscale.com>
This adapts the existing in-process logcatcher from tstest/integration
into a public type and uses it on the side of testcontrol. This also
fixes a bug in the Alpine Linux OpenRC unit that makes every value in
`/etc/default/tailscaled` exported into tailscaled's environment, a-la
systemd [Service].EnviromentFile.
Signed-off-by: Christine Dodrill <xe@tailscale.com>
This does a few things:
1. Rewrites the tests so that we get a log of what individual tests
failed at the end of a test run.
2. Adds a test that runs an HTTP server via the tester tailscale node and
then has the VMs connect to that over Tailscale.
3. Dials the VM over Tailscale and ensures it answers SSH requests.
4. Other minor framework refactoring.
Signed-off-by: Christine Dodrill <xe@tailscale.com>
Oracle Linux[1] is a CentOS fork. It is not very special. I am adding it
to the integration jungle because I am adding it to pkgs and the website
directions.
[1]: https://www.oracle.com/linux/
Signed-off-by: Christine Dodrill <xe@tailscale.com>
It was caching too aggressively, as it didn't see our deps due to our
running "go install tailscaled" as a child process.
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This makes sure `tailscale status` and `tailscale ping` works. It also
switches goexpect to use a batch instead of manually banging out each
line, which makes the tests so much easier to read.
Signed-off-by: Christine Dodrill <xe@tailscale.com>
This puts nix build logs on the filesystem so that we can debug them
later. This also disables nixos unstable until
https://github.com/NixOS/nixpkgs/issues/128783 is fixed.
Signed-off-by: Christine Dodrill <xe@tailscale.com>
After allowing for custom DERP maps, it's convenient to be able to see their latency in
netcheck. This adds a query to the local tailscaled for the current DERPMap.
Updates #1264
Signed-off-by: julianknodt <julianknodt@gmail.com>
Okay, so, at a high level testing NixOS is a lot different than
other distros due to NixOS' determinism. Normally NixOS wants packages to
be defined in either an overlay, a custom packageOverrides or even
yolo-inline as a part of the system configuration. This is going to have
us take a different approach compared to other distributions. The overall
plan here is as following:
1. make the binaries as normal
2. template in their paths as raw strings to the nixos system module
3. run `nixos-generators -f qcow -o $CACHE_DIR/tailscale/nixos/version -c generated-config.nix`
4. pass that to the steps that make the virtual machine
It doesn't really make sense for us to use a premade virtual machine image
for this as that will make it harder to deterministically create the image.
Nix commands generate a lot of output, so their output is hidden behind the
`-verbose-nix-output` flag.
This unfortunately makes this test suite have a hard dependency on
Nix/NixOS, however the test suite has only ever been run on NixOS (and I
am not sure if it runs on other distros at all), so this probably isn't too
big of an issue.
Signed-off-by: Christine Dodrill <xe@tailscale.com>