diff --git a/tstest/integration/vms/regex_flag.go b/tstest/integration/vms/regex_flag.go new file mode 100644 index 000000000..5a78ca41e --- /dev/null +++ b/tstest/integration/vms/regex_flag.go @@ -0,0 +1,30 @@ +// 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. + +package vms + +import "regexp" + +type regexValue struct { + r *regexp.Regexp +} + +func (r *regexValue) String() string { + if r.r == nil { + return "" + } + + return r.r.String() +} + +func (r *regexValue) Set(val string) error { + if rex, err := regexp.Compile(val); err != nil { + return err + } else { + r.r = rex + return nil + } +} + +func (r regexValue) Unwrap() *regexp.Regexp { return r.r } diff --git a/tstest/integration/vms/regex_flag_test.go b/tstest/integration/vms/regex_flag_test.go new file mode 100644 index 000000000..d241ef78e --- /dev/null +++ b/tstest/integration/vms/regex_flag_test.go @@ -0,0 +1,22 @@ +// 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. + +package vms + +import ( + "flag" + "testing" +) + +func TestRegexFlag(t *testing.T) { + var v regexValue + fs := flag.NewFlagSet(t.Name(), flag.PanicOnError) + fs.Var(&v, "regex", "regex to parse") + + const want = `.*` + fs.Parse([]string{"-regex", want}) + if v.Unwrap().String() != want { + t.Fatalf("got wrong regex: %q, wanted: %q", v.Unwrap().String(), want) + } +} diff --git a/tstest/integration/vms/vms_test.go b/tstest/integration/vms/vms_test.go index a30a95e4a..25c612879 100644 --- a/tstest/integration/vms/vms_test.go +++ b/tstest/integration/vms/vms_test.go @@ -41,6 +41,11 @@ import ( const securePassword = "hunter2" var runVMTests = flag.Bool("run-vm-tests", false, "if set, run expensive (10G+ ram) VM based integration tests") +var distroRex *regexValue = func() *regexValue { + result := ®exValue{r: regexp.MustCompile(`.*`)} + flag.Var(result, "distro-regex", "The regex that matches what distros should be run") + return result +}() type Distro struct { name string // amazon-linux @@ -360,6 +365,8 @@ func TestVMIntegrationEndToEnd(t *testing.T) { dir := t.TempDir() + rex := distroRex.Unwrap() + ln, err := net.Listen("tcp", deriveBindhost(t)+":0") if err != nil { t.Fatalf("can't make TCP listener: %v", err) @@ -417,11 +424,20 @@ func TestVMIntegrationEndToEnd(t *testing.T) { loginServer := fmt.Sprintf("http://%s", ln.Addr()) t.Logf("loginServer: %s", loginServer) + var numDistros = 0 + cancels := make(chan func(), len(distros)) t.Run("mkvm", func(t *testing.T) { for n, distro := range distros { n, distro := n, distro + if rex.MatchString(distro.name) { + t.Logf("%s matches %s", distro.name, rex) + numDistros++ + } else { + continue + } + t.Run(distro.name, func(t *testing.T) { t.Parallel() @@ -450,13 +466,13 @@ func TestVMIntegrationEndToEnd(t *testing.T) { for { <-waiter.C ipMu.Lock() - if len(ipMap) == len(distros) { + if len(ipMap) == numDistros { ipMu.Unlock() break } else { if n%30 == 0 { t.Logf("ipMap: %d", len(ipMap)) - t.Logf("distros: %d", len(distros)) + t.Logf("distros: %d", numDistros) } } n++