get.porter.sh/porter@v1.3.0/tests/smoke/hello_test.go (about)

     1  //go:build smoke
     2  
     3  package smoke
     4  
     5  import (
     6  	"testing"
     7  
     8  	"get.porter.sh/porter/tests"
     9  	"get.porter.sh/porter/tests/testdata"
    10  	"get.porter.sh/porter/tests/tester"
    11  	"github.com/stretchr/testify/require"
    12  	"github.com/uwu-tools/magex/shx"
    13  )
    14  
    15  // Test general flows in porter
    16  func TestHelloBundle(t *testing.T) {
    17  	// I am always using require, so that we stop immediately upon an error
    18  	// A long test is hard to debug when it fails in the middle and keeps going
    19  	test, err := tester.NewTest(t)
    20  	defer test.Close()
    21  	require.NoError(t, err, "test setup failed")
    22  
    23  	test.PrepareTestBundle()
    24  	require.NoError(t, shx.Copy("testdata/buncfg.json", test.TestDir))
    25  	require.NoError(t, shx.Copy("testdata/plugins.yaml", test.TestDir))
    26  	test.Chdir(test.TestDir)
    27  
    28  	// Verify plugins installation
    29  	// This also does a quick regression test to validate that we can change the verbosity to a different value than what is in the config file and have it respected
    30  	_, output := test.RequirePorter("plugins", "install", "-f", "plugins.yaml", "--verbosity=info")
    31  	require.Contains(t, output, "installed azure plugin", "expected to see plugin successfully installed")
    32  	require.NotContainsf(t, output, "Downloading https://cdn.porter.sh/plugins/atom.xml", "Debug information should not be printed because verbosity is set to info")
    33  
    34  	// Run a stateless action before we install and make sure nothing is persisted
    35  	_, output = test.RequirePorter("invoke", testdata.MyBuns, "--action=dry-run", "--reference", testdata.MyBunsRef, "-c=mybuns")
    36  	t.Log(output)
    37  	test.RequireInstallationNotFound(test.CurrentNamespace(), testdata.MyBuns)
    38  
    39  	// Install the bundle and verify the correct output is printed
    40  	_, output = test.RequirePorter("install", testdata.MyBuns, "--reference", testdata.MyBunsRef, "--label", "test=true", "-p=mybuns", "-c=mybuns", "--param", "password=supersecret")
    41  	require.Contains(t, output, "Hello, *******", "expected to see output printed from the bundle itself")
    42  	// Make sure that when the mixin uses span.Debug to print the command it is running, that it's being printed
    43  	require.Contains(t, output, "/cnab/app ./helpers.sh install", "expected to see output printed from the porter runtime libraries")
    44  
    45  	// Should not see the mybuns installation in the global namespace
    46  	test.RequireInstallationNotFound("", testdata.MyBuns)
    47  
    48  	// Should see the installation in the current namespace, it should be successful
    49  	installation := test.RequireInstallationExists(test.CurrentNamespace(), testdata.MyBuns)
    50  	require.Equal(t, "succeeded", installation.Status.ResultStatus)
    51  
    52  	// Logs should have been persisted for the run
    53  	test.RequirePorter("installation", "logs", "show", "-i=mybuns")
    54  
    55  	// Run a no-op action to check the status and check that the run was persisted
    56  	// Also checks that we are processing file parameters properly, when templated and read from the filesystem
    57  	_, output = test.RequirePorter("invoke", testdata.MyBuns, "--action=status", "-c=mybuns", "--param", "cfg=./buncfg.json")
    58  	require.Contains(t, output, `{"color": "blue"}`, "templated file parameter was not decoded properly")
    59  	require.Contains(t, output, `is a unicorn`, "state file parameter was not decoded properly")
    60  
    61  	// Check that the last action is still install, a noop action shouldn't update the installation status
    62  	installation = test.RequireInstallationExists(test.CurrentNamespace(), testdata.MyBuns)
    63  	require.Equal(t, "install", installation.Status.Action) // Install should be the last modifying action
    64  	// TODO(carolynvs): check that status shows up as a run
    65  
    66  	// Install in the test namespace, and do not persist the logs
    67  	test.RequirePorter("install", testdata.MyBuns, "--reference", testdata.MyBunsRef, "--namespace=test", "-c=mybuns", "-p=mybuns", "--no-logs", "--param", "password=supersecret")
    68  	_, _, err = test.RunPorter("installation", "logs", "show", "--namespace=test", "-i=mybuns")
    69  	require.Error(t, err, "expected log retrieval to fail")
    70  	require.Contains(t, err.Error(), "no logs found")
    71  	displayInstallation, err := test.ShowInstallation("test", testdata.MyBuns)
    72  	require.NoError(t, err)
    73  	require.Len(t, displayInstallation.ParameterSets, 1)
    74  
    75  	// Let's try out list filtering!
    76  	// Search by namespace
    77  	installations, err := test.ListInstallations(false, "test", "", nil)
    78  	require.NoError(t, err)
    79  	require.Len(t, installations, 2, "expected two installations in the test namespace: mybuns-db and mybuns")
    80  	require.Equal(t, "mybuns-db", installations[0].Name)
    81  	require.Equal(t, "mybuns", installations[1].Name)
    82  
    83  	// Search by name
    84  	installations, err = test.ListInstallations(true, "", testdata.MyBuns, nil)
    85  	require.NoError(t, err)
    86  	require.Len(t, installations, 4, "expected four installations with mybuns in the name")
    87  
    88  	// Search by label
    89  	installations, err = test.ListInstallations(true, "", "", []string{"test=true"})
    90  	require.NoError(t, err)
    91  	require.Len(t, installations, 1, "expected one installations labeled with test=true")
    92  
    93  	// Validate that we can't accidentally overwrite an installation
    94  	_, _, err = test.RunPorter("install", testdata.MyBuns, "--reference", testdata.MyBunsRef, "--namespace=test", "-c=mybuns", "--param", "password=supersecret")
    95  	tests.RequireErrorContains(t, err, "The installation has already been successfully installed")
    96  
    97  	// We should be able to repeat install with --force
    98  	test.RequirePorter("install", testdata.MyBuns, "--reference", testdata.MyBunsRef, "--namespace=test", "-c=mybuns", "--force", "--param", "password=supersecret")
    99  
   100  	// Upgrade our installation, passing the same cred/param set that is already specified, it shouldn't create duplicates
   101  	// We are also overriding a different parameter, the old value for password should be remembered even though we didn't explicitly set it
   102  	test.RequirePorter("upgrade", testdata.MyBuns, "--namespace", test.CurrentNamespace(), "-p=mybuns", "-c=mybuns", "--param", "log_level=1")
   103  	// no duplicate in credential set or parameter set on the installation
   104  	// record
   105  	displayInstallation, err = test.ShowInstallation(test.CurrentNamespace(), testdata.MyBuns)
   106  	require.NoError(t, err)
   107  	require.Len(t, displayInstallation.ParameterSets, 1)
   108  	require.Len(t, displayInstallation.CredentialSets, 1)
   109  	param, ok := displayInstallation.ResolvedParameters.Get("password")
   110  	require.True(t, ok, "Could not find resolved parameter 'password'")
   111  	require.Equal(t, "supersecret", param.Value, "Expected that the previous override provided during install should be remembered and reused during upgrade")
   112  	param, ok = displayInstallation.ResolvedParameters.Get("log_level")
   113  	require.True(t, ok, "Could not find resolved parameter 'log_level'")
   114  	require.Equal(t, float64(1), param.Value, "Expected the new override for log_level to be used")
   115  
   116  	// Uninstall and remove the installation
   117  	test.RequirePorter("uninstall", testdata.MyBuns, "--namespace", test.CurrentNamespace(), "-c=mybuns")
   118  	displayInstallations, err := test.ListInstallations(false, test.CurrentNamespace(), testdata.MyBuns, nil)
   119  	require.NoError(t, err, "List installations failed")
   120  	require.Len(t, displayInstallations, 2, "expected the installations to still be returned by porter list even though it's uninstalled")
   121  	require.NotEmpty(t, displayInstallations[0].Status.Uninstalled, "expected the installations to be flagged as uninstalled")
   122  	require.NotEmpty(t, displayInstallations[1].Status.Uninstalled, "expected the installations to be flagged as uninstalled")
   123  
   124  	test.RequirePorter("installation", "delete", testdata.MyBuns, "--namespace", test.CurrentNamespace())
   125  	test.RequireInstallationNotFound(test.CurrentNamespace(), testdata.MyBuns)
   126  
   127  	// Let's test some negatives!
   128  
   129  	// Cannot perform a modifying or stateful action without an installation
   130  	_, _, err = test.RunPorter("upgrade", "missing", "--reference", testdata.MyBunsRef)
   131  	test.RequireNotFoundReturned(err)
   132  
   133  	_, _, err = test.RunPorter("uninstall", "missing", "--reference", testdata.MyBunsRef)
   134  	test.RequireNotFoundReturned(err)
   135  
   136  	_, _, err = test.RunPorter("invoke", "--action=boom", "missing", "--reference", testdata.MyBunsRef)
   137  	test.RequireNotFoundReturned(err)
   138  
   139  	_, _, err = test.RunPorter("invoke", "--action=status", "missing", "--reference", testdata.MyBunsRef)
   140  	test.RequireNotFoundReturned(err)
   141  
   142  	// Test that outputs are collected when a bundle fails
   143  	_, _, err = test.RunPorter("install", "fail-with-outputs", "--reference", testdata.MyBunsRef, "-c=mybuns", "-p=mybuns", "--param", "chaos_monkey=true")
   144  	require.Error(t, err, "the chaos monkey should have failed the installation")
   145  	myLogs, _ := test.RequirePorter("installation", "outputs", "show", "mylogs", "-i=fail-with-outputs")
   146  	require.Contains(t, myLogs, "Hello, porterci")
   147  
   148  	myLogsListed, _ := test.RequirePorter("installation", "outputs", "list", "-i=fail-with-outputs")
   149  	require.Contains(t, myLogsListed, "Hello, porterci")
   150  }