istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/networking/core/match/match_test.go (about)

     1  package match
     2  
     3  // Copyright Istio Authors
     4  //
     5  // Licensed under the Apache License, Version 2.0 (the "License");
     6  // you may not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing, software
    12  // distributed under the License is distributed on an "AS IS" BASIS,
    13  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14  // See the License for the specific language governing permissions and
    15  // limitations under the License.
    16  
    17  import (
    18  	"testing"
    19  
    20  	matcher "github.com/cncf/xds/go/xds/type/matcher/v3"
    21  	"github.com/google/go-cmp/cmp"
    22  
    23  	"istio.io/istio/pkg/util/protomarshal"
    24  )
    25  
    26  func TestCleanupEmptyMaps(t *testing.T) {
    27  	tc := []struct {
    28  		name  string
    29  		given func() Mapper
    30  		want  func() *matcher.Matcher
    31  	}{
    32  		{
    33  			name: "empty map at depth = 0",
    34  			given: func() Mapper {
    35  				// root (dest port):
    36  				//   <no matches>
    37  				//   fallback (dest ip):
    38  				//     1.2.3.4: chain
    39  				fallback := NewDestinationIP()
    40  				fallback.Map["1.2.3.4"] = ToChain("chain")
    41  
    42  				root := NewDestinationPort()
    43  				root.OnNoMatch = ToMatcher(fallback.Matcher)
    44  				return root
    45  			},
    46  			want: func() *matcher.Matcher {
    47  				// root (dest ip):
    48  				//   1.2.3.4: chain
    49  
    50  				// fallback becomes root
    51  				want := NewDestinationIP()
    52  				want.Map["1.2.3.4"] = ToChain("chain")
    53  				return want.Matcher
    54  			},
    55  		},
    56  		{
    57  			name: "empty map at depth = 1",
    58  			given: func() Mapper {
    59  				// root (dest port)
    60  				//   15001:
    61  				//     inner (dest ip):
    62  				//       <no matches>
    63  				//       fallback: chain
    64  				inner := NewDestinationIP()
    65  				inner.OnNoMatch = ToChain("chain")
    66  
    67  				root := NewDestinationPort()
    68  				root.Map["15001"] = ToMatcher(inner.Matcher)
    69  				return root
    70  			},
    71  			want: func() *matcher.Matcher {
    72  				// dest port
    73  				// 15001: chain
    74  				want := NewDestinationPort()
    75  				want.Map["15001"] = ToChain("chain")
    76  				return want.Matcher
    77  			},
    78  		},
    79  		{
    80  			name: "empty map at depth = 0 and 1",
    81  			given: func() Mapper {
    82  				// root (dest port)
    83  				//   fallback:
    84  				//     inner (dest ip):
    85  				//       <no matches>
    86  				//       fallback: chain
    87  				leaf := NewSourceIP()
    88  				leaf.Map["1.2.3.4"] = ToChain("chain")
    89  
    90  				inner := NewDestinationIP()
    91  				inner.OnNoMatch = ToMatcher(leaf.Matcher)
    92  
    93  				root := NewDestinationPort()
    94  				root.OnNoMatch = ToMatcher(inner.Matcher)
    95  				return root
    96  			},
    97  			want: func() *matcher.Matcher {
    98  				// src port
    99  				// 15001: chain
   100  				want := NewSourceIP()
   101  				want.Map["1.2.3.4"] = ToChain("chain")
   102  				return want.Matcher
   103  			},
   104  		},
   105  		{
   106  			name: "empty map at depths = 1 and 2",
   107  			given: func() Mapper {
   108  				// root (dest port)
   109  				//   15001:
   110  				//     middle (dest ip):
   111  				//       fallback:
   112  				//         inner (src ip):
   113  				//           fallback: chain
   114  				inner := NewSourceIP()
   115  				inner.OnNoMatch = ToChain("chain")
   116  
   117  				middle := NewDestinationIP()
   118  				middle.OnNoMatch = ToMatcher(inner.Matcher)
   119  
   120  				root := NewDestinationPort()
   121  				root.Map["15001"] = ToMatcher(middle.Matcher)
   122  				return root
   123  			},
   124  			want: func() *matcher.Matcher {
   125  				// dest port
   126  				// 15001: chain
   127  				want := NewDestinationPort()
   128  				want.Map["15001"] = ToChain("chain")
   129  				return want.Matcher
   130  			},
   131  		},
   132  	}
   133  
   134  	for _, tt := range tc {
   135  		t.Run(tt.name, func(t *testing.T) {
   136  			got := tt.given().BuildMatcher()
   137  			haveJSON, _ := protomarshal.ToJSONWithIndent(got, "  ")
   138  			wantJSON, _ := protomarshal.ToJSONWithIndent(tt.want(), "  ")
   139  
   140  			if diff := cmp.Diff(haveJSON, wantJSON, cmp.AllowUnexported()); diff != "" {
   141  				t.Error(diff)
   142  			}
   143  		})
   144  	}
   145  }