WIP: Deployment #3

Manually merged
MassiveAtoms merged 8 commits from development into master 2020-08-02 14:56:54 +00:00
12 changed files with 376 additions and 18 deletions
Showing only changes of commit d56911901b - Show all commits

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
# project specific # project specific
settings.json settings.json
db.sqlite3 db.sqlite3
*.prof
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files
__pycache__/ __pycache__/

View File

@ -80,6 +80,12 @@ DEBUG_TOOLBAR_PANELS = [
######################################################################## ########################################################################
## DERUG ## ## DERUG ##
# SILKY_PYTHON_PROFILER = True
# SILKY_PYTHON_PROFILER_BINARY = True
# SILKY_PYTHON_PROFILER_RESULT_PATH = BASE_DIR + "/profiler"
# SILKY_META = True
LOGIN_REDIRECT_URL = '/books' LOGIN_REDIRECT_URL = '/books'
# Application definition # Application definition
@ -92,14 +98,14 @@ INSTALLED_APPS = [
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
"library", "library",
# "silk", # "silk", # DEBUG/profilling purposes
# 'debug_toolbar', # DEBUG purposes # 'debug_toolbar', # DEBUG purposes
] ]
MIDDLEWARE = [ MIDDLEWARE = [
# 'silk.middleware.SilkyMiddleware', # DEBUG/profiling purposes # 'silk.middleware.SilkyMiddleware', # DEBUG/profiling purposes
# 'debug_toolbar.middleware.DebugToolbarMiddleware', # DEBUG purposes # 'debug_toolbar.middleware.DebugToolbarMiddleware', # DEBUG purposes
'django.middleware.cache.UpdateCacheMiddleware', # cache # 'django.middleware.cache.UpdateCacheMiddleware', # cache
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
@ -107,8 +113,11 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware', # cache # 'django.middleware.cache.FetchFromCacheMiddleware', # cache
] ]
## ##
########################################################################
ROOT_URLCONF = 'CalibreWebCompanion.urls' ROOT_URLCONF = 'CalibreWebCompanion.urls'

View File

