dubbo.apache.org/dubbo-go/v3@v3.1.1/remoting/xds/ewatcher/ewatcher_test.go (about)

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one or more
     3   * contributor license agreements.  See the NOTICE file distributed with
     4   * this work for additional information regarding copyright ownership.
     5   * The ASF licenses this file to You under the Apache License, Version 2.0
     6   * (the "License"); you may not use this file except in compliance with
     7   * the License.  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  
    18  package ewatcher
    19  
    20  import (
    21  	"sync"
    22  	"testing"
    23  )
    24  
    25  import (
    26  	"github.com/stretchr/testify/assert"
    27  )
    28  
    29  import (
    30  	"dubbo.apache.org/dubbo-go/v3/common/constant"
    31  	"dubbo.apache.org/dubbo-go/v3/registry"
    32  	mockRegistry "dubbo.apache.org/dubbo-go/v3/registry/mocks"
    33  	"dubbo.apache.org/dubbo-go/v3/remoting"
    34  	"dubbo.apache.org/dubbo-go/v3/xds/client/resource"
    35  )
    36  
    37  const (
    38  	clusterNameFoo   = "outbound|20000||dubbo-go-app.svc.cluster.local"
    39  	hostAddrFoo      = "dubbo-go-app.svc.cluster.local:20000"
    40  	hostNameFoo      = "dubbo-go-app.svc.cluster.local"
    41  	hostPortFoo      = "20000"
    42  	interfaceNameFoo = "api.Greeter"
    43  	serviceKeyFoo    = "provider::api.Greeter"
    44  )
    45  
    46  var (
    47  	endpointHealthyUpdate = &resource.EndpointsUpdate{
    48  		Localities: []resource.Locality{
    49  			{
    50  				Endpoints: []resource.Endpoint{
    51  					{
    52  						Address:      hostAddrFoo,
    53  						HealthStatus: resource.EndpointHealthStatusHealthy,
    54  					},
    55  				},
    56  			},
    57  		},
    58  	}
    59  
    60  	endpointUnHealthyUpdate = &resource.EndpointsUpdate{
    61  		Localities: []resource.Locality{
    62  			{
    63  				Endpoints: []resource.Endpoint{
    64  					{
    65  						Address:      hostAddrFoo,
    66  						HealthStatus: resource.EndpointHealthStatusUnhealthy,
    67  					},
    68  				},
    69  			},
    70  		},
    71  	}
    72  
    73  	endpointUnknownUpdate = &resource.EndpointsUpdate{
    74  		Localities: []resource.Locality{
    75  			{
    76  				Endpoints: []resource.Endpoint{
    77  					{
    78  						Address:      hostAddrFoo,
    79  						HealthStatus: resource.EndpointHealthStatusUnknown,
    80  					},
    81  				},
    82  			},
    83  		},
    84  	}
    85  )
    86  
    87  func TestNewEWatcherAndSetCancelFunction(t *testing.T) {
    88  	hostAddrListenerMapFoo := map[string]map[string]registry.NotifyListener{
    89  		hostAddrFoo: {
    90  			serviceKeyFoo: &mockRegistry.NotifyListener{},
    91  		},
    92  	}
    93  	ewatcher := NewEndpointWatcherCtxImpl(clusterNameFoo, hostAddrFoo, interfaceNameFoo, &sync.RWMutex{}, hostAddrListenerMapFoo)
    94  	assert.NotNil(t, ewatcher)
    95  
    96  	cancel := func() {}
    97  	ewatcher.SetCancelFunction(cancel)
    98  }
    99  
   100  func TestNewEWatcherHandle(t *testing.T) {
   101  	mockListener := newMockListener()
   102  	hostAddrListenerMapFoo := map[string]map[string]registry.NotifyListener{
   103  		hostAddrFoo: {
   104  			serviceKeyFoo: mockListener,
   105  		},
   106  	}
   107  	ewatcher := NewEndpointWatcherCtxImpl(clusterNameFoo, hostAddrFoo, interfaceNameFoo, &sync.RWMutex{}, hostAddrListenerMapFoo)
   108  	assert.NotNil(t, ewatcher)
   109  
   110  	ewatcher.Handle(*endpointHealthyUpdate, nil)
   111  	assert.Equal(t, 1, len(mockListener.Events))
   112  	assert.Equal(t, remoting.EventTypeUpdate, mockListener.Events[0].Action)
   113  	assert.Equal(t, hostNameFoo, mockListener.Events[0].Service.Ip)
   114  	assert.Equal(t, hostPortFoo, mockListener.Events[0].Service.Port)
   115  
   116  	ewatcher.Handle(*endpointUnknownUpdate, nil)
   117  	assert.Equal(t, 2, len(mockListener.Events))
   118  	assert.Equal(t, remoting.EventTypeUpdate, mockListener.Events[1].Action)
   119  	assert.Equal(t, hostNameFoo, mockListener.Events[1].Service.Ip)
   120  	assert.Equal(t, hostPortFoo, mockListener.Events[1].Service.Port)
   121  
   122  	ewatcher.Handle(*endpointUnHealthyUpdate, nil)
   123  	assert.Equal(t, 3, len(mockListener.Events))
   124  	assert.Equal(t, remoting.EventTypeDel, mockListener.Events[2].Action)
   125  	assert.Equal(t, hostNameFoo, mockListener.Events[2].Service.Ip)
   126  	assert.Equal(t, hostPortFoo, mockListener.Events[2].Service.Port)
   127  
   128  }
   129  
   130  func TestNewEWatcherDestroy(t *testing.T) {
   131  	mockListener := newMockListener()
   132  	hostAddrListenerMapFoo := map[string]map[string]registry.NotifyListener{
   133  		hostAddrFoo: {
   134  			serviceKeyFoo: mockListener,
   135  		},
   136  	}
   137  	ewatcher := NewEndpointWatcherCtxImpl(clusterNameFoo, hostAddrFoo, interfaceNameFoo, &sync.RWMutex{}, hostAddrListenerMapFoo)
   138  	assert.NotNil(t, ewatcher)
   139  
   140  	ewatcher.SetCancelFunction(func() {})
   141  	ewatcher.Destroy()
   142  
   143  	assert.Equal(t, len(mockListener.Events), 1)
   144  	assert.Equal(t, mockListener.Events[0].Action, remoting.EventTypeDel)
   145  	assert.Equal(t, mockListener.Events[0].Service.Location, constant.MeshAnyAddrMatcher)
   146  	assert.Equal(t, mockListener.Events[0].Service.GetParam(constant.MeshSubsetKey, ""), "")
   147  	assert.Equal(t, mockListener.Events[0].Service.GetParam(constant.MeshClusterIDKey, ""), clusterNameFoo)
   148  	assert.Equal(t, mockListener.Events[0].Service.GetParam(constant.MeshHostAddrKey, ""), hostAddrFoo)
   149  }
   150  
   151  func TestNewEWatcherDestroyWithNilCancel(t *testing.T) {
   152  	mockListener := newMockListener()
   153  	hostAddrListenerMapFoo := map[string]map[string]registry.NotifyListener{
   154  		hostAddrFoo: {
   155  			serviceKeyFoo: mockListener,
   156  		},
   157  	}
   158  	ewatcher := NewEndpointWatcherCtxImpl(clusterNameFoo, hostAddrFoo, interfaceNameFoo, &sync.RWMutex{}, hostAddrListenerMapFoo)
   159  	assert.NotNil(t, ewatcher)
   160  
   161  	// test nil cancel
   162  	ewatcher.Destroy()
   163  
   164  	assert.Equal(t, len(mockListener.Events), 1)
   165  	assert.Equal(t, mockListener.Events[0].Action, remoting.EventTypeDel)
   166  	assert.Equal(t, mockListener.Events[0].Service.Location, constant.MeshAnyAddrMatcher)
   167  	assert.Equal(t, mockListener.Events[0].Service.GetParam(constant.MeshSubsetKey, ""), "")
   168  	assert.Equal(t, mockListener.Events[0].Service.GetParam(constant.MeshClusterIDKey, ""), clusterNameFoo)
   169  	assert.Equal(t, mockListener.Events[0].Service.GetParam(constant.MeshHostAddrKey, ""), hostAddrFoo)
   170  }
   171  
   172  func TestGenerateRegistryEvent(t *testing.T) {
   173  	// todo Add test
   174  
   175  }
   176  
   177  func newMockListener() *mockListener {
   178  	return &mockListener{
   179  		Events: make([]*registry.ServiceEvent, 0),
   180  	}
   181  }
   182  
   183  type mockListener struct {
   184  	Events []*registry.ServiceEvent
   185  }
   186  
   187  func (m *mockListener) Notify(event *registry.ServiceEvent) {
   188  	m.Events = append(m.Events, event)
   189  }
   190  
   191  func (m *mockListener) NotifyAll(events []*registry.ServiceEvent, f func()) {
   192  	m.Events = append(m.Events, events...)
   193  }