func waitForTestServerReady(port int, path string, timeout time.Duration) <-chan bool {
	return pkgserver.Ready(func() (*http.Response, error) {
		resp, err := testServerClient().Get(fmt.Sprintf("https://localhost:%d/%s", port, path))
		return resp, err
	},
		pkgserver.WaitTimeoutParam(timeout),
	)
}
waitForTestServerReady returns a channel that returns true when a test server is ready on the provided port. Returns
false if the server is not ready within the provided timeout duration.
package integration
import (
	"bytes"
	"context"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"testing"
	"time"
	"github.com/nmiyake/pkg/dirs"
	"github.com/palantir/conjure-go-runtime/v2/conjure-go-server/httpserver"
	pkgserver "github.com/palantir/pkg/httpserver"
	"github.com/palantir/pkg/refreshable"
	_ "github.com/palantir/witchcraft-go-logging/wlog-zap"
	"github.com/palantir/witchcraft-go-server/v2/config"
	"github.com/palantir/witchcraft-go-server/v2/witchcraft"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"gopkg.in/yaml.v2"
)
const (
	basePath       = "/example"
	productName    = "example"
	productVersion = "1.2.3"
	userAgent      = "example/1.2.3"
	installYML     = "var/conf/install.yml"
	runtimeYML     = "var/conf/runtime.yml"
)
func createAndRunTestServer(t *testing.T, initFn witchcraft.InitFunc, logOutputBuffer io.Writer) (server *witchcraft.Server, port int, managementPort int, serverErr <-chan error, cleanup func()) {
	var err error
	port, err = pkgserver.AvailablePort()
	require.NoError(t, err)
	managementPort, err = pkgserver.AvailablePort()
	require.NoError(t, err)
	server, serverErr, cleanup = createAndRunCustomTestServer(t, port, managementPort, initFn, logOutputBuffer, createTestServer)
	return server, port, managementPort, serverErr, cleanup
}
type serverCreatorFn func(t *testing.T, initFn witchcraft.InitFunc, installCfg config.Install, logOutputBuffer io.Writer) *witchcraft.Server
func createAndRunCustomTestServer(t *testing.T, port, managementPort int, initFn witchcraft.InitFunc, logOutputBuffer io.Writer, createServer serverCreatorFn) (server *witchcraft.Server, serverErr <-chan error, cleanup func()) {
	installCfg := config.Install{
		ProductName:   productName,
		UseConsoleLog: true,
		Server: config.Server{
			Address:        "localhost",
			Port:           port,
			ManagementPort: managementPort,
			ContextPath:    basePath,
		},
	}
	var err error
	var dir string
	dir, cleanup, err = dirs.TempDir("", "test-server")
	success := false
	defer func() {
		if !success {
			cleanup()
		}
	}()
	require.NoError(t, err)
	restoreWd, err := dirs.SetwdWithRestorer(dir)
	require.NoError(t, err)
	defer restoreWd()
	err = os.MkdirAll("var/conf", 0755)
	require.NoError(t, err)
	installCfgYML, err := yaml.Marshal(installCfg)
	require.NoError(t, err)
	err = ioutil.WriteFile(installYML, installCfgYML, 0644)
	require.NoError(t, err)
	err = ioutil.WriteFile(runtimeYML, []byte(`logging:\n  level: info`), 0644)
	require.NoError(t, err)
	server = createServer(t, initFn, installCfg, logOutputBuffer)
	serverChan := make(chan error)
	go func() {
		serverChan <- server.Start()
	}()
	serverErr = serverChan
	success = <-waitForTestServerReady(port, "example/ok", 5*time.Second)
	if !success {
		errMsg := "timed out waiting for server to start"
		select {
		case err := <-serverChan:
			errMsg = fmt.Sprintf("%s: %+v", errMsg, err)
		default:
		}
		require.Fail(t, errMsg)
	}
	return server, serverErr, cleanup
}
func createTestServer(t *testing.T, initFn witchcraft.InitFunc, installCfg config.Install, logOutputBuffer io.Writer) (server *witchcraft.Server) {
	server = witchcraft.
		NewServer().
		WithInitFunc(func(ctx context.Context, initInfo witchcraft.InitInfo) (func(), error) {
			err := initInfo.Router.Get("/ok", http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
				httpserver.WriteJSONResponse(rw, "ok", http.StatusOK)
			}))
			if err != nil {
				return nil, err
			}
			if initFn != nil {
				return initFn(ctx, initInfo)
			}
			return nil, nil
		}).
		WithInstallConfig(installCfg).
		WithRuntimeConfigProvider(refreshable.NewDefaultRefreshable([]byte{})).
		WithECVKeyProvider(witchcraft.ECVKeyNoOp()).
		WithDisableGoRuntimeMetrics().
		WithSelfSignedCertificate()
	if logOutputBuffer != nil {
		server.WithLoggerStdoutWriter(logOutputBuffer)
	}
	return server
}