func Run()

in go/wtl/wtl.go [75:257]


func Run(d diagnostics.Diagnostics, testPath, mdPath string, httpPort, httpsPort, debuggerPort int) int {
	ctx := context.Background()

	testTerminated := make(chan os.Signal)
	signal.Notify(testTerminated, syscall.SIGTERM, syscall.SIGINT)

	proxyStarted := make(chan error)
	envStarted := make(chan error)
	testFinished := make(chan int)
	envShutdown := make(chan error)

	mdFile, err := bazel.Runfile(mdPath)
	if err != nil {
		log.Print(err)
		return 127
	}

	md, err := metadata.FromFile(mdFile, nil)
	if err != nil {
		d.Severe(err)
		return 127
	}

	if debuggerPort != 0 {
		md.DebuggerPort = debuggerPort
	}

	testExe, err := bazel.Runfile(testPath)
	if err != nil {
		d.Severe(err)
		return 127
	}

	env, err := buildEnv(md, d)
	if err != nil {
		d.Severe(err)
		return 127
	}

	if httpPort == 0 {
		p, err := portpicker.PickUnusedPort()
		if err != nil {
			d.Severe(err)
			return 127
		}
		httpPort = p
		defer portpicker.RecycleUnusedPort(httpPort)
	}

	if httpsPort == 0 {
		p, err := portpicker.PickUnusedPort()
		if err != nil {
			d.Severe(err)
			return 127
		}
		httpsPort = p
		defer portpicker.RecycleUnusedPort(httpsPort)
	}

	p, err := proxy.New(env, md, d, httpPort, httpsPort)
	if err != nil {
		d.Severe(err)
		return 127
	}

	tmpDir, err := bazel.NewTmpDir("test")
	if err != nil {
		d.Severe(err)
		return 127
	}

	testCmd := exec.Command(testExe, flag.Args()...)

	envVars := map[string]string{
		"WEB_TEST_HTTP_SERVER":      fmt.Sprintf("http://%s", p.HTTPAddress),
		"WEB_TEST_WEBDRIVER_SERVER": fmt.Sprintf("http://%s/wd/hub", p.HTTPAddress),
		"TEST_TMPDIR":               tmpDir,
		"WEB_TEST_TMPDIR":           bazel.TestTmpDir(),
		"WEB_TEST_TARGET":           testPath,
	}

	if p.HTTPSAddress != "" {
		envVars["WEB_TEST_HTTPS_SERVER"] = fmt.Sprintf("https://%s", p.HTTPSAddress)
	}

	testCmd.Env = cmdhelper.BulkUpdateEnv(os.Environ(), envVars)

	testCmd.Stdout = os.Stdout
	testCmd.Stderr = os.Stderr
	testCmd.Stdin = os.Stdin

	go func() {
		envStarted <- env.SetUp(ctx)
	}()

	shutdownFunc := func() {
		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()
		// When the environment shutdowns or fails to shutdown, a message will be sent to envShutdown.
		go func() {
			var errors []error

			if err := p.Shutdown(ctx); err != nil {
				errors = append(errors, err)
			}
			if err := env.TearDown(ctx); err != nil {
				errors = append(errors, err)
			}
			switch len(errors) {
			case 0:
				envShutdown <- nil
			case 1:
				envShutdown <- errors[0]
			default:
				envShutdown <- fmt.Errorf("errors shutting down environment: %v", errors)
			}
		}()

		select {
		case <-testTerminated:
			d.Warning(errors.New("WTL", "test timed out during environment shutdown."))
		case <-ctx.Done():
			d.Warning(errors.New("WTL", "environment shutdown took longer than 5 seconds."))
		case err := <-envShutdown:
			if err != nil {
				d.Warning(err)
			}
		}
	}

	go func() {
		proxyStarted <- p.Start(ctx)
	}()

	for done := false; !done; {
		select {
		case <-testTerminated:
			return 0x8f
		case err := <-proxyStarted:
			if err != nil {
				d.Severe(err)
				return 127
			}
			done = true
		case err := <-envStarted:
			if err != nil {
				d.Severe(err)
				return 127
			}
			defer shutdownFunc()
		}
	}

	go func() {
		if status := testCmd.Run(); status != nil {
			log.Printf("test failed %v", status)
			if ee, ok := err.(*exec.ExitError); ok {
				if ws, ok := ee.Sys().(syscall.WaitStatus); ok {
					testFinished <- ws.ExitStatus()
					return
				}
			}
			testFinished <- 1
			return
		}
		testFinished <- 0
	}()

	for {
		select {
		case <-testTerminated:
			return 0x8f
		case err := <-envStarted:
			if err != nil {
				d.Severe(err)
				return 127
			}
			defer shutdownFunc()
		case status := <-testFinished:
			return status
		}
	}
}