Skip to content

Commit 360c808

Browse files
GSVarshaFerenc-
authored andcommitted
capture headers for lambda
Signed-off-by: Varsha GS <[email protected]>
1 parent 4fde367 commit 360c808

File tree

1 file changed

+191
-7
lines changed

1 file changed

+191
-7
lines changed

tests/clients/boto3/test_boto3_lambda.py

Lines changed: 191 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,21 @@
22
# (c) Copyright Instana Inc. 2020
33

44
from __future__ import absolute_import
5-
from io import BytesIO
6-
from zipfile import ZipFile
75
import unittest
86
import json
97

108
import boto3
11-
import pytest
12-
139
# TODO: Remove branching when we drop support for Python 3.7
14-
import sys
15-
if sys.version_info >= (3, 8):
10+
from sys import version_info
11+
if version_info >= (3, 8):
1612
from moto import mock_aws
1713
else:
1814
from moto import mock_lambda as mock_aws
1915

20-
from instana.singletons import tracer
16+
from instana.singletons import tracer, agent
2117
from ...helpers import get_first_span_by_filter
2218

19+
@unittest.skip(version_info < (3, 8), "Test skipped on Python < 3.8")
2320
class TestLambda(unittest.TestCase):
2421
def setUp(self):
2522
""" Clear all spans before a test run """
@@ -71,3 +68,190 @@ def test_lambda_invoke(self):
7168
self.assertEqual(boto_span.data['http']['status'], 200)
7269
self.assertEqual(boto_span.data['http']['method'], 'POST')
7370
self.assertEqual(boto_span.data['http']['url'], f'{endpoint}:443/Invoke')
71+
72+
73+
def test_request_header_capture_before_call(self):
74+
original_extra_http_headers = agent.options.extra_http_headers
75+
agent.options.extra_http_headers = ['X-Capture-This', 'X-Capture-That']
76+
77+
# Access the event system on the S3 client
78+
event_system = self.aws_lambda.meta.events
79+
80+
request_headers = {
81+
'X-Capture-This': 'this',
82+
'X-Capture-That': 'that'
83+
}
84+
85+
# Create a function that adds custom headers
86+
def add_custom_header_before_call(params, **kwargs):
87+
params['headers'].update(request_headers)
88+
89+
# Register the function to before-call event.
90+
event_system.register('before-call.lambda.Invoke', add_custom_header_before_call)
91+
92+
with tracer.start_active_span('test'):
93+
result = self.aws_lambda.invoke(FunctionName=self.function_name, Payload=json.dumps({"message": "success"}))
94+
95+
self.assertEqual(result["StatusCode"], 200)
96+
result_payload = json.loads(result["Payload"].read().decode("utf-8"))
97+
self.assertIn("message", result_payload)
98+
self.assertEqual("success", result_payload["message"])
99+
100+
spans = tracer.recorder.queued_spans()
101+
self.assertEqual(2, len(spans))
102+
103+
filter = lambda span: span.n == "sdk"
104+
test_span = get_first_span_by_filter(spans, filter)
105+
self.assertTrue(test_span)
106+
107+
filter = lambda span: span.n == "boto3"
108+
boto_span = get_first_span_by_filter(spans, filter)
109+
self.assertTrue(boto_span)
110+
111+
self.assertEqual(boto_span.t, test_span.t)
112+
self.assertEqual(boto_span.p, test_span.s)
113+
114+
self.assertIsNone(test_span.ec)
115+
self.assertIsNone(boto_span.ec)
116+
117+
self.assertEqual(boto_span.data['boto3']['op'], 'Invoke')
118+
endpoint = f'https://lambda.{self.lambda_region}.amazonaws.com'
119+
self.assertEqual(boto_span.data['boto3']['ep'], endpoint)
120+
self.assertEqual(boto_span.data['boto3']['reg'], self.lambda_region)
121+
self.assertIn('FunctionName', boto_span.data['boto3']['payload'])
122+
self.assertEqual(boto_span.data['boto3']['payload']['FunctionName'], self.function_name)
123+
self.assertEqual(boto_span.data['http']['status'], 200)
124+
self.assertEqual(boto_span.data['http']['method'], 'POST')
125+
self.assertEqual(boto_span.data['http']['url'], f'{endpoint}:443/Invoke')
126+
127+
self.assertIn("X-Capture-This", boto_span.data["http"]["header"])
128+
self.assertEqual("this", boto_span.data["http"]["header"]["X-Capture-This"])
129+
self.assertIn("X-Capture-That", boto_span.data["http"]["header"])
130+
self.assertEqual("that", boto_span.data["http"]["header"]["X-Capture-That"])
131+
132+
agent.options.extra_http_headers = original_extra_http_headers
133+
134+
135+
def test_request_header_capture_before_sign(self):
136+
original_extra_http_headers = agent.options.extra_http_headers
137+
agent.options.extra_http_headers = ['X-Custom-1', 'X-Custom-2']
138+
139+
# Access the event system on the S3 client
140+
event_system = self.aws_lambda.meta.events
141+
142+
request_headers = {
143+
'X-Custom-1': 'Value1',
144+
'X-Custom-2': 'Value2'
145+
}
146+
147+
# Create a function that adds custom headers
148+
def add_custom_header_before_sign(request, **kwargs):
149+
for name, value in request_headers.items():
150+
request.headers.add_header(name, value)
151+
152+
# Register the function to before-sign event.
153+
event_system.register_first('before-sign.lambda.Invoke', add_custom_header_before_sign)
154+
155+
with tracer.start_active_span('test'):
156+
result = self.aws_lambda.invoke(FunctionName=self.function_name, Payload=json.dumps({"message": "success"}))
157+
158+
self.assertEqual(result["StatusCode"], 200)
159+
result_payload = json.loads(result["Payload"].read().decode("utf-8"))
160+
self.assertIn("message", result_payload)
161+
self.assertEqual("success", result_payload["message"])
162+
163+
spans = tracer.recorder.queued_spans()
164+
self.assertEqual(2, len(spans))
165+
166+
filter = lambda span: span.n == "sdk"
167+
test_span = get_first_span_by_filter(spans, filter)
168+
self.assertTrue(test_span)
169+
170+
filter = lambda span: span.n == "boto3"
171+
boto_span = get_first_span_by_filter(spans, filter)
172+
self.assertTrue(boto_span)
173+
174+
self.assertEqual(boto_span.t, test_span.t)
175+
self.assertEqual(boto_span.p, test_span.s)
176+
177+
self.assertIsNone(test_span.ec)
178+
self.assertIsNone(boto_span.ec)
179+
180+
self.assertEqual(boto_span.data['boto3']['op'], 'Invoke')
181+
endpoint = f'https://lambda.{self.lambda_region}.amazonaws.com'
182+
self.assertEqual(boto_span.data['boto3']['ep'], endpoint)
183+
self.assertEqual(boto_span.data['boto3']['reg'], self.lambda_region)
184+
self.assertIn('FunctionName', boto_span.data['boto3']['payload'])
185+
self.assertEqual(boto_span.data['boto3']['payload']['FunctionName'], self.function_name)
186+
self.assertEqual(boto_span.data['http']['status'], 200)
187+
self.assertEqual(boto_span.data['http']['method'], 'POST')
188+
self.assertEqual(boto_span.data['http']['url'], f'{endpoint}:443/Invoke')
189+
190+
self.assertIn("X-Custom-1", boto_span.data["http"]["header"])
191+
self.assertEqual("Value1", boto_span.data["http"]["header"]["X-Custom-1"])
192+
self.assertIn("X-Custom-2", boto_span.data["http"]["header"])
193+
self.assertEqual("Value2", boto_span.data["http"]["header"]["X-Custom-2"])
194+
195+
agent.options.extra_http_headers = original_extra_http_headers
196+
197+
198+
def test_response_header_capture(self):
199+
original_extra_http_headers = agent.options.extra_http_headers
200+
agent.options.extra_http_headers = ['X-Capture-This-Too', 'X-Capture-That-Too']
201+
202+
# Access the event system on the S3 client
203+
event_system = self.aws_lambda.meta.events
204+
205+
response_headers = {
206+
"X-Capture-This-Too": "this too",
207+
"X-Capture-That-Too": "that too",
208+
}
209+
210+
# Create a function that sets the custom headers in the after-call event.
211+
def modify_after_call_args(parsed, **kwargs):
212+
parsed['ResponseMetadata']['HTTPHeaders'].update(response_headers)
213+
214+
# Register the function to an event
215+
event_system.register('after-call.lambda.Invoke', modify_after_call_args)
216+
217+
with tracer.start_active_span('test'):
218+
result = self.aws_lambda.invoke(FunctionName=self.function_name, Payload=json.dumps({"message": "success"}))
219+
220+
self.assertEqual(result["StatusCode"], 200)
221+
result_payload = json.loads(result["Payload"].read().decode("utf-8"))
222+
self.assertIn("message", result_payload)
223+
self.assertEqual("success", result_payload["message"])
224+
225+
spans = tracer.recorder.queued_spans()
226+
self.assertEqual(2, len(spans))
227+
228+
filter = lambda span: span.n == "sdk"
229+
test_span = get_first_span_by_filter(spans, filter)
230+
self.assertTrue(test_span)
231+
232+
filter = lambda span: span.n == "boto3"
233+
boto_span = get_first_span_by_filter(spans, filter)
234+
self.assertTrue(boto_span)
235+
236+
self.assertEqual(boto_span.t, test_span.t)
237+
self.assertEqual(boto_span.p, test_span.s)
238+
239+
self.assertIsNone(test_span.ec)
240+
self.assertIsNone(boto_span.ec)
241+
242+
self.assertEqual(boto_span.data['boto3']['op'], 'Invoke')
243+
endpoint = f'https://lambda.{self.lambda_region}.amazonaws.com'
244+
self.assertEqual(boto_span.data['boto3']['ep'], endpoint)
245+
self.assertEqual(boto_span.data['boto3']['reg'], self.lambda_region)
246+
self.assertIn('FunctionName', boto_span.data['boto3']['payload'])
247+
self.assertEqual(boto_span.data['boto3']['payload']['FunctionName'], self.function_name)
248+
self.assertEqual(boto_span.data['http']['status'], 200)
249+
self.assertEqual(boto_span.data['http']['method'], 'POST')
250+
self.assertEqual(boto_span.data['http']['url'], f'{endpoint}:443/Invoke')
251+
252+
self.assertIn("X-Capture-This-Too", boto_span.data["http"]["header"])
253+
self.assertEqual("this too", boto_span.data["http"]["header"]["X-Capture-This-Too"])
254+
self.assertIn("X-Capture-That-Too", boto_span.data["http"]["header"])
255+
self.assertEqual("that too", boto_span.data["http"]["header"]["X-Capture-That-Too"])
256+
257+
agent.options.extra_http_headers = original_extra_http_headers

0 commit comments

Comments
 (0)