1111# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212# See the License for the specific language governing permissions and
1313# limitations under the License.
14-
14+ #
1515from unittest .mock import Mock , patch
1616
17+ import pytest
18+ from falcon import __version__ as _falcon_verison
1719from falcon import testing
20+ from packaging import version as package_version
1821
1922from opentelemetry import trace
2023from opentelemetry .instrumentation .falcon import FalconInstrumentor
@@ -84,9 +87,7 @@ def test_head(self):
8487 self ._test_method ("HEAD" )
8588
8689 def _test_method (self , method ):
87- self .client ().simulate_request (
88- method = method , path = "/hello" , remote_addr = "127.0.0.1"
89- )
90+ self .client ().simulate_request (method = method , path = "/hello" )
9091 spans = self .memory_exporter .get_finished_spans ()
9192 self .assertEqual (len (spans ), 1 )
9293 span = spans [0 ]
@@ -105,17 +106,23 @@ def _test_method(self, method):
105106 SpanAttributes .NET_HOST_PORT : 80 ,
106107 SpanAttributes .HTTP_HOST : "falconframework.org" ,
107108 SpanAttributes .HTTP_TARGET : "/" ,
108- SpanAttributes .NET_PEER_IP : "127.0.0.1" ,
109109 SpanAttributes .NET_PEER_PORT : "65133" ,
110110 SpanAttributes .HTTP_FLAVOR : "1.1" ,
111111 "falcon.resource" : "HelloWorldResource" ,
112112 SpanAttributes .HTTP_STATUS_CODE : 201 ,
113113 },
114114 )
115+ # In falcon<3, NET_PEER_IP is always set by default to 127.0.0.1
116+ # In falcon>3, NET_PEER_IP is not set to anything by default to
117+ # https://github.com/falconry/falcon/blob/5233d0abed977d9dab78ebadf305f5abe2eef07c/falcon/testing/helpers.py#L1168-L1172 # noqa
118+ if SpanAttributes .NET_PEER_IP in span .attributes :
119+ self .assertEqual (
120+ span .attributes [SpanAttributes .NET_PEER_IP ], "127.0.0.1"
121+ )
115122 self .memory_exporter .clear ()
116123
117124 def test_404 (self ):
118- self .client ().simulate_get ("/does-not-exist" , remote_addr = "127.0.0.1" )
125+ self .client ().simulate_get ("/does-not-exist" )
119126 spans = self .memory_exporter .get_finished_spans ()
120127 self .assertEqual (len (spans ), 1 )
121128 span = spans [0 ]
@@ -130,16 +137,22 @@ def test_404(self):
130137 SpanAttributes .NET_HOST_PORT : 80 ,
131138 SpanAttributes .HTTP_HOST : "falconframework.org" ,
132139 SpanAttributes .HTTP_TARGET : "/" ,
133- SpanAttributes .NET_PEER_IP : "127.0.0.1" ,
134140 SpanAttributes .NET_PEER_PORT : "65133" ,
135141 SpanAttributes .HTTP_FLAVOR : "1.1" ,
136142 SpanAttributes .HTTP_STATUS_CODE : 404 ,
137143 },
138144 )
145+ # In falcon<3, NET_PEER_IP is always set by default to 127.0.0.1
146+ # In falcon>3, NET_PEER_IP is not set to anything by default to
147+ # https://github.com/falconry/falcon/blob/5233d0abed977d9dab78ebadf305f5abe2eef07c/falcon/testing/helpers.py#L1168-L1172 # noqa
148+ if SpanAttributes .NET_PEER_IP in span .attributes :
149+ self .assertEqual (
150+ span .attributes [SpanAttributes .NET_PEER_IP ], "127.0.0.1"
151+ )
139152
140153 def test_500 (self ):
141154 try :
142- self .client ().simulate_get ("/error" , remote_addr = "127.0.0.1" )
155+ self .client ().simulate_get ("/error" )
143156 except NameError :
144157 pass
145158 spans = self .memory_exporter .get_finished_spans ()
@@ -161,12 +174,18 @@ def test_500(self):
161174 SpanAttributes .NET_HOST_PORT : 80 ,
162175 SpanAttributes .HTTP_HOST : "falconframework.org" ,
163176 SpanAttributes .HTTP_TARGET : "/" ,
164- SpanAttributes .NET_PEER_IP : "127.0.0.1" ,
165177 SpanAttributes .NET_PEER_PORT : "65133" ,
166178 SpanAttributes .HTTP_FLAVOR : "1.1" ,
167179 SpanAttributes .HTTP_STATUS_CODE : 500 ,
168180 },
169181 )
182+ # In falcon<3, NET_PEER_IP is always set by default to 127.0.0.1
183+ # In falcon>3, NET_PEER_IP is not set to anything by default to
184+ # https://github.com/falconry/falcon/blob/5233d0abed977d9dab78ebadf305f5abe2eef07c/falcon/testing/helpers.py#L1168-L1172 # noqa
185+ if SpanAttributes .NET_PEER_IP in span .attributes :
186+ self .assertEqual (
187+ span .attributes [SpanAttributes .NET_PEER_IP ], "127.0.0.1"
188+ )
170189
171190 def test_uninstrument (self ):
172191 self .client ().simulate_get (path = "/hello" )
@@ -191,7 +210,7 @@ def test_exclude_lists(self):
191210 self .assertEqual (len (span_list ), 1 )
192211
193212 def test_traced_request_attributes (self ):
194- self .client ().simulate_get (path = "/hello? q=abc" )
213+ self .client ().simulate_get (path = "/hello" , query_string = " q=abc" )
195214 span = self .memory_exporter .get_finished_spans ()[0 ]
196215 self .assertIn ("query_string" , span .attributes )
197216 self .assertEqual (span .attributes ["query_string" ], "q=abc" )
@@ -201,7 +220,9 @@ def test_trace_response(self):
201220 orig = get_global_response_propagator ()
202221 set_global_response_propagator (TraceResponsePropagator ())
203222
204- response = self .client ().simulate_get (path = "/hello?q=abc" )
223+ response = self .client ().simulate_get (
224+ path = "/hello" , query_string = "q=abc"
225+ )
205226 self .assertTraceResponseHeaderMatchesSpan (
206227 response .headers , self .memory_exporter .get_finished_spans ()[0 ]
207228 )
@@ -215,7 +236,7 @@ def test_traced_not_recording(self):
215236 mock_tracer .start_span .return_value = mock_span
216237 with patch ("opentelemetry.trace.get_tracer" ) as tracer :
217238 tracer .return_value = mock_tracer
218- self .client ().simulate_get (path = "/hello? q=abc" )
239+ self .client ().simulate_get (path = "/hello" , query_string = " q=abc" )
219240 self .assertFalse (mock_span .is_recording ())
220241 self .assertTrue (mock_span .is_recording .called )
221242 self .assertFalse (mock_span .set_attribute .called )
@@ -261,7 +282,7 @@ def response_hook(self, span, req, resp):
261282 span .update_name ("set from hook" )
262283
263284 def test_hooks (self ):
264- self .client ().simulate_get (path = "/hello? q=abc" )
285+ self .client ().simulate_get (path = "/hello" , query_string = " q=abc" )
265286 span = self .memory_exporter .get_finished_spans ()[0 ]
266287
267288 self .assertEqual (span .name , "set from hook" )
@@ -343,6 +364,11 @@ def test_custom_request_header_not_added_in_internal_span(self):
343364 for key , _ in not_expected .items ():
344365 self .assertNotIn (key , span .attributes )
345366
367+ @pytest .mark .skipif (
368+ condition = package_version .parse (_falcon_verison )
369+ < package_version .parse ("2.0.0" ),
370+ reason = "falcon<2 does not implement custom response headers" ,
371+ )
346372 def test_custom_response_header_added_in_server_span (self ):
347373 self .client ().simulate_request (
348374 method = "GET" , path = "/test_custom_response_headers"
@@ -366,6 +392,11 @@ def test_custom_response_header_added_in_server_span(self):
366392 for key , _ in not_expected .items ():
367393 self .assertNotIn (key , span .attributes )
368394
395+ @pytest .mark .skipif (
396+ condition = package_version .parse (_falcon_verison )
397+ < package_version .parse ("2.0.0" ),
398+ reason = "falcon<2 does not implement custom response headers" ,
399+ )
369400 def test_custom_response_header_not_added_in_internal_span (self ):
370401 tracer = trace .get_tracer (__name__ )
371402 with tracer .start_as_current_span ("test" , kind = trace .SpanKind .SERVER ):
0 commit comments