get.porter.sh/porter@v1.3.0/pkg/storage/run_test.go (about) 1 package storage 2 3 import ( 4 "encoding/json" 5 "testing" 6 "time" 7 8 "get.porter.sh/porter/pkg/cnab" 9 "get.porter.sh/porter/pkg/secrets" 10 "get.porter.sh/porter/pkg/test" 11 "github.com/cnabio/cnab-go/bundle" 12 "github.com/cnabio/cnab-go/bundle/definition" 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 ) 16 17 func TestRun_NewResultFrom(t *testing.T) { 18 run := NewRun("dev", "mybuns") 19 cnabResult := cnab.Result{ 20 ID: "resultID", 21 ClaimID: "claimID", 22 Created: time.Now(), 23 Message: "message", 24 Status: "status", 25 OutputMetadata: cnab.OutputMetadata{"myoutput": map[string]string{}}, 26 Custom: map[string]interface{}{"custom": true}, 27 } 28 29 result := run.NewResultFrom(cnabResult) 30 assert.Equal(t, cnabResult.ID, result.ID) 31 assert.Equal(t, run.Namespace, result.Namespace) 32 assert.Equal(t, run.Installation, result.Installation) 33 assert.Equal(t, run.ID, result.RunID) 34 assert.Equal(t, cnabResult.Created, result.Created) 35 assert.Equal(t, cnabResult.Status, result.Status) 36 assert.Equal(t, cnabResult.Message, result.Message) 37 assert.Equal(t, cnabResult.OutputMetadata, result.OutputMetadata) 38 assert.Equal(t, cnabResult.Custom, result.Custom) 39 } 40 41 func TestRun_ShouldRecord(t *testing.T) { 42 t.Run("stateless, not modifies", func(t *testing.T) { 43 b := bundle.Bundle{ 44 Actions: map[string]bundle.Action{ 45 "dry-run": { 46 Modifies: false, 47 Stateless: true, 48 }, 49 }, 50 } 51 52 r := Run{Bundle: b, Action: "dry-run"} 53 assert.False(t, r.ShouldRecord()) 54 }) 55 56 t.Run("stateful, not modifies", func(t *testing.T) { 57 b := bundle.Bundle{ 58 Actions: map[string]bundle.Action{ 59 "audit": { 60 Modifies: false, 61 Stateless: false, 62 }, 63 }, 64 } 65 66 r := Run{Bundle: b, Action: "audit"} 67 assert.True(t, r.ShouldRecord()) 68 }) 69 70 t.Run("modifies", func(t *testing.T) { 71 b := bundle.Bundle{ 72 Actions: map[string]bundle.Action{ 73 "editstuff": { 74 Modifies: true, 75 Stateless: false, 76 }, 77 }, 78 } 79 80 r := Run{Bundle: b, Action: "editstuff"} 81 assert.True(t, r.ShouldRecord()) 82 }) 83 84 t.Run("missing definition", func(t *testing.T) { 85 b := bundle.Bundle{} 86 87 r := Run{Bundle: b, Action: "missing"} 88 assert.True(t, r.ShouldRecord()) 89 }) 90 91 t.Run("has user defined output", func(t *testing.T) { 92 b := bundle.Bundle{ 93 Actions: map[string]bundle.Action{ 94 "editstuff": { 95 Modifies: false, 96 Stateless: true, 97 }, 98 }, 99 Outputs: map[string]bundle.Output{ 100 "testdata": { 101 ApplyTo: []string{"editstuff"}, 102 }, 103 }, 104 } 105 106 r := Run{Bundle: b, Action: "editstuff"} 107 assert.True(t, r.ShouldRecord()) 108 }) 109 110 t.Run("has only internal bundle level output", func(t *testing.T) { 111 b := bundle.Bundle{ 112 Definitions: definition.Definitions{ 113 "porter-state": &definition.Schema{ 114 Type: "string", 115 ContentEncoding: "base64", 116 Comment: cnab.PorterInternal, 117 }, 118 }, 119 Actions: map[string]bundle.Action{ 120 "editstuff": { 121 Modifies: false, 122 Stateless: true, 123 }, 124 }, 125 Outputs: map[string]bundle.Output{ 126 "porter-state": {Definition: "porter-state"}, 127 }, 128 } 129 130 r := Run{Bundle: b, Action: "editstuff"} 131 assert.False(t, r.ShouldRecord()) 132 }) 133 134 } 135 136 func TestRun_TypedParameterValues(t *testing.T) { 137 sensitive := true 138 bun := bundle.Bundle{ 139 Definitions: definition.Definitions{ 140 "foo": &definition.Schema{ 141 Type: "integer", 142 WriteOnly: &sensitive, 143 }, 144 "baz": &definition.Schema{ 145 Type: "string", 146 }, 147 "porter-state": &definition.Schema{ 148 Type: "string", 149 ContentEncoding: "base64", 150 Comment: cnab.PorterInternal, 151 }, 152 }, 153 Parameters: map[string]bundle.Parameter{ 154 "foo": { 155 Definition: "foo", 156 }, 157 "baz": { 158 Definition: "baz", 159 }, 160 "name": { 161 Definition: "name", 162 }, 163 "porter-state": { 164 Definition: "porter-state", 165 }, 166 }, 167 RequiredExtensions: []string{ 168 cnab.FileParameterExtensionKey, 169 }, 170 } 171 172 run := NewRun("dev", "mybuns") 173 run.Bundle = bun 174 run.Parameters = NewParameterSet(run.Namespace, run.Bundle.Name, 175 ValueStrategy("baz", "baz-test"), 176 ValueStrategy("name", "porter-test"), 177 ValueStrategy("porter-state", ""), 178 secrets.SourceMap{Name: "foo", Source: secrets.Source{Strategy: secrets.SourceSecret, Hint: "runID"}, ResolvedValue: "5"}) 179 180 expected := map[string]interface{}{ 181 "baz": "baz-test", 182 "name": "porter-test", 183 "porter-state": nil, 184 "foo": 5, 185 } 186 187 typed := run.TypedParameterValues() 188 require.Equal(t, len(run.Parameters.Parameters), len(typed)) 189 require.Equal(t, len(expected), len(typed)) 190 191 for name, value := range typed { 192 v, ok := expected[name] 193 require.True(t, ok) 194 require.Equal(t, v, value) 195 } 196 } 197 198 func TestRun_MarshalJSON(t *testing.T) { 199 // Verify that when a run is marshaled that the bundle field is saved as an escaped json string 200 r1 := Run{ID: "foo", Bundle: exampleBundle} 201 202 data, err := json.Marshal(r1) 203 require.NoError(t, err, "Marshal failed") 204 205 test.CompareGoldenFile(t, "testdata/marshaled_run.json", string(data)) 206 207 var r2 Run 208 err = json.Unmarshal(data, &r2) 209 require.NoError(t, err, "Unmarshal failed") 210 211 assert.Equal(t, r1, r2, "The run did not survive the round trip") 212 }