If we interrupt `tailscale up` and then run it again, we should only print a single auth URL.
(t *testing.T)
| 550 | // If we interrupt `tailscale up` and then run it again, we should only |
| 551 | // print a single auth URL. |
| 552 | func TestOneNodeUpInterruptedAuth(t *testing.T) { |
| 553 | tstest.Parallel(t) |
| 554 | |
| 555 | env := NewTestEnv(t, ConfigureControl( |
| 556 | func(control *testcontrol.Server) { |
| 557 | control.RequireAuth = true |
| 558 | control.AllNodesSameUser = true |
| 559 | }, |
| 560 | )) |
| 561 | |
| 562 | n := NewTestNode(t, env) |
| 563 | d := n.StartDaemon() |
| 564 | defer d.MustCleanShutdown(t) |
| 565 | |
| 566 | cmdArgs := []string{"up", "--login-server=" + env.ControlURL()} |
| 567 | |
| 568 | // The first time we run the command, we wait for an auth URL to be |
| 569 | // printed, and then we cancel the command -- equivalent to ^C. |
| 570 | // |
| 571 | // At this point, we've connected to control to get an auth URL, |
| 572 | // and printed it in the CLI, but not clicked it. |
| 573 | t.Logf("Running command for the first time: %s", strings.Join(cmdArgs, " ")) |
| 574 | cmd1 := n.Tailscale(cmdArgs...) |
| 575 | |
| 576 | // This handler watches for auth URLs in stdout, then cancels the |
| 577 | // running `tailscale up` CLI command. |
| 578 | cmd1.Stdout = &authURLParserWriter{t: t, authURLFn: func(urlStr string) error { |
| 579 | t.Logf("saw auth URL %q", urlStr) |
| 580 | cmd1.Process.Kill() |
| 581 | return nil |
| 582 | }} |
| 583 | cmd1.Stderr = cmd1.Stdout |
| 584 | |
| 585 | if err := cmd1.Run(); !isNonZeroExitCode(err) { |
| 586 | t.Fatalf("Command did not fail with non-zero exit code: %q", err) |
| 587 | } |
| 588 | |
| 589 | // Because we didn't click the auth URL, we should still be in NeedsLogin. |
| 590 | n.AwaitBackendState("NeedsLogin") |
| 591 | |
| 592 | // The second time we run the command, we click the first auth URL we see |
| 593 | // and check that we log in correctly. |
| 594 | // |
| 595 | // In #17361, there was a bug where we'd print two auth URLs, and you could |
| 596 | // click either auth URL and log in to control, but logging in through the |
| 597 | // first URL would leave `tailscale up` hanging. |
| 598 | // |
| 599 | // Using `authURLHandler` ensures we only print the new, correct auth URL. |
| 600 | // |
| 601 | // If we print both URLs, it will throw an error because it only expects |
| 602 | // to log in with one auth URL. |
| 603 | // |
| 604 | // If we only print the stale auth URL, the test will timeout because |
| 605 | // `tailscale up` will never return. |
| 606 | t.Logf("Running command for the second time: %s", strings.Join(cmdArgs, " ")) |
| 607 | |
| 608 | var authURLCount atomic.Int32 |
| 609 |
nothing calls this directly
no test coverage detected
searching dependent graphs…