get.porter.sh/porter@v1.3.0/pkg/porter/reconcile_test.go (about) 1 package porter 2 3 import ( 4 "context" 5 "path/filepath" 6 "testing" 7 "time" 8 9 "get.porter.sh/porter/pkg/cnab" 10 "get.porter.sh/porter/pkg/portercontext" 11 "get.porter.sh/porter/pkg/secrets" 12 "get.porter.sh/porter/pkg/storage" 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 ) 16 17 func TestPorter_IsInstallationInSync(t *testing.T) { 18 const helloRef = "ghcr.io/getporter/examples/porter-hello:v0.2.0" 19 20 cxt := portercontext.New() 21 bun, err := cnab.LoadBundle(cxt, filepath.Join("testdata/bundle.json")) 22 require.NoError(t, err) 23 24 t.Run("new installation with uninstalled true", func(t *testing.T) { 25 ctx := context.Background() 26 p := NewTestPorter(t) 27 defer p.Close() 28 29 i := storage.NewInstallation("", "mybuns") 30 i.Uninstalled = true 31 opts := NewInstallOptions() 32 opts.Reference = helloRef 33 require.NoError(t, p.applyActionOptionsToInstallation(ctx, opts, &i)) 34 35 insync, err := p.IsInstallationInSync(p.RootContext, i, nil, opts) 36 require.NoError(t, err) 37 assert.True(t, insync) 38 assert.Contains(t, p.TestConfig.TestContext.GetOutput(), "Ignoring because installation.uninstalled is true but the installation doesn't exist yet") 39 }) 40 41 t.Run("new installation with uninstalled false", func(t *testing.T) { 42 ctx := context.Background() 43 p := NewTestPorter(t) 44 defer p.Close() 45 46 i := storage.NewInstallation("", "mybuns") 47 opts := NewInstallOptions() 48 opts.Reference = helloRef 49 require.NoError(t, p.applyActionOptionsToInstallation(ctx, opts, &i)) 50 51 insync, err := p.IsInstallationInSync(p.RootContext, i, nil, opts) 52 require.NoError(t, err) 53 assert.False(t, insync) 54 assert.Contains(t, p.TestConfig.TestContext.GetOutput(), "Triggering because the installation has not completed successfully yet") 55 }) 56 57 t.Run("installed - no changes", func(t *testing.T) { 58 ctx := context.Background() 59 p := NewTestPorter(t) 60 defer p.Close() 61 62 myps := storage.ParameterSet{ 63 ParameterSetSpec: storage.ParameterSetSpec{ 64 Name: "myps", 65 Parameters: []secrets.SourceMap{ 66 storage.ValueStrategy("my-second-param", "override"), 67 }, 68 }, 69 } 70 err := p.Parameters.InsertParameterSet(ctx, myps) 71 require.NoError(t, err) 72 73 i := storage.NewInstallation("", "mybuns") 74 i.ParameterSets = []string{"myps"} 75 i.Status.Installed = &now 76 run := i.NewRun(cnab.ActionUpgrade, bun) 77 // Use the default values from the bundle.json so that we don't trigger reconciliation 78 run.Parameters.Parameters = []secrets.SourceMap{storage.ValueStrategy("my-second-param", "override")} 79 upgradeOpts := NewUpgradeOptions() 80 upgradeOpts.bundleRef = &cnab.BundleReference{Definition: bun} 81 require.NoError(t, p.applyActionOptionsToInstallation(ctx, upgradeOpts, &i)) 82 83 insync, err := p.IsInstallationInSync(p.RootContext, i, &run, upgradeOpts) 84 require.NoError(t, err) 85 assert.True(t, insync) 86 // Nothing is printed out in this case, the calling function will print "up-to-date" for us 87 }) 88 89 t.Run("installed - bundle digest changed", func(t *testing.T) { 90 ctx := context.Background() 91 p := NewTestPorter(t) 92 defer p.Close() 93 94 i := storage.NewInstallation("", "mybuns") 95 i.Status.Installed = &now 96 i.Status.BundleDigest = "olddigest" 97 run := storage.Run{ 98 BundleDigest: "olddigest", 99 } 100 upgradeOpts := NewUpgradeOptions() 101 upgradeOpts.bundleRef = &cnab.BundleReference{Definition: bun, Digest: "newdigest"} 102 require.NoError(t, p.applyActionOptionsToInstallation(ctx, upgradeOpts, &i)) 103 104 insync, err := p.IsInstallationInSync(p.RootContext, i, &run, upgradeOpts) 105 require.NoError(t, err) 106 assert.False(t, insync) 107 assert.Contains(t, p.TestConfig.TestContext.GetOutput(), "Triggering because the bundle definition has changed") 108 }) 109 110 t.Run("installed - param changed", func(t *testing.T) { 111 ctx := context.Background() 112 p := NewTestPorter(t) 113 defer p.Close() 114 115 i := storage.NewInstallation("", "mybuns") 116 i.Status.Installed = &now 117 run := i.NewRun(cnab.ActionUpgrade, bun) 118 run.Parameters.Parameters = []secrets.SourceMap{storage.ValueStrategy("my-second-param", "newvalue")} 119 upgradeOpts := NewUpgradeOptions() 120 upgradeOpts.bundleRef = &cnab.BundleReference{Definition: bun} 121 require.NoError(t, p.applyActionOptionsToInstallation(ctx, upgradeOpts, &i)) 122 123 insync, err := p.IsInstallationInSync(p.RootContext, i, &run, upgradeOpts) 124 require.NoError(t, err) 125 assert.False(t, insync) 126 assert.Contains(t, p.TestConfig.TestContext.GetOutput(), "Triggering because the parameters have changed") 127 128 }) 129 130 t.Run("installed - credential set changed", func(t *testing.T) { 131 ctx := context.Background() 132 p := NewTestPorter(t) 133 defer p.Close() 134 135 i := storage.NewInstallation("", "mybuns") 136 i.Status.Installed = &now 137 i.CredentialSets = []string{"newcreds"} 138 run := i.NewRun(cnab.ActionUpgrade, bun) 139 run.CredentialSets = []string{"oldcreds"} 140 // Use the default values from the bundle.json so they don't trigger the reconciliation 141 run.Parameters.Parameters = []secrets.SourceMap{storage.ValueStrategy("my-second-param", "spring-music-demo")} 142 upgradeOpts := NewUpgradeOptions() 143 upgradeOpts.bundleRef = &cnab.BundleReference{Definition: bun} 144 require.NoError(t, p.applyActionOptionsToInstallation(ctx, upgradeOpts, &i)) 145 146 insync, err := p.IsInstallationInSync(p.RootContext, i, &run, upgradeOpts) 147 require.NoError(t, err) 148 assert.False(t, insync) 149 assert.Contains(t, p.TestConfig.TestContext.GetOutput(), "Triggering because the credential set names have changed") 150 151 }) 152 153 t.Run("installed - uninstalled change to true", func(t *testing.T) { 154 ctx := context.Background() 155 p := NewTestPorter(t) 156 defer p.Close() 157 158 i := storage.NewInstallation("", "mybuns") 159 i.Uninstalled = true // trigger uninstall 160 i.Status.Installed = &now 161 opts := NewUninstallOptions() 162 opts.Reference = helloRef 163 require.NoError(t, p.applyActionOptionsToInstallation(ctx, opts, &i)) 164 165 insync, err := p.IsInstallationInSync(p.RootContext, i, nil, opts) 166 require.NoError(t, err) 167 assert.False(t, insync) 168 assert.Contains(t, p.TestConfig.TestContext.GetOutput(), "Triggering because installation.uninstalled is true") 169 }) 170 171 t.Run("uninstalled: uninstalled set to back to false", func(t *testing.T) { 172 ctx := context.Background() 173 p := NewTestPorter(t) 174 defer p.Close() 175 176 installTime := now.Add(-time.Second * 5) 177 i := storage.NewInstallation("", "mybuns") 178 i.Uninstalled = false 179 i.Status.Installed = &installTime 180 i.Status.Uninstalled = &now 181 opts := NewUninstallOptions() 182 opts.Reference = helloRef 183 require.NoError(t, p.applyActionOptionsToInstallation(ctx, opts, &i)) 184 185 insync, err := p.IsInstallationInSync(p.RootContext, i, nil, NewUninstallOptions()) 186 require.NoError(t, err) 187 assert.True(t, insync) 188 assert.Contains(t, p.TestConfig.TestContext.GetOutput(), "Ignoring because the installation is uninstalled") 189 }) 190 }