@@ -7,17 +7,22 @@ import (
77 "net"
88 "os"
99 "testing"
10+ "time"
1011
1112 papiv1 "github.com/gotify/plugin-api"
1213 "github.com/gotify/plugin-api/v2"
1314 "github.com/gotify/plugin-api/v2/generated/protobuf"
1415 "github.com/gotify/plugin-api/v2/transport"
16+ "github.com/stretchr/testify/assert"
1517 "google.golang.org/grpc"
1618 "google.golang.org/grpc/credentials"
19+ "google.golang.org/grpc/keepalive"
1720 "google.golang.org/protobuf/types/known/emptypb"
1821)
1922
2023func testMinimalImpl (t * testing.T , listener net.Listener , addr string ) {
24+ assert := assert .New (t )
25+
2126 pluginInfo := GetGotifyPluginInfo ()
2227
2328 client , err := transport .NewEphemeralTLSClient ()
@@ -39,53 +44,63 @@ func testMinimalImpl(t *testing.T, listener net.Listener, addr string) {
3944 client .Kex (reqFileRx , respFileTx )
4045 }()
4146
47+ var thisInstance * Plugin
48+ instanceInitialized := make (chan struct {})
49+
4250 compatV1 , err := plugin .NewCompatV1Rpc (& plugin.CompatV1 {
4351 GetPluginInfo : GetGotifyPluginInfo ,
4452 GetInstance : func (user papiv1.UserContext ) (papiv1.Plugin , error ) {
45- return NewGotifyPluginInstance (user ), nil
53+ thisInstance = NewGotifyPluginInstance (user ).(* Plugin )
54+ defer close (instanceInitialized )
55+ return thisInstance , nil
4656 },
4757 }, []string {
4858 "-kex-req-file" , fmt .Sprintf ("/proc/self/fd/%d" , reqTx ),
4959 "-kex-resp-file" , fmt .Sprintf ("/proc/self/fd/%d" , respRx ),
5060 })
51- if err != nil {
52- t .Fatal (err )
53- }
61+ assert .NoError (err )
5462
5563 go func () {
5664 compatV1 .ServeTLS (listener , "" , "" )
5765 }()
5866
59- rpcClient , err := grpc .NewClient (addr , grpc .WithTransportCredentials (credentials .NewTLS (client .ClientTLSConfig (pluginInfo .ModulePath ))))
60- if err != nil {
61- t .Fatal (err )
62- }
67+ rpcClient , err := grpc .NewClient (addr , grpc .WithTransportCredentials (credentials .NewTLS (client .ClientTLSConfig (pluginInfo .ModulePath ))), grpc .WithKeepaliveParams (keepalive.ClientParameters {
68+ Time : 10 * time .Millisecond ,
69+ PermitWithoutStream : true ,
70+ }))
71+ assert .NoError (err )
6372
6473 pluginClient := protobuf .NewPluginClient (rpcClient )
6574 version , err := pluginClient .GetPluginInfo (context .Background (), & emptypb.Empty {})
66- if err != nil {
67- t .Fatal (err )
68- }
69- if version .Name != pluginInfo .Name {
70- t .Fatal ("expected " , pluginInfo .Name , " got " , version .Name )
71- }
72- if version .Version != pluginInfo .Version {
73- t .Fatal ("expected " , pluginInfo .Version , " got " , version .Version )
74- }
75+ assert .NoError (err )
76+ assert .Equal (pluginInfo .Name , version .Name )
77+ assert .Equal (pluginInfo .Version , version .Version )
7578
76- pluginClient .SetEnable (context .Background (), & protobuf.SetEnableRequest {
79+ stream , err := pluginClient .RunUserInstance (context .Background (), & protobuf.UserInstanceRequest {
7780 User : & protobuf.UserContext {
7881 Id : uint64 (1 ),
7982 Name : "test" ,
8083 Admin : false ,
8184 },
82- Enable : true ,
8385 })
84- if err != nil {
85- t .Fatal (err )
86+ assert .NoError (err )
87+
88+ assert .NoError (stream .CloseSend ())
89+ <- instanceInitialized
90+ assert .True (thisInstance .enabled , "plugin should be enabled after connect" )
91+
92+ pluginClient .GracefulShutdown (context .Background (), & emptypb.Empty {})
93+ for {
94+ _ , err := stream .Recv ()
95+ if err != nil {
96+ if err == io .EOF {
97+ break
98+ }
99+ t .Fatal (err )
100+ }
86101 }
87102
88- stream , err := pluginClient .RunUserInstance (context .Background (), & protobuf.UserInstanceRequest {
103+ streamHang , err := pluginClient .RunUserInstance (context .Background (), & protobuf.UserInstanceRequest {
89104 User : & protobuf.UserContext {
90105 Id : uint64 (1 ),
91106 Name : "test" ,
@@ -95,16 +110,32 @@ func testMinimalImpl(t *testing.T, listener net.Listener, addr string) {
95110 if err != nil {
96111 t .Fatal (err )
97112 }
113+ if err := streamHang .CloseSend (); err != nil {
114+ t .Fatal (err )
115+ }
116+ _ , err = streamHang .Recv ()
117+ assert .Error (err , "expected error when not sending keepalive" )
118+ assert .False (thisInstance .enabled , "plugin should be disabled after hang" )
98119
120+ streamReentrant , err := pluginClient .RunUserInstance (context .Background (), & protobuf.UserInstanceRequest {
121+ User : & protobuf.UserContext {
122+ Id : uint64 (1 ),
123+ Name : "test" ,
124+ Admin : false ,
125+ },
126+ })
127+ assert .NoError (err )
99128 pluginClient .GracefulShutdown (context .Background (), & emptypb.Empty {})
100- stream .CloseSend ()
129+ if err := streamReentrant .CloseSend (); err != nil {
130+ assert .NoError (err )
131+ }
101132 for {
102- _ , err := stream .Recv ()
133+ _ , err := streamReentrant .Recv ()
103134 if err != nil {
104135 if err == io .EOF {
105136 break
106137 }
107- t . Fatal (err )
138+ assert . NoError (err )
108139 }
109140 }
110141}
0 commit comments