Skip to content

Commit c413835

Browse files
feat: add catalog update env metadata changeset
1 parent cbc2fa5 commit c413835

3 files changed

Lines changed: 245 additions & 0 deletions

File tree

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package changesets
2+
3+
import (
4+
"errors"
5+
6+
cldfdatastore "github.com/smartcontractkit/chainlink-deployments-framework/datastore"
7+
cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment"
8+
cldfops "github.com/smartcontractkit/chainlink-deployments-framework/operations"
9+
10+
"github.com/smartcontractkit/cld-changesets/catalog/operations"
11+
)
12+
13+
// UpdateEnvMetadataChangeset updates existing env metadata entries in the Catalog service.
14+
type UpdateEnvMetadataChangeset struct{}
15+
16+
type UpdateEnvMetadataChangesetInput struct {
17+
EnvMetadata cldfdatastore.EnvMetadata `json:"envMetadata"`
18+
}
19+
20+
// VerifyPreconditions ensures the input is valid.
21+
func (UpdateEnvMetadataChangeset) VerifyPreconditions(e cldf.Environment, input UpdateEnvMetadataChangesetInput) error {
22+
if input.EnvMetadata.Metadata == nil {
23+
return errors.New("missing env metadata input")
24+
}
25+
if e.DataStore == nil {
26+
return errors.New("missing datastore in environment")
27+
}
28+
29+
return nil
30+
}
31+
32+
// Apply executes the changeset, updating the env metadata in the Catalog service.
33+
func (UpdateEnvMetadataChangeset) Apply(
34+
e cldf.Environment, input UpdateEnvMetadataChangesetInput,
35+
) (cldf.ChangesetOutput, error) {
36+
deps := operations.UpdateEnvMetadataDeps{DataStore: e.DataStore}
37+
opInput := operations.UpdateEnvMetadataInput{EnvMetadata: input.EnvMetadata}
38+
39+
report, err := cldfops.ExecuteOperation(e.OperationsBundle, operations.UpdateEnvMetadataOp, deps, opInput)
40+
out := cldf.ChangesetOutput{
41+
DataStore: report.Output.DataStore,
42+
Reports: []cldfops.Report[any, any]{report.ToGenericReport()},
43+
}
44+
if err != nil {
45+
return out, err
46+
}
47+
48+
return out, nil
49+
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package changesets
2+
3+
import (
4+
"testing"
5+
6+
"github.com/Masterminds/semver/v3"
7+
"github.com/google/go-cmp/cmp"
8+
"github.com/google/go-cmp/cmp/cmpopts"
9+
"github.com/stretchr/testify/require"
10+
11+
cldfdatastore "github.com/smartcontractkit/chainlink-deployments-framework/datastore"
12+
cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment"
13+
cldfoperations "github.com/smartcontractkit/chainlink-deployments-framework/operations"
14+
cldflogger "github.com/smartcontractkit/chainlink-deployments-framework/pkg/logger"
15+
16+
"github.com/smartcontractkit/cld-changesets/catalog/operations"
17+
)
18+
19+
func TestUpdateEnvMetadataChangeset_VerifyPreconditions(t *testing.T) {
20+
t.Parallel()
21+
22+
envMetadata := cldfdatastore.EnvMetadata{Metadata: "value"}
23+
24+
tests := []struct {
25+
name string
26+
env cldf.Environment
27+
input UpdateEnvMetadataChangesetInput
28+
wantErr string
29+
}{
30+
{
31+
name: "success: valid preconditions",
32+
env: cldf.Environment{DataStore: func() cldfdatastore.DataStore {
33+
ds := cldfdatastore.NewMemoryDataStore()
34+
err := ds.EnvMetadata().Set(envMetadata)
35+
require.NoError(t, err)
36+
37+
return ds.Seal()
38+
}()},
39+
input: UpdateEnvMetadataChangesetInput{
40+
EnvMetadata: envMetadata,
41+
},
42+
},
43+
{
44+
name: "failure: missing datastore",
45+
env: cldf.Environment{},
46+
input: UpdateEnvMetadataChangesetInput{
47+
EnvMetadata: envMetadata,
48+
},
49+
wantErr: "missing datastore in environment",
50+
},
51+
{
52+
name: "failure: no env metadata given",
53+
env: cldf.Environment{DataStore: cldfdatastore.NewMemoryDataStore().Seal()},
54+
input: UpdateEnvMetadataChangesetInput{
55+
EnvMetadata: cldfdatastore.EnvMetadata{},
56+
},
57+
wantErr: "missing env metadata input",
58+
},
59+
}
60+
for _, tt := range tests {
61+
t.Run(tt.name, func(t *testing.T) {
62+
t.Parallel()
63+
64+
err := UpdateEnvMetadataChangeset{}.VerifyPreconditions(tt.env, tt.input)
65+
66+
if tt.wantErr == "" {
67+
require.NoError(t, err)
68+
} else {
69+
require.ErrorContains(t, err, tt.wantErr)
70+
}
71+
})
72+
}
73+
}
74+
75+
func TestUpdateEnvMetadataChangeset_Apply(t *testing.T) {
76+
t.Parallel()
77+
78+
envMetadata := cldfdatastore.EnvMetadata{Metadata: "value"}
79+
envMetadataUpdated := cldfdatastore.EnvMetadata{Metadata: "updated-value"}
80+
81+
tests := []struct {
82+
name string
83+
env cldf.Environment
84+
input UpdateEnvMetadataChangesetInput
85+
want cldf.ChangesetOutput
86+
wantErr string
87+
}{
88+
{
89+
name: "success: updates two entries in env metadata",
90+
env: cldf.Environment{
91+
DataStore: testDataStoreWithEnvMetadata(t, envMetadata).Seal(),
92+
OperationsBundle: cldfoperations.NewBundle(t.Context, cldflogger.Test(t), cldfoperations.NewMemoryReporter()),
93+
},
94+
input: UpdateEnvMetadataChangesetInput{
95+
EnvMetadata: envMetadataUpdated,
96+
},
97+
want: cldf.ChangesetOutput{
98+
DataStore: testDataStoreWithEnvMetadata(t, envMetadataUpdated),
99+
Reports: []cldfoperations.Report[any, any]{{
100+
Def: cldfoperations.Definition{
101+
ID: "catalog-update-env-metadata",
102+
Version: semver.MustParse("1.0.0"),
103+
Description: "Update env metadata entries in the Catalog service",
104+
},
105+
Input: operations.UpdateEnvMetadataInput{
106+
EnvMetadata: envMetadataUpdated,
107+
},
108+
Output: operations.UpdateEnvMetadataOutput{
109+
DataStore: testDataStoreWithEnvMetadata(t, envMetadataUpdated),
110+
},
111+
}},
112+
},
113+
},
114+
}
115+
for _, tt := range tests {
116+
t.Run(tt.name, func(t *testing.T) {
117+
t.Parallel()
118+
119+
got, err := UpdateEnvMetadataChangeset{}.Apply(tt.env, tt.input)
120+
121+
if tt.wantErr == "" {
122+
require.NoError(t, err)
123+
require.Empty(t,
124+
cmp.Diff(tt.want, got,
125+
cmpopts.IgnoreFields(cldfoperations.Report[any, any]{}, "ID", "Timestamp"),
126+
cmpopts.IgnoreUnexported(cldfdatastore.MemoryAddressRefStore{}, cldfdatastore.MemoryChainMetadataStore{},
127+
cldfdatastore.MemoryContractMetadataStore{}, cldfdatastore.MemoryEnvMetadataStore{})))
128+
} else {
129+
require.ErrorContains(t, err, tt.wantErr)
130+
}
131+
})
132+
}
133+
}
134+
135+
// ----- helpers -----
136+
137+
func testDataStoreWithEnvMetadata(
138+
t *testing.T, metadata cldfdatastore.EnvMetadata,
139+
) cldfdatastore.MutableDataStore {
140+
t.Helper()
141+
142+
ds := cldfdatastore.NewMemoryDataStore()
143+
err := ds.EnvMetadata().Set(metadata)
144+
require.NoError(t, err)
145+
146+
return ds
147+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package operations
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/Masterminds/semver/v3"
7+
8+
cldfdatastore "github.com/smartcontractkit/chainlink-deployments-framework/datastore"
9+
cldfops "github.com/smartcontractkit/chainlink-deployments-framework/operations"
10+
)
11+
12+
// UpdateEnvMetadataDeps holds non-serializable dependencies for the
13+
// UpdateEnvMetadataOp operation.
14+
type UpdateEnvMetadataDeps struct {
15+
DataStore cldfdatastore.DataStore
16+
}
17+
18+
// UpdateEnvMetadataInput is the serializable input of an UpdateEnvMetadataOp invocation.
19+
type UpdateEnvMetadataInput struct {
20+
EnvMetadata cldfdatastore.EnvMetadata
21+
}
22+
23+
// UpdateEnvMetadataOutput is the serializable output of an UpdateEnvMetadataOp invocation.
24+
type UpdateEnvMetadataOutput struct {
25+
DataStore cldfdatastore.MutableDataStore
26+
}
27+
28+
// UpdateEnvMetadataOp updates existing env metadata entries in the Catalog service.
29+
var UpdateEnvMetadataOp = cldfops.NewOperation(
30+
"catalog-update-env-metadata",
31+
semver.MustParse("1.0.0"),
32+
"Update env metadata entries in the Catalog service",
33+
func(b cldfops.Bundle, deps UpdateEnvMetadataDeps, input UpdateEnvMetadataInput) (UpdateEnvMetadataOutput, error) {
34+
dataStore := cldfdatastore.NewMemoryDataStore()
35+
err := dataStore.Merge(deps.DataStore)
36+
if err != nil {
37+
return UpdateEnvMetadataOutput{}, fmt.Errorf("failed to create memory data store: %w", err)
38+
}
39+
40+
err = dataStore.EnvMetadata().Set(input.EnvMetadata)
41+
if err != nil {
42+
return UpdateEnvMetadataOutput{}, fmt.Errorf("failed to update env metadata in catalog store: %w", err)
43+
}
44+
45+
b.Logger.Infow("Catalog EnvMetadata updated successfully")
46+
47+
return UpdateEnvMetadataOutput{DataStore: dataStore}, nil
48+
},
49+
)

0 commit comments

Comments
 (0)