func StartTestServer()

in app/testing/testserver.go [63:201]


func StartTestServer(t Logger, customFlags []string) (result TestServer, err error) {
	stopCh := make(chan struct{})
	configDoneCh := make(chan struct{})
	var capturedConfig config.CompletedConfig
	tearDown := func() {
		close(stopCh)
		if len(result.TmpDir) != 0 {
			os.RemoveAll(result.TmpDir)
		}
	}
	defer func() {
		if result.TearDownFn == nil {
			tearDown()
		}
	}()

	result.TmpDir, err = ioutil.TempDir("", "cloud-controller-manager")
	if err != nil {
		return result, fmt.Errorf("failed to create temp dir: %v", err)
	}

	s, err := options.NewCloudControllerManagerOptions()
	if err != nil {
		return TestServer{}, err
	}

	cloudInitializer := func(config *config.CompletedConfig) cloudprovider.Interface {
		capturedConfig = *config
		// send signal to indicate the capturedConfig has been properly set
		close(configDoneCh)
		cloudConfig := config.ComponentConfig.KubeCloudShared.CloudProvider
		cloud, err := cloudprovider.InitCloudProvider(cloudConfig.Name, cloudConfig.CloudConfigFile)
		if err != nil {
			t.Fatalf("Cloud provider could not be initialized: %v", err)
		}
		s.SecureServing.ServerCert.CertDirectory = result.TmpDir
		if cloud == nil {
			t.Fatalf("Cloud provider is nil")
		}
		return cloud
	}
	fss := cliflag.NamedFlagSets{}
	command := app.NewCloudControllerManagerCommand(s, cloudInitializer, app.DefaultInitFuncConstructors, fss, stopCh)

	commandArgs := []string{}
	listeners := []net.Listener{}
	disableInsecure := false
	disableSecure := false
	for _, arg := range customFlags {
		if strings.HasPrefix(arg, "--secure-port=") {
			if arg == "--secure-port=0" {
				commandArgs = append(commandArgs, arg)
				disableSecure = true
			}
		} else if strings.HasPrefix(arg, "--port=") {
			if arg == "--port=0" {
				commandArgs = append(commandArgs, arg)
				disableInsecure = true
			}
		} else if strings.HasPrefix(arg, "--cert-dir=") {
			// skip it
		} else {
			commandArgs = append(commandArgs, arg)
		}
	}

	if !disableSecure {
		listener, bindPort, err := createListenerOnFreePort()
		if err != nil {
			return result, fmt.Errorf("failed to create listener: %v", err)
		}
		listeners = append(listeners, listener)
		commandArgs = append(commandArgs, fmt.Sprintf("--secure-port=%d", bindPort))
		commandArgs = append(commandArgs, fmt.Sprintf("--cert-dir=%s", result.TmpDir))

		t.Logf("cloud-controller-manager will listen securely on port %d...", bindPort)
	}
	if !disableInsecure {
		listener, bindPort, err := createListenerOnFreePort()
		if err != nil {
			return result, fmt.Errorf("failed to create listener: %v", err)
		}
		listeners = append(listeners, listener)
		commandArgs = append(commandArgs, fmt.Sprintf("--port=%d", bindPort))

		t.Logf("cloud-controller-manager will listen securely on port %d...", bindPort)
	}
	for _, listener := range listeners {
		listener.Close()
	}

	errCh := make(chan error)
	go func() {
		command.SetArgs(commandArgs)
		if err := command.Execute(); err != nil {
			errCh <- err
		}
		close(errCh)
	}()

	select {
	case <-configDoneCh:

	case err := <-errCh:
		return result, err
	}

	t.Logf("Waiting for /healthz to be ok...")
	client, err := kubernetes.NewForConfig(capturedConfig.LoopbackClientConfig)
	if err != nil {
		return result, fmt.Errorf("failed to create a client: %v", err)
	}
	err = wait.Poll(100*time.Millisecond, 30*time.Second, func() (bool, error) {
		select {
		case err := <-errCh:
			return false, err
		default:
		}

		result := client.CoreV1().RESTClient().Get().AbsPath("/healthz").Do(context.TODO())
		status := 0
		result.StatusCode(&status)
		if status == 200 {
			return true, nil
		}
		return false, nil
	})
	if err != nil {
		return result, fmt.Errorf("failed to wait for /healthz to return ok: %v", err)
	}

	// from here the caller must call tearDown
	result.LoopbackClientConfig = capturedConfig.LoopbackClientConfig
	result.Options = s
	result.Config = &capturedConfig
	result.TearDownFn = tearDown

	return result, nil
}