@@ -6,7 +6,13 @@ package lua
66import  (
77	"testing" 
88
9+ 	envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" 
10+ 	envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" 
11+ 	envoy_lua_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/http/lua/v3" 
12+ 	envoy_http_v3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" 
913	"github.com/stretchr/testify/require" 
14+ 	"google.golang.org/protobuf/proto" 
15+ 	"google.golang.org/protobuf/types/known/anypb" 
1016
1117	"github.com/hashicorp/consul/api" 
1218	"github.com/hashicorp/consul/envoyextensions/extensioncommon" 
@@ -17,17 +23,15 @@ func TestConstructor(t *testing.T) {
1723		m  :=  map [string ]interface {}{
1824			"ProxyType" : "connect-proxy" ,
1925			"Listener" :  "inbound" ,
20- 			"Script" :    "lua-script " ,
26+ 			"Script" :    "function envoy_on_request(request_handle) request_handle:headers():add('test', 'test') end " ,
2127		}
22- 
2328		for  k , v  :=  range  overrides  {
2429			m [k ] =  v 
2530		}
26- 
2731		return  m 
2832	}
2933
30- 	cases  :=  map [string ]struct  {
34+ 	tests  :=  map [string ]struct  {
3135		extensionName  string 
3236		arguments      map [string ]interface {}
3337		expected       lua 
@@ -59,7 +63,16 @@ func TestConstructor(t *testing.T) {
5963			expected : lua {
6064				ProxyType : "connect-proxy" ,
6165				Listener :  "inbound" ,
62- 				Script :    "lua-script" ,
66+ 				Script :    "function envoy_on_request(request_handle) request_handle:headers():add('test', 'test') end" ,
67+ 			},
68+ 			ok : true ,
69+ 		},
70+ 		"api gateway proxy type" : {
71+ 			arguments : makeArguments (map [string ]interface {}{"ProxyType" : "api-gateway" }),
72+ 			expected : lua {
73+ 				ProxyType : "api-gateway" ,
74+ 				Listener :  "inbound" ,
75+ 				Script :    "function envoy_on_request(request_handle) request_handle:headers():add('test', 'test') end" ,
6376			},
6477			ok : true ,
6578		},
@@ -68,23 +81,21 @@ func TestConstructor(t *testing.T) {
6881			expected : lua {
6982				ProxyType : "connect-proxy" ,
7083				Listener :  "inbound" ,
71- 				Script :    "lua-script " ,
84+ 				Script :    "function envoy_on_request(request_handle) request_handle:headers():add('test', 'test') end " ,
7285			},
7386			ok : true ,
7487		},
7588	}
7689
77- 	for  n , tc  :=  range  cases  {
78- 		t .Run (n , func (t  * testing.T ) {
79- 
90+ 	for  name , tc  :=  range  tests  {
91+ 		t .Run (name , func (t  * testing.T ) {
8092			extensionName  :=  api .BuiltinLuaExtension 
8193			if  tc .extensionName  !=  ""  {
8294				extensionName  =  tc .extensionName 
8395			}
8496
85- 			svc  :=  api.CompoundServiceName {Name : "svc" }
8697			ext  :=  extensioncommon.RuntimeConfig {
87- 				ServiceName : svc ,
98+ 				ServiceName : api. CompoundServiceName { Name :  " svc" } ,
8899				EnvoyExtension : api.EnvoyExtension {
89100					Name :      extensionName ,
90101					Arguments : tc .arguments ,
@@ -102,3 +113,161 @@ func TestConstructor(t *testing.T) {
102113		})
103114	}
104115}
116+ 
117+ func  TestLuaExtension_PatchFilter (t  * testing.T ) {
118+ 	makeFilter  :=  func (filters  []* envoy_http_v3.HttpFilter ) * envoy_listener_v3.Filter  {
119+ 		hcm  :=  & envoy_http_v3.HttpConnectionManager {
120+ 			HttpFilters : filters ,
121+ 		}
122+ 		any , err  :=  anypb .New (hcm )
123+ 		require .NoError (t , err )
124+ 		return  & envoy_listener_v3.Filter {
125+ 			Name : "envoy.filters.network.http_connection_manager" ,
126+ 			ConfigType : & envoy_listener_v3.Filter_TypedConfig {
127+ 				TypedConfig : any ,
128+ 			},
129+ 		}
130+ 	}
131+ 
132+ 	makeLuaFilter  :=  func (script  string ) * envoy_http_v3.HttpFilter  {
133+ 		luaConfig  :=  & envoy_lua_v3.Lua {
134+ 			DefaultSourceCode : & envoy_core_v3.DataSource {
135+ 				Specifier : & envoy_core_v3.DataSource_InlineString {
136+ 					InlineString : script ,
137+ 				},
138+ 			},
139+ 		}
140+ 		return  & envoy_http_v3.HttpFilter {
141+ 			Name : "envoy.filters.http.lua" ,
142+ 			ConfigType : & envoy_http_v3.HttpFilter_TypedConfig {
143+ 				TypedConfig : mustMarshalAny (luaConfig ),
144+ 			},
145+ 		}
146+ 	}
147+ 
148+ 	tests  :=  map [string ]struct  {
149+ 		extension       * lua 
150+ 		filter          * envoy_listener_v3.Filter 
151+ 		isInbound       bool 
152+ 		expectedFilter  * envoy_listener_v3.Filter 
153+ 		expectPatched   bool 
154+ 		expectError     string 
155+ 	}{
156+ 		"non-http filter is ignored" : {
157+ 			extension : & lua {
158+ 				ProxyType : "connect-proxy" ,
159+ 				Listener :  "inbound" ,
160+ 				Script :    "function envoy_on_request(request_handle) end" ,
161+ 			},
162+ 			filter : & envoy_listener_v3.Filter {
163+ 				Name : "envoy.filters.network.tcp_proxy" ,
164+ 			},
165+ 			expectedFilter : & envoy_listener_v3.Filter {
166+ 				Name : "envoy.filters.network.tcp_proxy" ,
167+ 			},
168+ 			expectPatched : false ,
169+ 		},
170+ 		"listener direction mismatch" : {
171+ 			extension : & lua {
172+ 				ProxyType : "connect-proxy" ,
173+ 				Listener :  "inbound" ,
174+ 				Script :    "function envoy_on_request(request_handle) end" ,
175+ 			},
176+ 			filter : makeFilter ([]* envoy_http_v3.HttpFilter {
177+ 				{Name : "envoy.filters.http.router" },
178+ 			}),
179+ 			isInbound :      false ,
180+ 			expectedFilter : makeFilter ([]* envoy_http_v3.HttpFilter {{Name : "envoy.filters.http.router" }}),
181+ 			expectPatched :  false ,
182+ 		},
183+ 		"successful patch with router filter" : {
184+ 			extension : & lua {
185+ 				ProxyType : "connect-proxy" ,
186+ 				Listener :  "inbound" ,
187+ 				Script :    "function envoy_on_request(request_handle) end" ,
188+ 			},
189+ 			filter : makeFilter ([]* envoy_http_v3.HttpFilter {
190+ 				{Name : "envoy.filters.http.router" },
191+ 			}),
192+ 			isInbound : true ,
193+ 			expectedFilter : makeFilter ([]* envoy_http_v3.HttpFilter {
194+ 				makeLuaFilter ("function envoy_on_request(request_handle) end" ),
195+ 				{Name : "envoy.filters.http.router" },
196+ 			}),
197+ 			expectPatched : true ,
198+ 		},
199+ 		"successful patch with multiple filters" : {
200+ 			extension : & lua {
201+ 				ProxyType : "connect-proxy" ,
202+ 				Listener :  "inbound" ,
203+ 				Script :    "function envoy_on_request(request_handle) end" ,
204+ 			},
205+ 			filter : makeFilter ([]* envoy_http_v3.HttpFilter {
206+ 				{Name : "envoy.filters.http.other1" },
207+ 				{Name : "envoy.filters.http.router" },
208+ 				{Name : "envoy.filters.http.other2" },
209+ 			}),
210+ 			isInbound : true ,
211+ 			expectedFilter : makeFilter ([]* envoy_http_v3.HttpFilter {
212+ 				{Name : "envoy.filters.http.other1" },
213+ 				makeLuaFilter ("function envoy_on_request(request_handle) end" ),
214+ 				{Name : "envoy.filters.http.router" },
215+ 				{Name : "envoy.filters.http.other2" },
216+ 			}),
217+ 			expectPatched : true ,
218+ 		},
219+ 		"invalid filter config" : {
220+ 			extension : & lua {
221+ 				ProxyType : "connect-proxy" ,
222+ 				Listener :  "inbound" ,
223+ 				Script :    "function envoy_on_request(request_handle) end" ,
224+ 			},
225+ 			filter : & envoy_listener_v3.Filter {
226+ 				Name : "envoy.filters.network.http_connection_manager" ,
227+ 				ConfigType : & envoy_listener_v3.Filter_TypedConfig {
228+ 					TypedConfig : & anypb.Any {},
229+ 				},
230+ 			},
231+ 			isInbound :      true ,
232+ 			expectedFilter : nil ,
233+ 			expectPatched :  false ,
234+ 			expectError :    "error unmarshalling filter" ,
235+ 		},
236+ 	}
237+ 
238+ 	for  name , tc  :=  range  tests  {
239+ 		t .Run (name , func (t  * testing.T ) {
240+ 			direction  :=  extensioncommon .TrafficDirectionOutbound 
241+ 			if  tc .isInbound  {
242+ 				direction  =  extensioncommon .TrafficDirectionInbound 
243+ 			}
244+ 
245+ 			payload  :=  extensioncommon.FilterPayload {
246+ 				Message :          tc .filter ,
247+ 				TrafficDirection : direction ,
248+ 			}
249+ 
250+ 			filter , patched , err  :=  tc .extension .PatchFilter (payload )
251+ 
252+ 			if  tc .expectError  !=  ""  {
253+ 				require .Error (t , err )
254+ 				require .Contains (t , err .Error (), tc .expectError )
255+ 				return 
256+ 			}
257+ 
258+ 			require .NoError (t , err )
259+ 			require .Equal (t , tc .expectPatched , patched )
260+ 			if  tc .expectedFilter  !=  nil  {
261+ 				require .Equal (t , tc .expectedFilter , filter )
262+ 			}
263+ 		})
264+ 	}
265+ }
266+ 
267+ func  mustMarshalAny (m  proto.Message ) * anypb.Any  {
268+ 	a , err  :=  anypb .New (m )
269+ 	if  err  !=  nil  {
270+ 		panic (err )
271+ 	}
272+ 	return  a 
273+ }
0 commit comments