Skip to content

Commit

Permalink
issue-76: Disable the log for a specific stub (#110)
Browse files Browse the repository at this point in the history
* issue-76: Disable the log for a specific stub

* issue-76: fixes partial coverage

* issue-76: replaces is_logging_enabled with enable_logging

* issue-76: moves enable_logging to top
  • Loading branch information
lowitea authored Mar 17, 2021
1 parent d1b21e2 commit 11a008f
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 19 deletions.
18 changes: 18 additions & 0 deletions http_stubs/migrations/0006_httpstub_is_logging_enabled.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 3.1.4 on 2021-03-16 22:37

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('http_stubs', '0005_httpstub_request_script_logentry_result_script'),
]

operations = [
migrations.AddField(
model_name='httpstub',
name='enable_logging',
field=models.BooleanField(default=False, help_text='Enables logging of requests', verbose_name='Logging'),
),
]
5 changes: 5 additions & 0 deletions http_stubs/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ class HTTPStub(models.Model):
help_text='Path is a regular expression',
default=False,
)
enable_logging = models.BooleanField(
verbose_name='Logging',
help_text='Enables logging of requests',
default=False,
)
method = models.CharField(
verbose_name='Request method',
max_length=10,
Expand Down
23 changes: 17 additions & 6 deletions http_stubs/tasks.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
from typing import Optional

import requests
from billiard.exceptions import SoftTimeLimitExceeded
Expand All @@ -25,22 +26,32 @@


@celery_app.task()
def run_request_script(log_id: int, script: str, request_body: str) -> None:
def run_request_script(
script: str,
request_body: str,
log_id: Optional[int] = None,
) -> None:
"""Task for run custom scripts from http stubs.
:param log_id: LogEntry.id
:param script: HTTPStub.request_script
:param request_body: text body from a request
"""
log: LogEntry = LogEntry.objects.get(pk=log_id)
log: Optional[LogEntry] = None
if log_id is not None:
log = LogEntry.objects.get(pk=log_id)

loc = {'request_body': request_body, **restricted_builtins}
byte_code = compile_restricted(script)
try:
exec(byte_code, loc, None) # noqa: S102, WPS421
except SoftTimeLimitExceeded:
log.result_script = 'Error: Execution time limit exceeded'
log_msg = 'Error: Execution time limit exceeded'
except Exception as err:
log.result_script = f'Error: {err}'
log_msg = f'Error: {err}'
else:
log.result_script = 'Done'
log.save()
log_msg = 'Done'

if log is not None:
log.result_script = log_msg
log.save()
11 changes: 10 additions & 1 deletion http_stubs/tests/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@ def test_run_request_script(script, expect, log_entity_factory):
:param log_entity_factory: a factory for make LogEntity
"""
log = log_entity_factory()
run_request_script.delay(log_id=log.id, script=script, request_body='')
run_request_script.delay(script=script, request_body='', log_id=log.id)
log.refresh_from_db()
assert log.result_script == expect


@pytest.mark.parametrize('script', ('a = 1', '1 / 0'))
def test_run_without_log(script):
"""Tests run task without log_id.
:param script: a request script
"""
run_request_script.run(script=script, request_body='')
17 changes: 15 additions & 2 deletions http_stubs/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,12 @@ def test_write_log(self, http_stub_factory, client):
:param client: http client fixture
"""
content_type = 'text/plain'
http_body = http_stub_factory(
http_stub = http_stub_factory(
method=HTTPMethod.POST.name,
path='/regex/',
regex_path=True,
request_script='a = 1',
enable_logging=True,
)

request_path = f'/regex/?query={"search" * 300}'
Expand All @@ -78,11 +79,23 @@ def _datefmt(date) -> str: # noqa:WPS430
'Cookie': '',
}
assert log.body == 'test'
assert log.http_stub == http_body
assert log.http_stub == http_stub
assert log.method == HTTPMethod.POST.name
assert log.path == f'http://testserver{request_path}'
assert log.result_script == 'Done'

def test_empty_log(self, http_stub_factory, client):
"""Tests http stub without logs.
:param http_stub_factory: HTTPStub factory
:param client: http client fixture
"""
stub_path = '/test/'
http_stub_factory(method=HTTPMethod.POST.name, path=stub_path)
response = client.post(stub_path)
assert response.status_code == HTTPStatus.OK
assert LogEntry.objects.last() is None

@pytest.mark.parametrize('method', HTTPMethod.names())
def test_exist_regexp_stub(self, method: str, http_stub_factory, client):
"""Tests response for the regex stub.
Expand Down
23 changes: 13 additions & 10 deletions http_stubs/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,24 @@ def dispatch(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
if not stub:
return HttpResponseNotFound()

log = LogEntry.objects.create(
path=request.build_absolute_uri(),
method=request.method,
source_ip=request.META['REMOTE_ADDR'],
body=request.body.decode('utf-8'),
headers=dict(request.headers),
http_stub=stub,
result_script='Was launched' if stub.request_script else '',
)
log = None

if stub.enable_logging:
log = LogEntry.objects.create(
path=request.build_absolute_uri(),
method=request.method,
source_ip=request.META['REMOTE_ADDR'],
body=request.body.decode('utf-8'),
headers=dict(request.headers),
http_stub=stub,
result_script='Was launched' if stub.request_script else '',
)

if stub.request_script:
run_request_script.delay(
log_id=log.pk,
script=stub.request_script,
request_body=request.body.decode('utf-8'),
log_id=log.pk if log else None,
)

sleep(stub.resp_delay / 1000)
Expand Down

0 comments on commit 11a008f

Please sign in to comment.