diff --git a/tests/models.py b/tests/models.py index b07664349..def707962 100644 --- a/tests/models.py +++ b/tests/models.py @@ -100,6 +100,34 @@ class RegularFieldsModel(models.Model): return 'method' +class RegularFieldsModel2(models.Model): + """ + A model class for testing regular flat fields. + """ + auto_field = models.AutoField(primary_key=True) + big_integer_field = models.BigIntegerField() + boolean_field = models.BooleanField(default=False) + char_field = models.CharField(max_length=100) + comma_separated_integer_field = models.CommaSeparatedIntegerField(max_length=100) + date_field = models.DateField() + datetime_field = models.DateTimeField() + decimal_field = models.DecimalField(max_digits=3, decimal_places=1) + email_field = models.EmailField(max_length=100) + float_field = models.FloatField() + integer_field = models.IntegerField() + null_boolean_field = models.NullBooleanField() + positive_integer_field = models.PositiveIntegerField() + positive_small_integer_field = models.PositiveSmallIntegerField() + slug_field = models.SlugField(max_length=100) + small_integer_field = models.SmallIntegerField() + text_field = models.TextField() + time_field = models.TimeField() + url_field = models.URLField(max_length=100) + + def method(self): + return 'method' + + class RegularFieldsAndFKModel(models.Model): """ A model class for testing regular flat fields. @@ -128,3 +156,33 @@ class RegularFieldsAndFKModel(models.Model): def method(self): return 'method' + + +class RegularFieldsAndFKModel2(models.Model): + """ + A model class for testing regular flat fields. + """ + auto_field = models.AutoField(primary_key=True) + big_integer_field = models.BigIntegerField() + boolean_field = models.BooleanField(default=False) + char_field = models.CharField(max_length=100) + comma_separated_integer_field = models.CommaSeparatedIntegerField(max_length=100) + date_field = models.DateField() + datetime_field = models.DateTimeField() + decimal_field = models.DecimalField(max_digits=3, decimal_places=1) + email_field = models.EmailField(max_length=100) + float_field = models.FloatField() + integer_field = models.IntegerField() + null_boolean_field = models.NullBooleanField() + positive_integer_field = models.PositiveIntegerField() + positive_small_integer_field = models.PositiveSmallIntegerField() + slug_field = models.SlugField(max_length=100) + small_integer_field = models.SmallIntegerField() + text_field = models.TextField() + time_field = models.TimeField() + url_field = models.URLField(max_length=100) + fk = models.ForeignKey(RegularFieldsModel2) + + def method(self): + return 'method' + diff --git a/tests/test_full_stack_benchmarks.py b/tests/test_full_stack_benchmarks.py new file mode 100644 index 000000000..98ab15258 --- /dev/null +++ b/tests/test_full_stack_benchmarks.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python +# coding: utf-8 +from pytest import mark +from datetime import datetime +from decimal import Decimal +from rest_framework import viewsets, serializers +from rest_framework.reverse import reverse +from rest_framework.routers import DefaultRouter +from rest_framework.test import APITransactionTestCase +from tests.models import RegularFieldsAndFKModel2, RegularFieldsModel2 + +data = { + 'big_integer_field': 100000, + 'char_field': 'a', + 'comma_separated_integer_field': '1,2', + 'date_field': datetime.now().date(), + 'datetime_field': datetime.now(), + 'decimal_field': Decimal('1.5'), + 'email_field': 'somewhere@overtherainbow.com', + 'float_field': 0.443, + 'integer_field': 55, + 'null_boolean_field': True, + 'positive_integer_field': 1, + 'positive_small_integer_field': 1, + 'slug_field': 'slug-friendly-text', + 'small_integer_field': 1, + 'text_field': 'lorem ipsum', + 'time_field': datetime.now().time(), + 'url_field': 'https://overtherainbow.com' +} + +data_list = [data for _ in range(100)] + + +class TestSerializer(serializers.ModelSerializer): + class Meta: + model = RegularFieldsModel2 + fields = list(data.keys()) + ['method'] + + +class TestNestedSerializer(serializers.ModelSerializer): + fk = TestSerializer() + + class Meta: + model = RegularFieldsAndFKModel2 + fields = list(data.keys()) + ['fk', 'method'] + + +class RegularFieldsAndFKViewSet(viewsets.ModelViewSet): + queryset = RegularFieldsAndFKModel2.objects.all() + serializer_class = TestNestedSerializer + + +router = DefaultRouter() +router.register('benchmark', RegularFieldsAndFKViewSet, base_name='benchmark') + +urlpatterns = router.urls + + +class FullStackBenchmarksTestCase(APITransactionTestCase): + urls = 'tests.test_full_stack_benchmarks' + + def setUp(self): + RegularFieldsModel2.objects.bulk_create([RegularFieldsModel2(**d) for d in data_list]) + + RegularFieldsAndFKModel2.objects.bulk_create( + [RegularFieldsAndFKModel2(fk=o, **data) for o in RegularFieldsModel2.objects.all()]) + + self.first_pk = RegularFieldsAndFKModel2.objects.only('pk').first().pk + self.last_pk = RegularFieldsAndFKModel2.objects.only('pk').last().pk + + @mark.bench('viewsets.ModelViewSet.list', iterations=1000) + def test_viewset_list(self): + url = reverse('benchmark-list') + + response = self.client.get(url) + assert response.status_code == 200, (response.rendered_content, url) + + @mark.bench('viewsets.ModelViewSet.retrieve', iterations=10000) + def test_viewset_retrieve(self): + url = reverse('benchmark-detail', args=[self.first_pk]) + + response = self.client.get(url) + assert response.status_code == 200, (response.rendered_content, url) + + @mark.bench('viewsets.ModelViewSet.create', iterations=1000) + def test_viewset_create(self): + url = reverse('benchmark-list') + + new_data = data.copy() + new_data['fk'] = data.copy() + + response = self.client.post(url, data=new_data) + assert response.status_code == 201, (response.rendered_content, url) + + @mark.bench('viewsets.ModelViewSet.update', iterations=1000) + def test_viewset_update(self): + url = reverse('benchmark-detail', args=[self.first_pk]) + + new_data = data.copy() + new_fk = RegularFieldsModel2.objects.create(**data) + new_fk_data = data.copy() + new_fk_data['auto_field'] = new_fk.pk + new_data['fk'] = new_fk_data + + response = self.client.put(url, data=new_data) + assert response.status_code == 200, (response.rendered_content, url) + + @mark.bench('viewsets.ModelViewSet.partial_update', iterations=1000) + def test_viewset_partial_update(self): + url = reverse('benchmark-detail', args=[self.first_pk]) + + new_fk = RegularFieldsModel2.objects.create(**data) + new_fk_data = data.copy() + new_fk_data['auto_field'] = new_fk.pk + new_data = {'fk': new_fk_data} + + response = self.client.patch(url, data=new_data) + assert response.status_code == 200, (response.rendered_content, url) + + @mark.bench('viewsets.ModelViewSet.destroy', iterations=10000) + def test_viewset_delete(self): + new_fk = RegularFieldsModel2.objects.create(**data) + new_obj = RegularFieldsAndFKModel2.objects.create(fk=new_fk, **data) + + url = reverse('benchmark-detail', args=[new_obj.pk]) + + response = self.client.delete(url) + assert response.status_code == 204, (response.rendered_content, url)