github.com/replicatedhq/ship@v0.55.0/integration/base/integration_test.go (about)

     1  package base
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os"
     9  	"path"
    10  	"strings"
    11  	"testing"
    12  
    13  	"github.com/docker/docker/client"
    14  	. "github.com/onsi/ginkgo"
    15  	. "github.com/onsi/gomega"
    16  	"github.com/onsi/gomega/format"
    17  	"github.com/replicatedhq/ship/integration"
    18  	"github.com/replicatedhq/ship/pkg/cli"
    19  	"github.com/replicatedhq/ship/pkg/state"
    20  	yaml "gopkg.in/yaml.v3"
    21  )
    22  
    23  type TestMetadata struct {
    24  	CustomerID          string `yaml:"customer_id"`
    25  	InstallationID      string `yaml:"installation_id"`
    26  	ReleaseVersion      string `yaml:"release_version"`
    27  	SetChannelName      string `yaml:"set_channel_name"`
    28  	SetGitHubContents   string `yaml:"set_github_contents"`
    29  	DisableOnline       bool   `yaml:"disable_online"`
    30  	NoStateFile         bool   `yaml:"no_state_file"` // used to denote that there is no input state.json
    31  	SetEntitlementsJSON string `yaml:"set_entitlements_json"`
    32  	//debugging
    33  	SkipCleanup bool     `yaml:"skip_cleanup"`
    34  	Args        []string `yaml:"args"`
    35  }
    36  
    37  func TestShipApp(t *testing.T) {
    38  	RegisterFailHandler(Fail)
    39  	format.MaxDepth = 30
    40  	RunSpecs(t, "ship app")
    41  }
    42  
    43  var _ = Describe("ship app", func() {
    44  	dockerClient, err := client.NewClientWithOpts(client.FromEnv)
    45  	if err != nil {
    46  		panic(err)
    47  	}
    48  	dockerClient.NegotiateAPIVersion(context.Background())
    49  
    50  	integrationDir, err := os.Getwd()
    51  	if err != nil {
    52  		panic(err)
    53  	}
    54  
    55  	files, err := ioutil.ReadDir(integrationDir)
    56  	if err != nil {
    57  		panic(err)
    58  	}
    59  
    60  	for _, file := range files {
    61  		if file.IsDir() {
    62  			Context(fmt.Sprintf("When the spec in %q is run", file.Name()), func() {
    63  				testPath := path.Join(integrationDir, file.Name())
    64  				testInputPath := path.Join(testPath, "input")
    65  				var testOutputPath string
    66  				var testMetadata TestMetadata
    67  
    68  				BeforeEach(func() {
    69  					err = os.Setenv("NO_OS_EXIT", "1")
    70  					Expect(err).NotTo(HaveOccurred())
    71  					// create a temporary directory within this directory to compare files with
    72  					testOutputPath, err = ioutil.TempDir(testPath, "_test_")
    73  					Expect(err).NotTo(HaveOccurred())
    74  					err = os.Chdir(testOutputPath)
    75  					Expect(err).NotTo(HaveOccurred())
    76  
    77  					// read the test metadata
    78  					testMetadata = readMetadata(testPath)
    79  				}, 20)
    80  
    81  				AfterEach(func() {
    82  					if !testMetadata.SkipCleanup && os.Getenv("SHIP_INTEGRATION_SKIP_CLEANUP_ALL") == "" {
    83  						err := state.GetSingleton().RemoveStateFile()
    84  						Expect(err).NotTo(HaveOccurred())
    85  
    86  						// remove the temporary directory
    87  						err = os.RemoveAll(testOutputPath)
    88  						Expect(err).NotTo(HaveOccurred())
    89  					}
    90  
    91  					err = os.Chdir(integrationDir)
    92  					Expect(err).NotTo(HaveOccurred())
    93  				}, 20)
    94  
    95  				It("Should output files matching those expected when running app command in local mode", func() {
    96  					cmd := cli.RootCmd()
    97  					buf := new(bytes.Buffer)
    98  					cmd.SetOutput(buf)
    99  					upstream := fmt.Sprintf(
   100  						"%s?customer_id=%s&installation_id=%s&release_semver=%s",
   101  						path.Join(testInputPath, ".ship/ship.yml"),
   102  						testMetadata.CustomerID, testMetadata.InstallationID, testMetadata.ReleaseVersion,
   103  					)
   104  					args := []string{
   105  						"init",
   106  						upstream,
   107  						fmt.Sprintf("--set-channel-name=%s", testMetadata.SetChannelName),
   108  						fmt.Sprintf("--set-github-contents=%s", testMetadata.SetGitHubContents),
   109  						"--headless",
   110  						"--files-in-state",
   111  						"--log-level=off",
   112  						"--terraform-apply-yes",
   113  					}
   114  					if testMetadata.NoStateFile {
   115  						os.Setenv("PRELOAD_TEST_STATE", "")
   116  					} else {
   117  						args = append(args, fmt.Sprintf("--state-file=%s", path.Join(testInputPath, ".ship/state.json")))
   118  						os.Setenv("PRELOAD_TEST_STATE", "1")
   119  					}
   120  
   121  					if testMetadata.SetEntitlementsJSON != "" {
   122  						args = append(args, fmt.Sprintf("--set-entitlements-json=%s", testMetadata.SetEntitlementsJSON))
   123  					}
   124  
   125  					args = append(args, testMetadata.Args...)
   126  
   127  					cmd.SetArgs(args)
   128  					err := cmd.Execute()
   129  					Expect(err).NotTo(HaveOccurred())
   130  
   131  					ignoreUpstreamContents := map[string][]string{
   132  						".ship/state.json": {"v1.upstreamContents", "v1.shipVersion", "v1.contentSHA"},
   133  					}
   134  
   135  					//compare the files in the temporary directory with those in the "expected" directory
   136  					result, err := integration.CompareDir(path.Join(testPath, "expected"), testOutputPath, map[string]string{
   137  						"__upstream__": strings.Replace(upstream, "&", "\\u0026", -1),
   138  					}, []string{".ship/upstream"}, ignoreUpstreamContents)
   139  					Expect(err).NotTo(HaveOccurred())
   140  					Expect(result).To(BeTrue())
   141  				}, 60)
   142  
   143  				It("Should output files matching those expected when communicating with the graphql api", func() {
   144  					if testMetadata.DisableOnline {
   145  						Skip("Online test skipped")
   146  					}
   147  					cmd := cli.RootCmd()
   148  					buf := new(bytes.Buffer)
   149  					cmd.SetOutput(buf)
   150  					upstream := fmt.Sprintf(
   151  						"staging.replicated.app/integration?customer_id=%s&installation_id=%s&release_semver=%s",
   152  						testMetadata.CustomerID, testMetadata.InstallationID, testMetadata.ReleaseVersion,
   153  					)
   154  					args := []string{
   155  						"init",
   156  						upstream,
   157  						"--headless",
   158  						"--files-in-state",
   159  						"--log-level=off",
   160  						"--terraform-apply-yes",
   161  					}
   162  					if testMetadata.NoStateFile {
   163  						os.Setenv("PRELOAD_TEST_STATE", "")
   164  					} else {
   165  						args = append(args, fmt.Sprintf("--state-file=%s", path.Join(testInputPath, ".ship/state.json")))
   166  						os.Setenv("PRELOAD_TEST_STATE", "1")
   167  					}
   168  					cmd.SetArgs(args)
   169  					err := cmd.Execute()
   170  					Expect(err).NotTo(HaveOccurred())
   171  
   172  					ignoreUpstreamContents := map[string][]string{
   173  						".ship/state.json": {"v1.upstreamContents", "v1.shipVersion"},
   174  					}
   175  
   176  					//compare the files in the temporary directory with those in the "expected" directory
   177  					result, err := integration.CompareDir(path.Join(testPath, "expected"), testOutputPath, map[string]string{
   178  						"__upstream__": strings.Replace(upstream, "&", "\\u0026", -1),
   179  					}, []string{".ship/upstream"}, ignoreUpstreamContents)
   180  					Expect(err).NotTo(HaveOccurred())
   181  					Expect(result).To(BeTrue())
   182  				}, 60)
   183  			})
   184  		}
   185  	}
   186  })
   187  
   188  func readMetadata(testPath string) TestMetadata {
   189  	var testMetadata TestMetadata
   190  	metadataBytes, err := ioutil.ReadFile(path.Join(testPath, "metadata.yaml"))
   191  	Expect(err).NotTo(HaveOccurred())
   192  	err = yaml.Unmarshal(metadataBytes, &testMetadata)
   193  	Expect(err).NotTo(HaveOccurred())
   194  
   195  	return testMetadata
   196  }