istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pilot/pkg/model/validation_test.go (about)

     1  // Copyright Istio Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package model
    16  
    17  import (
    18  	"testing"
    19  
    20  	"istio.io/istio/pkg/config/labels"
    21  	"istio.io/istio/pkg/config/protocol"
    22  )
    23  
    24  var service1 = &Service{
    25  	Hostname:       "one.service.com",
    26  	DefaultAddress: "192.168.3.1", // VIP
    27  	Ports: PortList{
    28  		&Port{Name: "http", Port: 81, Protocol: protocol.HTTP},
    29  		&Port{Name: "http-alt", Port: 8081, Protocol: protocol.HTTP},
    30  	},
    31  }
    32  
    33  func TestServiceInstanceValidate(t *testing.T) {
    34  	endpointWithLabels := func(lbls labels.Instance) *IstioEndpoint {
    35  		return &IstioEndpoint{
    36  			Address:      "192.168.1.1",
    37  			EndpointPort: 10001,
    38  			Labels:       lbls,
    39  		}
    40  	}
    41  
    42  	cases := []struct {
    43  		name     string
    44  		instance *ServiceInstance
    45  		valid    bool
    46  	}{
    47  		{
    48  			name: "nil service",
    49  			instance: &ServiceInstance{
    50  				Endpoint: endpointWithLabels(labels.Instance{}),
    51  			},
    52  		},
    53  		{
    54  			name: "bad label",
    55  			instance: &ServiceInstance{
    56  				Service:  service1,
    57  				Endpoint: endpointWithLabels(labels.Instance{"*": "-"}),
    58  			},
    59  		},
    60  		{
    61  			name: "invalid service",
    62  			instance: &ServiceInstance{
    63  				Service:  &Service{},
    64  				Endpoint: &IstioEndpoint{},
    65  			},
    66  		},
    67  		{
    68  			name: "invalid endpoint port and service port",
    69  			instance: &ServiceInstance{
    70  				Service: service1,
    71  				Endpoint: &IstioEndpoint{
    72  					Address:      "192.168.1.2",
    73  					EndpointPort: 1000000,
    74  				},
    75  			},
    76  		},
    77  		{
    78  			name: "endpoint missing service port",
    79  			instance: &ServiceInstance{
    80  				Service: service1,
    81  				ServicePort: &Port{
    82  					Name:     service1.Ports[1].Name + "-extra",
    83  					Port:     service1.Ports[1].Port,
    84  					Protocol: service1.Ports[1].Protocol,
    85  				},
    86  				Endpoint: &IstioEndpoint{
    87  					Address:      "192.168.1.2",
    88  					EndpointPort: uint32(service1.Ports[1].Port),
    89  				},
    90  			},
    91  		},
    92  		{
    93  			name: "endpoint port and protocol mismatch",
    94  			instance: &ServiceInstance{
    95  				Service: service1,
    96  				ServicePort: &Port{
    97  					Name:     "http",
    98  					Port:     service1.Ports[1].Port + 1,
    99  					Protocol: protocol.GRPC,
   100  				},
   101  				Endpoint: &IstioEndpoint{
   102  					Address:      "192.168.1.2",
   103  					EndpointPort: uint32(service1.Ports[1].Port),
   104  				},
   105  			},
   106  		},
   107  	}
   108  	for _, c := range cases {
   109  		t.Run(c.name, func(t *testing.T) {
   110  			if got := c.instance.Validate(); (got == nil) != c.valid {
   111  				t.Fatalf("%s failed: got valid=%v but wanted valid=%v: %v", c.name, got == nil, c.valid, got)
   112  			}
   113  		})
   114  	}
   115  }
   116  
   117  func TestServiceValidate(t *testing.T) {
   118  	ports := PortList{
   119  		{Name: "http", Port: 80, Protocol: protocol.HTTP},
   120  		{Name: "http-alt", Port: 8080, Protocol: protocol.HTTP},
   121  	}
   122  	badPorts := PortList{
   123  		{Port: 80, Protocol: protocol.HTTP},
   124  		{Name: "http-alt^", Port: 8080, Protocol: protocol.HTTP},
   125  		{Name: "http", Port: -80, Protocol: protocol.HTTP},
   126  	}
   127  
   128  	address := "192.168.1.1"
   129  
   130  	cases := []struct {
   131  		name    string
   132  		service *Service
   133  		valid   bool
   134  	}{
   135  		{
   136  			name: "empty hostname",
   137  			service: &Service{
   138  				Hostname:       "",
   139  				DefaultAddress: address,
   140  				Ports:          ports,
   141  			},
   142  		},
   143  		{
   144  			name: "invalid hostname",
   145  			service: &Service{
   146  				Hostname:       "hostname.^.com",
   147  				DefaultAddress: address,
   148  				Ports:          ports,
   149  			},
   150  		},
   151  		{
   152  			name: "empty ports",
   153  			service: &Service{
   154  				Hostname:       "hostname",
   155  				DefaultAddress: address,
   156  			},
   157  		},
   158  		{
   159  			name: "bad ports",
   160  			service: &Service{
   161  				Hostname:       "hostname",
   162  				DefaultAddress: address,
   163  				Ports:          badPorts,
   164  			},
   165  		},
   166  	}
   167  	for _, c := range cases {
   168  		if got := c.service.Validate(); (got == nil) != c.valid {
   169  			t.Errorf("%s failed: got valid=%v but wanted valid=%v: %v", c.name, got == nil, c.valid, got)
   170  		}
   171  	}
   172  }