github.com/emc-advanced-dev/unik@v0.0.0-20190717152701-a58d3e8e33b7/test/helpers/test_helpers.go (about)

     1  package helpers
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/sirupsen/logrus"
     6  	"github.com/emc-advanced-dev/pkg/errors"
     7  	"github.com/solo-io/unik/pkg/client"
     8  	"github.com/solo-io/unik/pkg/config"
     9  	unikos "github.com/solo-io/unik/pkg/os"
    10  	"github.com/solo-io/unik/pkg/types"
    11  	"github.com/solo-io/unik/pkg/util"
    12  	"io/ioutil"
    13  	"os"
    14  	"os/exec"
    15  	"path/filepath"
    16  	"runtime"
    17  	"time"
    18  )
    19  
    20  type TempUnikHome struct {
    21  	Dir string
    22  }
    23  
    24  func (t *TempUnikHome) SetupUnik() {
    25  	if runtime.GOOS == "darwin" {
    26  		tmpDir := filepath.Join(os.Getenv("HOME"), ".unik", "tmp")
    27  		os.Setenv("TMPDIR", tmpDir)
    28  		os.MkdirAll(tmpDir, 0755)
    29  	}
    30  
    31  	n, err := ioutil.TempDir("", "unikhome.")
    32  	if err != nil {
    33  		panic(err)
    34  	}
    35  	config.Internal.UnikHome = n
    36  
    37  	t.Dir = n
    38  }
    39  
    40  func (t *TempUnikHome) TearDownUnik() {
    41  	os.RemoveAll(t.Dir)
    42  }
    43  
    44  func requireEnvVar(key string) (string, error) {
    45  	val := os.Getenv(key)
    46  	if val == "" {
    47  		return "", errors.New(fmt.Sprintf("%s must be set", key), nil)
    48  	}
    49  	return val, nil
    50  }
    51  
    52  func NewAwsConfig() (_ config.Aws, err error) {
    53  	region, err := requireEnvVar("AWS_REGION")
    54  	if err != nil {
    55  		return
    56  	}
    57  	zone, err := requireEnvVar("AWS_AVAILABILITY_ZONE")
    58  	if err != nil {
    59  		return
    60  	}
    61  	return config.Aws{
    62  		Name:   "TEST-AWS-CONFIG",
    63  		Region: region,
    64  		Zone:   zone,
    65  	}, nil
    66  }
    67  
    68  func NewVirtualboxConfig() (_ config.Virtualbox, err error) {
    69  	adapterName, err := requireEnvVar("VBOX_ADAPTER_NAME")
    70  	if err != nil {
    71  		return
    72  	}
    73  	adapterType, err := requireEnvVar("VBOX_ADAPTER_TYPE")
    74  	if err != nil {
    75  		return
    76  	}
    77  
    78  	return config.Virtualbox{
    79  		Name:                  "TEST-VBOX-CONFIG",
    80  		AdapterName:           adapterName,
    81  		VirtualboxAdapterType: config.VirtualboxAdapterType(adapterType),
    82  	}, nil
    83  }
    84  
    85  func NewVsphereConfig() (_ config.Vsphere, err error) {
    86  	vsphereUser, err := requireEnvVar("VSPHERE_USERNAME")
    87  	if err != nil {
    88  		return
    89  	}
    90  	vspherePassword, err := requireEnvVar("VSPHERE_PASSWORD")
    91  	if err != nil {
    92  		return
    93  	}
    94  	vsphereUrl, err := requireEnvVar("VSPHERE_URL")
    95  	if err != nil {
    96  		return
    97  	}
    98  	vsphereDatastore, err := requireEnvVar("VSPHERE_DATASTORE")
    99  	if err != nil {
   100  		return
   101  	}
   102  	vsphereDatacenter, err := requireEnvVar("VSPHERE_DATACENTER")
   103  	if err != nil {
   104  		return
   105  	}
   106  	vsphereNetworkLabel, err := requireEnvVar("VSPHERE_NETWORK_LABEL")
   107  	if err != nil {
   108  		return
   109  	}
   110  
   111  	return config.Vsphere{
   112  		Name:            "TEST-VSPHERE-CONFIG",
   113  		VsphereUser:     vsphereUser,
   114  		VspherePassword: vspherePassword,
   115  		VsphereURL:      vsphereUrl,
   116  		Datastore:       vsphereDatastore,
   117  		Datacenter:      vsphereDatacenter,
   118  		NetworkLabel:    vsphereNetworkLabel,
   119  	}, nil
   120  }
   121  
   122  func NewQemuConfig() (_ config.Qemu, err error) {
   123  	return config.Qemu{
   124  		Name:         "TEST-QEMU-CONFIG",
   125  		NoGraphic:    true,
   126  		DebuggerPort: 3001,
   127  	}, nil
   128  }
   129  
   130  func NewXenConfig() (_ config.Xen, err error) {
   131  	pvGrubKernel, err := requireEnvVar("PV_KERNEL")
   132  	if err != nil {
   133  		return
   134  	}
   135  	return config.Xen{
   136  		Name:       "TEST-XEN-CONFIG",
   137  		XenBridge:  "xenbr0",
   138  		KernelPath: pvGrubKernel,
   139  	}, nil
   140  }
   141  
   142  func NewTestConfig() (cfg config.DaemonConfig) {
   143  	noConfig := true
   144  	if os.Getenv("TEST_AWS") != "" && os.Getenv("TEST_AWS") != "0" {
   145  		awsConfig, err := NewAwsConfig()
   146  		if err != nil {
   147  			logrus.Panic(err)
   148  		}
   149  		cfg.Providers.Aws = append(cfg.Providers.Aws, awsConfig)
   150  		noConfig = false
   151  	}
   152  	if os.Getenv("TEST_VIRTUALBOX") != "" && os.Getenv("TEST_VIRTUALBOX") != "0" {
   153  		vboxConfig, err := NewVirtualboxConfig()
   154  		if err != nil {
   155  			logrus.Panic(err)
   156  		}
   157  		cfg.Providers.Virtualbox = append(cfg.Providers.Virtualbox, vboxConfig)
   158  		noConfig = false
   159  	}
   160  	if os.Getenv("TEST_VSPHERE") != "" && os.Getenv("TEST_VSPHERE") != "0" {
   161  		vsphereConfig, err := NewVsphereConfig()
   162  		if err != nil {
   163  			logrus.Panic(err)
   164  		}
   165  		cfg.Providers.Vsphere = append(cfg.Providers.Vsphere, vsphereConfig)
   166  		noConfig = false
   167  	}
   168  	if os.Getenv("TEST_QEMU") != "" && os.Getenv("TEST_QEMU") != "0" {
   169  		qemuConfig, err := NewQemuConfig()
   170  		if err != nil {
   171  			logrus.Panic(err)
   172  		}
   173  		cfg.Providers.Qemu = append(cfg.Providers.Qemu, qemuConfig)
   174  		noConfig = false
   175  	}
   176  	if os.Getenv("TEST_XEN") != "" && os.Getenv("TEST_XEN") != "0" {
   177  		xenConfig, err := NewXenConfig()
   178  		if err != nil {
   179  			logrus.Panic(err)
   180  		}
   181  		cfg.Providers.Xen = append(cfg.Providers.Xen, xenConfig)
   182  		noConfig = false
   183  	}
   184  	if noConfig {
   185  		logrus.WithField("cfg", cfg).Panic("at least one config must be specified with TEST_<Provider>")
   186  	}
   187  	return
   188  }
   189  
   190  func MakeContainers(projectRoot string) error {
   191  	cmd := exec.Command("make", "-C", projectRoot, "containers")
   192  	util.LogCommand(cmd, true)
   193  	return cmd.Run()
   194  }
   195  
   196  func RemoveContainers(projectRoot string) error {
   197  	cmd := exec.Command("make", "-C", projectRoot, "remove-containers")
   198  	util.LogCommand(cmd, false)
   199  	return cmd.Run()
   200  }
   201  
   202  func TarExampleApp(appDir string) (*os.File, error) {
   203  	projectRoot := GetProjectRoot()
   204  	absRoot, err := filepath.Abs(projectRoot)
   205  	if err != nil {
   206  		return nil, errors.New("getting abs of "+projectRoot, err)
   207  	}
   208  	path := filepath.Join(absRoot, "docs", "examples", appDir)
   209  	logrus.Debugf("tarring sources at %s", path)
   210  	sourceTar, err := ioutil.TempFile("", "example.app.tar.gz.")
   211  	if err != nil {
   212  		return nil, errors.New("failed to create tmp tar file", err)
   213  	}
   214  	if err := unikos.Compress(path, sourceTar.Name()); err != nil {
   215  		os.RemoveAll(path)
   216  		return nil, errors.New("failed to tar sources", err)
   217  	}
   218  	return sourceTar, nil
   219  }
   220  
   221  func TarTestApp(appDir string) (*os.File, error) {
   222  	projectRoot := GetProjectRoot()
   223  	absRoot, err := filepath.Abs(projectRoot)
   224  	if err != nil {
   225  		return nil, errors.New("getting abs of "+projectRoot, err)
   226  	}
   227  	path := filepath.Join(absRoot, "test", "test_apps", appDir)
   228  	logrus.Debugf("tarring sources at %s", path)
   229  	sourceTar, err := ioutil.TempFile("", "test.app.tar.gz.")
   230  	if err != nil {
   231  		return nil, errors.New("failed to create tmp tar file", err)
   232  	}
   233  	if err := unikos.Compress(path, sourceTar.Name()); err != nil {
   234  		return nil, errors.New("failed to tar sources", err)
   235  	}
   236  	return sourceTar, nil
   237  }
   238  
   239  func TarTestVolume() (*os.File, error) {
   240  	projectRoot := GetProjectRoot()
   241  	absRoot, err := filepath.Abs(projectRoot)
   242  	if err != nil {
   243  		return nil, errors.New("getting abs of "+projectRoot, err)
   244  	}
   245  	path := filepath.Join(absRoot, "test", "test_apps", "test_volume")
   246  	logrus.Debugf("tarring data at %s", path)
   247  	dataTar, err := ioutil.TempFile("", "test.data.tar.gz.")
   248  	if err != nil {
   249  		return nil, errors.New("failed to create tmp tar file", err)
   250  	}
   251  	if err := unikos.Compress(path, dataTar.Name()); err != nil {
   252  		return nil, errors.New("failed to tar data", err)
   253  	}
   254  	return dataTar, nil
   255  }
   256  
   257  func BuildExampleImage(daemonUrl, exampleName, compiler, provider string, mounts []string) (*types.Image, error) {
   258  	force := true
   259  	noCleanup := false
   260  	testSourceTar, err := TarExampleApp(exampleName)
   261  	if err != nil {
   262  		return nil, errors.New("tarring example app", err)
   263  	}
   264  	defer os.RemoveAll(testSourceTar.Name())
   265  	return client.UnikClient(daemonUrl).Images().Build(exampleName, testSourceTar.Name(), compiler, provider, "", mounts, force, noCleanup)
   266  }
   267  
   268  func BuildTestImage(daemonUrl, appDir, compiler, provider string, mounts []string) (*types.Image, error) {
   269  	force := true
   270  	noCleanup := false
   271  	testSourceTar, err := TarTestApp(appDir)
   272  	if err != nil {
   273  		return nil, errors.New("tarring test app", err)
   274  	}
   275  	defer os.RemoveAll(testSourceTar.Name())
   276  	return client.UnikClient(daemonUrl).Images().Build(appDir, testSourceTar.Name(), compiler, provider, "", mounts, force, noCleanup)
   277  }
   278  
   279  func RunExampleInstance(daemonUrl, instanceName, imageName string, mountPointsToVols map[string]string) (*types.Instance, error) {
   280  	noCleanup := false
   281  	env := map[string]string{"FOO": "BAR"}
   282  	memoryMb := 128
   283  	return client.UnikClient(daemonUrl).Instances().Run(instanceName, imageName, mountPointsToVols, env, memoryMb, noCleanup, false)
   284  }
   285  
   286  func CreateExampleVolume(daemonUrl, volumeName, provider string, size int) (*types.Volume, error) {
   287  	return client.UnikClient(daemonUrl).Volumes().Create(volumeName, "", provider, size, false)
   288  }
   289  
   290  func CreateTestDataVolume(daemonUrl, volumeName, provider string) (*types.Volume, error) {
   291  	dataTar, err := TarTestVolume()
   292  	if err != nil {
   293  		return nil, errors.New("tarring test data volume", err)
   294  	}
   295  	defer os.RemoveAll(dataTar.Name())
   296  	return client.UnikClient(daemonUrl).Volumes().Create(volumeName, dataTar.Name(), provider, 0, false)
   297  }
   298  
   299  func GetProjectRoot() string {
   300  	projectRoot := os.Getenv("PROJECT_ROOT")
   301  	if projectRoot == "" {
   302  		_, filename, _, ok := runtime.Caller(1)
   303  		if !ok {
   304  			logrus.Panic("could not get current file")
   305  		}
   306  		projectRoot = filepath.Join(filepath.Dir(filename), "..", "..")
   307  	}
   308  	logrus.Infof("using %s as project root", projectRoot)
   309  	return projectRoot
   310  }
   311  
   312  func WaitForIp(daemonUrl, instanceId string, timeout time.Duration) (string, error) {
   313  	errc := make(chan error)
   314  	go func() {
   315  		<-time.After(timeout)
   316  		errc <- errors.New("getting instance ip timed out after "+timeout.String(), nil)
   317  	}()
   318  
   319  	resultc := make(chan string)
   320  	go func() {
   321  		logrus.Infof("retrieving ip for instance %s", instanceId)
   322  		started := time.Now()
   323  		end := started.Add(timeout)
   324  		for {
   325  			instance, err := client.UnikClient(daemonUrl).Instances().Get(instanceId)
   326  			if err != nil {
   327  				errc <- errors.New("getting instance from UniK daemon", err)
   328  				return
   329  			}
   330  			if instance.IpAddress != "" {
   331  				resultc <- instance.IpAddress
   332  				return
   333  			}
   334  			logrus.Debugf("sleeping %v left...", end.Sub(time.Now()))
   335  			time.Sleep(time.Second)
   336  		}
   337  	}()
   338  	select {
   339  	case result := <-resultc:
   340  		return result, nil
   341  	case err := <-errc:
   342  		return "", err
   343  	}
   344  }