@@ -406,3 +406,221 @@ func TestIncorrectHandshake(t *testing.T) {
406406 return
407407 }
408408}
409+
410+
411+ // TestServerStopWithNilServer tests stopping a server with nil server field
412+ func TestServerStopWithNilServer (t * testing.T ) {
413+ server := & RemotePluginServer {}
414+ err := server .Stop ()
415+ if err != nil {
416+ t .Errorf ("expected no error when stopping nil server, got: %v" , err )
417+ }
418+ }
419+
420+ // TestServerStartAndStop tests basic server start and stop
421+ func TestServerStartAndStop (t * testing.T ) {
422+ port , err := network .GetRandomPort ()
423+ if err != nil {
424+ t .Fatalf ("failed to get random port: %v" , err )
425+ }
426+
427+ oss , err := factory .Load ("local" , cloudoss.OSSArgs {
428+ Local : & cloudoss.Local {
429+ Path : "./storage" ,
430+ },
431+ })
432+ if err != nil {
433+ t .Fatalf ("failed to load local storage: %v" , err )
434+ }
435+
436+ config := & app.Config {
437+ PluginRemoteInstallingHost : "127.0.0.1" ,
438+ PluginRemoteInstallingPort : port ,
439+ PluginRemoteInstallingMaxConn : 1 ,
440+ PluginRemoteInstallServerEventLoopNums : 1 ,
441+ }
442+
443+ server := NewDebuggingPluginServer (config , media_transport .NewAssetsBucket (oss , "assets" , 10 ))
444+
445+ // Start server in background
446+ done := make (chan error , 1 )
447+ go func () {
448+ done <- server .Launch ()
449+ }()
450+
451+ // Wait for server to start
452+ time .Sleep (1 * time .Second )
453+
454+ // Verify server is listening
455+ conn , err := net .DialTimeout ("tcp" , fmt .Sprintf ("127.0.0.1:%d" , port ), 500 * time .Millisecond )
456+ if err != nil {
457+ t .Fatalf ("server not listening after 1s: %v" , err )
458+ }
459+ conn .Close ()
460+
461+ // Stop server
462+ if err := server .Stop (); err != nil {
463+ t .Errorf ("failed to stop server: %v" , err )
464+ }
465+
466+ // Wait for launch to return
467+ select {
468+ case err := <- done :
469+ if err != nil {
470+ t .Logf ("launch returned error (expected): %v" , err )
471+ }
472+ case <- time .After (3 * time .Second ):
473+ t .Error ("launch did not return after stop" )
474+ }
475+
476+ // Verify server is not listening
477+ time .Sleep (100 * time .Millisecond )
478+ conn , err = net .DialTimeout ("tcp" , fmt .Sprintf ("127.0.0.1:%d" , port ), 500 * time .Millisecond )
479+ if err == nil {
480+ conn .Close ()
481+ t .Error ("server still listening after stop" )
482+ }
483+ }
484+
485+ // TestServerStopIdempotent tests that stopping multiple times is safe
486+ func TestServerStopIdempotent (t * testing.T ) {
487+ port , err := network .GetRandomPort ()
488+ if err != nil {
489+ t .Fatalf ("failed to get random port: %v" , err )
490+ }
491+
492+ oss , err := factory .Load ("local" , cloudoss.OSSArgs {
493+ Local : & cloudoss.Local {
494+ Path : "./storage" ,
495+ },
496+ })
497+ if err != nil {
498+ t .Fatalf ("failed to load local storage: %v" , err )
499+ }
500+
501+ config := & app.Config {
502+ PluginRemoteInstallingHost : "127.0.0.1" ,
503+ PluginRemoteInstallingPort : port ,
504+ PluginRemoteInstallingMaxConn : 1 ,
505+ PluginRemoteInstallServerEventLoopNums : 1 ,
506+ }
507+
508+ server := NewDebuggingPluginServer (config , media_transport .NewAssetsBucket (oss , "assets" , 10 ))
509+
510+ // Start server
511+ go func () {
512+ server .Launch ()
513+ }()
514+
515+ time .Sleep (1 * time .Second )
516+
517+ // Stop multiple times
518+ for i := 0 ; i < 3 ; i ++ {
519+ if err := server .Stop (); err != nil {
520+ t .Errorf ("stop %d failed: %v" , i + 1 , err )
521+ }
522+ }
523+ }
524+
525+ // TestServerQuickRestart tests immediate restart after stop
526+ func TestServerQuickRestart (t * testing.T ) {
527+ port , err := network .GetRandomPort ()
528+ if err != nil {
529+ t .Fatalf ("failed to get random port: %v" , err )
530+ }
531+
532+ oss , err := factory .Load ("local" , cloudoss.OSSArgs {
533+ Local : & cloudoss.Local {
534+ Path : "./storage" ,
535+ },
536+ })
537+ if err != nil {
538+ t .Fatalf ("failed to load local storage: %v" , err )
539+ }
540+
541+ config := & app.Config {
542+ PluginRemoteInstallingHost : "127.0.0.1" ,
543+ PluginRemoteInstallingPort : port ,
544+ PluginRemoteInstallingMaxConn : 1 ,
545+ PluginRemoteInstallServerEventLoopNums : 1 ,
546+ }
547+
548+ // First server
549+ server1 := NewDebuggingPluginServer (config , media_transport .NewAssetsBucket (oss , "assets" , 10 ))
550+ go server1 .Launch ()
551+ time .Sleep (1 * time .Second )
552+
553+ // Verify first server is listening
554+ conn , err := net .DialTimeout ("tcp" , fmt .Sprintf ("127.0.0.1:%d" , port ), 500 * time .Millisecond )
555+ if err != nil {
556+ t .Fatalf ("first server not listening: %v" , err )
557+ }
558+ conn .Close ()
559+
560+ // Stop first server
561+ server1 .Stop ()
562+ time .Sleep (200 * time .Millisecond )
563+
564+ // Start second server on same port
565+ server2 := NewDebuggingPluginServer (config , media_transport .NewAssetsBucket (oss , "assets" , 10 ))
566+ go server2 .Launch ()
567+ time .Sleep (1 * time .Second )
568+
569+ // Verify second server is listening
570+ conn , err = net .DialTimeout ("tcp" , fmt .Sprintf ("127.0.0.1:%d" , port ), 500 * time .Millisecond )
571+ if err != nil {
572+ t .Errorf ("second server not listening: %v" , err )
573+ } else {
574+ conn .Close ()
575+ }
576+
577+ // Cleanup
578+ server2 .Stop ()
579+ }
580+
581+ // TestServerStopConcurrent tests concurrent stop calls
582+ func TestServerStopConcurrent (t * testing.T ) {
583+ port , err := network .GetRandomPort ()
584+ if err != nil {
585+ t .Fatalf ("failed to get random port: %v" , err )
586+ }
587+
588+ oss , err := factory .Load ("local" , cloudoss.OSSArgs {
589+ Local : & cloudoss.Local {
590+ Path : "./storage" ,
591+ },
592+ })
593+ if err != nil {
594+ t .Fatalf ("failed to load local storage: %v" , err )
595+ }
596+
597+ config := & app.Config {
598+ PluginRemoteInstallingHost : "127.0.0.1" ,
599+ PluginRemoteInstallingPort : port ,
600+ PluginRemoteInstallingMaxConn : 1 ,
601+ PluginRemoteInstallServerEventLoopNums : 1 ,
602+ }
603+
604+ server := NewDebuggingPluginServer (config , media_transport .NewAssetsBucket (oss , "assets" , 10 ))
605+ go server .Launch ()
606+ time .Sleep (1 * time .Second )
607+
608+ // Concurrent stops
609+ done := make (chan struct {})
610+ for i := 0 ; i < 3 ; i ++ {
611+ go func () {
612+ server .Stop ()
613+ done <- struct {}{}
614+ }()
615+ }
616+
617+ // Wait for all stops to complete
618+ for i := 0 ; i < 3 ; i ++ {
619+ <- done
620+ }
621+ }
622+
623+ // TestServerLaunchWithRetry is skipped due to long execution time
624+ func TestServerLaunchWithRetry (t * testing.T ) {
625+ t .Skip ("Skipping - requires 12+ seconds for retry mechanism" )
626+ }
0 commit comments