...

Source file src/edge-infra.dev/pkg/k8s/object/objects_test.go

Documentation: edge-infra.dev/pkg/k8s/object

     1  package object
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/google/go-cmp/cmp"
    10  	"k8s.io/apimachinery/pkg/api/errors"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  	"sigs.k8s.io/controller-runtime/pkg/client"
    13  
    14  	"edge-infra.dev/pkg/k8s/object/fobject"
    15  )
    16  
    17  func TestCmpMaskData(t *testing.T) {
    18  	testCases := []struct {
    19  		name     string
    20  		current  map[string]interface{}
    21  		future   map[string]interface{}
    22  		expected string
    23  	}{
    24  		{
    25  			name:     "empty",
    26  			current:  map[string]interface{}{},
    27  			future:   map[string]interface{}{},
    28  			expected: "",
    29  		},
    30  		{
    31  			name: "no change",
    32  			current: map[string]interface{}{
    33  				"foo": "bar",
    34  			},
    35  			future: map[string]interface{}{
    36  				"foo": "bar",
    37  			},
    38  			expected: "",
    39  		},
    40  		{
    41  			name: "simple value changed",
    42  			current: map[string]interface{}{
    43  				"foo": "bar",
    44  			},
    45  			future: map[string]interface{}{
    46  				"foo": "baz",
    47  			},
    48  			expected: fmt.Sprintf("foo\": string(\"%s\")", DefaultMask),
    49  		},
    50  		{
    51  			name: "simple value changed with different casing",
    52  			current: map[string]interface{}{
    53  				"foo": "bar",
    54  			},
    55  			future: map[string]interface{}{
    56  				"FOO": "baz",
    57  			},
    58  			expected: fmt.Sprintf("foo\": string(\"%s\")", DefaultMask),
    59  		},
    60  		{
    61  			name: "value changed with different casing and different values",
    62  			current: map[string]interface{}{
    63  				"foo": "bar",
    64  				"baz": "qux",
    65  			},
    66  			future: map[string]interface{}{
    67  				"foo": "baz",
    68  				"baz": "qux",
    69  			},
    70  			expected: fmt.Sprintf("baz\": string(\"%s\")", DefaultMask),
    71  		},
    72  	}
    73  
    74  	t.Parallel()
    75  	for _, tc := range testCases {
    76  		tc := tc
    77  		t.Run(tc.name, func(t *testing.T) {
    78  			t.Parallel()
    79  			c, ft := CmpMaskData(tc.current, tc.future)
    80  			if diff := cmp.Diff(c, ft); !strings.Contains(diff, tc.expected) {
    81  				t.Errorf("Unexpected value in Diff")
    82  			}
    83  		})
    84  	}
    85  }
    86  
    87  func TestReadObjects_DropsInvalid(t *testing.T) {
    88  	testCases := []struct {
    89  		name      string
    90  		resources string
    91  		expected  int
    92  	}{
    93  		{
    94  			name: "valid resources",
    95  			resources: `
    96  ---
    97  apiVersion: v1
    98  kind: Secret
    99  metadata:
   100    name: test
   101    namespace: default
   102  immutable: true
   103  stringData:
   104    key: "private-key"
   105  ---
   106  apiVersion: pkg.crossplane.io/v1
   107  kind: Provider
   108  metadata:
   109    name: crossplane-provider-aws2
   110  spec:
   111    package: crossplane/provider-aws:v0.23.0
   112    controllerConfigRef:
   113      name: provider-aws
   114  `,
   115  			expected: 2,
   116  		},
   117  		{
   118  			name: "some invalid resources",
   119  			resources: `
   120  ---
   121  piVersion: pkg.crossplane.io/v1
   122  kind: Provider
   123  metadata:
   124    name: crossplane-provider-aws1
   125  spec:
   126    package: crossplane/provider-aws:v0.23.0
   127    controllerConfigRef:
   128      name: provider-aws
   129  ---
   130  apiVersion: v1
   131  kind: Secret
   132  metadata:
   133    name: test
   134    namespace: default
   135  immutable: true
   136  stringData:
   137    key: "private-key"
   138  `,
   139  			expected: 1,
   140  		},
   141  	}
   142  
   143  	t.Parallel()
   144  	for _, tc := range testCases {
   145  		tc := tc
   146  		t.Run(tc.name, func(t *testing.T) {
   147  			t.Parallel()
   148  			objects, err := ReadObjects(strings.NewReader(tc.resources))
   149  			if err != nil {
   150  				t.Errorf("unexpected error: %v", err)
   151  			}
   152  
   153  			if len(objects) != tc.expected {
   154  				t.Errorf("unexpected number of objects in %v", objects)
   155  			}
   156  		})
   157  	}
   158  }
   159  
   160  func TestIsDeleted(t *testing.T) {
   161  	tcs := map[string]struct {
   162  		obj      client.Object
   163  		err      error
   164  		expected bool
   165  	}{
   166  		"Marked for deletion no error": {
   167  			&fobject.Fake{ObjectMeta: metav1.ObjectMeta{DeletionTimestamp: &metav1.Time{Time: time.Now()}}},
   168  			nil,
   169  			true,
   170  		},
   171  		"Marked for deletion error IsGone": {
   172  			&fobject.Fake{ObjectMeta: metav1.ObjectMeta{DeletionTimestamp: &metav1.Time{Time: time.Now()}}},
   173  			errors.NewGone(""),
   174  			true,
   175  		},
   176  		"Marked for deletion error IsNotFound": {
   177  			&fobject.Fake{ObjectMeta: metav1.ObjectMeta{DeletionTimestamp: &metav1.Time{Time: time.Now()}}},
   178  			errors.NewNotFound(fobject.FakeGroupResource, ""),
   179  			true,
   180  		},
   181  		"Error IsGone": {
   182  			&fobject.Fake{},
   183  			errors.NewGone(""),
   184  			true,
   185  		},
   186  		"Error IsNotFound": {
   187  			&fobject.Fake{},
   188  			errors.NewNotFound(fobject.FakeGroupResource, ""),
   189  			true,
   190  		},
   191  		"Not deleted": {
   192  			&fobject.Fake{},
   193  			nil,
   194  			false,
   195  		},
   196  	}
   197  
   198  	t.Parallel()
   199  	for name, tc := range tcs {
   200  		tc := tc
   201  		t.Run(name, func(t *testing.T) {
   202  			t.Parallel()
   203  			actual := IsDeleted(tc.obj, tc.err)
   204  			if tc.expected != actual {
   205  				t.Error("expected", tc.expected, "got", actual,
   206  					"error", tc.err, "object", tc.obj)
   207  			}
   208  		})
   209  	}
   210  }
   211  
   212  func TestFmtObject(t *testing.T) {
   213  	tcs := map[string]struct {
   214  		obj      client.Object
   215  		expected string
   216  	}{
   217  		"Namespaced": {
   218  			&fobject.Fake{
   219  				TypeMeta:   metav1.TypeMeta{Kind: "Fake"},
   220  				ObjectMeta: metav1.ObjectMeta{Name: "special-boy", Namespace: "special-home"},
   221  			},
   222  			"Fake/special-home/special-boy",
   223  		},
   224  		"Cluster": {
   225  			&fobject.Fake{
   226  				TypeMeta:   metav1.TypeMeta{Kind: "Fake"},
   227  				ObjectMeta: metav1.ObjectMeta{Name: "special-girl"},
   228  			},
   229  			"Fake/special-girl",
   230  		},
   231  	}
   232  
   233  	t.Parallel()
   234  	for name, tc := range tcs {
   235  		tc := tc
   236  		t.Run(name, func(t *testing.T) {
   237  			t.Parallel()
   238  			actual := FmtObject(tc.obj)
   239  			if tc.expected != actual {
   240  				t.Error("expected", tc.expected, "got", actual)
   241  			}
   242  		})
   243  	}
   244  }
   245  

View as plain text