@ -22,6 +22,7 @@ from django.conf import settings
from django.urls import include, path from django.urls import include, path
urlpatterns = [ urlpatterns = [
path('admin/', admin.site.urls), path('admin/', admin.site.urls),
path('accounts/', include('django.contrib.auth.urls')), path('accounts/', include('django.contrib.auth.urls')),

View File

@ -10,18 +10,19 @@ urlpatterns = [
path('ratings/', views.RatingListView.as_view(), name='ratings'), path('ratings/', views.RatingListView.as_view(), name='ratings'),
path('tags/', views.TagListView.as_view(), name='tags'), path('tags/', views.TagListView.as_view(), name='tags'),
path('series/', views.SeriesListView.as_view(), name='series'), path('series/', views.SeriesListView.as_view(), name='series'),
path('author/<int:pk>', views.AuthorDetailView.as_view(),
name='author-detail-view'),
path('author/<int:pk>', views.AuthorDetailView.as_view(), name='author-detail-view'),
path('book/<int:pk>', views.BookDetailView.as_view(), name='book-detail-view'), path('book/<int:pk>', views.BookDetailView.as_view(), name='book-detail-view'),
path('publisher/<int:pk>', views.PublisherDetailView.as_view(), name='publisher-detail-view'), path('publisher/<int:pk>', views.PublisherDetailView.as_view(),
path('rating/<int:pk>', views.RatingDetailView.as_view(), name='rating-detail-view'), name='publisher-detail-view'),
path('series/<int:pk>', views.SeriesDetailView.as_view(), name='series-detail-view'), path('rating/<int:pk>', views.RatingDetailView.as_view(),
name='rating-detail-view'),
path('series/<int:pk>', views.SeriesDetailView.as_view(),
name='series-detail-view'),
path('tag/<int:pk>', views.TagDetailView.as_view(), name='tag-detail-view'), path('tag/<int:pk>', views.TagDetailView.as_view(), name='tag-detail-view'),
path('results/', views.ResultsView.as_view(), name='results'), path('results/', views.ResultsView.as_view(), name='results'),
path('search/', views.SearchView.as_view(), name='search'), path('search/', views.SearchView.as_view(), name='search'),
path('accounts/sign_up/', views.sign_up, name="sign-up") path('accounts/sign_up/', views.sign_up, name="sign-up")

View File

@ -10,6 +10,9 @@ from django.contrib.auth import login
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
# might be helpful for vary headers later
from django.utils.decorators import method_decorator
@login_required @login_required
def index(request): def index(request):
@ -31,6 +34,9 @@ def sign_up(request):
class SearchView(generic.TemplateView): class SearchView(generic.TemplateView):
template_name = 'search.html' template_name = 'search.html'
def dispatch(self, *args, **kwargs):
return super(SearchView, self).dispatch(*args, **kwargs)
class ResultsView(generic.ListView): # no clue if this is secure. class ResultsView(generic.ListView): # no clue if this is secure.
# according to this https://stackoverflow.com/questions/13574043/how-do-django-forms-sanitize-text-input-to-prevent-sql-injection-xss-etc # according to this https://stackoverflow.com/questions/13574043/how-do-django-forms-sanitize-text-input-to-prevent-sql-injection-xss-etc
@ -38,6 +44,9 @@ class ResultsView(generic.ListView): # no clue if this is secure.
model = Book model = Book
template_name = 'results.html' template_name = 'results.html'
def dispatch(self, *args, **kwargs):
return super(ResultsView, self).dispatch(*args, **kwargs)
def get_queryset(self): # new def get_queryset(self): # new
title = self.request.GET.get('title') title = self.request.GET.get('title')
author = self.request.GET.get('author') author = self.request.GET.get('author')
@ -62,10 +71,16 @@ class ResultsView(generic.ListView): # no clue if this is secure.
class AuthorListView(generic.ListView): class AuthorListView(generic.ListView):
model = Author model = Author
def dispatch(self, *args, **kwargs):
return super(AuthorListView, self).dispatch(*args, **kwargs)
class BookListView(generic.ListView): class BookListView(generic.ListView):
model = Book model = Book
def dispatch(self, *args, **kwargs):
return super(BookListView, self).dispatch(*args, **kwargs)
def get_queryset(self): def get_queryset(self):
# Annotate the books with ratings, tags, etc # Annotate the books with ratings, tags, etc
# books = Book.objects.annotate( # books = Book.objects.annotate(
@ -76,21 +91,37 @@ class BookListView(generic.ListView):
class PublisherListView(generic.ListView): class PublisherListView(generic.ListView):
model = Publisher model = Publisher
def dispatch(self, *args, **kwargs):
return super(PublisherListView, self).dispatch(*args, **kwargs)
class RatingListView(generic.ListView): class RatingListView(generic.ListView):
model = Rating model = Rating
def dispatch(self, *args, **kwargs):
return super(RatingListView, self).dispatch(*args, **kwargs)
class SeriesListView(generic.ListView): # make url entry and template, sometime class SeriesListView(generic.ListView): # make url entry and template, sometime
model = Series model = Series
def dispatch(self, *args, **kwargs):
return super(SeriesListView, self).dispatch(*args, **kwargs)
class TagListView(generic.ListView): class TagListView(generic.ListView):
model = Tag model = Tag
def dispatch(self, *args, **kwargs):
return super(TagListView, self).dispatch(*args, **kwargs)
class AuthorDetailView(generic.DetailView): class AuthorDetailView(generic.DetailView):
model = Author model = Author
def dispatch(self, *args, **kwargs):
return super(AuthorDetailView, self).dispatch(*args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
# Call the base implementation first to get the context # Call the base implementation first to get the context
context = super(AuthorDetailView, self).get_context_data(**kwargs) context = super(AuthorDetailView, self).get_context_data(**kwargs)
@ -104,6 +135,9 @@ class AuthorDetailView(generic.DetailView):
class BookDetailView(generic.DetailView): class BookDetailView(generic.DetailView):
model = Book model = Book
def dispatch(self, *args, **kwargs):
return super(BookDetailView, self).dispatch(*args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
# Call the base implementation first to get the context # Call the base implementation first to get the context
context = super(BookDetailView, self).get_context_data(**kwargs) context = super(BookDetailView, self).get_context_data(**kwargs)
@ -122,6 +156,9 @@ class BookDetailView(generic.DetailView):
class PublisherDetailView(generic.DetailView): class PublisherDetailView(generic.DetailView):
model = Publisher model = Publisher
def dispatch(self, *args, **kwargs):
return super(PublisherDetailView, self).dispatch(*args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
# Call the base implementation first to get the context # Call the base implementation first to get the context
context = super(PublisherDetailView, self).get_context_data(**kwargs) context = super(PublisherDetailView, self).get_context_data(**kwargs)
@ -135,6 +172,9 @@ class PublisherDetailView(generic.DetailView):
class RatingDetailView(generic.DetailView): class RatingDetailView(generic.DetailView):
model = Rating model = Rating
def dispatch(self, *args, **kwargs):
return super(RatingDetailView, self).dispatch(*args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
# Call the base implementation first to get the context # Call the base implementation first to get the context
context = super(RatingDetailView, self).get_context_data(**kwargs) context = super(RatingDetailView, self).get_context_data(**kwargs)
@ -148,6 +188,9 @@ class RatingDetailView(generic.DetailView):
class TagDetailView(generic.DetailView): class TagDetailView(generic.DetailView):
model = Tag model = Tag
def dispatch(self, *args, **kwargs):
return super(TagDetailView, self).dispatch(*args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
# Call the base implementation first to get the context # Call the base implementation first to get the context
context = super(TagDetailView, self).get_context_data(**kwargs) context = super(TagDetailView, self).get_context_data(**kwargs)
@ -157,9 +200,13 @@ class TagDetailView(generic.DetailView):
context['books'] = sorted(books, key=lambda x: x.title) context['books'] = sorted(books, key=lambda x: x.title)
return context return context
class SeriesDetailView(generic.DetailView): class SeriesDetailView(generic.DetailView):
model = Series model = Series
def dispatch(self, *args, **kwargs):
return super(SeriesDetailView, self).dispatch(*args, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
# Call the base implementation first to get the context # Call the base implementation first to get the context
context = super(SeriesDetailView, self).get_context_data(**kwargs) context = super(SeriesDetailView, self).get_context_data(**kwargs)

22
loadtesting/bench.py Normal file
View File

@ -0,0 +1,22 @@
import csv
def floatify(mystring): # floatify probable floats
try:
return f"{float(mystring):3.3f}"
results = dict()
with open("calibre_stats.csv", "r") as cfile:
reader = csv.reader(cfile, delimiter=",")
for row in reader:
if not len(row):
continue
results[action] = {
"median" : floatify(row[4]),
"avg" : floatify(row[5]),
"min" : floatify(row[6]),
"max" : floatify(row[7]),
}

View File

@ -0,0 +1,2 @@
Method,Name,Error,Occurrences
GET,/book/<id>,500 Server Error: Internal Server Error for url: /book/<id>,3
1 Method Name Error Occurrences
2 GET /book/<id> 500 Server Error: Internal Server Error for url: /book/<id> 3

View File

@ -0,0 +1,20 @@
Type,Name,Request Count,Failure Count,Median Response Time,Average Response Time,Min Response Time,Max Response Time,Average Content Size,Requests/s,Failures/s,50%,66%,75%,80%,90%,95%,98%,99%,99.9%,99.99%,99.999%,100%
GET,/accounts/login/,20,0,48,65.55451154708862,14.944314956665039,260.83922386169434,2024.0,0.16925718599032696,0.0,53,60,79,82,180,260,260,260,260,260,260,260
POST,/accounts/login/,20,0,500.0,563.2974982261658,342.44489669799805,988.3866310119629,68954.9,0.16925718599032696,0.0,520,630,680,770,860,990,990,990,990,990,990,990
GET,/author/<id>,32,0,42,66.19161367416382,20.987987518310547,389.75977897644043,23424.375,0.2708114975845231,0.0,42,55,79,83,110,240,390,390,390,390,390,390
GET,/authors/,36,0,52,63.24449512693617,13.991117477416992,158.9028835296631,38376.63888888889,0.30466293478258855,0.0,56,70,76,76,99,150,160,160,160,160,160,160
GET,/book/<id>,91,3,57,71.04945968795609,19.988059997558594,273.82922172546387,31187.23076923077,0.7701201962559876,0.025388577898549043,57,72,87,90,130,170,230,270,270,270,270,270
GET,/books/,53,0,180.0,190.23628504771108,9.994029998779297,504.6887397766113,68252.92452830188,0.4485315428743664,0.0,180,200,220,240,270,410,480,500,500,500,500,500
GET,/publisher/<id>,19,0,46,62.593510276392884,22.986173629760742,190.87886810302734,29474.105263157893,0.16079432669081062,0.0,46,60,85,87,150,190,190,190,190,190,190,190
GET,/publishers/,22,0,41,52.96537009152499,9.990453720092773,127.92515754699707,30564.363636363636,0.18618290458935965,0.0,45,55,71,78,110,110,130,130,130,130,130,130
GET,/rating/<id>,47,0,56,69.93506817107505,28.981924057006836,293.81442070007324,33666.68085106383,0.39775438707726835,0.0,56,71,89,95,110,140,290,290,290,290,290,290
GET,/ratings/,9,0,84,76.82164510091145,22.31740951538086,146.39925956726074,30031.0,0.07616573369564714,0.0,84,93,120,130,150,150,150,150,150,150,150,150
GET,/search/,48,0,25,34.25489366054535,10.997772216796875,106.93764686584473,27502.3125,0.4062172463767847,0.0,25,36,41,43,72,87,110,110,110,110,110,110
GET,/series/,19,0,27,31.892036136827972,19.97995376586914,63.96055221557617,28473.894736842107,0.16079432669081062,0.0,27,31,37,39,62,64,64,64,64,64,64,64
GET,/tag/<id>,54,0,49,59.33219415170175,24.969100952148438,120.92876434326172,28703.61111111111,0.45699440217388276,0.0,52,70,85,92,110,110,120,120,120,120,120,120
GET,/tags/,36,0,48,66.21244218614366,10.992288589477539,373.7668991088867,33423.77777777778,0.30466293478258855,0.0,51,63,71,73,130,180,370,370,370,370,370,370
GET,search_by_author,48,0,35,49.331208070119224,8.999109268188477,187.8821849822998,27508.25,0.4062172463767847,0.0,35,41,56,62,120,160,190,190,190,190,190,190
GET,search_by_identifier,58,0,37,46.17996051393706,12.995004653930664,165.89641571044922,27873.603448275862,0.49084583937194814,0.0,38,46,55,59,97,100,120,170,170,170,170,170
GET,search_by_title,65,0,35,44.79830815241887,10.993003845214844,264.83631134033203,27183.56923076923,0.5500858544685626,0.0,35,41,50,54,61,110,140,260,260,260,260,260
GET,search_generic,117,0,40,51.21477852519761,9.992837905883789,282.82952308654785,28374.79487179487,0.9901545380434127,0.0,40,52,58,67,83,130,180,200,280,280,280,280
,Aggregated,794,3,45,77.63347637743433,8.999109268188477,988.3866310119629,32404.799748110832,6.71951028381598,0.025388577898549043,45,62,78,93,160,230,460,610,990,990,990,990
1 Type Name Request Count Failure Count Median Response Time Average Response Time Min Response Time Max Response Time Average Content Size Requests/s Failures/s 50% 66% 75% 80% 90% 95% 98% 99% 99.9% 99.99% 99.999% 100%
2 GET /accounts/login/ 20 0 48 65.55451154708862 14.944314956665039 260.83922386169434 2024.0 0.16925718599032696 0.0 53 60 79 82 180 260 260 260 260 260 260 260
3 POST /accounts/login/ 20 0 500.0 563.2974982261658 342.44489669799805 988.3866310119629 68954.9 0.16925718599032696 0.0 520 630 680 770 860 990 990 990 990 990 990 990
4 GET /author/<id> 32 0 42 66.19161367416382 20.987987518310547 389.75977897644043 23424.375 0.2708114975845231 0.0 42 55 79 83 110 240 390 390 390 390 390 390
5 GET /authors/ 36 0 52 63.24449512693617 13.991117477416992 158.9028835296631 38376.63888888889 0.30466293478258855 0.0 56 70 76 76 99 150 160 160 160 160 160 160
6 GET /book/<id> 91 3 57 71.04945968795609 19.988059997558594 273.82922172546387 31187.23076923077 0.7701201962559876 0.025388577898549043 57 72 87 90 130 170 230 270 270 270 270 270
7 GET /books/ 53 0 180.0 190.23628504771108 9.994029998779297 504.6887397766113 68252.92452830188 0.4485315428743664 0.0 180 200 220 240 270 410 480 500 500 500 500 500
8 GET /publisher/<id> 19 0 46 62.593510276392884 22.986173629760742 190.87886810302734 29474.105263157893 0.16079432669081062 0.0 46 60 85 87 150 190 190 190 190 190 190 190
9 GET /publishers/ 22 0 41 52.96537009152499 9.990453720092773 127.92515754699707 30564.363636363636 0.18618290458935965 0.0 45 55 71 78 110 110 130 130 130 130 130 130
10 GET /rating/<id> 47 0 56 69.93506817107505 28.981924057006836 293.81442070007324 33666.68085106383 0.39775438707726835 0.0 56 71 89 95 110 140 290 290 290 290 290 290
11 GET /ratings/ 9 0 84 76.82164510091145 22.31740951538086 146.39925956726074 30031.0 0.07616573369564714 0.0 84 93 120 130 150 150 150 150 150 150 150 150
12 GET /search/ 48 0 25 34.25489366054535 10.997772216796875 106.93764686584473 27502.3125 0.4062172463767847 0.0 25 36 41 43 72 87 110 110 110 110 110 110
13 GET /series/ 19 0 27 31.892036136827972 19.97995376586914 63.96055221557617 28473.894736842107 0.16079432669081062 0.0 27 31 37 39 62 64 64 64 64 64 64 64
14 GET /tag/<id> 54 0 49 59.33219415170175 24.969100952148438 120.92876434326172 28703.61111111111 0.45699440217388276 0.0 52 70 85 92 110 110 120 120 120 120 120 120
15 GET /tags/ 36 0 48 66.21244218614366 10.992288589477539 373.7668991088867 33423.77777777778 0.30466293478258855 0.0 51 63 71 73 130 180 370 370 370 370 370 370
16 GET search_by_author 48 0 35 49.331208070119224 8.999109268188477 187.8821849822998 27508.25 0.4062172463767847 0.0 35 41 56 62 120 160 190 190 190 190 190 190
17 GET search_by_identifier 58 0 37 46.17996051393706 12.995004653930664 165.89641571044922 27873.603448275862 0.49084583937194814 0.0 38 46 55 59 97 100 120 170 170 170 170 170
18 GET search_by_title 65 0 35 44.79830815241887 10.993003845214844 264.83631134033203 27183.56923076923 0.5500858544685626 0.0 35 41 50 54 61 110 140 260 260 260 260 260
19 GET search_generic 117 0 40 51.21477852519761 9.992837905883789 282.82952308654785 28374.79487179487 0.9901545380434127 0.0 40 52 58 67 83 130 180 200 280 280 280 280
20 Aggregated 794 3 45 77.63347637743433 8.999109268188477 988.3866310119629 32404.799748110832 6.71951028381598 0.025388577898549043 45 62 78 93 160 230 460 610 990 990 990 990

View File

@ -0,0 +1,61 @@
"Timestamp","User Count","Type","Name","Requests/s","Failures/s","50%","66%","75%","80%","90%","95%","98%","99%","99.9%","99.99%","99.999%","100%","Total Request Count","Total Failure Count","Total Median Response Time","Total Average Response Time","Total Min Response Time","Total Max Response Time","Total Average Content Size"
"1594955401","1","","Aggregated",0.00,0.00,"N/A","N/A","N/A","N/A","N/A","N/A","N/A","N/A","N/A","N/A","N/A","N/A",0,0,0,0,0,0,0
"1594955403","5","","Aggregated",0.00,0.00,30,390,410,410,450,450,450,450,450,450,450,450,12,0,26,152,10,450,19557
"1594955405","9","","Aggregated",5.00,0.00,31,48,360,380,410,450,470,470,470,470,470,470,25,0,31,135,10,470,25208
"1594955407","13","","Aggregated",5.75,0.00,48,72,380,390,490,770,780,780,780,780,780,780,40,0,45,169,10,779,29961
"1594955409","17","","Aggregated",6.17,0.00,64,260,380,410,500,780,860,990,990,990,990,990,57,0,64,210,10,988,31323
"1594955411","20","","Aggregated",6.38,0.00,60,180,370,410,610,770,860,990,990,990,990,990,79,0,60,198,10,988,31968
"1594955413","20","","Aggregated",7.00,0.00,56,140,260,370,610,770,860,990,990,990,990,990,92,0,53,182,10,988,32493
"1594955415","20","","Aggregated",7.90,0.00,55,110,200,260,530,680,860,990,990,990,990,990,107,0,53,166,10,988,32284
"1594955417","20","","Aggregated",8.00,0.00,51,95,150,180,520,630,860,990,990,990,990,990,119,0,51,153,10,988,32032
"1594955419","20","","Aggregated",7.90,0.00,43,53,91,110,170,520,630,630,630,630,630,630,133,0,49,143,10,988,32464
"1594955421","20","","Aggregated",7.70,0.00,43,55,73,85,120,160,190,240,240,240,240,240,147,0,50,136,10,988,32634
"1594955423","20","","Aggregated",7.50,0.00,41,53,70,75,110,160,190,240,240,240,240,240,158,0,49,129,10,988,32266
"1594955425","20","","Aggregated",6.40,0.00,39,50,56,70,110,160,170,190,190,190,190,190,173,0,48,123,9,988,32582
"1594955427","20","","Aggregated",6.40,0.00,43,56,74,87,150,160,170,190,190,190,190,190,185,0,48,120,9,988,33041
"1594955429","20","","Aggregated",6.60,0.00,41,55,70,78,150,160,160,170,170,170,170,170,199,0,48,115,9,988,32717
"1594955431","20","","Aggregated",6.60,0.00,38,52,59,70,120,160,160,170,170,170,170,170,211,0,45,111,9,988,32736
"1594955433","20","","Aggregated",6.30,0.00,38,45,54,59,110,150,160,170,170,170,170,170,224,0,43,106,9,988,32289
"1594955435","20","","Aggregated",6.50,0.00,42,55,72,85,150,170,170,190,190,190,190,190,235,0,45,106,9,988,32805
"1594955437","20","","Aggregated",6.40,0.00,38,51,59,70,95,160,170,190,190,190,190,190,246,0,45,104,9,988,32821
"1594955439","20","","Aggregated",6.10,0.00,36,54,65,71,130,170,190,200,200,200,200,200,260,0,45,101,9,988,32811
"1594955441","20","","Aggregated",5.90,0.00,47,60,71,72,150,180,190,200,200,200,200,200,272,0,45,99,9,988,32809
"1594955443","20","","Aggregated",6.10,0.00,52,65,72,81,150,180,190,200,200,200,200,200,284,1,45,97,9,988,32796
"1594955445","20","","Aggregated",6.30,0.10,49,60,66,72,100,160,200,210,210,210,210,210,297,1,46,96,9,988,32829
"1594955447","20","","Aggregated",6.10,0.10,51,65,74,92,130,180,200,210,210,210,210,210,310,1,46,95,9,988,32921
"1594955449","20","","Aggregated",6.00,0.10,46,55,66,80,130,140,190,210,210,210,210,210,326,1,45,92,8,988,32638
"1594955451","20","","Aggregated",7.00,0.10,44,55,74,83,130,170,190,210,210,210,210,210,339,1,45,91,8,988,32716
"1594955453","20","","Aggregated",6.80,0.10,42,57,82,88,140,180,190,210,210,210,210,210,356,1,45,90,8,988,32851
"1594955455","20","","Aggregated",6.70,0.00,41,57,82,88,140,190,190,210,210,210,210,210,370,1,45,89,8,988,33034
"1594955457","20","","Aggregated",7.00,0.00,38,56,63,82,120,180,190,210,210,210,210,210,386,1,45,88,8,988,32931
"1594955459","20","","Aggregated",7.30,0.00,45,63,82,88,130,180,190,210,210,210,210,210,399,1,45,87,8,988,32863
"1594955461","20","","Aggregated",7.00,0.00,45,62,74,93,140,160,190,210,210,210,210,210,414,1,45,86,8,988,32948
"1594955463","20","","Aggregated",6.70,0.00,57,72,96,110,140,190,220,260,260,260,260,260,429,1,46,87,8,988,33186
"1594955466","20","","Aggregated",7.30,0.00,58,72,93,110,140,160,220,260,260,260,260,260,441,1,45,85,8,988,33061
"1594955468","20","","Aggregated",7.20,0.00,52,62,74,110,150,170,220,260,260,260,260,260,455,1,45,85,8,988,33127
"1594955470","20","","Aggregated",7.10,0.00,47,62,73,93,150,200,220,260,260,260,260,260,472,1,45,83,8,988,32985
"1594955472","20","","Aggregated",7.10,0.00,41,60,70,73,110,170,220,270,270,270,270,270,484,1,45,84,8,988,33133
"1594955474","20","","Aggregated",7.60,0.00,39,56,73,78,110,170,220,270,270,270,270,270,498,1,45,82,8,988,32962
"1594955476","20","","Aggregated",6.80,0.00,41,56,72,77,99,150,220,270,270,270,270,270,512,1,45,81,8,988,32885
"1594955478","20","","Aggregated",7.10,0.00,43,73,85,92,110,200,240,270,270,270,270,270,525,1,45,82,8,988,32823
"1594955480","20","","Aggregated",6.90,0.00,50,76,92,97,110,190,240,290,290,290,290,290,539,1,46,82,8,988,32767
"1594955482","20","","Aggregated",6.70,0.00,58,85,110,110,150,200,280,290,290,290,290,290,553,1,47,83,8,988,32674
"1594955484","20","","Aggregated",6.80,0.00,66,90,110,110,180,240,280,290,290,290,290,290,565,1,46,82,8,988,32603
"1594955486","20","","Aggregated",6.60,0.00,70,87,110,110,150,260,290,500,500,500,500,500,578,1,47,82,8,988,32592
"1594955488","20","","Aggregated",6.50,0.00,65,81,110,130,230,410,480,500,500,500,500,500,591,1,48,84,8,988,32680
"1594955490","20","","Aggregated",6.50,0.00,70,89,120,150,260,410,480,500,500,500,500,500,600,1,48,84,8,988,32721
"1594955492","20","","Aggregated",6.10,0.00,60,79,110,160,230,410,480,500,500,500,500,500,613,2,48,84,8,988,32745
"1594955494","20","","Aggregated",5.80,0.00,60,79,110,160,230,410,480,500,500,500,500,500,625,2,48,83,8,988,32634
"1594955496","20","","Aggregated",6.10,0.10,54,73,100,150,190,280,410,480,480,480,480,480,636,2,47,83,8,988,32677
"1594955498","20","","Aggregated",6.00,0.10,49,65,73,86,170,240,280,390,390,390,390,390,649,2,47,83,8,988,32666
"1594955500","20","","Aggregated",6.00,0.10,49,58,72,73,150,170,240,390,390,390,390,390,660,2,48,82,8,988,32557
"1594955502","20","","Aggregated",5.90,0.10,47,54,58,65,73,150,240,390,390,390,390,390,679,2,47,81,8,988,32488
"1594955504","20","","Aggregated",6.60,0.10,42,51,55,58,73,130,150,390,390,390,390,390,691,2,47,80,8,988,32380
"1594955506","20","","Aggregated",6.50,0.00,45,53,58,71,130,160,190,220,220,220,220,220,708,2,47,81,8,988,32447
"1594955508","20","","Aggregated",7.00,0.00,45,54,76,87,140,170,190,220,220,220,220,220,719,2,47,81,8,988,32424
"1594955510","20","","Aggregated",6.70,0.00,45,53,70,84,140,170,190,220,220,220,220,220,733,2,47,80,8,988,32351
"1594955512","20","","Aggregated",7.10,0.00,43,53,78,90,150,170,190,220,220,220,220,220,745,2,46,79,8,988,32376
"1594955514","20","","Aggregated",6.70,0.00,40,58,70,87,150,170,190,220,220,220,220,220,761,2,46,78,8,988,32333
"1594955516","20","","Aggregated",6.80,0.00,34,43,50,53,69,90,170,170,170,170,170,170,773,2,45,78,8,988,32295
"1594955518","20","","Aggregated",6.40,0.00,34,43,55,62,89,100,170,220,220,220,220,220,787,3,46,78,8,988,32419
"1594955519","0","","Aggregated",6.40,0.00,35,43,55,64,89,100,170,220,220,220,220,220,794,3,45,77,8,988,32404
1 Timestamp User Count Type Name Requests/s Failures/s 50% 66% 75% 80% 90% 95% 98% 99% 99.9% 99.99% 99.999% 100% Total Request Count Total Failure Count Total Median Response Time Total Average Response Time Total Min Response Time Total Max Response Time Total Average Content Size
2 1594955401 1 Aggregated 0.00 0.00 N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A N/A 0 0 0 0 0 0 0
3 1594955403 5 Aggregated 0.00 0.00 30 390 410 410 450 450 450 450 450 450 450 450 12 0 26 152 10 450 19557
4 1594955405 9 Aggregated 5.00 0.00 31 48 360 380 410 450 470 470 470 470 470 470 25 0 31 135 10 470 25208
5 1594955407 13 Aggregated 5.75 0.00 48 72 380 390 490 770 780 780 780 780 780 780 40 0 45 169 10 779 29961
6 1594955409 17 Aggregated 6.17 0.00 64 260 380 410 500 780 860 990 990 990 990 990 57 0 64 210 10 988 31323
7 1594955411 20 Aggregated 6.38 0.00 60 180 370 410 610 770 860 990 990 990 990 990 79 0 60 198 10 988 31968
8 1594955413 20 Aggregated 7.00 0.00 56 140 260 370 610 770 860 990 990 990 990 990 92 0 53 182 10 988 32493
9 1594955415 20 Aggregated 7.90 0.00 55 110 200 260 530 680 860 990 990 990 990 990 107 0 53 166 10 988 32284
10 1594955417 20 Aggregated 8.00 0.00 51 95 150 180 520 630 860 990 990 990 990 990 119 0 51 153 10 988 32032
11 1594955419 20 Aggregated 7.90 0.00 43 53 91 110 170 520 630 630 630 630 630 630 133 0 49 143 10 988 32464
12 1594955421 20 Aggregated 7.70 0.00 43 55 73 85 120 160 190 240 240 240 240 240 147 0 50 136 10 988 32634
13 1594955423 20 Aggregated 7.50 0.00 41 53 70 75 110 160 190 240 240 240 240 240 158 0 49 129 10 988 32266
14 1594955425 20 Aggregated 6.40 0.00 39 50 56 70 110 160 170 190 190 190 190 190 173 0 48 123 9 988 32582
15 1594955427 20 Aggregated 6.40 0.00 43 56 74 87 150 160 170 190 190 190 190 190 185 0 48 120 9 988 33041
16 1594955429 20 Aggregated 6.60 0.00 41 55 70 78 150 160 160 170 170 170 170 170 199 0 48 115 9 988 32717
17 1594955431 20 Aggregated 6.60 0.00 38 52 59 70 120 160 160 170 170 170 170 170 211 0 45 111 9 988 32736
18 1594955433 20 Aggregated 6.30 0.00 38 45 54 59 110 150 160 170 170 170 170 170 224 0 43 106 9 988 32289
19 1594955435 20 Aggregated 6.50 0.00 42 55 72 85 150 170 170 190 190 190 190 190 235 0 45 106 9 988 32805
20 1594955437 20 Aggregated 6.40 0.00 38 51 59 70 95 160 170 190 190 190 190 190 246 0 45 104 9 988 32821
21 1594955439 20 Aggregated 6.10 0.00 36 54 65 71 130 170 190 200 200 200 200 200 260 0 45 101 9 988 32811
22 1594955441 20 Aggregated 5.90 0.00 47 60 71 72 150 180 190 200 200 200 200 200 272 0 45 99 9 988 32809
23 1594955443 20 Aggregated 6.10 0.00 52 65 72 81 150 180 190 200 200 200 200 200 284 1 45 97 9 988 32796
24 1594955445 20 Aggregated 6.30 0.10 49 60 66 72 100 160 200 210 210 210 210 210 297 1 46 96 9 988 32829
25 1594955447 20 Aggregated 6.10 0.10 51 65 74 92 130 180 200 210 210 210 210 210 310 1 46 95 9 988 32921
26 1594955449 20 Aggregated 6.00 0.10 46 55 66 80 130 140 190 210 210 210 210 210 326 1 45 92 8 988 32638
27 1594955451 20 Aggregated 7.00 0.10 44 55 74 83 130 170 190 210 210 210 210 210 339 1 45 91 8 988 32716
28 1594955453 20 Aggregated 6.80 0.10 42 57 82 88 140 180 190 210 210 210 210 210 356 1 45 90 8 988 32851
29 1594955455 20 Aggregated 6.70 0.00 41 57 82 88 140 190 190 210 210 210 210 210 370 1 45 89 8 988 33034
30 1594955457 20 Aggregated 7.00 0.00 38 56 63 82 120 180 190 210 210 210 210 210 386 1 45 88 8 988 32931
31 1594955459 20 Aggregated 7.30 0.00 45 63 82 88 130 180 190 210 210 210 210 210 399 1 45 87 8 988 32863
32 1594955461 20 Aggregated 7.00 0.00 45 62 74 93 140 160 190 210 210 210 210 210 414 1 45 86 8 988 32948
33 1594955463 20 Aggregated 6.70 0.00 57 72 96 110 140 190 220 260 260 260 260 260 429 1 46 87 8 988 33186
34 1594955466 20 Aggregated 7.30 0.00 58 72 93 110 140 160 220 260 260 260 260 260 441 1 45 85 8 988 33061
35 1594955468 20 Aggregated 7.20 0.00 52 62 74 110 150 170 220 260 260 260 260 260 455 1 45 85 8 988 33127
36 1594955470 20 Aggregated 7.10 0.00 47 62 73 93 150 200 220 260 260 260 260 260 472 1 45 83 8 988 32985
37 1594955472 20 Aggregated 7.10 0.00 41 60 70 73 110 170 220 270 270 270 270 270 484 1 45 84 8 988 33133
38 1594955474 20 Aggregated 7.60 0.00 39 56 73 78 110 170 220 270 270 270 270 270 498 1 45 82 8 988 32962
39 1594955476 20 Aggregated 6.80 0.00 41 56 72 77 99 150 220 270 270 270 270 270 512 1 45 81 8 988 32885
40 1594955478 20 Aggregated 7.10 0.00 43 73 85 92 110 200 240 270 270 270 270 270 525 1 45 82 8 988 32823
41 1594955480 20 Aggregated 6.90 0.00 50 76 92 97 110 190 240 290 290 290 290 290 539 1 46 82 8 988 32767
42 1594955482 20 Aggregated 6.70 0.00 58 85 110 110 150 200 280 290 290 290 290 290 553 1 47 83 8 988 32674
43 1594955484 20 Aggregated 6.80 0.00 66 90 110 110 180 240 280 290 290 290 290 290 565 1 46 82 8 988 32603
44 1594955486 20 Aggregated 6.60 0.00 70 87 110 110 150 260 290 500 500 500 500 500 578 1 47 82 8 988 32592
45 1594955488 20 Aggregated 6.50 0.00 65 81 110 130 230 410 480 500 500 500 500 500 591 1 48 84 8 988 32680
46 1594955490 20 Aggregated 6.50 0.00 70 89 120 150 260 410 480 500 500 500 500 500 600 1 48 84 8 988 32721
47 1594955492 20 Aggregated 6.10 0.00 60 79 110 160 230 410 480 500 500 500 500 500 613 2 48 84 8 988 32745
48 1594955494 20 Aggregated 5.80 0.00 60 79 110 160 230 410 480 500 500 500 500 500 625 2 48 83 8 988 32634
49 1594955496 20 Aggregated 6.10 0.10 54 73 100 150 190 280 410 480 480 480 480 480 636 2 47 83 8 988 32677
50 1594955498 20 Aggregated 6.00 0.10 49 65 73 86 170 240 280 390 390 390 390 390 649 2 47 83 8 988 32666
51 1594955500 20 Aggregated 6.00 0.10 49 58 72 73 150 170 240 390 390 390 390 390 660 2 48 82 8 988 32557
52 1594955502 20 Aggregated 5.90 0.10 47 54 58 65 73 150 240 390 390 390 390 390 679 2 47 81 8 988 32488
53 1594955504 20 Aggregated 6.60 0.10 42 51 55 58 73 130 150 390 390 390 390 390 691 2 47 80 8 988 32380
54 1594955506 20 Aggregated 6.50 0.00 45 53 58 71 130 160 190 220 220 220 220 220 708 2 47 81 8 988 32447
55 1594955508 20 Aggregated 7.00 0.00 45 54 76 87 140 170 190 220 220 220 220 220 719 2 47 81 8 988 32424
56 1594955510 20 Aggregated 6.70 0.00 45 53 70 84 140 170 190 220 220 220 220 220 733 2 47 80 8 988 32351
57 1594955512 20 Aggregated 7.10 0.00 43 53 78 90 150 170 190 220 220 220 220 220 745 2 46 79 8 988 32376
58 1594955514 20 Aggregated 6.70 0.00 40 58 70 87 150 170 190 220 220 220 220 220 761 2 46 78 8 988 32333
59 1594955516 20 Aggregated 6.80 0.00 34 43 50 53 69 90 170 170 170 170 170 170 773 2 45 78 8 988 32295
60 1594955518 20 Aggregated 6.40 0.00 34 43 55 62 89 100 170 220 220 220 220 220 787 3 46 78 8 988 32419
61 1594955519 0 Aggregated 6.40 0.00 35 43 55 64 89 100 170 220 220 220 220 220 794 3 45 77 8 988 32404

9
loadtesting/locust.conf Normal file
View File

@ -0,0 +1,9 @@
locustfile = locustfile.py
expect-workers = 50
host = http://127.0.0.1:8000
users = 20
hatch-rate = 2
run-time = 2m
headless = true
csv=calibre
only-summary=true

184
loadtesting/locustfile.py Normal file
View File

@ -0,0 +1,184 @@
from locust import HttpUser, task, between
import random
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
import json
# -------------------------------- fetching data to test with
with open("./../CalibreWebCompanion/settings.json", "r") as jfile:
calpath = json.load(jfile)["CALIBRE_DIR"] + "\\metadata.db"
engine = create_engine(f'sqlite:///{calpath}')
Base = declarative_base(engine)
class Author(Base): # needed
""""""
__tablename__ = 'authors'
__table_args__ = {'autoload': True}
# has int id, text name, sort
class Identifier(Base): # needed
""""""
__tablename__ = 'identifiers'
__table_args__ = {'autoload': True}
# has int id, int book, text value
class Publisher(Base): # needed
""""""
__tablename__ = 'publishers'
__table_args__ = {'autoload': True}
# has int id, text name
class Rating(Base): # needed
""""""
__tablename__ = 'ratings'
__table_args__ = {'autoload': True}
# has int id, int rating
class Series(Base): # needed
""""""
__tablename__ = 'series'
__table_args__ = {'autoload': True}
# has int id, text name
class Tag(Base): # needed
""""""
__tablename__ = 'tags'
__table_args__ = {'autoload': True}
# has int id, text name
class Book(Base): # needed
""""""
__tablename__ = 'books'
__table_args__ = {'autoload': True}
# has int id, text title, text sort, time timestamp, time pubdate,
# float series_index, text path
def loadSession():
""""""
metadata = Base.metadata
Session = sessionmaker(bind=engine)
session = Session()
return session
session = loadSession()
titles = [i.title for i in session.query(Book).all()]
authors = [i.name for i in session.query(Author).all()]
identifiers = [i.val for i in session.query(Identifier).all()]
book_ids = [i.id for i in session.query(Book).all()]
author_ids = [i.id for i in session.query(Author).all()]
publisher_ids = [i.id for i in session.query(Publisher).all()]
rating_ids = [i.id for i in session.query(Rating).all()]
series_ids = [i.id for i in session.query(Series).all()]
tag_ids = [i.id for i in session.query(Tag).all()]
def randlist(mylist):
return mylist[random.randint(0, len(mylist) - 1)]
class UserBehavior(HttpUser):
wait_time = between(1, 5)
def on_start(self):
""" on_start is called when a Locust start before any task is scheduled """
r = self.client.get('/accounts/login/')
self.client.headers['Referer'] = self.client.base_url
n = random.randint(0, 5)
self.client.post('/accounts/login/',
{
"username": f"performance{n}",
"password": "profiling1234",
'csrfmiddlewaretoken': r.cookies["csrftoken"]
})
@task(10)
def search_by_title(self):
title = randlist(titles)
self.client.get(f"/results/?title={title}", name="search_by_title")
@task(10)
def booklist(self):
self.client.get("/books/")
@task(15)
def bookdetail(self):
pk = randlist(book_ids)
self.client.get(f"/book/{pk}", name="/book/<id>")
@task(10)
def search_by_author(self):
author = randlist(authors)
self.client.get(f"/results/?author={author}", name="search_by_author")
@task(6)
def authorlist(self):
self.client.get("/authors/")
@task(5)
def authordetail(self):
pk = randlist(author_ids)
self.client.get(f"/author/{pk}", name="/author/<id>")
@task(10)
def search_by_id(self):
id_ = randlist(identifiers)
self.client.get(f"/results/?identifier={id_}", name="search_by_identifier")
@task(20)
def search_generic(self):
t = random.randint(0, 3)
if not t:
term = randlist(titles)
elif t == 1:
term = randlist(authors)
else:
term = randlist(identifiers)
self.client.get(f"/results/?generic={term}", name="search_generic")
@task(8)
def searchbad(self):
self.client.get("/search/")
@task(1)
def ratingslist(self):
self.client.get("/ratings/")
@task(10)
def ratingdetail(self):
pk = randlist(rating_ids)
self.client.get(f"/rating/{pk}", name="/rating/<id>")
@task(5)
def taglist(self):
self.client.get("/tags/")
@task(10)
def tagdetail(self):
pk = randlist(tag_ids)
self.client.get(f"/tag/{pk}", name="/tag/<id>")
@task(4)
def serieslist(self):
self.client.get("/series/")
@task(4)
def publisherlist(self):
self.client.get("/publishers/")
@task(4)
def publisherdetail(self):
pk = randlist(publisher_ids)
self.client.get(f"/publisher/{pk}", name="/publisher/<id>")

View File

@ -3,3 +3,4 @@ django>=3.0.8
django-debug-toolbar>=2.2 django-debug-toolbar>=2.2
django-silk>=4.0 django-silk>=4.0
locust>=1.1 locust>=1.1
sqlalchemy>=1.3.15