github.com/replicatedcom/ship@v0.50.0/integration/update/integration_test.go (about)

     1  package integration
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os"
     9  	"path"
    10  	"testing"
    11  
    12  	"github.com/docker/docker/client"
    13  	. "github.com/onsi/ginkgo"
    14  	. "github.com/onsi/gomega"
    15  	"github.com/onsi/gomega/format"
    16  	"github.com/replicatedhq/ship/integration"
    17  	"github.com/replicatedhq/ship/pkg/cli"
    18  	"github.com/replicatedhq/ship/pkg/state"
    19  	yaml "gopkg.in/yaml.v3"
    20  )
    21  
    22  type TestMetadata struct {
    23  	Args []string `yaml:"args"`
    24  	Skip bool     `yaml:"skip"`
    25  
    26  	// debugging
    27  	SkipCleanup  bool     `yaml:"skip_cleanup"`
    28  	IgnoredFiles []string `yaml:"ignoredFiles"`
    29  }
    30  
    31  func TestShipUpdate(t *testing.T) {
    32  	RegisterFailHandler(Fail)
    33  	format.MaxDepth = 30
    34  	RunSpecs(t, "ship update")
    35  }
    36  
    37  var _ = Describe("ship update", func() {
    38  	dockerClient, err := client.NewEnvClient()
    39  	if err != nil {
    40  		panic(err)
    41  	}
    42  	dockerClient.NegotiateAPIVersion(context.Background())
    43  
    44  	integrationDir, err := os.Getwd()
    45  	if err != nil {
    46  		panic(err)
    47  	}
    48  
    49  	files, err := ioutil.ReadDir(integrationDir)
    50  	if err != nil {
    51  		panic(err)
    52  	}
    53  
    54  	for _, file := range files {
    55  		if file.IsDir() {
    56  			Context(fmt.Sprintf("When the spec in %q is run", file.Name()), func() {
    57  				testPath := path.Join(integrationDir, file.Name())
    58  				testInputPath := path.Join(testPath, "input")
    59  				var testOutputPath string
    60  				var testMetadata TestMetadata
    61  
    62  				BeforeEach(func() {
    63  					os.Setenv("NO_OS_EXIT", "1")
    64  					// create a temporary directory within this directory to compare files with
    65  					testOutputPath, err = ioutil.TempDir(testPath, "_test_")
    66  					Expect(err).NotTo(HaveOccurred())
    67  
    68  					integration.RecursiveCopy(testInputPath, testOutputPath)
    69  
    70  					// the test needs to execute in the same directory throughout the lifecycle of `ship update`
    71  					testInputPath = testOutputPath
    72  
    73  					err = os.Chdir(testOutputPath)
    74  					Expect(err).NotTo(HaveOccurred())
    75  
    76  					// read the test metadata
    77  					testMetadata = readMetadata(testPath)
    78  				}, 20)
    79  
    80  				AfterEach(func() {
    81  					if !testMetadata.SkipCleanup && os.Getenv("SHIP_INTEGRATION_SKIP_CLEANUP_ALL") == "" {
    82  						err := state.GetSingleton().RemoveStateFile()
    83  						Expect(err).NotTo(HaveOccurred())
    84  
    85  						// remove the temporary directory
    86  						err = os.RemoveAll(testOutputPath)
    87  						Expect(err).NotTo(HaveOccurred())
    88  					}
    89  					os.Chdir(integrationDir)
    90  				}, 20)
    91  
    92  				It("Should output files matching those expected when running in update mode", func() {
    93  					if testMetadata.Skip {
    94  						return
    95  					}
    96  
    97  					cmd := cli.RootCmd()
    98  					buf := new(bytes.Buffer)
    99  					cmd.SetOutput(buf)
   100  					os.Setenv("PRELOAD_TEST_STATE", "1")
   101  					args := []string{
   102  						"update",
   103  						"--headless",
   104  						fmt.Sprintf("--state-file=%s", path.Join(testInputPath, ".ship/state.json")),
   105  					}
   106  					args = append(args, testMetadata.Args...)
   107  					cmd.SetArgs(args)
   108  					err := cmd.Execute()
   109  					Expect(err).NotTo(HaveOccurred())
   110  
   111  					ignoreEntitlementSig := map[string][]string{
   112  						".ship/state.json": {
   113  							"v1.upstreamContents.appRelease.configSpec",
   114  							"v1.upstreamContents.appRelease.entitlementSpec",
   115  							"v1.upstreamContents.appRelease.entitlements",
   116  							"v1.upstreamContents.appRelease.registrySecret",
   117  							"v1.upstreamContents.appRelease.analyzeSpec",
   118  							"v1.upstreamContents.appRelease.collectSpec",
   119  							"v1.shipVersion",
   120  						},
   121  						".ship/upstream/appRelease.json": {
   122  							"configSpec",
   123  							"entitlementSpec",
   124  							"entitlements",
   125  							"registrySecret",
   126  							"analyzeSpec",
   127  							"collectSpec",
   128  						},
   129  					}
   130  
   131  					// compare the files in the temporary directory with those in the "expected" directory
   132  					// TODO: text based comparison of state files is brittle because helm values are being merged.
   133  					// they should really be compared using the versioned state object
   134  					result, err := integration.CompareDir(path.Join(testPath, "expected"), testOutputPath, map[string]string{}, testMetadata.IgnoredFiles, ignoreEntitlementSig)
   135  					Expect(err).NotTo(HaveOccurred())
   136  					Expect(result).To(BeTrue())
   137  				}, 60)
   138  			})
   139  		}
   140  	}
   141  })
   142  
   143  func readMetadata(testPath string) TestMetadata {
   144  	var testMetadata TestMetadata
   145  	metadataBytes, err := ioutil.ReadFile(path.Join(testPath, "metadata.yaml"))
   146  	Expect(err).NotTo(HaveOccurred())
   147  	err = yaml.Unmarshal(metadataBytes, &testMetadata)
   148  	Expect(err).NotTo(HaveOccurred())
   149  
   150  	return testMetadata
   151  }