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 }