get.porter.sh/porter@v1.3.0/tests/integration/dependenciesv2_test.go (about)

     1  //go:build integration
     2  
     3  package integration
     4  
     5  import (
     6  	"context"
     7  	"os"
     8  	"path/filepath"
     9  	"testing"
    10  
    11  	"get.porter.sh/porter/pkg/cnab"
    12  	"get.porter.sh/porter/pkg/experimental"
    13  	"get.porter.sh/porter/pkg/porter"
    14  	"get.porter.sh/porter/pkg/storage"
    15  	"github.com/stretchr/testify/assert"
    16  	"github.com/stretchr/testify/require"
    17  )
    18  
    19  func TestSharedDependencies(t *testing.T) {
    20  	t.Parallel()
    21  	p := porter.NewTestPorter(t)
    22  	defer p.Close()
    23  	ctx := p.SetupIntegrationTest()
    24  
    25  	p.Config.SetExperimentalFlags(experimental.FlagDependenciesV2)
    26  
    27  	namespace := p.RandomString(10)
    28  
    29  	bunDir, err := os.MkdirTemp("", "porter-mysql-")
    30  	require.NoError(p.T(), err, "could not create temp directory at all")
    31  	defer os.RemoveAll(bunDir)
    32  
    33  	setupWordpress_v2(ctx, p, namespace, bunDir)
    34  	upgradeWordpressBundle_v2(ctx, p, namespace)
    35  	invokeWordpressBundle_v2(ctx, p, namespace)
    36  	uninstallWordpressBundle_v2(ctx, p, namespace)
    37  	defer cleanupWordpressBundle_v2(ctx, p, namespace)
    38  
    39  }
    40  
    41  func setupMysql(ctx context.Context, p *porter.TestPorter, namespace string, bunDir string) {
    42  	p.TestConfig.TestContext.AddTestDirectory(filepath.Join(p.RepoRoot, "build/testdata/bundles/mysql"), bunDir+"/mysql")
    43  
    44  	p.Chdir(bunDir + "/mysql")
    45  
    46  	publishOpts := porter.PublishOptions{}
    47  	publishOpts.Force = true
    48  	err := publishOpts.Validate(p.Config)
    49  	require.NoError(p.T(), err, "validation of publish opts for dependent bundle failed")
    50  
    51  	err = p.Publish(ctx, publishOpts)
    52  	require.NoError(p.T(), err, "publish of dependent bundle failed")
    53  	installOpts := porter.NewInstallOptions()
    54  
    55  	installOpts.Namespace = namespace
    56  	installOpts.CredentialIdentifiers = []string{"ci"} // Use the ci credential set, porter should remember this for later
    57  
    58  	err = installOpts.Validate(ctx, []string{}, p.Porter)
    59  	require.NoError(p.T(), err, "validation of install opts for shared mysql bundle failed")
    60  
    61  	err = p.InstallBundle(ctx, installOpts)
    62  	require.NoError(p.T(), err, "install of shared mysql bundle failed namespace %s", namespace)
    63  
    64  	mysqlinst, err := p.Installations.GetInstallation(ctx, namespace, "mysql")
    65  	require.NoError(p.T(), err, "could not fetch installation status for the dependency")
    66  
    67  	//Set the label on the installation so Porter knows to grab it
    68  	mysqlinst.SetLabel("sh.porter.SharingGroup", "myapp")
    69  	err = p.Installations.UpdateInstallation(ctx, mysqlinst)
    70  	require.NoError(p.T(), err, "could not add label to mysql inst")
    71  
    72  }
    73  
    74  func setupWordpress_v2(ctx context.Context, p *porter.TestPorter, namespace string, bunDir string) {
    75  	setupMysql(ctx, p, namespace, bunDir)
    76  	p.CopyDirectory(filepath.Join(p.RepoRoot, "build/testdata/bundles/wordpressv2"), ".", false)
    77  
    78  	publishOpts := porter.PublishOptions{}
    79  	publishOpts.Force = true
    80  	err := publishOpts.Validate(p.Config)
    81  	require.NoError(p.T(), err, "validation of publish opts for dependent bundle failed")
    82  
    83  	err = p.Publish(ctx, publishOpts)
    84  	require.NoError(p.T(), err, "publish of dependent bundle failed")
    85  
    86  	installOpts := porter.NewInstallOptions()
    87  	installOpts.Namespace = namespace
    88  	installOpts.CredentialIdentifiers = []string{"ci"} // Use the ci credential set, porter should remember this for later
    89  	installOpts.Params = []string{
    90  		"wordpress-password=mypassword",
    91  		"namespace=" + namespace,
    92  	}
    93  
    94  	err = installOpts.Validate(ctx, []string{}, p.Porter)
    95  	require.NoError(p.T(), err, "validation of install opts for root bundle failed")
    96  
    97  	err = p.InstallBundle(ctx, installOpts)
    98  	require.NoError(p.T(), err, "install of root bundle failed namespace %s", namespace)
    99  
   100  	numInst, err := p.Installations.ListInstallations(ctx, storage.ListOptions{Namespace: namespace})
   101  	assert.Equal(p.T(), 2, len(numInst))
   102  
   103  	i, err := p.Installations.GetInstallation(ctx, namespace, "mysql")
   104  	require.NoError(p.T(), err, "could not fetch installation status for the dependency")
   105  	assert.Equal(p.T(), cnab.StatusSucceeded, i.Status.ResultStatus, "the dependency wasn't recorded as being installed successfully")
   106  
   107  	// Verify that the bundle claim is present
   108  	i, err = p.Installations.GetInstallation(ctx, namespace, "wordpress")
   109  	require.NoError(p.T(), err, "could not fetch claim for the root bundle")
   110  	assert.Equal(p.T(), cnab.StatusSucceeded, i.Status.ResultStatus, "the root bundle wasn't recorded as being installed successfully")
   111  }
   112  
   113  func cleanupWordpressBundle_v2(ctx context.Context, p *porter.TestPorter, namespace string) {
   114  	uninstallOptions := porter.NewUninstallOptions()
   115  	uninstallOptions.Namespace = namespace
   116  	uninstallOptions.CredentialIdentifiers = []string{"ci"}
   117  	uninstallOptions.Delete = true
   118  	err := uninstallOptions.Validate(ctx, []string{}, p.Porter)
   119  	require.NoError(p.T(), err, "validation of uninstall opts for root bundle failed")
   120  
   121  	err = p.UninstallBundle(ctx, uninstallOptions)
   122  	require.NoError(p.T(), err, "uninstall of root bundle failed")
   123  
   124  	// This shouldn't get deleted, it existed before, and it should exist after
   125  	i, err := p.Installations.GetInstallation(ctx, namespace, "mysql")
   126  	assert.Equal(p.T(), cnab.StatusSucceeded, i.Status.ResultStatus, "the dependency wasn't recorded as being installed successfully")
   127  
   128  	// Verify that the root installation is deleted
   129  	i, err = p.Installations.GetInstallation(ctx, namespace, "wordpress")
   130  	require.ErrorIs(p.T(), err, storage.ErrNotFound{})
   131  	require.Equal(p.T(), storage.Installation{}, i)
   132  }
   133  
   134  func upgradeWordpressBundle_v2(ctx context.Context, p *porter.TestPorter, namespace string) {
   135  	upgradeOpts := porter.NewUpgradeOptions()
   136  	upgradeOpts.Namespace = namespace
   137  	// do not specify credential sets, porter should reuse what was specified from install
   138  	upgradeOpts.Params = []string{
   139  		"wordpress-password=mypassword",
   140  		"namespace=" + namespace,
   141  		"mysql#namespace=" + namespace,
   142  	}
   143  	err := upgradeOpts.Validate(ctx, []string{}, p.Porter)
   144  	require.NoError(p.T(), err, "validation of upgrade opts for root bundle failed")
   145  
   146  	err = p.UpgradeBundle(ctx, upgradeOpts)
   147  	require.NoError(p.T(), err, "upgrade of root bundle failed")
   148  
   149  	// Verify that the dependency claim is still installed
   150  	// upgrade should not change our status
   151  	i, err := p.Installations.GetInstallation(ctx, namespace, "mysql")
   152  	require.NoError(p.T(), err, "could not fetch claim for the dependency")
   153  
   154  	assert.Equal(p.T(), cnab.StatusSucceeded, i.Status.ResultStatus, "the dependency wasn't recorded as being upgraded successfully")
   155  
   156  	// Verify that the bundle claim is upgraded
   157  	i, err = p.Installations.GetInstallation(ctx, namespace, "wordpress")
   158  	require.NoError(p.T(), err, "could not fetch claim for the root bundle")
   159  	c, err := p.Installations.GetLastRun(ctx, i.Namespace, i.Name)
   160  	require.NoError(p.T(), err, "GetLastClaim failed")
   161  	assert.Equal(p.T(), cnab.ActionUpgrade, c.Action, "the root bundle wasn't recorded as being upgraded")
   162  	assert.Equal(p.T(), cnab.StatusSucceeded, i.Status.ResultStatus, "the root bundle wasn't recorded as being upgraded successfully")
   163  
   164  	// Check that we are using the original credential set specified during install
   165  	require.Len(p.T(), i.CredentialSets, 1, "expected only one credential set associated to the installation")
   166  	assert.Equal(p.T(), "ci", i.CredentialSets[0], "expected to use the alternate credential set")
   167  }
   168  
   169  func invokeWordpressBundle_v2(ctx context.Context, p *porter.TestPorter, namespace string) {
   170  	invokeOpts := porter.NewInvokeOptions()
   171  	invokeOpts.Namespace = namespace
   172  	invokeOpts.Action = "ping"
   173  	// Use a different set of creds to run this rando command
   174  	invokeOpts.CredentialIdentifiers = []string{"ci2"}
   175  	invokeOpts.Params = []string{
   176  		"wordpress-password=mypassword",
   177  		"namespace=" + namespace,
   178  	}
   179  	err := invokeOpts.Validate(ctx, []string{}, p.Porter)
   180  	require.NoError(p.T(), err, "validation of invoke opts for root bundle failed")
   181  
   182  	err = p.InvokeBundle(ctx, invokeOpts)
   183  	require.NoError(p.T(), err, "invoke of root bundle failed")
   184  
   185  	// Verify that the dependency claim is invoked
   186  
   187  	i, err := p.Installations.GetInstallation(ctx, namespace, "mysql")
   188  	require.NoError(p.T(), err, "could not fetch claim for the dependency")
   189  	c, err := p.Installations.GetLastRun(ctx, i.Namespace, i.Name)
   190  	require.NoError(p.T(), err, "GetLastClaim failed")
   191  	assert.Equal(p.T(), "ping", c.Action, "the dependency wasn't recorded as being invoked")
   192  	assert.Equal(p.T(), cnab.StatusSucceeded, i.Status.ResultStatus, "the dependency wasn't recorded as being invoked successfully")
   193  
   194  	// Verify that the bundle claim is invoked
   195  	i, err = p.Installations.GetInstallation(ctx, namespace, "wordpress")
   196  	require.NoError(p.T(), err, "could not fetch claim for the root bundle")
   197  	c, err = p.Installations.GetLastRun(ctx, i.Namespace, i.Name)
   198  	require.NoError(p.T(), err, "GetLastClaim failed")
   199  	assert.Equal(p.T(), "ping", c.Action, "the root bundle wasn't recorded as being invoked")
   200  	assert.Equal(p.T(), cnab.StatusSucceeded, i.Status.ResultStatus, "the root bundle wasn't recorded as being invoked successfully")
   201  
   202  	// Check that we are now using the alternate credentials with the bundle
   203  	require.Len(p.T(), i.CredentialSets, 1, "expected only one credential set associated to the installation")
   204  	assert.Equal(p.T(), "ci2", i.CredentialSets[0], "expected to use the alternate credential set")
   205  }
   206  
   207  func uninstallWordpressBundle_v2(ctx context.Context, p *porter.TestPorter, namespace string) {
   208  
   209  	uninstallOptions := porter.NewUninstallOptions()
   210  	uninstallOptions.Namespace = namespace
   211  	// Now go back to using the original set of credentials
   212  	uninstallOptions.CredentialIdentifiers = []string{"ci"}
   213  	uninstallOptions.Params = []string{
   214  		"namespace=" + namespace,
   215  		"mysql#namespace=" + namespace,
   216  	}
   217  	err := uninstallOptions.Validate(ctx, []string{}, p.Porter)
   218  	require.NoError(p.T(), err, "validation of uninstall opts for root bundle failed")
   219  
   220  	err = p.UninstallBundle(ctx, uninstallOptions)
   221  	require.NoError(p.T(), err, "uninstall of root bundle failed")
   222  
   223  	// Verify that the bundle claim is uninstalled
   224  	i, err := p.Installations.GetInstallation(ctx, namespace, "wordpress")
   225  	require.NoError(p.T(), err, "could not fetch installation for the root bundle")
   226  	c, err := p.Installations.GetLastRun(ctx, i.Namespace, i.Name)
   227  	require.NoError(p.T(), err, "GetLastClaim failed")
   228  	assert.Equal(p.T(), cnab.ActionUninstall, c.Action, "the root bundle wasn't recorded as being uninstalled")
   229  	assert.Equal(p.T(), cnab.StatusSucceeded, i.Status.ResultStatus, "the root bundle wasn't recorded as being uninstalled successfully")
   230  
   231  	// Check that we are now using the original credentials with the bundle
   232  	require.Len(p.T(), i.CredentialSets, 1, "expected only one credential set associated to the installation")
   233  	assert.Equal(p.T(), "ci", i.CredentialSets[0], "expected to use the alternate credential set")
   234  
   235  }