func getTestContextFrom(t *testing.T, tmpDir string) *testContext {
	log.Infof("Using temporary directory: %s\n", tmpDir)
	c := &testContext{
		t:       t,
		tmpDir:  tmpDir,
		testDir: getTestDir(t),
	}
	log.Info("Installing kind...")
	c.runWithConfig(commandConfig{CheckError: true, Env: env("GO111MODULE=on", "HOME="+tmpDir, "CGO_ENABLED=0"), Stdout: os.Stdout, Stderr: os.Stderr},
		"go", "get", "sigs.k8s.io/kind@v0.9.0")
	log.Info("Installing footloose...")
	c.runWithConfig(commandConfig{CheckError: true, Env: env("GO111MODULE=on", "HOME="+tmpDir, "CGO_ENABLED=0"), Stdout: os.Stdout, Stderr: os.Stderr},
		"go", "get", "github.com/weaveworks/footloose")
	log.Info("Installing clusterctl...")
	for {
		fetchCmd := fmt.Sprintf("curl -L https://github.com/kubernetes-sigs/cluster-api/releases/download/v0.3.10/clusterctl-%s-%s -o %s/clusterctl && chmod a+x %s/clusterctl",
			c.getOS(), c.getArch(), c.tmpDir, c.tmpDir)
		c.runAndCheckError("sh", "-c", fetchCmd)
		_, _, err := c.runCollectingOutput(filepath.Join(c.tmpDir, "clusterctl"), "version")
		if err == nil {
			break
		}
	}
	err := os.Setenv("HOME", c.tmpDir)
	require.NoError(c.t, err)
	kindCmd := filepath.Join(c.tmpDir, "go", "bin", "kind")
	c.run(kindCmd, "delete", "cluster")
	c.runAndCheckError(kindCmd, "create", "cluster")
	return c
}
Creates a testContext, doing the following:
- creating a temporary directory (tmpDir) which will be established as HOME (for user-relative configuration)
- installing kind
- installing clusterctl
- cleaning up any existing kind clusters
- creating a new kind cluster
package test
import (
	"bytes"
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"
	"time"
	log "github.com/sirupsen/logrus"
	"github.com/stretchr/testify/require"
	existinginfrav1 "github.com/weaveworks/cluster-api-provider-existinginfra/apis/cluster.weave.works/v1alpha3"
	capeios "github.com/weaveworks/cluster-api-provider-existinginfra/pkg/apis/wksprovider/machine/os"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/plan"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/plan/recipe"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/plan/resource"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/plan/runners/ssh"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/plan/runners/sudo"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/specs"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/utilities/envcfg"
	"github.com/weaveworks/cluster-api-provider-existinginfra/pkg/utilities/object"
)
type testContext struct {
	t       *testing.T
	tmpDir  string
	testDir string
}
type commandConfig struct {
	CheckError bool
	Dir        string
	Env        []string
	Stdout     *os.File
	Stderr     *os.File
}
func getTestContext(t *testing.T) *testContext {
	tmpDir, err := ioutil.TempDir("", "tmp_dir")
	require.NoError(t, err)
	return getTestContextFrom(t, tmpDir)
}