@@ -21,19 +21,37 @@ const (
2121 mockSecretID = secrets .ID ("mockSecretID" )
2222)
2323
24- var (
25- mockPlugin = & mockedPlugin {
26- pattern : "*" ,
27- id : mockSecretID ,
28- }
29- )
30-
3124type mockedPlugin struct {
3225 pattern string
3326 id secrets.ID
3427 configureErr error
3528}
3629
30+ type MockedPluginOption func (* mockedPlugin )
31+
32+ func newMockedPlugin (options ... MockedPluginOption ) * mockedPlugin {
33+ m := & mockedPlugin {
34+ pattern : "*" ,
35+ id : mockSecretID ,
36+ }
37+ for _ , opt := range options {
38+ opt (m )
39+ }
40+ return m
41+ }
42+
43+ func WithPattern (pattern string ) MockedPluginOption {
44+ return func (mp * mockedPlugin ) {
45+ mp .pattern = pattern
46+ }
47+ }
48+
49+ func WithID (id secrets.ID ) MockedPluginOption {
50+ return func (mp * mockedPlugin ) {
51+ mp .id = id
52+ }
53+ }
54+
3755func (m mockedPlugin ) GetSecret (context.Context , secrets.Request ) (secrets.Envelope , error ) {
3856 return secrets.Envelope {ID : m .id , Value : []byte (mockSecretValue )}, nil
3957}
@@ -59,27 +77,90 @@ func Test_newExternalPlugin(t *testing.T) {
5977 }{
6078 {
6179 name : "create external plugin" ,
80+ test : func (t * testing.T , l net.Listener , conn net.Conn ) {
81+ doneRuntime := make (chan struct {})
82+ go func () {
83+ p := mockExternalPluginRuntime (t , l )
84+ e , err := p .GetSecret (t .Context (), secrets.Request {ID : mockSecretID })
85+ assert .NoError (t , err )
86+ assert .Equal (t , mockSecretValue , string (e .Value ))
87+ assert .NoError (t , p .close ())
88+ close (doneRuntime )
89+ }()
90+
91+ s , err := p .New (newMockedPlugin (), p .WithPluginName ("my-plugin" ), p .WithConnection (conn ))
92+ require .NoError (t , err )
93+ assert .NoError (t , s .Run (context .Background ()))
94+ <- doneRuntime
95+ },
96+ },
97+ {
98+ name : "plugin returns error on GetSecret" ,
99+ test : func (t * testing.T , l net.Listener , conn net.Conn ) {
100+ doneRuntime := make (chan struct {})
101+ go func () {
102+ p := mockExternalPluginRuntime (t , l )
103+ _ , err := p .GetSecret (t .Context (), secrets.Request {ID : mockSecretID })
104+ assert .ErrorContains (t , err , "id mismatch" )
105+ assert .NoError (t , p .close ())
106+ close (doneRuntime )
107+ }()
108+
109+ s , err := p .New (newMockedPlugin (WithID ("rewrite-id" )), p .WithPluginName ("my-plugin" ), p .WithConnection (conn ))
110+ require .NoError (t , err )
111+ assert .NoError (t , s .Run (context .Background ()))
112+ <- doneRuntime
113+ },
114+ },
115+ {
116+ name : "cancelling plugin.run() shuts down the runtime" ,
117+ test : func (t * testing.T , l net.Listener , conn net.Conn ) {
118+ doneRuntime := make (chan struct {})
119+ donePlugin := make (chan struct {})
120+ downRuntime := make (chan struct {})
121+ go func () {
122+ p := mockExternalPluginRuntime (t , l )
123+ e , err := p .GetSecret (t .Context (), secrets.Request {ID : mockSecretID })
124+ assert .NoError (t , err )
125+ assert .Equal (t , mockSecretValue , string (e .Value ))
126+ close (doneRuntime )
127+ <- donePlugin
128+ assert .NoError (t , p .close ())
129+ close (downRuntime )
130+ }()
131+
132+ s , err := p .New (newMockedPlugin (), p .WithPluginName ("my-plugin" ), p .WithConnection (conn ))
133+ require .NoError (t , err )
134+ ctx , cancel := context .WithCancel (t .Context ())
135+
136+ go func () {
137+ assert .NoError (t , s .Run (ctx ))
138+ close (donePlugin )
139+ }()
140+ <- doneRuntime
141+ cancel ()
142+ <- downRuntime
143+ },
144+ },
145+ {
146+ name : "plugins with invalid patterns are rejected" ,
62147 test : func (t * testing.T , l net.Listener , conn net.Conn ) {
63148 doneRuntime := make (chan struct {})
64149 go func () {
65150 conn , err := l .Accept ()
66151 require .NoError (t , err )
67152
68- p , err : = newExternalPlugin (conn , setupValidator {
153+ _ , err = newExternalPlugin (conn , setupValidator {
69154 out : pluginCfgOut {engineName : "test-engine" , engineVersion : "1.0.0" , requestTimeout : 30 * time .Second },
70155 acceptPattern : func (secrets.Pattern ) error { return nil },
71156 })
72- require .NoError (t , err )
73- e , err := p .GetSecret (t .Context (), secrets.Request {ID : mockSecretID })
74- assert .NoError (t , err )
75- assert .Equal (t , mockSecretValue , string (e .Value ))
76- assert .NoError (t , p .close ())
157+ assert .ErrorContains (t , err , "invalid pattern" )
77158 close (doneRuntime )
78159 }()
79160
80- s , err := p .New (mockPlugin , p .WithPluginName ("my-plugin" ), p .WithConnection (conn ))
161+ s , err := p .New (newMockedPlugin ( WithPattern ( "a*a" )) , p .WithPluginName ("my-plugin" ), p .WithConnection (conn ))
81162 require .NoError (t , err )
82- assert .NoError (t , s .Run (context . Background ()))
163+ assert .ErrorContains (t , s .Run (t . Context ()), "invalid pattern" )
83164 <- doneRuntime
84165 },
85166 },
@@ -101,3 +182,15 @@ func Test_newExternalPlugin(t *testing.T) {
101182 })
102183 }
103184}
185+
186+ func mockExternalPluginRuntime (t * testing.T , l net.Listener ) * plugin {
187+ conn , err := l .Accept ()
188+ require .NoError (t , err )
189+
190+ p , err := newExternalPlugin (conn , setupValidator {
191+ out : pluginCfgOut {engineName : "test-engine" , engineVersion : "1.0.0" , requestTimeout : 30 * time .Second },
192+ acceptPattern : func (secrets.Pattern ) error { return nil },
193+ })
194+ require .NoError (t , err )
195+ return p
196+ }
0 commit comments