Skip to content

Commit

Permalink
Add support for storages, that don't implement full filesystem path
Browse files Browse the repository at this point in the history
  • Loading branch information
mizi committed Sep 12, 2022
1 parent 8664e8c commit 77fcdcf
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 2 deletions.
26 changes: 26 additions & 0 deletions project/tests/test_collector.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
from django.test import TestCase
from tests.util import DictStorage

from silk.collector import DataCollector

from .factories import RequestMinFactory


class TestCollector(TestCase):
def test_singleton(self):
Expand All @@ -19,3 +22,26 @@ def test_clear(self):
self.test_query_registration()
DataCollector().clear()
self.assertFalse(DataCollector().queries)

def test_finalise(self):
request = RequestMinFactory()
DataCollector().configure(request)
with self.subTest("Default file-based storage"):
DataCollector().finalise()
file = DataCollector().request.prof_file
self.assertIsNotNone(file)
with file.storage.open(file.name) as f:
content = f.read()
self.assertTrue(content)

# Some storages, such as S3Boto3Storage, don't support local file system path.
# Simulate this behaviour using DictStorage.
with self.subTest("Pathless storage"):
request.prof_file.storage = DictStorage()
DataCollector().finalise()
file = DataCollector().request.prof_file
self.assertIsNotNone(file)
with file.storage.open(file.name) as f:
content = f.read()
self.assertTrue(content)
self.assertGreater(len(content), 0)
22 changes: 22 additions & 0 deletions project/tests/util.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import io
from unittest.mock import Mock

from django.core.files import File
from django.core.files.storage import Storage

from silk.models import Request


Expand All @@ -22,3 +26,21 @@ def delete_all_models(model_class):
while model_class.objects.count():
ids = model_class.objects.values_list('pk', flat=True)[:80]
model_class.objects.filter(pk__in=ids).delete()


class DictStorage(Storage):
"""Storage that stores files in a dictionary - for testing."""

def __init__(self):
self.files = {}

def open(self, name, mode="rb"):
if name not in self.files:
self.files[name] = b""
return File(io.BytesIO(self.files[name]), name=name)

def get_valid_name(self, name):
return name

def exists(self, name):
return name in self.files
5 changes: 3 additions & 2 deletions silk/collector.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import cProfile
import logging
import marshal
import pstats
from io import StringIO
from threading import local
Expand Down Expand Up @@ -144,8 +145,8 @@ def finalise(self):

if SilkyConfig().SILKY_PYTHON_PROFILER_BINARY:
file_name = self.request.prof_file.storage.get_available_name(f"{str(self.request.id)}.prof")
with open(self.request.prof_file.storage.path(file_name), 'w+b') as f:
ps.dump_stats(f.name)
with self.request.prof_file.storage.open(file_name, 'w+b') as f:
marshal.dump(ps.stats, f)
self.request.prof_file = f.name
self.request.save()

Expand Down

0 comments on commit 77fcdcf

Please sign in to comment.