Skip to content

Commit bbe0f82

Browse files
authored
Merge pull request #228 from apelisse/add-typename-different-from-version-test
Add typename different from version test
2 parents 26781d0 + f76ddd2 commit bbe0f82

File tree

2 files changed

+161
-4
lines changed

2 files changed

+161
-4
lines changed

merge/multiple_appliers_test.go

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1945,3 +1945,160 @@ func TestMultipleAppliersReliantFieldsConversions(t *testing.T) {
19451945
})
19461946
}
19471947
}
1948+
1949+
var versionDoesntMatchTypeName = func() Parser {
1950+
parser, err := typed.NewParser(`types:
1951+
- name: TypeV1
1952+
map:
1953+
fields:
1954+
- name: field_foo_rely_on_bar
1955+
type:
1956+
scalar: string
1957+
- name: common_field
1958+
type:
1959+
scalar: string
1960+
- name: TypeV2
1961+
map:
1962+
fields:
1963+
- name: required_field_bar
1964+
type:
1965+
scalar: string
1966+
- name: common_field
1967+
type:
1968+
scalar: string
1969+
`)
1970+
if err != nil {
1971+
panic(err)
1972+
}
1973+
return parser
1974+
}()
1975+
1976+
type versionDoesntMatchTypenameConverter struct{}
1977+
1978+
var _ merge.Converter = versionDoesntMatchTypenameConverter{}
1979+
1980+
func (r versionDoesntMatchTypenameConverter) Convert(v *typed.TypedValue, version fieldpath.APIVersion) (*typed.TypedValue, error) {
1981+
inVersion := fieldpath.APIVersion("")
1982+
switch fieldpath.APIVersion(*v.TypeRef().NamedType) {
1983+
case "TypeV1":
1984+
inVersion = "v1"
1985+
case "TypeV2":
1986+
inVersion = "v2"
1987+
default:
1988+
return nil, fmt.Errorf(`Invalid typename: %q, should be one of ["TypeV1", "TypeV2"]`, version)
1989+
}
1990+
if inVersion == version {
1991+
return v, nil
1992+
}
1993+
if inVersion == version {
1994+
return v, nil
1995+
}
1996+
y, err := yaml.Marshal(v.AsValue().Unstructured())
1997+
if err != nil {
1998+
return nil, err
1999+
}
2000+
inStr := string(y)
2001+
var outStr string
2002+
var outType string
2003+
switch version {
2004+
case "v1":
2005+
if !strings.Contains(inStr, "required_field_bar") {
2006+
return v, fmt.Errorf("missing requried field bar")
2007+
}
2008+
outType = "TypeV1"
2009+
outStr = strings.Replace(inStr, "required_field_bar", "field_foo_rely_on_bar", -1)
2010+
case "v2":
2011+
outType = "TypeV2"
2012+
outStr = strings.Replace(inStr, "field_foo_rely_on_bar", "required_field_bar", -1)
2013+
default:
2014+
return nil, missingVersionError
2015+
}
2016+
return versionDoesntMatchTypeName.Type(string(outType)).FromYAML(typed.YAMLObject(outStr))
2017+
}
2018+
2019+
func (r versionDoesntMatchTypenameConverter) IsMissingVersionError(err error) bool {
2020+
return err == missingVersionError
2021+
}
2022+
2023+
// This is the same test as TestMultipleAppliersReliantFieldsConversions
2024+
// but written without the internal test framework that assumes that
2025+
// typenames and versions match. The goal of this test is to make sure
2026+
// that no such assumptions are used in the tested code.
2027+
func TestVersionDoesntMatchTypename(t *testing.T) {
2028+
converter := versionDoesntMatchTypenameConverter{}
2029+
updater := &merge.Updater{Converter: converter}
2030+
2031+
for i := 0; i < 10; i++ {
2032+
// Apply in one version, apply in another, apply in a third.
2033+
live, err := versionDoesntMatchTypeName.Type("TypeV2").FromYAML(`{}`)
2034+
if err != nil {
2035+
t.Fatalf("Failed to parse empty object: %v", err)
2036+
}
2037+
managers := fieldpath.ManagedFields{}
2038+
config, err := versionDoesntMatchTypeName.Type("TypeV2").FromYAML(`{"required_field_bar": "a"}`)
2039+
if err != nil {
2040+
t.Fatalf("Failed to parse object: %v", err)
2041+
}
2042+
live, managers, err = updater.Apply(live, config, "v2", managers, "v2_applier", false)
2043+
if err != nil {
2044+
t.Fatalf("Failed to apply: %v", err)
2045+
}
2046+
2047+
live, err = converter.Convert(live, "v1")
2048+
if err != nil {
2049+
t.Fatalf("Failed to convert object to v1: %v", err)
2050+
}
2051+
config, err = versionDoesntMatchTypeName.Type("TypeV1").FromYAML(`{"common_field": "b"}`)
2052+
if err != nil {
2053+
t.Fatalf("Failed to parse object: %v", err)
2054+
}
2055+
2056+
live, managers, err = updater.Apply(live, config, "v1", managers, "v1_applier", false)
2057+
if err != nil {
2058+
t.Fatalf("Failed to apply: %v", err)
2059+
}
2060+
2061+
live, err = converter.Convert(live, "v2")
2062+
if err != nil {
2063+
t.Fatalf("Failed to convert object to v1: %v", err)
2064+
}
2065+
config, err = versionDoesntMatchTypeName.Type("TypeV2").FromYAML(`{"required_field_bar": "b"}`)
2066+
if err != nil {
2067+
t.Fatalf("Failed to parse object: %v", err)
2068+
}
2069+
live, managers, err = updater.Apply(live, config, "v2", managers, "v2_applier", false)
2070+
if err != nil {
2071+
t.Fatalf("Failed to apply: %v", err)
2072+
}
2073+
2074+
expectedObject, err := versionDoesntMatchTypeName.Type("TypeV2").FromYAML(`{"required_field_bar": "b", "common_field": "b"}`)
2075+
if err != nil {
2076+
t.Fatalf("Failed to parse object: %v", err)
2077+
}
2078+
if comparison, err := live.Compare(expectedObject); err != nil {
2079+
t.Fatalf("Failed to compare live with expected: %v", err)
2080+
} else if !comparison.IsSame() {
2081+
t.Fatalf("Live is different from expected:\n%v", comparison)
2082+
}
2083+
2084+
expectedManagers := fieldpath.ManagedFields{
2085+
"v2_applier": fieldpath.NewVersionedSet(
2086+
_NS(
2087+
_P("required_field_bar"),
2088+
),
2089+
"v2",
2090+
true,
2091+
),
2092+
"v1_applier": fieldpath.NewVersionedSet(
2093+
_NS(
2094+
_P("common_field"),
2095+
),
2096+
"v1",
2097+
true,
2098+
),
2099+
}
2100+
if !expectedManagers.Equals(managers) {
2101+
t.Fatalf("ManagedFields not as expected:\n%v", managers)
2102+
}
2103+
}
2104+
}

