Skip to content

Commit

Permalink
tests(django): increase coverage
Browse files Browse the repository at this point in the history
Signed-off-by: Varsha GS <varsha.gs@ibm.com>
  • Loading branch information
Varsha GS committed Aug 21, 2024
1 parent 9d86bea commit de9edc0
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 29 deletions.
60 changes: 33 additions & 27 deletions src/instana/instrumentation/django/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def process_response(self, request: "WSGIRequest", response: "HttpResponse") ->
try:
from django.urls import resolve
view_name = resolve(request.path)._func_path
path_tpl = "".join(self.__url_pattern_route(view_name))
path_tpl = "".join(url_pattern_route(view_name))
except Exception:
# the resolve method can fire a Resolver404 exception, in this case there is no matching route
# so the path_tpl is set to None in order not to be added as a tag
Expand All @@ -108,6 +108,9 @@ def process_response(self, request: "WSGIRequest", response: "HttpResponse") ->
if request.span.is_recording():
request.span.end()
request.span = None
if request.token:
context.detach(request.token)
request.token = None
return response

def process_exception(self, request: "WSGIRequest", exception: Exception) -> None:
Expand All @@ -119,32 +122,35 @@ def process_exception(self, request: "WSGIRequest", exception: Exception) -> Non
if request.span:
request.span.record_exception(exception)

def __url_pattern_route(self, view_name: str) -> Callable[..., object]:
from django.conf import settings
from django.urls import RegexURLResolver as URLResolver

urlconf = __import__(settings.ROOT_URLCONF, {}, {}, [''])

def list_urls(urlpatterns: List[str], parent_pattern: Optional[List[str]]=None) -> Callable[..., object]:
if not urlpatterns:
return
if parent_pattern is None:
parent_pattern = []
first = urlpatterns[0]
if isinstance(first, URLPattern):
if first.lookup_str == view_name:
if hasattr(first, "regex"):
return parent_pattern + [str(first.regex.pattern)]
else:
return parent_pattern + [str(first.pattern)]
elif isinstance(first, URLResolver):
def url_pattern_route(view_name: str) -> Callable[..., object]:
from django.conf import settings
try:
from django.urls import (RegexURLPattern as URLPattern, RegexURLResolver as URLResolver)
except ImportError:
from django.urls import URLPattern, URLResolver

urlconf = __import__(settings.ROOT_URLCONF, {}, {}, [''])

def list_urls(urlpatterns: List[str], parent_pattern: Optional[List[str]]=None) -> Callable[..., object]:
if not urlpatterns:
return
if parent_pattern is None:
parent_pattern = []
first = urlpatterns[0]
if isinstance(first, URLPattern):
if first.lookup_str == view_name:
if hasattr(first, "regex"):
return list_urls(first.url_patterns, parent_pattern + [str(first.regex.pattern)])
return parent_pattern + [str(first.regex.pattern)]
else:
return list_urls(first.url_patterns, parent_pattern + [str(first.pattern)])
return list_urls(urlpatterns[1:], parent_pattern)
return parent_pattern + [str(first.pattern)]
elif isinstance(first, URLResolver):
if hasattr(first, "regex"):
return list_urls(first.url_patterns, parent_pattern + [str(first.regex.pattern)])
else:
return list_urls(first.url_patterns, parent_pattern + [str(first.pattern)])
return list_urls(urlpatterns[1:], parent_pattern)

return list_urls(urlconf.urlpatterns)
return list_urls(urlconf.urlpatterns)


def load_middleware_wrapper(wrapped: Callable[..., None], instance: "WSGIHandler", args: Tuple[object, ...], kwargs: Dict[str, Any]) -> Callable[..., None]:
Expand All @@ -164,7 +170,7 @@ def load_middleware_wrapper(wrapped: Callable[..., None], instance: "WSGIHandler
else:
logger.warning("Instana: Couldn't add InstanaMiddleware to Django")

elif hasattr(settings, 'MIDDLEWARE_CLASSES') and settings.MIDDLEWARE_CLASSES is not None:
elif hasattr(settings, 'MIDDLEWARE_CLASSES') and settings.MIDDLEWARE_CLASSES is not None: # pragma: no cover
if DJ_INSTANA_MIDDLEWARE in settings.MIDDLEWARE_CLASSES:
return wrapped(*args, **kwargs)

Expand All @@ -175,7 +181,7 @@ def load_middleware_wrapper(wrapped: Callable[..., None], instance: "WSGIHandler
else:
logger.warning("Instana: Couldn't add InstanaMiddleware to Django")

else:
else: # pragma: no cover
logger.warning("Instana: Couldn't find middleware settings")

return wrapped(*args, **kwargs)
Expand All @@ -188,7 +194,7 @@ def load_middleware_wrapper(wrapped: Callable[..., None], instance: "WSGIHandler
logger.debug("Instrumenting django")
wrapt.wrap_function_wrapper('django.core.handlers.base', 'BaseHandler.load_middleware', load_middleware_wrapper)

if '/tmp/.instana/python' in sys.path:
if '/tmp/.instana/python' in sys.path: # pragma: no cover
# If we are instrumenting via AutoTrace (in an already running process), then the
# WSGI middleware has to be live reloaded.
from django.core.servers.basehttp import get_internal_wsgi_application
Expand Down
13 changes: 11 additions & 2 deletions tests/apps/app_django.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import time

try:
from django.urls import re_path
from django.urls import re_path, include
except ImportError:
from django.conf.urls import url as re_path

Expand Down Expand Up @@ -96,6 +96,10 @@ def cause_error(request):
raise Exception('This is a fake error: /cause-error')


def induce_exception(request):
raise Exception('This is a fake error: /induce-exception')


def another(request):
return HttpResponse('Stan wuz here!')

Expand Down Expand Up @@ -134,11 +138,16 @@ def response_with_headers(request):
return HttpResponse('Stan wuz here with headers!', headers=headers)


extra_patterns = [
re_path(r'^induce_exception$', induce_exception, name='induce_exception'),
]

urlpatterns = [
re_path(r'^$', index, name='index'),
re_path(r'^cause_error$', cause_error, name='cause_error'),
re_path(r'^another$', another),
re_path(r'^not_found$', not_found, name='not_found'),
re_path(r'^response_with_headers$', response_with_headers, name='response_with_headers'),
re_path(r"^exception$", include(extra_patterns)),
re_path(r'^complex$', complex, name='complex'),
re_path(r'^response_with_headers$', response_with_headers, name='response_with_headers')
]
13 changes: 13 additions & 0 deletions tests/frameworks/test_django.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from tests.apps.app_django import INSTALLED_APPS
from instana.singletons import agent, tracer
from tests.helpers import fail_with_message_and_span_dump, get_first_span_by_filter, drop_log_spans_from_list
from instana.instrumentation.django.middleware import url_pattern_route

apps.populate(INSTALLED_APPS)

Expand Down Expand Up @@ -573,3 +574,15 @@ def test_with_incoming_mixed_case_context(self) -> None:
assert 'Server-Timing' in response.headers
server_timing_value = "intid;desc=%s" % django_span.t
assert response.headers['Server-Timing'] == server_timing_value

def test_url_pattern_route(self) -> None:
view_name="app_django.another"
path_tpl = "".join(url_pattern_route(view_name))
assert path_tpl == "^another$"

view_name="app_django.complex"
try:
path_tpl = "".join(url_pattern_route(view_name))
except Exception:
path_tpl = None
assert path_tpl is None

0 comments on commit de9edc0

Please sign in to comment.