...

Source file src/k8s.io/kubernetes/pkg/apis/extensions/v1beta1/defaults_test.go

Documentation: k8s.io/kubernetes/pkg/apis/extensions/v1beta1

     1  /*
     2  Copyright 2015 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 v1beta1_test
    18  
    19  import (
    20  	"math"
    21  	"reflect"
    22  	"testing"
    23  
    24  	extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
    25  
    26  	v1 "k8s.io/api/core/v1"
    27  	apiequality "k8s.io/apimachinery/pkg/api/equality"
    28  	"k8s.io/apimachinery/pkg/api/resource"
    29  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    30  	"k8s.io/apimachinery/pkg/runtime"
    31  	"k8s.io/apimachinery/pkg/util/intstr"
    32  	"k8s.io/kubernetes/pkg/api/legacyscheme"
    33  	_ "k8s.io/kubernetes/pkg/apis/core/install"
    34  	_ "k8s.io/kubernetes/pkg/apis/extensions/install"
    35  	. "k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
    36  	utilpointer "k8s.io/utils/pointer"
    37  )
    38  
    39  func TestSetDefaultDaemonSetSpec(t *testing.T) {
    40  	defaultLabels := map[string]string{"foo": "bar"}
    41  	period := int64(v1.DefaultTerminationGracePeriodSeconds)
    42  	defaultTemplate := v1.PodTemplateSpec{
    43  		Spec: v1.PodSpec{
    44  			DNSPolicy:                     v1.DNSClusterFirst,
    45  			RestartPolicy:                 v1.RestartPolicyAlways,
    46  			SecurityContext:               &v1.PodSecurityContext{},
    47  			TerminationGracePeriodSeconds: &period,
    48  			SchedulerName:                 v1.DefaultSchedulerName,
    49  		},
    50  		ObjectMeta: metav1.ObjectMeta{
    51  			Labels: defaultLabels,
    52  		},
    53  	}
    54  	templateNoLabel := v1.PodTemplateSpec{
    55  		Spec: v1.PodSpec{
    56  			DNSPolicy:                     v1.DNSClusterFirst,
    57  			RestartPolicy:                 v1.RestartPolicyAlways,
    58  			SecurityContext:               &v1.PodSecurityContext{},
    59  			TerminationGracePeriodSeconds: &period,
    60  			SchedulerName:                 v1.DefaultSchedulerName,
    61  		},
    62  	}
    63  	tests := []struct {
    64  		original *extensionsv1beta1.DaemonSet
    65  		expected *extensionsv1beta1.DaemonSet
    66  	}{
    67  		{ // Labels change/defaulting test.
    68  			original: &extensionsv1beta1.DaemonSet{
    69  				Spec: extensionsv1beta1.DaemonSetSpec{
    70  					Template: defaultTemplate,
    71  				},
    72  			},
    73  			expected: &extensionsv1beta1.DaemonSet{
    74  				ObjectMeta: metav1.ObjectMeta{
    75  					Labels: defaultLabels,
    76  				},
    77  				Spec: extensionsv1beta1.DaemonSetSpec{
    78  					Selector: &metav1.LabelSelector{
    79  						MatchLabels: defaultLabels,
    80  					},
    81  					Template: defaultTemplate,
    82  					UpdateStrategy: extensionsv1beta1.DaemonSetUpdateStrategy{
    83  						Type: extensionsv1beta1.OnDeleteDaemonSetStrategyType,
    84  					},
    85  					RevisionHistoryLimit: utilpointer.Int32(10),
    86  				},
    87  			},
    88  		},
    89  		{ // Labels change/defaulting test.
    90  			original: &extensionsv1beta1.DaemonSet{
    91  				ObjectMeta: metav1.ObjectMeta{
    92  					Labels: map[string]string{
    93  						"bar": "foo",
    94  					},
    95  				},
    96  				Spec: extensionsv1beta1.DaemonSetSpec{
    97  					Template:             defaultTemplate,
    98  					RevisionHistoryLimit: utilpointer.Int32(1),
    99  				},
   100  			},
   101  			expected: &extensionsv1beta1.DaemonSet{
   102  				ObjectMeta: metav1.ObjectMeta{
   103  					Labels: map[string]string{
   104  						"bar": "foo",
   105  					},
   106  				},
   107  				Spec: extensionsv1beta1.DaemonSetSpec{
   108  					Selector: &metav1.LabelSelector{
   109  						MatchLabels: defaultLabels,
   110  					},
   111  					Template: defaultTemplate,
   112  					UpdateStrategy: extensionsv1beta1.DaemonSetUpdateStrategy{
   113  						Type: extensionsv1beta1.OnDeleteDaemonSetStrategyType,
   114  					},
   115  					RevisionHistoryLimit: utilpointer.Int32(1),
   116  				},
   117  			},
   118  		},
   119  		{ // Update strategy.
   120  			original: &extensionsv1beta1.DaemonSet{},
   121  			expected: &extensionsv1beta1.DaemonSet{
   122  				Spec: extensionsv1beta1.DaemonSetSpec{
   123  					Template: templateNoLabel,
   124  					UpdateStrategy: extensionsv1beta1.DaemonSetUpdateStrategy{
   125  						Type: extensionsv1beta1.OnDeleteDaemonSetStrategyType,
   126  					},
   127  					RevisionHistoryLimit: utilpointer.Int32(10),
   128  				},
   129  			},
   130  		},
   131  		{ // Custom unique label key.
   132  			original: &extensionsv1beta1.DaemonSet{
   133  				Spec: extensionsv1beta1.DaemonSetSpec{},
   134  			},
   135  			expected: &extensionsv1beta1.DaemonSet{
   136  				Spec: extensionsv1beta1.DaemonSetSpec{
   137  					Template: templateNoLabel,
   138  					UpdateStrategy: extensionsv1beta1.DaemonSetUpdateStrategy{
   139  						Type: extensionsv1beta1.OnDeleteDaemonSetStrategyType,
   140  					},
   141  					RevisionHistoryLimit: utilpointer.Int32(10),
   142  				},
   143  			},
   144  		},
   145  	}
   146  
   147  	for i, test := range tests {
   148  		original := test.original
   149  		expected := test.expected
   150  		obj2 := roundTrip(t, runtime.Object(original))
   151  		got, ok := obj2.(*extensionsv1beta1.DaemonSet)
   152  		if !ok {
   153  			t.Errorf("(%d) unexpected object: %v", i, got)
   154  			t.FailNow()
   155  		}
   156  		if !apiequality.Semantic.DeepEqual(got.Spec, expected.Spec) {
   157  			t.Errorf("(%d) got different than expected\ngot:\n\t%+v\nexpected:\n\t%+v", i, got.Spec, expected.Spec)
   158  		}
   159  	}
   160  }
   161  
   162  func TestSetDefaultDeployment(t *testing.T) {
   163  	defaultIntOrString := intstr.FromInt32(1)
   164  	differentIntOrString := intstr.FromInt32(5)
   165  	period := int64(v1.DefaultTerminationGracePeriodSeconds)
   166  	defaultTemplate := v1.PodTemplateSpec{
   167  		Spec: v1.PodSpec{
   168  			DNSPolicy:                     v1.DNSClusterFirst,
   169  			RestartPolicy:                 v1.RestartPolicyAlways,
   170  			SecurityContext:               &v1.PodSecurityContext{},
   171  			TerminationGracePeriodSeconds: &period,
   172  			SchedulerName:                 v1.DefaultSchedulerName,
   173  		},
   174  	}
   175  	tests := []struct {
   176  		original *extensionsv1beta1.Deployment
   177  		expected *extensionsv1beta1.Deployment
   178  	}{
   179  		{
   180  			original: &extensionsv1beta1.Deployment{},
   181  			expected: &extensionsv1beta1.Deployment{
   182  				Spec: extensionsv1beta1.DeploymentSpec{
   183  					Replicas: utilpointer.Int32(1),
   184  					Strategy: extensionsv1beta1.DeploymentStrategy{
   185  						Type: extensionsv1beta1.RollingUpdateDeploymentStrategyType,
   186  						RollingUpdate: &extensionsv1beta1.RollingUpdateDeployment{
   187  							MaxSurge:       &defaultIntOrString,
   188  							MaxUnavailable: &defaultIntOrString,
   189  						},
   190  					},
   191  					Template:                defaultTemplate,
   192  					ProgressDeadlineSeconds: utilpointer.Int32(math.MaxInt32),
   193  					RevisionHistoryLimit:    utilpointer.Int32(math.MaxInt32),
   194  				},
   195  			},
   196  		},
   197  		{
   198  			original: &extensionsv1beta1.Deployment{
   199  				Spec: extensionsv1beta1.DeploymentSpec{
   200  					Replicas: utilpointer.Int32(5),
   201  					Strategy: extensionsv1beta1.DeploymentStrategy{
   202  						RollingUpdate: &extensionsv1beta1.RollingUpdateDeployment{
   203  							MaxSurge: &differentIntOrString,
   204  						},
   205  					},
   206  				},
   207  			},
   208  			expected: &extensionsv1beta1.Deployment{
   209  				Spec: extensionsv1beta1.DeploymentSpec{
   210  					Replicas: utilpointer.Int32(5),
   211  					Strategy: extensionsv1beta1.DeploymentStrategy{
   212  						Type: extensionsv1beta1.RollingUpdateDeploymentStrategyType,
   213  						RollingUpdate: &extensionsv1beta1.RollingUpdateDeployment{
   214  							MaxSurge:       &differentIntOrString,
   215  							MaxUnavailable: &defaultIntOrString,
   216  						},
   217  					},
   218  					Template:                defaultTemplate,
   219  					ProgressDeadlineSeconds: utilpointer.Int32(math.MaxInt32),
   220  					RevisionHistoryLimit:    utilpointer.Int32(math.MaxInt32),
   221  				},
   222  			},
   223  		},
   224  		{
   225  			original: &extensionsv1beta1.Deployment{
   226  				Spec: extensionsv1beta1.DeploymentSpec{
   227  					Replicas: utilpointer.Int32(3),
   228  					Strategy: extensionsv1beta1.DeploymentStrategy{
   229  						Type:          extensionsv1beta1.RollingUpdateDeploymentStrategyType,
   230  						RollingUpdate: nil,
   231  					},
   232  				},
   233  			},
   234  			expected: &extensionsv1beta1.Deployment{
   235  				Spec: extensionsv1beta1.DeploymentSpec{
   236  					Replicas: utilpointer.Int32(3),
   237  					Strategy: extensionsv1beta1.DeploymentStrategy{
   238  						Type: extensionsv1beta1.RollingUpdateDeploymentStrategyType,
   239  						RollingUpdate: &extensionsv1beta1.RollingUpdateDeployment{
   240  							MaxSurge:       &defaultIntOrString,
   241  							MaxUnavailable: &defaultIntOrString,
   242  						},
   243  					},
   244  					Template:                defaultTemplate,
   245  					ProgressDeadlineSeconds: utilpointer.Int32(math.MaxInt32),
   246  					RevisionHistoryLimit:    utilpointer.Int32(math.MaxInt32),
   247  				},
   248  			},
   249  		},
   250  		{
   251  			original: &extensionsv1beta1.Deployment{
   252  				Spec: extensionsv1beta1.DeploymentSpec{
   253  					Replicas: utilpointer.Int32(5),
   254  					Strategy: extensionsv1beta1.DeploymentStrategy{
   255  						Type: extensionsv1beta1.RecreateDeploymentStrategyType,
   256  					},
   257  				},
   258  			},
   259  			expected: &extensionsv1beta1.Deployment{
   260  				Spec: extensionsv1beta1.DeploymentSpec{
   261  					Replicas: utilpointer.Int32(5),
   262  					Strategy: extensionsv1beta1.DeploymentStrategy{
   263  						Type: extensionsv1beta1.RecreateDeploymentStrategyType,
   264  					},
   265  					Template:                defaultTemplate,
   266  					ProgressDeadlineSeconds: utilpointer.Int32(math.MaxInt32),
   267  					RevisionHistoryLimit:    utilpointer.Int32(math.MaxInt32),
   268  				},
   269  			},
   270  		},
   271  		{
   272  			original: &extensionsv1beta1.Deployment{
   273  				Spec: extensionsv1beta1.DeploymentSpec{
   274  					Replicas: utilpointer.Int32(5),
   275  					Strategy: extensionsv1beta1.DeploymentStrategy{
   276  						Type: extensionsv1beta1.RecreateDeploymentStrategyType,
   277  					},
   278  					ProgressDeadlineSeconds: utilpointer.Int32(30),
   279  				},
   280  			},
   281  			expected: &extensionsv1beta1.Deployment{
   282  				Spec: extensionsv1beta1.DeploymentSpec{
   283  					Replicas: utilpointer.Int32(5),
   284  					Strategy: extensionsv1beta1.DeploymentStrategy{
   285  						Type: extensionsv1beta1.RecreateDeploymentStrategyType,
   286  					},
   287  					Template:                defaultTemplate,
   288  					ProgressDeadlineSeconds: utilpointer.Int32(30),
   289  					RevisionHistoryLimit:    utilpointer.Int32(math.MaxInt32),
   290  				},
   291  			},
   292  		},
   293  	}
   294  
   295  	for _, test := range tests {
   296  		original := test.original
   297  		expected := test.expected
   298  		obj2 := roundTrip(t, runtime.Object(original))
   299  		got, ok := obj2.(*extensionsv1beta1.Deployment)
   300  		if !ok {
   301  			t.Errorf("unexpected object: %v", got)
   302  			t.FailNow()
   303  		}
   304  		if !apiequality.Semantic.DeepEqual(got.Spec, expected.Spec) {
   305  			t.Errorf("object mismatch!\nexpected:\n\t%+v\ngot:\n\t%+v", got.Spec, expected.Spec)
   306  		}
   307  	}
   308  }
   309  
   310  func TestSetDefaultReplicaSet(t *testing.T) {
   311  	tests := []struct {
   312  		rs             *extensionsv1beta1.ReplicaSet
   313  		expectLabels   bool
   314  		expectSelector bool
   315  	}{
   316  		{
   317  			rs: &extensionsv1beta1.ReplicaSet{
   318  				Spec: extensionsv1beta1.ReplicaSetSpec{
   319  					Template: v1.PodTemplateSpec{
   320  						ObjectMeta: metav1.ObjectMeta{
   321  							Labels: map[string]string{
   322  								"foo": "bar",
   323  							},
   324  						},
   325  					},
   326  				},
   327  			},
   328  			expectLabels:   true,
   329  			expectSelector: true,
   330  		},
   331  		{
   332  			rs: &extensionsv1beta1.ReplicaSet{
   333  				ObjectMeta: metav1.ObjectMeta{
   334  					Labels: map[string]string{
   335  						"bar": "foo",
   336  					},
   337  				},
   338  				Spec: extensionsv1beta1.ReplicaSetSpec{
   339  					Template: v1.PodTemplateSpec{
   340  						ObjectMeta: metav1.ObjectMeta{
   341  							Labels: map[string]string{
   342  								"foo": "bar",
   343  							},
   344  						},
   345  					},
   346  				},
   347  			},
   348  			expectLabels:   false,
   349  			expectSelector: true,
   350  		},
   351  		{
   352  			rs: &extensionsv1beta1.ReplicaSet{
   353  				ObjectMeta: metav1.ObjectMeta{
   354  					Labels: map[string]string{
   355  						"bar": "foo",
   356  					},
   357  				},
   358  				Spec: extensionsv1beta1.ReplicaSetSpec{
   359  					Selector: &metav1.LabelSelector{
   360  						MatchLabels: map[string]string{
   361  							"some": "other",
   362  						},
   363  					},
   364  					Template: v1.PodTemplateSpec{
   365  						ObjectMeta: metav1.ObjectMeta{
   366  							Labels: map[string]string{
   367  								"foo": "bar",
   368  							},
   369  						},
   370  					},
   371  				},
   372  			},
   373  			expectLabels:   false,
   374  			expectSelector: false,
   375  		},
   376  		{
   377  			rs: &extensionsv1beta1.ReplicaSet{
   378  				Spec: extensionsv1beta1.ReplicaSetSpec{
   379  					Selector: &metav1.LabelSelector{
   380  						MatchLabels: map[string]string{
   381  							"some": "other",
   382  						},
   383  					},
   384  					Template: v1.PodTemplateSpec{
   385  						ObjectMeta: metav1.ObjectMeta{
   386  							Labels: map[string]string{
   387  								"foo": "bar",
   388  							},
   389  						},
   390  					},
   391  				},
   392  			},
   393  			expectLabels:   true,
   394  			expectSelector: false,
   395  		},
   396  	}
   397  
   398  	for _, test := range tests {
   399  		rs := test.rs
   400  		obj2 := roundTrip(t, runtime.Object(rs))
   401  		rs2, ok := obj2.(*extensionsv1beta1.ReplicaSet)
   402  		if !ok {
   403  			t.Errorf("unexpected object: %v", rs2)
   404  			t.FailNow()
   405  		}
   406  		if test.expectSelector != reflect.DeepEqual(rs2.Spec.Selector.MatchLabels, rs2.Spec.Template.Labels) {
   407  			if test.expectSelector {
   408  				t.Errorf("expected: %v, got: %v", rs2.Spec.Template.Labels, rs2.Spec.Selector)
   409  			} else {
   410  				t.Errorf("unexpected equality: %v", rs.Spec.Selector)
   411  			}
   412  		}
   413  		if test.expectLabels != reflect.DeepEqual(rs2.Labels, rs2.Spec.Template.Labels) {
   414  			if test.expectLabels {
   415  				t.Errorf("expected: %v, got: %v", rs2.Spec.Template.Labels, rs2.Labels)
   416  			} else {
   417  				t.Errorf("unexpected equality: %v", rs.Labels)
   418  			}
   419  		}
   420  	}
   421  }
   422  
   423  func TestSetDefaultReplicaSetReplicas(t *testing.T) {
   424  	tests := []struct {
   425  		rs             extensionsv1beta1.ReplicaSet
   426  		expectReplicas int32
   427  	}{
   428  		{
   429  			rs: extensionsv1beta1.ReplicaSet{
   430  				Spec: extensionsv1beta1.ReplicaSetSpec{
   431  					Template: v1.PodTemplateSpec{
   432  						ObjectMeta: metav1.ObjectMeta{
   433  							Labels: map[string]string{
   434  								"foo": "bar",
   435  							},
   436  						},
   437  					},
   438  				},
   439  			},
   440  			expectReplicas: 1,
   441  		},
   442  		{
   443  			rs: extensionsv1beta1.ReplicaSet{
   444  				Spec: extensionsv1beta1.ReplicaSetSpec{
   445  					Replicas: utilpointer.Int32(0),
   446  					Template: v1.PodTemplateSpec{
   447  						ObjectMeta: metav1.ObjectMeta{
   448  							Labels: map[string]string{
   449  								"foo": "bar",
   450  							},
   451  						},
   452  					},
   453  				},
   454  			},
   455  			expectReplicas: 0,
   456  		},
   457  		{
   458  			rs: extensionsv1beta1.ReplicaSet{
   459  				Spec: extensionsv1beta1.ReplicaSetSpec{
   460  					Replicas: utilpointer.Int32(3),
   461  					Template: v1.PodTemplateSpec{
   462  						ObjectMeta: metav1.ObjectMeta{
   463  							Labels: map[string]string{
   464  								"foo": "bar",
   465  							},
   466  						},
   467  					},
   468  				},
   469  			},
   470  			expectReplicas: 3,
   471  		},
   472  	}
   473  
   474  	for _, test := range tests {
   475  		rs := &test.rs
   476  		obj2 := roundTrip(t, runtime.Object(rs))
   477  		rs2, ok := obj2.(*extensionsv1beta1.ReplicaSet)
   478  		if !ok {
   479  			t.Errorf("unexpected object: %v", rs2)
   480  			t.FailNow()
   481  		}
   482  		if rs2.Spec.Replicas == nil {
   483  			t.Errorf("unexpected nil Replicas")
   484  		} else if test.expectReplicas != *rs2.Spec.Replicas {
   485  			t.Errorf("expected: %d replicas, got: %d", test.expectReplicas, *rs2.Spec.Replicas)
   486  		}
   487  	}
   488  }
   489  
   490  func TestDefaultRequestIsNotSetForReplicaSet(t *testing.T) {
   491  	s := v1.PodSpec{}
   492  	s.Containers = []v1.Container{
   493  		{
   494  			Resources: v1.ResourceRequirements{
   495  				Limits: v1.ResourceList{
   496  					v1.ResourceCPU: resource.MustParse("100m"),
   497  				},
   498  			},
   499  		},
   500  	}
   501  	rs := &extensionsv1beta1.ReplicaSet{
   502  		Spec: extensionsv1beta1.ReplicaSetSpec{
   503  			Replicas: utilpointer.Int32(3),
   504  			Template: v1.PodTemplateSpec{
   505  				ObjectMeta: metav1.ObjectMeta{
   506  					Labels: map[string]string{
   507  						"foo": "bar",
   508  					},
   509  				},
   510  				Spec: s,
   511  			},
   512  		},
   513  	}
   514  	output := roundTrip(t, runtime.Object(rs))
   515  	rs2 := output.(*extensionsv1beta1.ReplicaSet)
   516  	defaultRequest := rs2.Spec.Template.Spec.Containers[0].Resources.Requests
   517  	requestValue := defaultRequest[v1.ResourceCPU]
   518  	if requestValue.String() != "0" {
   519  		t.Errorf("Expected 0 request value, got: %s", requestValue.String())
   520  	}
   521  }
   522  
   523  func TestSetDefaultNetworkPolicy(t *testing.T) {
   524  	tests := []struct {
   525  		original *extensionsv1beta1.NetworkPolicy
   526  		expected *extensionsv1beta1.NetworkPolicy
   527  	}{
   528  		{ // Empty NetworkPolicy should be set to PolicyTypes Ingress
   529  			original: &extensionsv1beta1.NetworkPolicy{
   530  				Spec: extensionsv1beta1.NetworkPolicySpec{
   531  					PodSelector: metav1.LabelSelector{
   532  						MatchLabels: map[string]string{"a": "b"},
   533  					},
   534  				},
   535  			},
   536  			expected: &extensionsv1beta1.NetworkPolicy{
   537  				Spec: extensionsv1beta1.NetworkPolicySpec{
   538  					PodSelector: metav1.LabelSelector{
   539  						MatchLabels: map[string]string{"a": "b"},
   540  					},
   541  					PolicyTypes: []extensionsv1beta1.PolicyType{extensionsv1beta1.PolicyTypeIngress},
   542  				},
   543  			},
   544  		},
   545  		{ // Empty Ingress NetworkPolicy should be set to PolicyTypes Ingress
   546  			original: &extensionsv1beta1.NetworkPolicy{
   547  				Spec: extensionsv1beta1.NetworkPolicySpec{
   548  					PodSelector: metav1.LabelSelector{
   549  						MatchLabels: map[string]string{"a": "b"},
   550  					},
   551  					Ingress: []extensionsv1beta1.NetworkPolicyIngressRule{},
   552  				},
   553  			},
   554  			expected: &extensionsv1beta1.NetworkPolicy{
   555  				Spec: extensionsv1beta1.NetworkPolicySpec{
   556  					PodSelector: metav1.LabelSelector{
   557  						MatchLabels: map[string]string{"a": "b"},
   558  					},
   559  					Ingress:     []extensionsv1beta1.NetworkPolicyIngressRule{},
   560  					PolicyTypes: []extensionsv1beta1.PolicyType{extensionsv1beta1.PolicyTypeIngress},
   561  				},
   562  			},
   563  		},
   564  		{ // Defined Ingress and Egress should be set to Ingress,Egress
   565  			original: &extensionsv1beta1.NetworkPolicy{
   566  				Spec: extensionsv1beta1.NetworkPolicySpec{
   567  					PodSelector: metav1.LabelSelector{
   568  						MatchLabels: map[string]string{"a": "b"},
   569  					},
   570  					Ingress: []extensionsv1beta1.NetworkPolicyIngressRule{
   571  						{
   572  							From: []extensionsv1beta1.NetworkPolicyPeer{
   573  								{
   574  									PodSelector: &metav1.LabelSelector{
   575  										MatchLabels: map[string]string{"c": "d"},
   576  									},
   577  									NamespaceSelector: &metav1.LabelSelector{
   578  										MatchLabels: map[string]string{"c": "d"},
   579  									},
   580  								},
   581  							},
   582  						},
   583  					},
   584  					Egress: []extensionsv1beta1.NetworkPolicyEgressRule{
   585  						{
   586  							To: []extensionsv1beta1.NetworkPolicyPeer{
   587  								{
   588  									NamespaceSelector: &metav1.LabelSelector{
   589  										MatchLabels: map[string]string{"c": "d"},
   590  									},
   591  								},
   592  							},
   593  						},
   594  					},
   595  				},
   596  			},
   597  			expected: &extensionsv1beta1.NetworkPolicy{
   598  				Spec: extensionsv1beta1.NetworkPolicySpec{
   599  					PodSelector: metav1.LabelSelector{
   600  						MatchLabels: map[string]string{"a": "b"},
   601  					},
   602  					Ingress: []extensionsv1beta1.NetworkPolicyIngressRule{
   603  						{
   604  							From: []extensionsv1beta1.NetworkPolicyPeer{
   605  								{
   606  									PodSelector: &metav1.LabelSelector{
   607  										MatchLabels: map[string]string{"c": "d"},
   608  									},
   609  									NamespaceSelector: &metav1.LabelSelector{
   610  										MatchLabels: map[string]string{"c": "d"},
   611  									},
   612  								},
   613  							},
   614  						},
   615  					},
   616  					Egress: []extensionsv1beta1.NetworkPolicyEgressRule{
   617  						{
   618  							To: []extensionsv1beta1.NetworkPolicyPeer{
   619  								{
   620  									NamespaceSelector: &metav1.LabelSelector{
   621  										MatchLabels: map[string]string{"c": "d"},
   622  									},
   623  								},
   624  							},
   625  						},
   626  					},
   627  					PolicyTypes: []extensionsv1beta1.PolicyType{extensionsv1beta1.PolicyTypeIngress, extensionsv1beta1.PolicyTypeEgress},
   628  				},
   629  			},
   630  		},
   631  		{ // Egress only with unset PolicyTypes should be set to Ingress, Egress
   632  			original: &extensionsv1beta1.NetworkPolicy{
   633  				Spec: extensionsv1beta1.NetworkPolicySpec{
   634  					PodSelector: metav1.LabelSelector{
   635  						MatchLabels: map[string]string{"a": "b"},
   636  					},
   637  					Egress: []extensionsv1beta1.NetworkPolicyEgressRule{
   638  						{
   639  							To: []extensionsv1beta1.NetworkPolicyPeer{
   640  								{
   641  									NamespaceSelector: &metav1.LabelSelector{
   642  										MatchLabels: map[string]string{"c": "d"},
   643  									},
   644  								},
   645  							},
   646  						},
   647  					},
   648  				},
   649  			},
   650  			expected: &extensionsv1beta1.NetworkPolicy{
   651  				Spec: extensionsv1beta1.NetworkPolicySpec{
   652  					PodSelector: metav1.LabelSelector{
   653  						MatchLabels: map[string]string{"a": "b"},
   654  					},
   655  					Egress: []extensionsv1beta1.NetworkPolicyEgressRule{
   656  						{
   657  							To: []extensionsv1beta1.NetworkPolicyPeer{
   658  								{
   659  									NamespaceSelector: &metav1.LabelSelector{
   660  										MatchLabels: map[string]string{"c": "d"},
   661  									},
   662  								},
   663  							},
   664  						},
   665  					},
   666  					PolicyTypes: []extensionsv1beta1.PolicyType{extensionsv1beta1.PolicyTypeIngress, extensionsv1beta1.PolicyTypeEgress},
   667  				},
   668  			},
   669  		},
   670  		{ // Egress only with PolicyTypes set to Egress should be set to only Egress
   671  			original: &extensionsv1beta1.NetworkPolicy{
   672  				Spec: extensionsv1beta1.NetworkPolicySpec{
   673  					PodSelector: metav1.LabelSelector{
   674  						MatchLabels: map[string]string{"a": "b"},
   675  					},
   676  					Egress: []extensionsv1beta1.NetworkPolicyEgressRule{
   677  						{
   678  							To: []extensionsv1beta1.NetworkPolicyPeer{
   679  								{
   680  									NamespaceSelector: &metav1.LabelSelector{
   681  										MatchLabels: map[string]string{"Egress": "only"},
   682  									},
   683  								},
   684  							},
   685  						},
   686  					},
   687  					PolicyTypes: []extensionsv1beta1.PolicyType{extensionsv1beta1.PolicyTypeEgress},
   688  				},
   689  			},
   690  			expected: &extensionsv1beta1.NetworkPolicy{
   691  				Spec: extensionsv1beta1.NetworkPolicySpec{
   692  					PodSelector: metav1.LabelSelector{
   693  						MatchLabels: map[string]string{"a": "b"},
   694  					},
   695  					Egress: []extensionsv1beta1.NetworkPolicyEgressRule{
   696  						{
   697  							To: []extensionsv1beta1.NetworkPolicyPeer{
   698  								{
   699  									NamespaceSelector: &metav1.LabelSelector{
   700  										MatchLabels: map[string]string{"Egress": "only"},
   701  									},
   702  								},
   703  							},
   704  						},
   705  					},
   706  					PolicyTypes: []extensionsv1beta1.PolicyType{extensionsv1beta1.PolicyTypeEgress},
   707  				},
   708  			},
   709  		},
   710  	}
   711  
   712  	for i, test := range tests {
   713  		original := test.original
   714  		expected := test.expected
   715  		obj2 := roundTrip(t, runtime.Object(original))
   716  		got, ok := obj2.(*extensionsv1beta1.NetworkPolicy)
   717  		if !ok {
   718  			t.Errorf("(%d) unexpected object: %v", i, got)
   719  			t.FailNow()
   720  		}
   721  		if !apiequality.Semantic.DeepEqual(got.Spec, expected.Spec) {
   722  			t.Errorf("(%d) got different than expected\ngot:\n\t%+v\nexpected:\n\t%+v", i, got.Spec, expected.Spec)
   723  		}
   724  	}
   725  }
   726  
   727  func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
   728  	data, err := runtime.Encode(legacyscheme.Codecs.LegacyCodec(SchemeGroupVersion), obj)
   729  	if err != nil {
   730  		t.Errorf("%v\n %#v", err, obj)
   731  		return nil
   732  	}
   733  	obj2, err := runtime.Decode(legacyscheme.Codecs.UniversalDecoder(), data)
   734  	if err != nil {
   735  		t.Errorf("%v\nData: %s\nSource: %#v", err, string(data), obj)
   736  		return nil
   737  	}
   738  	obj3 := reflect.New(reflect.TypeOf(obj).Elem()).Interface().(runtime.Object)
   739  	err = legacyscheme.Scheme.Convert(obj2, obj3, nil)
   740  	if err != nil {
   741  		t.Errorf("%v\nSource: %#v", err, obj2)
   742  		return nil
   743  	}
   744  	return obj3
   745  }
   746  

View as plain text