diff --git a/api/filters/annotations/annotations_test.go b/api/filters/annotations/annotations_test.go index 39fd8e2e2..d52cd673a 100644 --- a/api/filters/annotations/annotations_test.go +++ b/api/filters/annotations/annotations_test.go @@ -16,32 +16,15 @@ import ( var annosFs = builtinconfig.MakeDefaultConfig().CommonAnnotations -type setEntryArg struct { - Key string - Value string - Tag string - NodePath []string -} - -var setEntryArgs []setEntryArg - -func setEntryCallbackStub(key, value, tag string, node *yaml.RNode) { - setEntryArgs = append(setEntryArgs, setEntryArg{ - Key: key, - Value: value, - Tag: tag, - NodePath: node.FieldPath(), - }) -} - func TestAnnotations_Filter(t *testing.T) { + mutationTrackStub := filtertest_test.MutationTrackerStub{} testCases := map[string]struct { input string expectedOutput string filter Filter fsslice types.FsSlice setEntryCallback func(key, value, tag string, node *yaml.RNode) - expectedSetEntryArgs []setEntryArg + expectedSetEntryArgs []filtertest_test.SetValueArg }{ "add": { input: ` @@ -261,14 +244,14 @@ spec: "b": "b1", }, }, - setEntryCallback: setEntryCallbackStub, + setEntryCallback: mutationTrackStub.MutationTracker, fsslice: []types.FieldSpec{ { Path: "spec/template/metadata/annotations", CreateIfNotPresent: true, }, }, - expectedSetEntryArgs: []setEntryArg{ + expectedSetEntryArgs: []filtertest_test.SetValueArg{ { Key: "a", Value: "a1", @@ -298,7 +281,7 @@ spec: } for tn, tc := range testCases { - setEntryArgs = nil + mutationTrackStub.Reset() t.Run(tn, func(t *testing.T) { filter := tc.filter filter.WithMutationTracker(tc.setEntryCallback) @@ -308,7 +291,7 @@ spec: strings.TrimSpace(filtertest_test.RunFilter(t, tc.input, filter))) { t.FailNow() } - if !assert.Equal(t, tc.expectedSetEntryArgs, setEntryArgs) { + if !assert.Equal(t, tc.expectedSetEntryArgs, mutationTrackStub.SetValueArgs()) { t.FailNow() } }) diff --git a/api/filters/imagetag/imagetag_test.go b/api/filters/imagetag/imagetag_test.go index a62f95a9f..d1f0bc1de 100644 --- a/api/filters/imagetag/imagetag_test.go +++ b/api/filters/imagetag/imagetag_test.go @@ -13,32 +13,15 @@ import ( "sigs.k8s.io/kustomize/kyaml/yaml" ) -type setValueArg struct { - Key string - Value string - Tag string - PrevValue string -} - -var setValueArgs []setValueArg - -func setValueCallbackStub(key, value, tag string, node *yaml.RNode) { - setValueArgs = append(setValueArgs, setValueArg{ - Key: key, - Value: value, - Tag: tag, - PrevValue: node.YNode().Value, - }) -} - func TestImageTagUpdater_Filter(t *testing.T) { + mutationTrackerStub := filtertest.MutationTrackerStub{} testCases := map[string]struct { input string expectedOutput string filter Filter fsSlice types.FsSlice setValueCallback func(key, value, tag string, node *yaml.RNode) - expectedSetValueArgs []setValueArg + expectedSetValueArgs []filtertest.SetValueArg }{ "ignore CustomResourceDefinition": { input: ` @@ -747,30 +730,30 @@ spec: Path: "spec/template/spec/initContainers[]/image", }, }, - setValueCallback: setValueCallbackStub, - expectedSetValueArgs: []setValueArg{ + setValueCallback: mutationTrackerStub.MutationTracker, + expectedSetValueArgs: []filtertest.SetValueArg{ { - Value: "busybox:v3", - PrevValue: "nginx:1.7.9", + Value: "busybox:v3", + NodePath: []string{"spec", "template", "spec", "containers", "image"}, }, { - Value: "busybox:v3", - PrevValue: "nginx:latest", + Value: "busybox:v3", + NodePath: []string{"spec", "template", "spec", "containers", "image"}, }, { - Value: "busybox:v3", - PrevValue: "nginx", + Value: "busybox:v3", + NodePath: []string{"spec", "template", "spec", "initContainers", "image"}, }, { - Value: "busybox:v3", - PrevValue: "nginx@sha256:111111111111111111", + Value: "busybox:v3", + NodePath: []string{"spec", "template", "spec", "initContainers", "image"}, }, }, }, } for tn, tc := range testCases { - setValueArgs = nil + mutationTrackerStub.Reset() t.Run(tn, func(t *testing.T) { filter := tc.filter filter.WithMutationTracker(tc.setValueCallback) @@ -780,7 +763,7 @@ spec: strings.TrimSpace(filtertest.RunFilter(t, tc.input, filter))) { t.FailNow() } - assert.Equal(t, tc.expectedSetValueArgs, setValueArgs) + assert.Equal(t, tc.expectedSetValueArgs, mutationTrackerStub.SetValueArgs()) }) } } diff --git a/api/filters/labels/labels_test.go b/api/filters/labels/labels_test.go index 45f4eff4e..0cdb0d126 100644 --- a/api/filters/labels/labels_test.go +++ b/api/filters/labels/labels_test.go @@ -14,31 +14,14 @@ import ( "sigs.k8s.io/kustomize/kyaml/yaml" ) -type setEntryArg struct { - Key string - Value string - Tag string - NodePath []string -} - -var setEntryArgs []setEntryArg - -func setEntryCallbackStub(key, value, tag string, node *yaml.RNode) { - setEntryArgs = append(setEntryArgs, setEntryArg{ - Key: key, - Value: value, - Tag: tag, - NodePath: node.FieldPath(), - }) -} - func TestLabels_Filter(t *testing.T) { + mutationTrackerStub := filtertest_test.MutationTrackerStub{} testCases := map[string]struct { input string expectedOutput string filter Filter setEntryCallback func(key, value, tag string, node *yaml.RNode) - expectedSetEntryArgs []setEntryArg + expectedSetEntryArgs []filtertest_test.SetValueArg }{ "add": { input: ` @@ -458,8 +441,8 @@ a: }, }, }, - setEntryCallback: setEntryCallbackStub, - expectedSetEntryArgs: []setEntryArg{ + setEntryCallback: mutationTrackerStub.MutationTracker, + expectedSetEntryArgs: []filtertest_test.SetValueArg{ { Key: "mage", Value: "yennefer", @@ -477,7 +460,7 @@ a: } for tn, tc := range testCases { - setEntryArgs = nil + mutationTrackerStub.Reset() t.Run(tn, func(t *testing.T) { tc.filter.WithMutationTracker(tc.setEntryCallback) if !assert.Equal(t, @@ -485,7 +468,7 @@ a: strings.TrimSpace(filtertest_test.RunFilter(t, tc.input, tc.filter))) { t.FailNow() } - if !assert.Equal(t, tc.expectedSetEntryArgs, setEntryArgs) { + if !assert.Equal(t, tc.expectedSetEntryArgs, mutationTrackerStub.SetValueArgs()) { t.FailNow() } }) diff --git a/api/filters/namespace/namespace.go b/api/filters/namespace/namespace.go index e554600bc..85484bf70 100644 --- a/api/filters/namespace/namespace.go +++ b/api/filters/namespace/namespace.go @@ -18,9 +18,17 @@ type Filter struct { // FsSlice contains the FieldSpecs to locate the namespace field FsSlice types.FsSlice `json:"fieldSpecs,omitempty" yaml:"fieldSpecs,omitempty"` + + trackableSetter filtersutil.TrackableSetter } var _ kio.Filter = Filter{} +var _ kio.TrackableFilter = &Filter{} + +// WithMutationTracker registers a callback which will be invoked each time a field is mutated +func (ns *Filter) WithMutationTracker(callback func(key, value, tag string, node *yaml.RNode)) { + ns.trackableSetter.WithMutationTracker(callback) +} func (ns Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { return kio.FilterAll(yaml.FilterFunc(ns.run)).Filter(nodes) @@ -44,7 +52,7 @@ func (ns Filter) run(node *yaml.RNode) (*yaml.RNode, error) { // transformations based on data -- :) err := node.PipeE(fsslice.Filter{ FsSlice: ns.FsSlice, - SetValue: filtersutil.SetScalar(ns.Namespace), + SetValue: ns.trackableSetter.SetScalar(ns.Namespace), CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode CreateTag: yaml.NodeTagString, }) @@ -77,7 +85,7 @@ func (ns Filter) metaNamespaceHack(obj *yaml.RNode, gvk resid.Gvk) error { FsSlice: []types.FieldSpec{ {Path: types.MetadataNamespacePath, CreateIfNotPresent: true}, }, - SetValue: filtersutil.SetScalar(ns.Namespace), + SetValue: ns.trackableSetter.SetScalar(ns.Namespace), CreateKind: yaml.ScalarNode, // Namespace is a ScalarNode } _, err := f.Filter(obj) @@ -123,11 +131,15 @@ func (ns Filter) roleBindingHack(obj *yaml.RNode, gvk resid.Gvk) error { } // set the namespace for the default account - v := yaml.NewScalarRNode(ns.Namespace) - return o.PipeE( + node, err := o.Pipe( yaml.LookupCreate(yaml.ScalarNode, "namespace"), - yaml.FieldSetter{Value: v}, ) + if err != nil { + return err + } + + return ns.trackableSetter.SetScalar(ns.Namespace)(node) + }) return err diff --git a/api/filters/namespace/namespace_test.go b/api/filters/namespace/namespace_test.go index e9854811e..302abe035 100644 --- a/api/filters/namespace/namespace_test.go +++ b/api/filters/namespace/namespace_test.go @@ -12,8 +12,11 @@ import ( "sigs.k8s.io/kustomize/api/internal/plugins/builtinconfig" filtertest_test "sigs.k8s.io/kustomize/api/testutils/filtertest" "sigs.k8s.io/kustomize/api/types" + "sigs.k8s.io/kustomize/kyaml/yaml" ) +var mutationTrackerStub = filtertest_test.MutationTrackerStub{} + var tests = []TestCase{ { name: "add", @@ -283,21 +286,91 @@ a: }, }, }, + + { + name: "mutation tracker", + input: ` +apiVersion: example.com/v1 +kind: Foo +metadata: + name: instance +--- +apiVersion: example.com/v1 +kind: RoleBinding +subjects: +- name: default +`, + expected: ` +apiVersion: example.com/v1 +kind: Foo +metadata: + name: instance + namespace: bar +a: + b: + c: bar +--- +apiVersion: example.com/v1 +kind: RoleBinding +subjects: +- name: default + namespace: bar +metadata: + namespace: bar +a: + b: + c: bar +`, + filter: namespace.Filter{Namespace: "bar"}, + fsslice: []types.FieldSpec{ + { + Path: "a/b/c", + CreateIfNotPresent: true, + }, + }, + mutationTracker: mutationTrackerStub.MutationTracker, + expectedSetValueArgs: []filtertest_test.SetValueArg{ + { + Value: "bar", + NodePath: []string{"metadata", "namespace"}, + }, + { + Value: "bar", + NodePath: []string{"a", "b", "c"}, + }, + { + Value: "bar", + NodePath: []string{"metadata", "namespace"}, + }, + { + Value: "bar", + NodePath: []string{"namespace"}, + }, + { + Value: "bar", + NodePath: []string{"a", "b", "c"}, + }, + }, + }, } type TestCase struct { - name string - input string - expected string - filter namespace.Filter - fsslice types.FsSlice + name string + input string + expected string + filter namespace.Filter + fsslice types.FsSlice + mutationTracker func(key, value, tag string, node *yaml.RNode) + expectedSetValueArgs []filtertest_test.SetValueArg } var config = builtinconfig.MakeDefaultConfig() func TestNamespace_Filter(t *testing.T) { for i := range tests { + mutationTrackerStub.Reset() test := tests[i] + test.filter.WithMutationTracker(test.mutationTracker) t.Run(test.name, func(t *testing.T) { test.filter.FsSlice = append(config.NameSpace, test.fsslice...) if !assert.Equal(t, @@ -306,6 +379,7 @@ func TestNamespace_Filter(t *testing.T) { filtertest_test.RunFilter(t, test.input, test.filter))) { t.FailNow() } + assert.Equal(t, test.expectedSetValueArgs, mutationTrackerStub.SetValueArgs()) }) } } diff --git a/api/filters/prefix/prefix.go b/api/filters/prefix/prefix.go index dc7fb134f..daa375d1f 100644 --- a/api/filters/prefix/prefix.go +++ b/api/filters/prefix/prefix.go @@ -18,9 +18,17 @@ type Filter struct { Prefix string `json:"prefix,omitempty" yaml:"prefix,omitempty"` FieldSpec types.FieldSpec `json:"fieldSpec,omitempty" yaml:"fieldSpec,omitempty"` + + trackableSetter filtersutil.TrackableSetter } var _ kio.Filter = Filter{} +var _ kio.TrackableFilter = &Filter{} + +// WithMutationTracker registers a callback which will be invoked each time a field is mutated +func (f *Filter) WithMutationTracker(callback func(key, value, tag string, node *yaml.RNode)) { + f.trackableSetter.WithMutationTracker(callback) +} func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { return kio.FilterAll(yaml.FilterFunc(f.run)).Filter(nodes) @@ -37,6 +45,6 @@ func (f Filter) run(node *yaml.RNode) (*yaml.RNode, error) { } func (f Filter) evaluateField(node *yaml.RNode) error { - return filtersutil.SetScalar(fmt.Sprintf( + return f.trackableSetter.SetScalar(fmt.Sprintf( "%s%s", f.Prefix, node.YNode().Value))(node) } diff --git a/api/filters/prefix/prefix_test.go b/api/filters/prefix/prefix_test.go index 2bcdbdeab..607aa757d 100644 --- a/api/filters/prefix/prefix_test.go +++ b/api/filters/prefix/prefix_test.go @@ -11,8 +11,11 @@ import ( "sigs.k8s.io/kustomize/api/filters/prefix" filtertest_test "sigs.k8s.io/kustomize/api/testutils/filtertest" "sigs.k8s.io/kustomize/api/types" + "sigs.k8s.io/kustomize/kyaml/yaml" ) +var mutationTrackerStub = filtertest_test.MutationTrackerStub{} + var tests = map[string]TestCase{ "prefix": { input: ` @@ -83,17 +86,61 @@ a: FieldSpec: types.FieldSpec{Path: "a/b/c"}, }, }, + + "mutation tracker": { + input: ` +apiVersion: example.com/v1 +kind: Foo +metadata: + name: instance +--- +apiVersion: example.com/v1 +kind: Bar +metadata: + name: instance +`, + expected: ` +apiVersion: example.com/v1 +kind: Foo +metadata: + name: foo-instance +--- +apiVersion: example.com/v1 +kind: Bar +metadata: + name: foo-instance +`, + filter: prefix.Filter{ + Prefix: "foo-", + FieldSpec: types.FieldSpec{Path: "metadata/name"}, + }, + mutationTracker: mutationTrackerStub.MutationTracker, + expectedSetValueArgs: []filtertest_test.SetValueArg{ + { + Value: "foo-instance", + NodePath: []string{"metadata", "name"}, + }, + { + Value: "foo-instance", + NodePath: []string{"metadata", "name"}, + }, + }, + }, } type TestCase struct { - input string - expected string - filter prefix.Filter + input string + expected string + filter prefix.Filter + mutationTracker func(key, value, tag string, node *yaml.RNode) + expectedSetValueArgs []filtertest_test.SetValueArg } func TestFilter(t *testing.T) { for name := range tests { + mutationTrackerStub.Reset() test := tests[name] + test.filter.WithMutationTracker(test.mutationTracker) t.Run(name, func(t *testing.T) { if !assert.Equal(t, strings.TrimSpace(test.expected), @@ -101,6 +148,7 @@ func TestFilter(t *testing.T) { filtertest_test.RunFilter(t, test.input, test.filter))) { t.FailNow() } + assert.Equal(t, test.expectedSetValueArgs, mutationTrackerStub.SetValueArgs()) }) } } diff --git a/api/filters/replicacount/replicacount.go b/api/filters/replicacount/replicacount.go index 8a503966a..84005f26a 100644 --- a/api/filters/replicacount/replicacount.go +++ b/api/filters/replicacount/replicacount.go @@ -14,9 +14,17 @@ import ( type Filter struct { Replica types.Replica `json:"replica,omitempty" yaml:"replica,omitempty"` FieldSpec types.FieldSpec `json:"fieldSpec,omitempty" yaml:"fieldSpec,omitempty"` + + trackableSetter filtersutil.TrackableSetter } var _ kio.Filter = Filter{} +var _ kio.TrackableFilter = &Filter{} + +// WithMutationTracker registers a callback which will be invoked each time a field is mutated +func (rc *Filter) WithMutationTracker(callback func(key, value, tag string, node *yaml.RNode)) { + rc.trackableSetter.WithMutationTracker(callback) +} func (rc Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { return kio.FilterAll(yaml.FilterFunc(rc.run)).Filter(nodes) @@ -33,5 +41,5 @@ func (rc Filter) run(node *yaml.RNode) (*yaml.RNode, error) { } func (rc Filter) set(node *yaml.RNode) error { - return filtersutil.SetScalar(strconv.FormatInt(rc.Replica.Count, 10))(node) + return rc.trackableSetter.SetScalar(strconv.FormatInt(rc.Replica.Count, 10))(node) } diff --git a/api/filters/replicacount/replicacount_test.go b/api/filters/replicacount/replicacount_test.go index a61889e2d..e690192fc 100644 --- a/api/filters/replicacount/replicacount_test.go +++ b/api/filters/replicacount/replicacount_test.go @@ -7,14 +7,17 @@ import ( "github.com/stretchr/testify/assert" filtertest_test "sigs.k8s.io/kustomize/api/testutils/filtertest" "sigs.k8s.io/kustomize/api/types" + "sigs.k8s.io/kustomize/kyaml/yaml" ) func TestFilter(t *testing.T) { - + mutationTrackerStub := filtertest_test.MutationTrackerStub{} testCases := map[string]struct { - input string - expected string - filter Filter + input string + expected string + filter Filter + mutationTracker func(key, value, tag string, node *yaml.RNode) + expectedSetValueArgs []filtertest_test.SetValueArg }{ "update field": { input: ` @@ -161,9 +164,43 @@ spec: FieldSpec: types.FieldSpec{Path: "spec/template/replicas"}, }, }, + "mutation tracker": { + input: ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dep +spec: + replicas: 5 +`, + expected: ` +apiVersion: apps/v1 +kind: Deployment +metadata: + name: dep +spec: + replicas: 42 +`, + filter: Filter{ + Replica: types.Replica{ + Name: "dep", + Count: 42, + }, + FieldSpec: types.FieldSpec{Path: "spec/replicas"}, + }, + mutationTracker: mutationTrackerStub.MutationTracker, + expectedSetValueArgs: []filtertest_test.SetValueArg{ + { + Value: "42", + NodePath: []string{"spec", "replicas"}, + }, + }, + }, } for tn, tc := range testCases { + mutationTrackerStub.Reset() + tc.filter.WithMutationTracker(tc.mutationTracker) t.Run(tn, func(t *testing.T) { if !assert.Equal(t, strings.TrimSpace(tc.expected), @@ -171,6 +208,7 @@ spec: filtertest_test.RunFilter(t, tc.input, tc.filter))) { t.FailNow() } + assert.Equal(t, tc.expectedSetValueArgs, mutationTrackerStub.SetValueArgs()) }) } } diff --git a/api/filters/suffix/suffix.go b/api/filters/suffix/suffix.go index a3df62557..babc257be 100644 --- a/api/filters/suffix/suffix.go +++ b/api/filters/suffix/suffix.go @@ -18,9 +18,17 @@ type Filter struct { Suffix string `json:"suffix,omitempty" yaml:"suffix,omitempty"` FieldSpec types.FieldSpec `json:"fieldSpec,omitempty" yaml:"fieldSpec,omitempty"` + + trackableSetter filtersutil.TrackableSetter } var _ kio.Filter = Filter{} +var _ kio.TrackableFilter = &Filter{} + +// WithMutationTracker registers a callback which will be invoked each time a field is mutated +func (f *Filter) WithMutationTracker(callback func(key, value, tag string, node *yaml.RNode)) { + f.trackableSetter.WithMutationTracker(callback) +} func (f Filter) Filter(nodes []*yaml.RNode) ([]*yaml.RNode, error) { return kio.FilterAll(yaml.FilterFunc(f.run)).Filter(nodes) @@ -37,6 +45,6 @@ func (f Filter) run(node *yaml.RNode) (*yaml.RNode, error) { } func (f Filter) evaluateField(node *yaml.RNode) error { - return filtersutil.SetScalar(fmt.Sprintf( + return f.trackableSetter.SetScalar(fmt.Sprintf( "%s%s", node.YNode().Value, f.Suffix))(node) } diff --git a/api/filters/suffix/suffix_test.go b/api/filters/suffix/suffix_test.go index 94020ed94..53489c746 100644 --- a/api/filters/suffix/suffix_test.go +++ b/api/filters/suffix/suffix_test.go @@ -11,8 +11,11 @@ import ( "sigs.k8s.io/kustomize/api/filters/suffix" filtertest_test "sigs.k8s.io/kustomize/api/testutils/filtertest" "sigs.k8s.io/kustomize/api/types" + "sigs.k8s.io/kustomize/kyaml/yaml" ) +var mutationTrackerStub = filtertest_test.MutationTrackerStub{} + var tests = map[string]TestCase{ "suffix": { input: ` @@ -83,17 +86,61 @@ a: FieldSpec: types.FieldSpec{Path: "a/b/c"}, }, }, + + "mutation tracker": { + input: ` +apiVersion: example.com/v1 +kind: Foo +metadata: + name: instance +--- +apiVersion: example.com/v1 +kind: Bar +metadata: + name: instance +`, + expected: ` +apiVersion: example.com/v1 +kind: Foo +metadata: + name: instance-foo +--- +apiVersion: example.com/v1 +kind: Bar +metadata: + name: instance-foo +`, + filter: suffix.Filter{ + Suffix: "-foo", + FieldSpec: types.FieldSpec{Path: "metadata/name"}, + }, + mutationTracker: mutationTrackerStub.MutationTracker, + expectedSetValueArgs: []filtertest_test.SetValueArg{ + { + Value: "instance-foo", + NodePath: []string{"metadata", "name"}, + }, + { + Value: "instance-foo", + NodePath: []string{"metadata", "name"}, + }, + }, + }, } type TestCase struct { - input string - expected string - filter suffix.Filter + input string + expected string + filter suffix.Filter + mutationTracker func(key, value, tag string, node *yaml.RNode) + expectedSetValueArgs []filtertest_test.SetValueArg } func TestFilter(t *testing.T) { for name := range tests { + mutationTrackerStub.Reset() test := tests[name] + test.filter.WithMutationTracker(test.mutationTracker) t.Run(name, func(t *testing.T) { if !assert.Equal(t, strings.TrimSpace(test.expected), @@ -101,6 +148,7 @@ func TestFilter(t *testing.T) { filtertest_test.RunFilter(t, test.input, test.filter))) { t.FailNow() } + assert.Equal(t, test.expectedSetValueArgs, mutationTrackerStub.SetValueArgs()) }) } } diff --git a/api/testutils/filtertest/runfilter.go b/api/testutils/filtertest/runfilter.go index 2cf775311..95f8d26c3 100644 --- a/api/testutils/filtertest/runfilter.go +++ b/api/testutils/filtertest/runfilter.go @@ -9,6 +9,7 @@ import ( "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/kio" + "sigs.k8s.io/kustomize/kyaml/yaml" ) func run(input string, f kio.Filter) (string, error) { @@ -46,3 +47,32 @@ func RunFilterE(t *testing.T, input string, f kio.Filter) (string, error) { } return output, nil } + +type SetValueArg struct { + Key string + Value string + Tag string + NodePath []string +} + +// MutationTrackerStub to help stub a mutation tracker for kio.TrackableFilter +type MutationTrackerStub struct { + setValueArgs []SetValueArg +} + +func (mts *MutationTrackerStub) MutationTracker(key, value, tag string, node *yaml.RNode) { + mts.setValueArgs = append(mts.setValueArgs, SetValueArg{ + Key: key, + Value: value, + Tag: tag, + NodePath: node.FieldPath(), + }) +} + +func (mts *MutationTrackerStub) SetValueArgs() []SetValueArg { + return mts.setValueArgs +} + +func (mts *MutationTrackerStub) Reset() { + mts.setValueArgs = nil +}