...

Source file src/sigs.k8s.io/structured-merge-diff/v4/merge/obsolete_versions_test.go

Documentation: sigs.k8s.io/structured-merge-diff/v4/merge

     1  /*
     2  Copyright 2019 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package merge_test
    18  
    19  import (
    20  	"fmt"
    21  	"testing"
    22  
    23  	"sigs.k8s.io/structured-merge-diff/v4/fieldpath"
    24  	. "sigs.k8s.io/structured-merge-diff/v4/internal/fixture"
    25  	"sigs.k8s.io/structured-merge-diff/v4/merge"
    26  	"sigs.k8s.io/structured-merge-diff/v4/typed"
    27  )
    28  
    29  // specificVersionConverter doesn't convert and return the exact same
    30  // object, but only for versions that are explicitely listed.
    31  type specificVersionConverter struct {
    32  	AcceptedVersions []fieldpath.APIVersion
    33  }
    34  
    35  func (d *specificVersionConverter) Convert(object *typed.TypedValue, version fieldpath.APIVersion) (*typed.TypedValue, error) {
    36  	for _, v := range d.AcceptedVersions {
    37  		if v == version {
    38  			return object, nil
    39  		}
    40  	}
    41  	return nil, fmt.Errorf("Unknown version: %v", version)
    42  }
    43  
    44  func (d *specificVersionConverter) IsMissingVersionError(err error) bool {
    45  	return err != nil
    46  }
    47  
    48  // Managers of fields in a version that no longer exist are
    49  // automatically removed. Make sure this works as intended.
    50  func TestObsoleteVersions(t *testing.T) {
    51  	converter := &specificVersionConverter{
    52  		AcceptedVersions: []fieldpath.APIVersion{"v1", "v2"},
    53  	}
    54  	state := State{
    55  		Updater: &merge.Updater{Converter: converter},
    56  		Parser:  DeducedParser,
    57  	}
    58  
    59  	if err := state.Update(typed.YAMLObject(`{"v1": 0}`), fieldpath.APIVersion("v1"), "v1"); err != nil {
    60  		t.Fatalf("Failed to apply: %v", err)
    61  	}
    62  	if err := state.Update(typed.YAMLObject(`{"v1": 0, "v2": 0}`), fieldpath.APIVersion("v2"), "v2"); err != nil {
    63  		t.Fatalf("Failed to apply: %v", err)
    64  	}
    65  	// Remove v1, add v3 instead.
    66  	converter.AcceptedVersions = []fieldpath.APIVersion{"v2", "v3"}
    67  
    68  	if err := state.Update(typed.YAMLObject(`{"v1": 0, "v2": 0, "v3": 0}`), fieldpath.APIVersion("v3"), "v3"); err != nil {
    69  		t.Fatalf("Failed to apply: %v", err)
    70  	}
    71  
    72  	managers := fieldpath.ManagedFields{
    73  		"v2": fieldpath.NewVersionedSet(
    74  			_NS(
    75  				_P("v2"),
    76  			),
    77  			"v2",
    78  			false,
    79  		),
    80  		"v3": fieldpath.NewVersionedSet(
    81  			_NS(
    82  				_P("v3"),
    83  			),
    84  			"v3",
    85  			false,
    86  		),
    87  	}
    88  	if diff := state.Managers.Difference(managers); len(diff) != 0 {
    89  		t.Fatalf("expected Managers to be %v, got %v", managers, state.Managers)
    90  	}
    91  }
    92  
    93  func TestApplyObsoleteVersion(t *testing.T) {
    94  	converter := &specificVersionConverter{
    95  		AcceptedVersions: []fieldpath.APIVersion{"v1"},
    96  	}
    97  	tparser, err := typed.NewParser(`types:
    98  - name: sets
    99    map:
   100      fields:
   101      - name: list
   102        type:
   103          list:
   104            elementType:
   105              scalar: string
   106            elementRelationship: associative`)
   107  	if err != nil {
   108  		t.Fatalf("Failed to create parser: %v", err)
   109  	}
   110  	parser := SameVersionParser{T: tparser.Type("sets")}
   111  	state := State{
   112  		Updater: &merge.Updater{Converter: converter},
   113  		Parser:  SameVersionParser{T: parser.Type("sets")},
   114  	}
   115  
   116  	if err := state.Apply(typed.YAMLObject(`{"list": ["a", "b", "c", "d"]}`), fieldpath.APIVersion("v1"), "apply", false); err != nil {
   117  		t.Fatalf("Failed to apply: %v", err)
   118  	}
   119  	// Remove v1, add v2 instead.
   120  	converter.AcceptedVersions = []fieldpath.APIVersion{"v2"}
   121  
   122  	if err := state.Apply(typed.YAMLObject(`{"list": ["a"]}`), fieldpath.APIVersion("v2"), "apply", false); err != nil {
   123  		t.Fatalf("Failed to apply: %v", err)
   124  	}
   125  
   126  	comparison, err := state.CompareLive(`{"list": ["a", "b", "c", "d"]}`, "v2")
   127  	if err != nil {
   128  		t.Fatalf("Failed to compare live object: %v", err)
   129  	}
   130  	if comparison != "" {
   131  		t.Fatalf("Unexpected object:\n%v", comparison)
   132  	}
   133  }
   134  

View as plain text