merge/update.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,8 @@ func (s *Updater) prune(merged *typed.TypedValue, managers fieldpath.ManagedFiel
218218
if lastSet == nil || lastSet.Set().Empty() {
219219
return merged, nil
220220
}
221-
convertedMerged, err := s.Converter.Convert(merged, lastSet.APIVersion())
221+
version := lastSet.APIVersion()
222+
convertedMerged, err := s.Converter.Convert(merged, version)
222223
if err != nil {
223224
if s.Converter.IsMissingVersionError(err) {
224225
return merged, nil
@@ -228,7 +229,7 @@ func (s *Updater) prune(merged *typed.TypedValue, managers fieldpath.ManagedFiel
228229

229230
sc, tr := convertedMerged.Schema(), convertedMerged.TypeRef()
230231
pruned := convertedMerged.RemoveItems(lastSet.Set().EnsureNamedFieldsAreMembers(sc, tr))
231-
pruned, err = s.addBackOwnedItems(convertedMerged, pruned, managers, applyingManager)
232+
pruned, err = s.addBackOwnedItems(convertedMerged, pruned, version, managers, applyingManager)
232233
if err != nil {
233234
return nil, fmt.Errorf("failed add back owned items: %v", err)
234235
}
@@ -241,7 +242,7 @@ func (s *Updater) prune(merged *typed.TypedValue, managers fieldpath.ManagedFiel
241242

242243
// addBackOwnedItems adds back any fields, list and map items that were removed by prune,
243244
// but other appliers or updaters (or the current applier's new config) claim to own.
244-
func (s *Updater) addBackOwnedItems(merged, pruned *typed.TypedValue, managedFields fieldpath.ManagedFields, applyingManager string) (*typed.TypedValue, error) {
245+
func (s *Updater) addBackOwnedItems(merged, pruned *typed.TypedValue, prunedVersion fieldpath.APIVersion, managedFields fieldpath.ManagedFields, applyingManager string) (*typed.TypedValue, error) {
245246
var err error
246247
managedAtVersion := map[fieldpath.APIVersion]*fieldpath.Set{}
247248
for _, managerSet := range managedFields {
@@ -252,7 +253,6 @@ func (s *Updater) addBackOwnedItems(merged, pruned *typed.TypedValue, managedFie
252253
}
253254
// Add back owned items at pruned version first to avoid conversion failure
254255
// caused by pruned fields which are required for conversion.
255-
prunedVersion := fieldpath.APIVersion(*pruned.TypeRef().NamedType)
256256
if managed, ok := managedAtVersion[prunedVersion]; ok {
257257
merged, pruned, err = s.addBackOwnedItemsForVersion(merged, pruned, prunedVersion, managed)
258258
if err != nil {

0 commit comments

Comments
 (0)