@@ -21,13 +21,21 @@ import (
21
21
"bytes"
22
22
"context"
23
23
"encoding/json"
24
+ "encoding/xml"
24
25
"fmt"
25
26
"net/http"
27
+ "net/http/httptest"
28
+ "net/url"
29
+ "reflect"
26
30
"testing"
27
31
"time"
32
+ "unsafe"
28
33
29
34
"github.com/emicklei/go-restful/v3"
35
+ apimodel "github.com/polarismesh/specification/source/go/api/v1/model"
36
+ "github.com/polarismesh/specification/source/go/api/v1/service_manage"
30
37
"github.com/stretchr/testify/assert"
38
+ "google.golang.org/protobuf/types/known/wrapperspb"
31
39
32
40
api "github.com/polarismesh/polaris/common/api/v1"
33
41
testsuit "github.com/polarismesh/polaris/test/suit"
@@ -37,12 +45,15 @@ func createEurekaServerForTest(
37
45
discoverSuit * testsuit.DiscoverTestSuit , options map [string ]interface {}) (* EurekaServer , error ) {
38
46
eurekaSrv := & EurekaServer {
39
47
namingServer : discoverSuit .DiscoverServer (),
48
+ originDiscoverSvr : discoverSuit .OriginDiscoverServer (),
40
49
healthCheckServer : discoverSuit .HealthCheckServer (),
50
+ allowAsyncRegis : false ,
41
51
}
42
52
err := eurekaSrv .Initialize (context .Background (), options , nil )
43
53
if err != nil {
44
54
return nil , err
45
55
}
56
+ eurekaSrv .registerInstanceChain ()
46
57
return eurekaSrv , nil
47
58
}
48
59
@@ -198,3 +209,210 @@ func TestCreateInstance(t *testing.T) {
198
209
assert .Nil (t , err )
199
210
checkInstanceAction (t , deltaAppResp .Applications , appId , instanceId , ActionDeleted )
200
211
}
212
+
213
+ // Test_EurekaWrite .
214
+ func Test_EurekaWrite (t * testing.T ) {
215
+ discoverSuit := & testsuit.DiscoverTestSuit {}
216
+ if err := discoverSuit .Initialize (); err != nil {
217
+ t .Fatal (err )
218
+ }
219
+ defer discoverSuit .Destroy ()
220
+
221
+ options := map [string ]interface {}{optionRefreshInterval : 5 , optionDeltaExpireInterval : 120 }
222
+ eurekaSrv , err := createEurekaServerForTest (discoverSuit , options )
223
+ assert .Nil (t , err )
224
+
225
+ mockIns := genMockEurekaInstance ()
226
+
227
+ t .Run ("RegisterInstance" , func (t * testing.T ) {
228
+ // pretty output must be created and written explicitly
229
+ output , err := xml .MarshalIndent (mockIns , " " , " " )
230
+ assert .NoError (t , err )
231
+
232
+ var body bytes.Buffer
233
+ _ , err = body .Write ([]byte (xml .Header ))
234
+ assert .NoError (t , err )
235
+ _ , err = body .Write (output )
236
+ assert .NoError (t , err )
237
+
238
+ mockReq := httptest .NewRequest ("" , fmt .Sprintf ("http://127.0.0.1:8761/eureka/v2/apps/%s" , mockIns .AppName ), & body )
239
+ mockReq .Header .Add (restful .HEADER_Accept , restful .MIME_XML )
240
+ mockReq .Header .Add (restful .HEADER_ContentType , restful .MIME_XML )
241
+ mockRsp := newMockResponseWriter ()
242
+
243
+ restfulReq := restful .NewRequest (mockReq )
244
+ injectRestfulReqPathParameters (t , restfulReq , map [string ]string {
245
+ ParamAppId : mockIns .AppName ,
246
+ })
247
+ // 这里是异步注册
248
+ eurekaSrv .RegisterApplication (restfulReq , restful .NewResponse (mockRsp ))
249
+ assert .Equal (t , http .StatusNoContent , mockRsp .statusCode )
250
+ assert .Equal (t , restfulReq .Attribute (statusCodeHeader ), uint32 (apimodel .Code_ExecuteSuccess ))
251
+
252
+ time .Sleep (5 * time .Second )
253
+ saveIns , err := eurekaSrv .originDiscoverSvr .Cache ().GetStore ().GetInstance (mockIns .InstanceId )
254
+ assert .NoError (t , err )
255
+ assert .NotNil (t , saveIns )
256
+ })
257
+
258
+ t .Run ("UpdateStatus" , func (t * testing.T ) {
259
+ t .Run ("StatusUnknown" , func (t * testing.T ) {
260
+ mockReq := httptest .NewRequest ("" , fmt .Sprintf ("http://127.0.0.1:8761/eureka/v2/apps/%s/%s/status" ,
261
+ mockIns .AppName , mockIns .InstanceId ), nil )
262
+ mockReq .PostForm = url.Values {}
263
+ mockReq .PostForm .Add (ParamValue , StatusUnknown )
264
+ mockRsp := newMockResponseWriter ()
265
+
266
+ restfulReq := restful .NewRequest (mockReq )
267
+ injectRestfulReqPathParameters (t , restfulReq , map [string ]string {
268
+ ParamAppId : mockIns .AppName ,
269
+ ParamInstId : mockIns .InstanceId ,
270
+ })
271
+ eurekaSrv .UpdateStatus (restfulReq , restful .NewResponse (mockRsp ))
272
+ assert .Equal (t , http .StatusOK , mockRsp .statusCode )
273
+ assert .Equal (t , restfulReq .Attribute (statusCodeHeader ), uint32 (apimodel .Code_ExecuteSuccess ))
274
+
275
+ //
276
+ saveIns , err := discoverSuit .Storage .GetInstance (mockIns .InstanceId )
277
+ assert .NoError (t , err )
278
+ assert .False (t , saveIns .Isolate ())
279
+ })
280
+
281
+ t .Run ("StatusDown" , func (t * testing.T ) {
282
+ mockReq := httptest .NewRequest ("" , fmt .Sprintf ("http://127.0.0.1:8761/eureka/v2/apps/%s/%s/status" ,
283
+ mockIns .AppName , mockIns .InstanceId ), nil )
284
+ mockReq .PostForm = url.Values {}
285
+ mockReq .PostForm .Add (ParamValue , StatusDown )
286
+ mockRsp := newMockResponseWriter ()
287
+
288
+ restfulReq := restful .NewRequest (mockReq )
289
+ injectRestfulReqPathParameters (t , restfulReq , map [string ]string {
290
+ ParamAppId : mockIns .AppName ,
291
+ ParamInstId : mockIns .InstanceId ,
292
+ })
293
+ eurekaSrv .UpdateStatus (restfulReq , restful .NewResponse (mockRsp ))
294
+ assert .Equal (t , http .StatusOK , mockRsp .statusCode )
295
+ assert .Equal (t , restfulReq .Attribute (statusCodeHeader ), uint32 (apimodel .Code_ExecuteSuccess ), fmt .Sprintf ("%d" , restfulReq .Attribute (statusCodeHeader )))
296
+
297
+ //
298
+ saveIns , err := discoverSuit .Storage .GetInstance (mockIns .InstanceId )
299
+ assert .NoError (t , err )
300
+ assert .True (t , saveIns .Isolate ())
301
+ assert .Equal (t , StatusDown , saveIns .Proto .Metadata [InternalMetadataStatus ])
302
+ })
303
+
304
+ t .Run ("StatusUp" , func (t * testing.T ) {
305
+ mockReq := httptest .NewRequest ("" , fmt .Sprintf ("http://127.0.0.1:8761/eureka/v2/apps/%s/%s/status" ,
306
+ mockIns .AppName , mockIns .InstanceId ), nil )
307
+ mockReq .PostForm = url.Values {}
308
+ mockReq .PostForm .Add (ParamValue , StatusUp )
309
+ mockRsp := newMockResponseWriter ()
310
+
311
+ restfulReq := restful .NewRequest (mockReq )
312
+ injectRestfulReqPathParameters (t , restfulReq , map [string ]string {
313
+ ParamAppId : mockIns .AppName ,
314
+ ParamInstId : mockIns .InstanceId ,
315
+ })
316
+ eurekaSrv .UpdateStatus (restfulReq , restful .NewResponse (mockRsp ))
317
+ assert .Equal (t , http .StatusOK , mockRsp .statusCode )
318
+ assert .Equal (t , restfulReq .Attribute (statusCodeHeader ), uint32 (apimodel .Code_ExecuteSuccess ), fmt .Sprintf ("%d" , restfulReq .Attribute (statusCodeHeader )))
319
+
320
+ //
321
+ saveIns , err := discoverSuit .Storage .GetInstance (mockIns .InstanceId )
322
+ assert .NoError (t , err )
323
+ assert .False (t , saveIns .Isolate ())
324
+ assert .Equal (t , StatusUp , saveIns .Proto .Metadata [InternalMetadataStatus ])
325
+ })
326
+
327
+ t .Run ("Polaris_UpdateInstances" , func (t * testing.T ) {
328
+ defer func () {
329
+ rsp := discoverSuit .OriginDiscoverServer ().UpdateInstances (discoverSuit .DefaultCtx , []* service_manage.Instance {
330
+ {
331
+ Id : wrapperspb .String (mockIns .InstanceId ),
332
+ Isolate : wrapperspb .Bool (false ),
333
+ },
334
+ })
335
+ assert .Equal (t , apimodel .Code_ExecuteSuccess , apimodel .Code (rsp .GetCode ().GetValue ()))
336
+ }()
337
+ rsp := discoverSuit .OriginDiscoverServer ().UpdateInstances (discoverSuit .DefaultCtx , []* service_manage.Instance {
338
+ {
339
+ Id : wrapperspb .String (mockIns .InstanceId ),
340
+ Isolate : wrapperspb .Bool (true ),
341
+ },
342
+ })
343
+ assert .Equal (t , apimodel .Code_ExecuteSuccess , apimodel .Code (rsp .GetCode ().GetValue ()))
344
+
345
+ // 在获取一次
346
+ saveIns , err := discoverSuit .Storage .GetInstance (mockIns .InstanceId )
347
+ assert .NoError (t , err )
348
+ assert .True (t , saveIns .Isolate ())
349
+ assert .Equal (t , StatusOutOfService , saveIns .Proto .Metadata [InternalMetadataStatus ])
350
+ })
351
+
352
+ t .Run ("Polaris_UpdateInstancesIsolate" , func (t * testing.T ) {
353
+ rsp := discoverSuit .OriginDiscoverServer ().UpdateInstances (discoverSuit .DefaultCtx , []* service_manage.Instance {
354
+ {
355
+ Id : wrapperspb .String (mockIns .InstanceId ),
356
+ Isolate : wrapperspb .Bool (true ),
357
+ },
358
+ })
359
+ assert .Equal (t , apimodel .Code_ExecuteSuccess , apimodel .Code (rsp .GetCode ().GetValue ()))
360
+
361
+ // 在获取一次
362
+ _ , saveInss , err := discoverSuit .Storage .GetExpandInstances (map [string ]string {
363
+ "id" : mockIns .InstanceId ,
364
+ }, map [string ]string {}, 0 , 10 )
365
+ assert .NoError (t , err )
366
+ assert .Equal (t , 1 , len (saveInss ))
367
+ assert .True (t , saveInss [0 ].Isolate ())
368
+ assert .Equal (t , StatusOutOfService , saveInss [0 ].Proto .Metadata [InternalMetadataStatus ])
369
+ })
370
+ })
371
+ }
372
+
373
+ func injectRestfulReqPathParameters (t * testing.T , req * restful.Request , params map [string ]string ) {
374
+ v := reflect .ValueOf (req )
375
+ if v .Kind () == reflect .Ptr {
376
+ v = v .Elem ()
377
+ }
378
+
379
+ field := v .FieldByName ("pathParameters" )
380
+ fieldVal := GetUnexportedField (field )
381
+
382
+ pathParameters , ok := fieldVal .(map [string ]string )
383
+ assert .True (t , ok )
384
+ for k , v := range params {
385
+ pathParameters [k ] = v
386
+ }
387
+ SetUnexportedField (field , params )
388
+ }
389
+
390
+ func genMockEurekaInstance () * InstanceInfo {
391
+ mockIns := & InstanceInfo {
392
+ XMLName : struct {}{},
393
+ InstanceId : "123" ,
394
+ AppName : "MOCK_SERVICE" ,
395
+ AppGroupName : "MOCK_SERVICE" ,
396
+ IpAddr : "127.0.0.1" ,
397
+ Sid : "" ,
398
+ Port : & PortWrapper {
399
+ Port : "8080" ,
400
+ RealPort : 8080 ,
401
+ Enabled : "true" ,
402
+ RealEnable : true ,
403
+ },
404
+ Status : StatusUp ,
405
+ OverriddenStatus : StatusUnknown ,
406
+ }
407
+ return mockIns
408
+ }
409
+
410
+ func SetUnexportedField (field reflect.Value , value interface {}) {
411
+ reflect .NewAt (field .Type (), unsafe .Pointer (field .UnsafeAddr ())).
412
+ Elem ().
413
+ Set (reflect .ValueOf (value ))
414
+ }
415
+
416
+ func GetUnexportedField (field reflect.Value ) interface {} {
417
+ return reflect .NewAt (field .Type (), unsafe .Pointer (field .UnsafeAddr ())).Elem ().Interface ()
418
+ }
0 commit comments