...

Source file src/edge-infra.dev/pkg/edge/gitops/fns/normalizer/sortrnodes_test.go

Documentation: edge-infra.dev/pkg/edge/gitops/fns/normalizer

     1  //nolint:dupl
     2  package normalizer
     3  
     4  import (
     5  	"fmt"
     6  	"strings"
     7  	"testing"
     8  
     9  	"sigs.k8s.io/kustomize/kyaml/kio"
    10  	"sigs.k8s.io/kustomize/kyaml/yaml"
    11  )
    12  
    13  func TestSortRNodesNoPathAnnotations(t *testing.T) {
    14  	var data = `apiVersion: v1
    15  kind: test
    16  spec:
    17    name: Bar
    18  ---
    19  apiVersion: v1
    20  kind: test
    21  spec:
    22    name: Baz
    23  ---
    24  apiVersion: v1
    25  kind: test
    26  spec:
    27    name: Foo
    28  `
    29  	nodes, err := kio.ParseAll(data)
    30  	if err != nil {
    31  		t.Fatal(err)
    32  	} else if len(nodes) != 3 {
    33  		t.Fatalf("Didn't parse into 3 nodes. Got %d", len(nodes))
    34  	} else if str, err := kio.StringAll(nodes); err != nil {
    35  		t.Fatal(err)
    36  	} else if str != data {
    37  		t.Logf("Original:\n%s\n", data)
    38  		t.Logf("Restringed:\n%s\n", str)
    39  		t.Fatalf("Expected the restringing of nodes to produce output identical to the input data.")
    40  	}
    41  
    42  	var orderings = [][]*yaml.RNode{
    43  		[]*yaml.RNode{nodes[0], nodes[1], nodes[2]},
    44  		[]*yaml.RNode{nodes[0], nodes[2], nodes[1]},
    45  		[]*yaml.RNode{nodes[1], nodes[0], nodes[2]},
    46  		[]*yaml.RNode{nodes[1], nodes[2], nodes[0]},
    47  		[]*yaml.RNode{nodes[2], nodes[0], nodes[1]},
    48  		[]*yaml.RNode{nodes[2], nodes[1], nodes[0]},
    49  	}
    50  
    51  	for i, ordering := range orderings {
    52  		sortRNodes(ordering)
    53  		if str, err := kio.StringAll(ordering); err != nil {
    54  			t.Fatal(err)
    55  		} else if str != data {
    56  			t.Logf("Original:\n%s\n", data)
    57  			t.Logf("Restringed:\n%s\n", str)
    58  			t.Fatalf("Expected the restringing of sorted nodes to produce output identical to the input data.")
    59  		}
    60  		t.Logf("Successfully sorted permutation %d", i)
    61  	}
    62  	t.Logf("Successfully sorted all %d permutations", len(orderings))
    63  }
    64  
    65  // TestSortRNodesWithApiVersionPrefixFnsEdgeNcrCom ensures that nodes with `apiVersionPrefixFnsEdgeNcrCom` are
    66  // not lexiographically sorted and their order is stable.
    67  func TestSortRNodesWithApiVersionPrefixFnsEdgeNcrCom(t *testing.T) {
    68  	var lexiSortedNodes1 = `apiVersion: v1
    69  kind: test
    70  metadata:
    71    annotations:
    72      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/one.yaml
    73  spec:
    74    name: Bar
    75  ---
    76  apiVersion: v1
    77  kind: test
    78  metadata:
    79    annotations:
    80      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/two.yaml
    81  spec:
    82    name: Maz
    83  `
    84  	var lexiSortedNodes2 = `apiVersion: v1
    85  kind: test
    86  metadata:
    87    annotations:
    88      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/one.yaml
    89  spec:
    90    name: Foo
    91  ---
    92  apiVersion: v1
    93  kind: test
    94  metadata:
    95    annotations:
    96      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/two.yaml
    97  spec:
    98    name: Fuz
    99  `
   100  
   101  	var lexiSortedNodes3 = `apiVersion: v1
   102  kind: test
   103  metadata:
   104    annotations:
   105      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/one.yaml
   106  spec:
   107    name: Fum
   108  ---
   109  apiVersion: v1
   110  kind: test
   111  metadata:
   112    annotations:
   113      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/two.yaml
   114  spec:
   115    name: Fee
   116  `
   117  
   118  	var stableNodes1 = fmt.Sprintf(`apiVersion: %sv1
   119  kind: test
   120  metadata:
   121    annotations:
   122      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/three.yaml
   123  spec:
   124    name: Zar
   125  ---
   126  apiVersion: %sv1
   127  kind: test
   128  metadata:
   129    annotations:
   130      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/three.yaml
   131  spec:
   132    name: Arr
   133  ---
   134  apiVersion: %sv1
   135  kind: test
   136  metadata:
   137    annotations:
   138      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/three.yaml
   139  spec:
   140    name: Maz
   141  `, apiVersionPrefixFnsEdgeNcrCom, apiVersionPrefixFnsEdgeNcrCom, apiVersionPrefixFnsEdgeNcrCom)
   142  
   143  	var stableNodes2 = fmt.Sprintf(`apiVersion: %sv1
   144  kind: test
   145  metadata:
   146    annotations:
   147      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/three.yaml
   148  spec:
   149    name: Foo
   150  ---
   151  apiVersion: %sv1
   152  kind: test
   153  metadata:
   154    annotations:
   155      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/three.yaml
   156  spec:
   157    name: Fuz
   158  ---
   159  apiVersion: %sv1
   160  kind: test
   161  metadata:
   162    annotations:
   163      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/three.yaml
   164  spec:
   165    name: Fam
   166  `, apiVersionPrefixFnsEdgeNcrCom, apiVersionPrefixFnsEdgeNcrCom, apiVersionPrefixFnsEdgeNcrCom)
   167  
   168  	var nodes []*yaml.RNode
   169  	for _, unparsed := range []string{lexiSortedNodes1, stableNodes1, lexiSortedNodes2, stableNodes2, lexiSortedNodes3} {
   170  		parsed, err := kio.ParseAll(unparsed)
   171  		if err != nil {
   172  			t.Fatal(err)
   173  		}
   174  		nodes = append(nodes, parsed...)
   175  	}
   176  
   177  	if len(nodes) != 12 {
   178  		t.Fatalf("Didn't parse into 12 nodes. Got %d", len(nodes))
   179  	}
   180  
   181  	var stableVisited = -1
   182  	var stableOrder = []string{"Zar", "Arr", "Maz", "Foo", "Fuz", "Fam"} // <--- This is the test
   183  	for _, n := range nodes {
   184  		meta, err := n.GetMeta()
   185  		if err != nil {
   186  			t.Fatal(err)
   187  		}
   188  		if !strings.HasPrefix(meta.TypeMeta.APIVersion, apiVersionPrefixFnsEdgeNcrCom) {
   189  			continue
   190  		}
   191  
   192  		stableVisited++
   193  		want := stableOrder[stableVisited]
   194  
   195  		name, err := n.Pipe(yaml.Lookup("spec", "name"))
   196  		if err != nil {
   197  			t.Fatal(err)
   198  		} else if value, err := name.String(); err != nil {
   199  			t.Fatal(err)
   200  		} else if want != strings.TrimSpace(value) {
   201  			t.Fatalf("Did not sort correctly. At index %d got %q and want %q", stableVisited, value, want)
   202  		} else {
   203  			t.Logf("Got correct value %q at index %d", want, stableVisited)
   204  		}
   205  	}
   206  	t.Logf("Successfully got correct values in stable order for all %d nodes", len(stableOrder))
   207  }
   208  
   209  func TestSortRNodesWithDifferentPathAnnotations(t *testing.T) {
   210  	var data = `apiVersion: v3
   211  kind: test
   212  metadata:
   213    annotations:
   214      internal.config.kubernetes.io/path: 'manifests/clusterregistry/clusters/edge/Bar.yaml'
   215      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/Bar.yaml
   216  spec:
   217    name: Bar
   218  ---
   219  apiVersion: v2
   220  kind: test
   221  metadata:
   222    annotations:
   223      internal.config.kubernetes.io/path: 'manifests/clusterregistry/clusters/edge/Baz.yaml'
   224      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/Baz.yaml
   225  spec:
   226    name: Baz
   227  ---
   228  apiVersion: v1
   229  kind: test
   230  metadata:
   231    annotations:
   232      internal.config.kubernetes.io/path: 'manifests/clusterregistry/clusters/edge/Foo.yaml'
   233      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/Foo.yaml
   234  spec:
   235    name: Foo
   236  `
   237  	nodes, err := kio.ParseAll(data)
   238  	if err != nil {
   239  		t.Fatal(err)
   240  	} else if len(nodes) != 3 {
   241  		t.Fatalf("Didn't parse into 3 nodes. Got %d", len(nodes))
   242  	} else if str, err := kio.StringAll(nodes); err != nil {
   243  		t.Fatal(err)
   244  	} else if str != data {
   245  		t.Logf("Original:\n%s\n", data)
   246  		t.Logf("Restringed:\n%s\n", str)
   247  		t.Fatalf("Expected the restringing of nodes to produce output identical to the input data.")
   248  	}
   249  
   250  	var orderings = [][]*yaml.RNode{
   251  		[]*yaml.RNode{nodes[0], nodes[1], nodes[2]},
   252  		[]*yaml.RNode{nodes[0], nodes[2], nodes[1]},
   253  		[]*yaml.RNode{nodes[1], nodes[0], nodes[2]},
   254  		[]*yaml.RNode{nodes[1], nodes[2], nodes[0]},
   255  		[]*yaml.RNode{nodes[2], nodes[0], nodes[1]},
   256  		[]*yaml.RNode{nodes[2], nodes[1], nodes[0]},
   257  	}
   258  
   259  	for i, ordering := range orderings {
   260  		sortRNodes(ordering)
   261  		if str, err := kio.StringAll(ordering); err != nil {
   262  			t.Fatal(err)
   263  		} else if str != data {
   264  			t.Logf("Original:\n%s\n", data)
   265  			t.Logf("Restringed:\n%s\n", str)
   266  			t.Fatalf("Expected the restringing of sorted nodes to produce output identical to the input data.")
   267  		}
   268  		t.Logf("Successfully sorted permutation %d", i)
   269  	}
   270  	t.Logf("Successfully sorted all %d permutations", len(orderings))
   271  }
   272  
   273  func TestSortRNodesWithIdenticalPathAnnotations(t *testing.T) {
   274  	var data = `apiVersion: v1
   275  kind: test
   276  metadata:
   277    annotations:
   278      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/one.yaml
   279      internal.config.kubernetes.io/path: 'manifests/clusterregistry/clusters/edge/one.yaml'
   280  spec:
   281    name: Bar
   282  ---
   283  apiVersion: v1
   284  kind: test
   285  metadata:
   286    annotations:
   287      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/one.yaml
   288      internal.config.kubernetes.io/path: 'manifests/clusterregistry/clusters/edge/one.yaml'
   289  spec:
   290    name: Baz
   291  ---
   292  apiVersion: v1
   293  kind: test
   294  metadata:
   295    annotations:
   296      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/two.yaml
   297      internal.config.kubernetes.io/path: 'manifests/clusterregistry/clusters/edge/one.yaml'
   298  spec:
   299    name: Foo
   300  ---
   301  apiVersion: v1
   302  kind: test
   303  metadata:
   304    annotations:
   305      config.kubernetes.io/path: manifests/clusterregistry/clusters/edge/two.yaml
   306      internal.config.kubernetes.io/path: 'manifests/clusterregistry/clusters/edge/one.yaml'
   307  spec:
   308    name: Fuz
   309  `
   310  	nodes, err := kio.ParseAll(data)
   311  	if err != nil {
   312  		t.Fatal(err)
   313  	} else if len(nodes) != 4 {
   314  		t.Fatalf("Didn't parse into 4 nodes. Got %d", len(nodes))
   315  	} else if str, err := kio.StringAll(nodes); err != nil {
   316  		t.Fatal(err)
   317  	} else if str != data {
   318  		t.Logf("Original:\n%s\n", data)
   319  		t.Logf("Restringed:\n%s\n", str)
   320  		t.Fatalf("Expected the restringing of nodes to produce output identical to the input data.")
   321  	}
   322  
   323  	var orderings = [][]*yaml.RNode{
   324  		[]*yaml.RNode{nodes[0], nodes[1], nodes[2], nodes[3]},
   325  		[]*yaml.RNode{nodes[0], nodes[1], nodes[3], nodes[2]},
   326  		[]*yaml.RNode{nodes[0], nodes[2], nodes[1], nodes[3]},
   327  		[]*yaml.RNode{nodes[0], nodes[2], nodes[3], nodes[1]},
   328  		[]*yaml.RNode{nodes[0], nodes[3], nodes[1], nodes[2]},
   329  		[]*yaml.RNode{nodes[0], nodes[3], nodes[2], nodes[1]},
   330  		[]*yaml.RNode{nodes[1], nodes[0], nodes[2], nodes[3]},
   331  		[]*yaml.RNode{nodes[1], nodes[0], nodes[3], nodes[2]},
   332  		[]*yaml.RNode{nodes[1], nodes[2], nodes[0], nodes[3]},
   333  		[]*yaml.RNode{nodes[1], nodes[2], nodes[3], nodes[0]},
   334  		[]*yaml.RNode{nodes[1], nodes[3], nodes[0], nodes[2]},
   335  		[]*yaml.RNode{nodes[1], nodes[3], nodes[2], nodes[0]},
   336  		[]*yaml.RNode{nodes[2], nodes[0], nodes[1], nodes[3]},
   337  		[]*yaml.RNode{nodes[2], nodes[0], nodes[3], nodes[1]},
   338  		[]*yaml.RNode{nodes[2], nodes[1], nodes[0], nodes[3]},
   339  		[]*yaml.RNode{nodes[2], nodes[1], nodes[3], nodes[0]},
   340  		[]*yaml.RNode{nodes[2], nodes[3], nodes[0], nodes[1]},
   341  		[]*yaml.RNode{nodes[2], nodes[3], nodes[1], nodes[0]},
   342  		[]*yaml.RNode{nodes[3], nodes[0], nodes[1], nodes[2]},
   343  		[]*yaml.RNode{nodes[3], nodes[0], nodes[2], nodes[1]},
   344  		[]*yaml.RNode{nodes[3], nodes[1], nodes[0], nodes[2]},
   345  		[]*yaml.RNode{nodes[3], nodes[1], nodes[2], nodes[0]},
   346  		[]*yaml.RNode{nodes[3], nodes[2], nodes[0], nodes[1]},
   347  		[]*yaml.RNode{nodes[3], nodes[2], nodes[1], nodes[0]},
   348  	}
   349  
   350  	for i, ordering := range orderings {
   351  		sortRNodes(ordering)
   352  		if str, err := kio.StringAll(ordering); err != nil {
   353  			t.Fatal(err)
   354  		} else if str != data {
   355  			t.Logf("Original:\n%s\n", data)
   356  			t.Logf("Restringed:\n%s\n", str)
   357  			t.Fatalf("Expected the restringing of sorted nodes to produce output identical to the input data.")
   358  		}
   359  		t.Logf("Successfully sorted permutation %d", i)
   360  	}
   361  	t.Logf("Successfully sorted all %d permutations", len(orderings))
   362  }
   363  

View as plain text