k8s.io/kubernetes@v1.29.3/pkg/api/v1/endpoints/util_test.go (about)

     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 endpoints
    18  
    19  import (
    20  	"reflect"
    21  	"testing"
    22  
    23  	v1 "k8s.io/api/core/v1"
    24  	"k8s.io/apimachinery/pkg/types"
    25  	"k8s.io/apimachinery/pkg/util/dump"
    26  )
    27  
    28  func podRef(uid string) *v1.ObjectReference {
    29  	ref := v1.ObjectReference{UID: types.UID(uid)}
    30  	return &ref
    31  }
    32  
    33  func TestPackSubsets(t *testing.T) {
    34  	// The downside of table-driven tests is that some things have to live outside the table.
    35  	fooObjRef := v1.ObjectReference{Name: "foo"}
    36  	barObjRef := v1.ObjectReference{Name: "bar"}
    37  
    38  	testCases := []struct {
    39  		name   string
    40  		given  []v1.EndpointSubset
    41  		expect []v1.EndpointSubset
    42  	}{
    43  		{
    44  			name:   "empty everything",
    45  			given:  []v1.EndpointSubset{{Addresses: []v1.EndpointAddress{}, Ports: []v1.EndpointPort{}}},
    46  			expect: []v1.EndpointSubset{},
    47  		}, {
    48  			name:   "empty addresses",
    49  			given:  []v1.EndpointSubset{{Addresses: []v1.EndpointAddress{}, Ports: []v1.EndpointPort{{Port: 111}}}},
    50  			expect: []v1.EndpointSubset{},
    51  		}, {
    52  			name:   "empty ports",
    53  			given:  []v1.EndpointSubset{{Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, Ports: []v1.EndpointPort{}}},
    54  			expect: []v1.EndpointSubset{{Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, Ports: nil}},
    55  		}, {
    56  			name:   "empty ports",
    57  			given:  []v1.EndpointSubset{{NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, Ports: []v1.EndpointPort{}}},
    58  			expect: []v1.EndpointSubset{{NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}}, Ports: nil}},
    59  		}, {
    60  			name: "one set, one ip, one port",
    61  			given: []v1.EndpointSubset{{
    62  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
    63  				Ports:     []v1.EndpointPort{{Port: 111}},
    64  			}},
    65  			expect: []v1.EndpointSubset{{
    66  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
    67  				Ports:     []v1.EndpointPort{{Port: 111}},
    68  			}},
    69  		}, {
    70  			name: "one set, one ip, one port (IPv6)",
    71  			given: []v1.EndpointSubset{{
    72  				Addresses: []v1.EndpointAddress{{IP: "beef::1:2:3:4"}},
    73  				Ports:     []v1.EndpointPort{{Port: 111}},
    74  			}},
    75  			expect: []v1.EndpointSubset{{
    76  				Addresses: []v1.EndpointAddress{{IP: "beef::1:2:3:4"}},
    77  				Ports:     []v1.EndpointPort{{Port: 111}},
    78  			}},
    79  		}, {
    80  			name: "one set, one notReady ip, one port",
    81  			given: []v1.EndpointSubset{{
    82  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
    83  				Ports:             []v1.EndpointPort{{Port: 111}},
    84  			}},
    85  			expect: []v1.EndpointSubset{{
    86  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
    87  				Ports:             []v1.EndpointPort{{Port: 111}},
    88  			}},
    89  		}, {
    90  			name: "one set, one ip, one UID, one port",
    91  			given: []v1.EndpointSubset{{
    92  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
    93  				Ports:     []v1.EndpointPort{{Port: 111}},
    94  			}},
    95  			expect: []v1.EndpointSubset{{
    96  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
    97  				Ports:     []v1.EndpointPort{{Port: 111}},
    98  			}},
    99  		}, {
   100  			name: "one set, one notReady ip, one UID, one port",
   101  			given: []v1.EndpointSubset{{
   102  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
   103  				Ports:             []v1.EndpointPort{{Port: 111}},
   104  			}},
   105  			expect: []v1.EndpointSubset{{
   106  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
   107  				Ports:             []v1.EndpointPort{{Port: 111}},
   108  			}},
   109  		}, {
   110  			name: "one set, one ip, empty UID, one port",
   111  			given: []v1.EndpointSubset{{
   112  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("")}},
   113  				Ports:     []v1.EndpointPort{{Port: 111}},
   114  			}},
   115  			expect: []v1.EndpointSubset{{
   116  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("")}},
   117  				Ports:     []v1.EndpointPort{{Port: 111}},
   118  			}},
   119  		}, {
   120  			name: "one set, one notReady ip, empty UID, one port",
   121  			given: []v1.EndpointSubset{{
   122  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("")}},
   123  				Ports:             []v1.EndpointPort{{Port: 111}},
   124  			}},
   125  			expect: []v1.EndpointSubset{{
   126  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("")}},
   127  				Ports:             []v1.EndpointPort{{Port: 111}},
   128  			}},
   129  		}, {
   130  			name: "one set, two ips, one port",
   131  			given: []v1.EndpointSubset{{
   132  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "5.6.7.8"}},
   133  				Ports:     []v1.EndpointPort{{Port: 111}},
   134  			}},
   135  			expect: []v1.EndpointSubset{{
   136  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "5.6.7.8"}},
   137  				Ports:     []v1.EndpointPort{{Port: 111}},
   138  			}},
   139  		}, {
   140  			name: "one set, two mixed ips, one port",
   141  			given: []v1.EndpointSubset{{
   142  				Addresses:         []v1.EndpointAddress{{IP: "1.2.3.4"}},
   143  				NotReadyAddresses: []v1.EndpointAddress{{IP: "5.6.7.8"}},
   144  				Ports:             []v1.EndpointPort{{Port: 111}},
   145  			}},
   146  			expect: []v1.EndpointSubset{{
   147  				Addresses:         []v1.EndpointAddress{{IP: "1.2.3.4"}},
   148  				NotReadyAddresses: []v1.EndpointAddress{{IP: "5.6.7.8"}},
   149  				Ports:             []v1.EndpointPort{{Port: 111}},
   150  			}},
   151  		}, {
   152  			name: "one set, two duplicate ips, one port, notReady is covered by ready",
   153  			given: []v1.EndpointSubset{{
   154  				Addresses:         []v1.EndpointAddress{{IP: "1.2.3.4"}},
   155  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   156  				Ports:             []v1.EndpointPort{{Port: 111}},
   157  			}},
   158  			expect: []v1.EndpointSubset{{
   159  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   160  				Ports:             []v1.EndpointPort{{Port: 111}},
   161  			}},
   162  		}, {
   163  			name: "one set, one ip, two ports",
   164  			given: []v1.EndpointSubset{{
   165  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   166  				Ports:     []v1.EndpointPort{{Port: 111}, {Port: 222}},
   167  			}},
   168  			expect: []v1.EndpointSubset{{
   169  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   170  				Ports:     []v1.EndpointPort{{Port: 111}, {Port: 222}},
   171  			}},
   172  		}, {
   173  			name: "one set, dup ips, one port",
   174  			given: []v1.EndpointSubset{{
   175  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "1.2.3.4"}},
   176  				Ports:     []v1.EndpointPort{{Port: 111}},
   177  			}},
   178  			expect: []v1.EndpointSubset{{
   179  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   180  				Ports:     []v1.EndpointPort{{Port: 111}},
   181  			}},
   182  		}, {
   183  			name: "one set, dup ips, one port (IPv6)",
   184  			given: []v1.EndpointSubset{{
   185  				Addresses: []v1.EndpointAddress{{IP: "beef::1"}, {IP: "beef::1"}},
   186  				Ports:     []v1.EndpointPort{{Port: 111}},
   187  			}},
   188  			expect: []v1.EndpointSubset{{
   189  				Addresses: []v1.EndpointAddress{{IP: "beef::1"}},
   190  				Ports:     []v1.EndpointPort{{Port: 111}},
   191  			}},
   192  		}, {
   193  			name: "one set, dup ips with target-refs, one port",
   194  			given: []v1.EndpointSubset{{
   195  				Addresses: []v1.EndpointAddress{
   196  					{IP: "1.2.3.4", TargetRef: &fooObjRef},
   197  					{IP: "1.2.3.4", TargetRef: &barObjRef},
   198  				},
   199  				Ports: []v1.EndpointPort{{Port: 111}},
   200  			}},
   201  			expect: []v1.EndpointSubset{{
   202  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: &fooObjRef}},
   203  				Ports:     []v1.EndpointPort{{Port: 111}},
   204  			}},
   205  		}, {
   206  			name: "one set, dup mixed ips with target-refs, one port",
   207  			given: []v1.EndpointSubset{{
   208  				Addresses: []v1.EndpointAddress{
   209  					{IP: "1.2.3.4", TargetRef: &fooObjRef},
   210  				},
   211  				NotReadyAddresses: []v1.EndpointAddress{
   212  					{IP: "1.2.3.4", TargetRef: &barObjRef},
   213  				},
   214  				Ports: []v1.EndpointPort{{Port: 111}},
   215  			}},
   216  			expect: []v1.EndpointSubset{{
   217  				// finding the same address twice is considered an error on input, only the first address+port
   218  				// reference is preserved
   219  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: &fooObjRef}},
   220  				Ports:             []v1.EndpointPort{{Port: 111}},
   221  			}},
   222  		}, {
   223  			name: "one set, one ip, dup ports",
   224  			given: []v1.EndpointSubset{{
   225  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   226  				Ports:     []v1.EndpointPort{{Port: 111}, {Port: 111}},
   227  			}},
   228  			expect: []v1.EndpointSubset{{
   229  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   230  				Ports:     []v1.EndpointPort{{Port: 111}},
   231  			}},
   232  		}, {
   233  			name: "two sets, dup ip, dup port",
   234  			given: []v1.EndpointSubset{{
   235  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   236  				Ports:     []v1.EndpointPort{{Port: 111}},
   237  			}, {
   238  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   239  				Ports:     []v1.EndpointPort{{Port: 111}},
   240  			}},
   241  			expect: []v1.EndpointSubset{{
   242  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   243  				Ports:     []v1.EndpointPort{{Port: 111}},
   244  			}},
   245  		}, {
   246  			name: "two sets, dup mixed ip, dup port",
   247  			given: []v1.EndpointSubset{{
   248  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   249  				Ports:     []v1.EndpointPort{{Port: 111}},
   250  			}, {
   251  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   252  				Ports:             []v1.EndpointPort{{Port: 111}},
   253  			}},
   254  			expect: []v1.EndpointSubset{{
   255  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   256  				Ports:             []v1.EndpointPort{{Port: 111}},
   257  			}},
   258  		}, {
   259  			name: "two sets, dup ip, two ports",
   260  			given: []v1.EndpointSubset{{
   261  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   262  				Ports:     []v1.EndpointPort{{Port: 111}},
   263  			}, {
   264  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   265  				Ports:     []v1.EndpointPort{{Port: 222}},
   266  			}},
   267  			expect: []v1.EndpointSubset{{
   268  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   269  				Ports:     []v1.EndpointPort{{Port: 111}, {Port: 222}},
   270  			}},
   271  		}, {
   272  			name: "two sets, dup ip, dup uids, two ports",
   273  			given: []v1.EndpointSubset{{
   274  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
   275  				Ports:     []v1.EndpointPort{{Port: 111}},
   276  			}, {
   277  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
   278  				Ports:     []v1.EndpointPort{{Port: 222}},
   279  			}},
   280  			expect: []v1.EndpointSubset{{
   281  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
   282  				Ports:     []v1.EndpointPort{{Port: 111}, {Port: 222}},
   283  			}},
   284  		}, {
   285  			name: "two sets, dup mixed ip, dup uids, two ports",
   286  			given: []v1.EndpointSubset{{
   287  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
   288  				Ports:     []v1.EndpointPort{{Port: 111}},
   289  			}, {
   290  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
   291  				Ports:             []v1.EndpointPort{{Port: 222}},
   292  			}},
   293  			expect: []v1.EndpointSubset{{
   294  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
   295  				Ports:     []v1.EndpointPort{{Port: 111}},
   296  			}, {
   297  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
   298  				Ports:             []v1.EndpointPort{{Port: 222}},
   299  			}},
   300  		}, {
   301  			name: "two sets, two ips, dup port",
   302  			given: []v1.EndpointSubset{{
   303  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   304  				Ports:     []v1.EndpointPort{{Port: 111}},
   305  			}, {
   306  				Addresses: []v1.EndpointAddress{{IP: "5.6.7.8"}},
   307  				Ports:     []v1.EndpointPort{{Port: 111}},
   308  			}},
   309  			expect: []v1.EndpointSubset{{
   310  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "5.6.7.8"}},
   311  				Ports:     []v1.EndpointPort{{Port: 111}},
   312  			}},
   313  		}, {
   314  			name: "two set, dup ip, two uids, dup ports",
   315  			given: []v1.EndpointSubset{{
   316  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
   317  				Ports:     []v1.EndpointPort{{Port: 111}},
   318  			}, {
   319  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-2")}},
   320  				Ports:     []v1.EndpointPort{{Port: 111}},
   321  			}},
   322  			expect: []v1.EndpointSubset{{
   323  				Addresses: []v1.EndpointAddress{
   324  					{IP: "1.2.3.4", TargetRef: podRef("uid-1")},
   325  					{IP: "1.2.3.4", TargetRef: podRef("uid-2")},
   326  				},
   327  				Ports: []v1.EndpointPort{{Port: 111}},
   328  			}},
   329  		}, {
   330  			name: "two set, dup ip, with and without uid, dup ports",
   331  			given: []v1.EndpointSubset{{
   332  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   333  				Ports:     []v1.EndpointPort{{Port: 111}},
   334  			}, {
   335  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-2")}},
   336  				Ports:     []v1.EndpointPort{{Port: 111}},
   337  			}},
   338  			expect: []v1.EndpointSubset{{
   339  				Addresses: []v1.EndpointAddress{
   340  					{IP: "1.2.3.4"},
   341  					{IP: "1.2.3.4", TargetRef: podRef("uid-2")},
   342  				},
   343  				Ports: []v1.EndpointPort{{Port: 111}},
   344  			}},
   345  		}, {
   346  			name: "two sets, two ips, two dup ip with uid, dup port, wrong order",
   347  			given: []v1.EndpointSubset{{
   348  				Addresses: []v1.EndpointAddress{{IP: "5.6.7.8"}},
   349  				Ports:     []v1.EndpointPort{{Port: 111}},
   350  			}, {
   351  				Addresses: []v1.EndpointAddress{{IP: "5.6.7.8", TargetRef: podRef("uid-1")}},
   352  				Ports:     []v1.EndpointPort{{Port: 111}},
   353  			}, {
   354  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
   355  				Ports:     []v1.EndpointPort{{Port: 111}},
   356  			}, {
   357  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   358  				Ports:     []v1.EndpointPort{{Port: 111}},
   359  			}},
   360  			expect: []v1.EndpointSubset{{
   361  				Addresses: []v1.EndpointAddress{
   362  					{IP: "1.2.3.4"},
   363  					{IP: "1.2.3.4", TargetRef: podRef("uid-1")},
   364  					{IP: "5.6.7.8"},
   365  					{IP: "5.6.7.8", TargetRef: podRef("uid-1")},
   366  				},
   367  				Ports: []v1.EndpointPort{{Port: 111}},
   368  			}},
   369  		}, {
   370  			name: "two sets, two mixed ips, two dup ip with uid, dup port, wrong order, ends up with split addresses",
   371  			given: []v1.EndpointSubset{{
   372  				Addresses: []v1.EndpointAddress{{IP: "5.6.7.8"}},
   373  				Ports:     []v1.EndpointPort{{Port: 111}},
   374  			}, {
   375  				NotReadyAddresses: []v1.EndpointAddress{{IP: "5.6.7.8", TargetRef: podRef("uid-1")}},
   376  				Ports:             []v1.EndpointPort{{Port: 111}},
   377  			}, {
   378  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4", TargetRef: podRef("uid-1")}},
   379  				Ports:             []v1.EndpointPort{{Port: 111}},
   380  			}, {
   381  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   382  				Ports:             []v1.EndpointPort{{Port: 111}},
   383  			}},
   384  			expect: []v1.EndpointSubset{{
   385  				Addresses: []v1.EndpointAddress{
   386  					{IP: "5.6.7.8"},
   387  				},
   388  				NotReadyAddresses: []v1.EndpointAddress{
   389  					{IP: "1.2.3.4"},
   390  					{IP: "1.2.3.4", TargetRef: podRef("uid-1")},
   391  					{IP: "5.6.7.8", TargetRef: podRef("uid-1")},
   392  				},
   393  				Ports: []v1.EndpointPort{{Port: 111}},
   394  			}},
   395  		}, {
   396  			name: "two sets, two ips, two ports",
   397  			given: []v1.EndpointSubset{{
   398  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   399  				Ports:     []v1.EndpointPort{{Port: 111}},
   400  			}, {
   401  				Addresses: []v1.EndpointAddress{{IP: "5.6.7.8"}},
   402  				Ports:     []v1.EndpointPort{{Port: 222}},
   403  			}},
   404  			expect: []v1.EndpointSubset{{
   405  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   406  				Ports:     []v1.EndpointPort{{Port: 111}},
   407  			}, {
   408  				Addresses: []v1.EndpointAddress{{IP: "5.6.7.8"}},
   409  				Ports:     []v1.EndpointPort{{Port: 222}},
   410  			}},
   411  		}, {
   412  			name: "four sets, three ips, three ports, jumbled",
   413  			given: []v1.EndpointSubset{{
   414  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   415  				Ports:     []v1.EndpointPort{{Port: 111}},
   416  			}, {
   417  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.5"}},
   418  				Ports:     []v1.EndpointPort{{Port: 222}},
   419  			}, {
   420  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.6"}},
   421  				Ports:     []v1.EndpointPort{{Port: 111}},
   422  			}, {
   423  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.5"}},
   424  				Ports:     []v1.EndpointPort{{Port: 333}},
   425  			}},
   426  			expect: []v1.EndpointSubset{{
   427  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "1.2.3.6"}},
   428  				Ports:     []v1.EndpointPort{{Port: 111}},
   429  			}, {
   430  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.5"}},
   431  				Ports:     []v1.EndpointPort{{Port: 222}, {Port: 333}},
   432  			}},
   433  		}, {
   434  			name: "four sets, three mixed ips, three ports, jumbled",
   435  			given: []v1.EndpointSubset{{
   436  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}},
   437  				Ports:     []v1.EndpointPort{{Port: 111}},
   438  			}, {
   439  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.5"}},
   440  				Ports:             []v1.EndpointPort{{Port: 222}},
   441  			}, {
   442  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.6"}},
   443  				Ports:     []v1.EndpointPort{{Port: 111}},
   444  			}, {
   445  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.5"}},
   446  				Ports:             []v1.EndpointPort{{Port: 333}},
   447  			}},
   448  			expect: []v1.EndpointSubset{{
   449  				Addresses: []v1.EndpointAddress{{IP: "1.2.3.4"}, {IP: "1.2.3.6"}},
   450  				Ports:     []v1.EndpointPort{{Port: 111}},
   451  			}, {
   452  				NotReadyAddresses: []v1.EndpointAddress{{IP: "1.2.3.5"}},
   453  				Ports:             []v1.EndpointPort{{Port: 222}, {Port: 333}},
   454  			}},
   455  		},
   456  	}
   457  
   458  	for _, tc := range testCases {
   459  		result := RepackSubsets(tc.given)
   460  		if !reflect.DeepEqual(result, SortSubsets(tc.expect)) {
   461  			t.Errorf("case %q: expected %s, got %s", tc.name, dump.Pretty(SortSubsets(tc.expect)), dump.Pretty(result))
   462  		}
   463  	}
   464  }