@@ -21,13 +21,21 @@ import (
2121 "bytes"
2222 "context"
2323 "encoding/json"
24+ "encoding/xml"
2425 "fmt"
2526 "net/http"
27+ "net/http/httptest"
28+ "net/url"
29+ "reflect"
2630 "testing"
2731 "time"
32+ "unsafe"
2833
2934 "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"
3037 "github.com/stretchr/testify/assert"
38+ "google.golang.org/protobuf/types/known/wrapperspb"
3139
3240 api "github.com/polarismesh/polaris/common/api/v1"
3341 testsuit "github.com/polarismesh/polaris/test/suit"
@@ -37,12 +45,15 @@ func createEurekaServerForTest(
3745 discoverSuit * testsuit.DiscoverTestSuit , options map [string ]interface {}) (* EurekaServer , error ) {
3846 eurekaSrv := & EurekaServer {
3947 namingServer : discoverSuit .DiscoverServer (),
48+ originDiscoverSvr : discoverSuit .OriginDiscoverServer (),
4049 healthCheckServer : discoverSuit .HealthCheckServer (),
50+ allowAsyncRegis : false ,
4151 }
4252 err := eurekaSrv .Initialize (context .Background (), options , nil )
4353 if err != nil {
4454 return nil , err
4555 }
56+ eurekaSrv .registerInstanceChain ()
4657 return eurekaSrv , nil
4758}
4859
@@ -198,3 +209,210 @@ func TestCreateInstance(t *testing.T) {
198209 assert .Nil (t , err )
199210 checkInstanceAction (t , deltaAppResp .Applications , appId , instanceId , ActionDeleted )
200211}
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