Commit 66f4325c authored by sebastien letort's avatar sebastien letort

Merge branch 'metrics' of https://gitlab.inria.fr/allgo/allgo into metrics

parents 829cf402 f9608307
......@@ -2,7 +2,6 @@
## AIMS : provide function to populate the DB for tests.
## USAGE :
## AUTHORS : sletort@irisa.fr
from datetime import datetime
......@@ -10,7 +9,8 @@ from django.db import connection
from main.models import Job, User, Webapp,DockerOs,JobQueue,AllgoUser
def with_users( l_usernames ):
def with_users( usernames ):
"""usernames is a list."""
# Note : bulk_create should be the most efficient way to create several users.
# but I cannot managed to build AllgoUser with this.
# ~ User.objects.bulk_create([
......@@ -21,14 +21,14 @@ def with_users( l_usernames ):
# ~ ])
# Note: It seems AllgoUsers are created without asking !
for name in l_usernames:
o_user = User.objects.create_user(
username = name,
email = name+'@localhost',
password = '')
# ~ print( name + " id=" + str( o_user.id ) )
# ~ l_ = AllgoUser.objects.all()
# ~ [ print(str(x)) for x in l_ ]
for name in usernames:
o_user = User.objects.create_user(
username = name,
email = name+'@localhost',
password = '')
# ~ print( name + " id=" + str( o_user.id ) )
# ~ l_ = AllgoUser.objects.all()
# ~ [ print(str(x)) for x in l_ ]
# with_users
def with_vitals():
......@@ -36,16 +36,16 @@ def with_vitals():
DockerOs.objects.create(name="debian:stable")
JobQueue.objects.create( name = "default", is_default = True, )
def with_webapps( d_apps ):
"""d_apps= { user: l_app_names }
def with_webapps( apps ):
"""apps= { user: l_app_names }
Will use the first docker_os."""
o_docker_os = DockerOs.objects.first()
o_job_queue = JobQueue.objects.first()
for user in d_apps:
for user in apps:
o_user = User.objects.get(username=user)
for app_name in d_apps[user]:
for app_name in apps[user]:
Webapp.objects.create(
name = app_name,
docker_os = o_docker_os,
......@@ -63,7 +63,7 @@ def with_various_jobs_from_one_app():
o_app = Webapp.objects.first()
o_job_queue = JobQueue.objects.first()
l_jobs = [
jobs = [
[ # all jobs for user1
[ "05/01/2019", "17/01/2019", Job.SUCCESS, ],
[ "07/01/2019", "10/01/2019", Job.SUCCESS, ],
......@@ -97,10 +97,10 @@ def with_various_jobs_from_one_app():
],
]
lo_users = User.objects.all()
for i in range(len(l_jobs)):
o_user = lo_users[i]
for start,end,result in l_jobs[i]:
users = User.objects.all()
for i in range(len(jobs)):
o_user = users[i]
for start,end,result in jobs[i]:
o_job = Job.objects.create(
queue = o_job_queue,
webapp = o_app,
......
......@@ -2,7 +2,6 @@
## AIMS : test the metric API.
## USAGE :
## AUTHORS : sletort@irisa.fr
import logging
from unittest import skip
......@@ -44,35 +43,38 @@ class ApiMetricsTestCase(TestCase):
self.req_factory = RequestFactory()
@classmethod
def _build_url(cls, d_params=None):
if d_params is None:
def _build_url(cls, params=None):
"""params is a dictionnary"""
if params is None:
return cls.API_URL
l_args = []
for k,v in d_params.items():
l_args.append( "{}={}".format(k,v) )
args = []
for k,v in params.items():
args.append( "{}={}".format(k,v) )
api_url = cls.API_URL + "=?" + "&".join(l_args)
api_url = cls.API_URL + "=?" + "&".join(args)
return api_url
def create_view(self, what):
SLEEP_ID = '1'
return Metrics.as_view()(self.request, SLEEP_ID, what)
def assert_json_struct(self, d_json):
l_keys = list(d_json.keys())
self.assertEqual(l_keys, [self.APP_NAME], "WebApp is the only key.")
d_apps = d_json[self.APP_NAME]
def assert_json_struct(self, json_):
"""json_ is a dictionnary of json data"""
keys_ = list(json_.keys())
self.assertEqual(keys_, [self.APP_NAME], "WebApp is the only key.")
d_apps = json_[self.APP_NAME]
self.assertIn('from', d_apps)
self.assertIn('to', d_apps)
self.assertIn('data', d_apps)
def assert_record(self, d_record, d_format):
for k,type_ in d_format.items():
self.assertIn(k, d_record )
self.assertTrue(isinstance(d_record[k], type_))
def assert_record(self, record, format_):
"""record and format_ are a dictionnaries"""
for k,type_ in format_.items():
self.assertIn(k, record )
self.assertTrue(isinstance(record[k], type_))
def check_api(self, what, d_record_fmt):
def check_api(self, what, record_fmt):
url = self._build_url()
self.request = self.req_factory.get(url)
self.request.user = User.objects.get(username='Bob')
......@@ -81,12 +83,12 @@ class ApiMetricsTestCase(TestCase):
self.assertIsInstance(o_response, JsonResponse)
str_response = o_response.content.decode('utf-8')
d_json = json.loads( str_response )
self.assert_json_struct(d_json)
json_ = json.loads( str_response )
self.assert_json_struct(json_)
# check one random record of data
d_record = random.choice( d_json[self.APP_NAME]['data'] )
self.assert_record( d_record, d_record_fmt )
record = random.choice( json_[self.APP_NAME]['data'] )
self.assert_record( record, record_fmt )
# TODO: manage time_period as date !
......@@ -133,8 +135,8 @@ class ApiMetricsTestCase(TestCase):
@tag( 'format' )
def test_per_user(self):
d_format = { 'n': int, 'uname': str, 'user': int, 'time_period': str }
self.check_api( 'per_user', d_format )
format_ = { 'n': int, 'uname': str, 'user': int, 'time_period': str }
self.check_api( 'per_user', format_ )
# I cannot manage to make "01-01-1 00:00" be validated with this.
# It seems that only 4 digits years are allowed.
......@@ -145,33 +147,34 @@ class ApiMetricsTestCase(TestCase):
@tag( 'format' )
def test_per_state(self):
d_format = { 'n': int, 'result': str, 'time_period': str }
self.check_api( 'per_state', d_format )
format_ = { 'n': int, 'result': str, 'time_period': str }
self.check_api( 'per_state', format_ )
@tag( 'format' )
def test_created(self):
d_format = { 'n': int, 'time_period': str }
self.check_api( 'created', d_format )
format_ = { 'n': int, 'time_period': str }
self.check_api( 'created', format_ )
def check_results(self, what, ld_expected):
def check_results(self, what, expected):
"""expected is a list of expected dictionnaries"""
url = self._build_url({ 'step': 'month', 'from': '2019-01-01', 'to':'2019-05-01' })
self.request = self.req_factory.get(url)
self.request.user = User.objects.get(username='Bob')
o_response = self.create_view(what)
str_response = o_response.content.decode('utf-8')
d_json = json.loads(str_response)
l_data = d_json[self.APP_NAME]['data']
json_ = json.loads(str_response)
data = json_[self.APP_NAME]['data']
N = len(ld_expected)
self.assertTrue(N==len(l_data), "number of elements")
N = len(expected)
self.assertTrue(N==len(data), "number of elements")
for i in range(N):
self.assertIn(ld_expected[i], l_data)
self.assertIn(expected[i], data)
@tag( 'results' )
def test_per_state_results(self):
ld_expected = [
expected = [
{'time_period': '2019-01-01', 'result': 'SUCCESS', 'n': 2},
{'time_period': '2019-01-01', 'result': 'ERROR', 'n': 1},
{'time_period': '2019-02-01', 'result': 'SUCCESS', 'n': 2},
......@@ -183,11 +186,11 @@ class ApiMetricsTestCase(TestCase):
{'time_period': '2019-04-01', 'result': 'ERROR', 'n': 2},
{'time_period': '2019-04-01', 'result': 'ABORTED', 'n': 2},
]
self.check_results('per_state', ld_expected)
self.check_results('per_state', expected)
@tag( 'result' )
def test_per_user_results(self):
ld_expected = [
expected = [
{'uname': 'Bob', 'user': 1, 'n': 3, 'time_period': '2019-01-01'},
{'uname': 'Bob', 'user': 1, 'n': 1, 'time_period': '2019-02-01'},
{'uname': 'Liz', 'user': 2, 'n': 2, 'time_period': '2019-02-01'},
......@@ -199,17 +202,17 @@ class ApiMetricsTestCase(TestCase):
{'uname': 'Zaza', 'user': 3, 'n': 3, 'time_period': '2019-04-01'},
{'uname': 'Lol', 'user': 4, 'n': 2, 'time_period': '2019-04-01'},
]
self.check_results('per_user', ld_expected)
self.check_results('per_user', expected)
@tag( 'results' )
def test_created_results(self):
ld_expected = [
expected = [
{'time_period': '2019-01-01', 'n': 4},
{'time_period': '2019-02-01', 'n': 6},
{'time_period': '2019-03-01', 'n': 3},
{'time_period': '2019-04-01', 'n': 10},
]
self.check_results('created', ld_expected)
self.check_results('created', expected)
if __name__ == '__main__':
......
......@@ -1489,21 +1489,22 @@ class RunnerDelete(UserAccessMixin, DeleteView):
# Metrics
# -----------------------------------------------------------------------------
class Metrics(ProviderAccessMixin, TemplateView):
class Metrics(UserAccessMixin, TemplateView):
template_name = 'metrics.html'
def get(self, request ):
if request.user.is_superuser:
l_apps = Webapp.objects.all()
def get_context_data(self, **kwargs ):
if self.request.user.is_superuser:
apps = Webapp.objects.all()
else:
l_apps = Webapp.objects.filter(user=request.user)
d_params = {
'apps': l_apps.order_by('name'),
'show_form': 0 != len(l_apps),
}
log.info( "Site metrics. User = {}".format(str(request.user)) )
return render( request, self.template_name, d_params )
apps = Webapp.objects.filter(user=self.request.user)
# context is a dictionnary
context = super().get_context_data(**kwargs)
context['apps'] = apps.order_by('name')
context['show_form'] = 0 != len(apps)
log.info( "Site metrics. User = {}".format(str(self.request.user)) )
return context
@csrf_exempt
......
......@@ -115,6 +115,7 @@ THIRD_PARTY_APPS = [
'allauth.socialaccount',
'allauth.socialaccount.providers.gitlab',
'taggit',
'django_extensions',
]
LOCAL_APPS = [
'main',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment