Milimetric has submitted this change and it was merged.
Change subject: Controller and front end changes for async upload
......................................................................
Controller and front end changes for async upload
First round of tests are all passing, going onto UI changes
Change-Id: I9cdf44864043e60342e1f4113d2fa3310f71b08e
Card: analytics 818.2
Card: analytics 818.4
Card: analytics 818.5
---
M tests/test_controllers/test_cohorts.py
M tests/test_metrics/test_survivors.py
M tests/test_models/test_cohort.py
M tests/test_models/test_run_report.py
M wikimetrics/config/db_config.yaml
M wikimetrics/controllers/cohorts.py
M wikimetrics/models/cohort.py
M wikimetrics/models/report_nodes/run_report.py
A wikimetrics/models/report_nodes/validate_report.py
9 files changed, 252 insertions(+), 182 deletions(-)
diff --git a/tests/test_controllers/test_cohorts.py
b/tests/test_controllers/test_cohorts.py
index 2ab599d..43f6418 100644
--- a/tests/test_controllers/test_cohorts.py
+++ b/tests/test_controllers/test_cohorts.py
@@ -1,6 +1,6 @@
# -*- coding:utf-8 -*-
import json
-from nose.tools import assert_equal, raises, assert_true
+from nose.tools import assert_equal, raises, assert_true, assert_false
from tests.fixtures import WebTest
from wikimetrics.controllers.cohorts import (
parse_username,
@@ -30,8 +30,13 @@
assert_equal(parsed['cohorts'][0]['name'], self.cohort.name)
def test_list_includes_only_validated(self):
- cohorts = [Cohort(name='c1', validated=False), Cohort(name='c2',
validated=True)]
+ # There is already one cohort, add one more validated and one not
validated
+ cohorts = [
+ Cohort(name='c1', enabled=True, validated=False),
+ Cohort(name='c2', enabled=True, validated=True)
+ ]
self.session.add_all(cohorts)
+ self.session.commit()
owners = [
CohortUser(
cohort_id=c.id,
@@ -41,12 +46,13 @@
for c in cohorts
]
self.session.add_all(owners)
+ self.session.commit()
response = self.app.get('/cohorts/list', follow_redirects=True)
parsed = json.loads(response.data)
assert_equal(len(parsed['cohorts']), 2)
- assert_equal(parsed['cohorts'][0].validated, True)
- assert_equal(parsed['cohorts'][1].validated, True)
+ assert_false('c1' in [c['name'] for c in parsed['cohorts']])
+ assert_true('c2' in [c['name'] for c in parsed['cohorts']])
def test_detail(self):
response = self.app.get('/cohorts/detail/{0}'.format(self.cohort.id))
@@ -79,14 +85,6 @@
valid_user = normalize_user(parsed_user, 'enwiki')
assert_equal(valid_user[0], self.editors[0].user_id)
assert_equal(valid_user[1], 'Editor test-specific-0')
-
- def test_get_cohort_by_name_not_found(self):
- response = self.app.get('/cohorts/detail/1-OI--LASJLI---LIJSL$EIOJ')
- assert_equal(response.status_code, 404)
-
- def test_get_cohort_by_id_not_found(self):
- response = self.app.get('/cohorts/detail/133715435033')
- assert_equal(response.status_code, 404)
def test_cohort_upload_finish_existing_name(self):
response = self.app.post('/cohorts/create', data=dict(
@@ -164,6 +162,12 @@
assert_equal(cohort.default_project, 'enwiki')
def test_validate_cohort_name_allowed(self):
+ response = self.app.get('/cohorts/validate/name?name=sleijslij')
+
+ assert_equal(response.status_code, 200)
+ assert_equal(json.loads(response.data), True)
+
+ def test_validate_cohort_name_not_allowed(self):
response = self.app.get('/cohorts/validate/name?name={0}'.format(
self.cohort.name)
)
diff --git a/tests/test_metrics/test_survivors.py
b/tests/test_metrics/test_survivors.py
index 8319057..bb35aea 100644
--- a/tests/test_metrics/test_survivors.py
+++ b/tests/test_metrics/test_survivors.py
@@ -1,8 +1,8 @@
-from datetime import datetime
+from datetime import datetime, timedelta
from time import time
from nose.tools import assert_equal
-from tests.fixtures import DatabaseWithSurvivorCohortTest
+from tests.fixtures import DatabaseTest, i
from wikimetrics.metrics import Survival
from wikimetrics.models import (
Cohort, MetricReport, WikiUser, CohortWikiUser, MediawikiUser,
@@ -10,113 +10,112 @@
)
-class SurvivalTest(DatabaseWithSurvivorCohortTest):
+class SurvivalTest(DatabaseTest):
+
+ def setUp(self):
+ one_hour = timedelta(hours=1)
+ reg = datetime.now() - one_hour * 48
+
+ DatabaseTest.setUp(self)
+ self.create_test_cohort(
+ editor_count=3,
+ revisions_per_editor=2,
+ user_registrations=i(reg),
+ revision_timestamps=[
+ [i(reg + one_hour) , i(reg + one_hour * 25)],
+ [i(reg + one_hour * 20), i(reg + one_hour * 40)],
+ [i(reg + one_hour * 30), i(reg + one_hour * 73)],
+ ],
+ revision_lengths=10
+ )
+
+ self.e1 = self.editors[0].user_id
+ self.e2 = self.editors[1].user_id
+ self.e3 = self.editors[2].user_id
def test_case1_24h_count1(self):
m = Survival(
- namespaces=[self.survivors_namespace],
- survival_hours=1 * 24
+ namespaces=[0],
+ survival_hours=24,
)
results = m(list(self.cohort), self.mwSession)
-
- assert_equal(results[self.mw_dan_id][Survival.id], True)
- assert_equal(results[self.mw_evan_id][Survival.id], True)
- assert_equal(results[self.mw_andrew_id][Survival.id] , True)
+
+ assert_equal(results[self.e1][Survival.id], True)
+ assert_equal(results[self.e2][Survival.id], True)
+ assert_equal(results[self.e3][Survival.id] , True)
def test_case1_72h_count1(self):
m = Survival(
- namespaces=[self.survivors_namespace],
- survival_hours=3 * 24
+ namespaces=[0],
+ survival_hours=72,
)
results = m(list(self.cohort), self.mwSession)
-
- assert_equal(results[self.mw_dan_id][Survival.id], False)
- assert_equal(results[self.mw_evan_id][Survival.id], False)
- assert_equal(results[self.mw_andrew_id][Survival.id] , True)
+
+ assert_equal(results[self.e1][Survival.id], False)
+ assert_equal(results[self.e2][Survival.id], False)
+ assert_equal(results[self.e3][Survival.id] , True)
def test_case1_24h_count3(self):
m = Survival(
- namespaces=[self.survivors_namespace],
- survival_hours=1 * 24,
- number_of_edits=3
- )
- results = m(list(self.cohort), self.mwSession)
-
- assert_equal(results[self.mw_dan_id][Survival.id], False)
- assert_equal(results[self.mw_evan_id][Survival.id], False)
- assert_equal(results[self.mw_andrew_id][Survival.id] , True)
-
- def test_case2_24h_count3_sunset72h(self):
- m = Survival(
- namespaces=[self.survivors_namespace],
+ namespaces=[0],
survival_hours=1 * 24,
number_of_edits=3,
- sunset_in_hours=3 * 24
)
results = m(list(self.cohort), self.mwSession)
-
- assert_equal(results[self.mw_dan_id][Survival.id], False)
- assert_equal(results[self.mw_evan_id][Survival.id], False)
- assert_equal(results[self.mw_andrew_id][Survival.id] , True)
+
+ assert_equal(results[self.e1][Survival.id], False)
+ assert_equal(results[self.e2][Survival.id], False)
+ assert_equal(results[self.e3][Survival.id], False)
+
+ def test_case2_24h_count2_sunset72h(self):
+ m = Survival(
+ namespaces=[0],
+ survival_hours=24,
+ number_of_edits=2,
+ sunset_in_hours=72,
+ )
+ results = m(list(self.cohort), self.mwSession)
+
+ assert_equal(results[self.e1][Survival.id], False)
+ assert_equal(results[self.e2][Survival.id], False)
+ assert_equal(results[self.e3][Survival.id] , True)
def test_default(self):
m = Survival(
- namespaces=[self.survivors_namespace],
+ namespaces=[0],
)
results = m(list(self.cohort), self.mwSession)
#self.debug_query = m.debug_query
-
- assert_equal(results[self.mw_dan_id][Survival.id], True)
- assert_equal(results[self.mw_evan_id][Survival.id], True)
- assert_equal(results[self.mw_andrew_id][Survival.id] , True)
+
+ assert_equal(results[self.e1][Survival.id], True)
+ assert_equal(results[self.e2][Survival.id], True)
+ assert_equal(results[self.e3][Survival.id] , True)
def test_censored1(self):
-
- # NOTE: setting sunset_in_hours 10000 days in the future
- # This means that in 82 years, this test will break
m = Survival(
- namespaces=[self.survivors_namespace],
- number_of_edits=6,
- survival_hours=30000 * 24,
+ namespaces=[0],
+ number_of_edits=3,
+ survival_hours=24,
sunset_in_hours=30000 * 24
)
results = m(list(self.cohort), self.mwSession)
assert_equal(results, {
- self.mw_dan_id: {'censored': 1, Survival.id: 0},
- self.mw_evan_id: {'censored': 1, Survival.id: 0},
- self.mw_andrew_id: {'censored': 1, Survival.id: 0},
- self.mw_diederik_id: {'censored': 0, Survival.id: 0},
+ self.e1: {'censored': 1, Survival.id: 0},
+ self.e2: {'censored': 1, Survival.id: 0},
+ self.e3: {'censored': 1, Survival.id: 0},
})
-
+
def test_censored2(self):
-
- # NOTE: setting sunset_in_hours 10000 days in the future
- # This means that in 82 years, this test will break
- andrew_user = self.mwSession.query(MediawikiUser) \
- .filter(MediawikiUser.user_id == self.mw_andrew_id) \
- .first()
- andrew_revs = self.mwSession.query(Revision) \
- .join(MediawikiUser) \
- .filter(MediawikiUser.user_id == self.mw_andrew_id) \
- .order_by(Revision.rev_timestamp) \
- .all()
-
m = Survival(
- namespaces=[self.survivors_namespace],
+ namespaces=[0],
number_of_edits=2,
- survival_hours=int(
- ((andrew_revs[2].rev_timestamp - andrew_user.user_registration)
- .total_seconds())
- /
- (3600)
- ),
- sunset_in_hours=2 * 48
+ survival_hours=0,
+ sunset_in_hours=26
)
results = m(list(self.cohort), self.mwSession)
-
+
assert_equal(results, {
- self.mw_dan_id: {'censored': 0, Survival.id: 0},
- self.mw_evan_id: {'censored': 0, Survival.id: 0},
- self.mw_andrew_id: {'censored': 0, Survival.id: 1},
- self.mw_diederik_id: {'censored': 0, Survival.id: 0},
+ self.e1: {'censored': 0, Survival.id: 1},
+ self.e2: {'censored': 0, Survival.id: 0},
+ self.e3: {'censored': 0, Survival.id: 0},
})
diff --git a/tests/test_models/test_cohort.py b/tests/test_models/test_cohort.py
index bd94059..008f968 100644
--- a/tests/test_models/test_cohort.py
+++ b/tests/test_models/test_cohort.py
@@ -1,5 +1,5 @@
from nose.tools import assert_equal
-from wikimetrics.models import Cohort
+from wikimetrics.models import Cohort, WikiUser
from ..fixtures import DatabaseTest
@@ -9,26 +9,42 @@
self.common_cohort_1()
def test_iter(self):
- self.editors[0].valid = False
- self.editors[1].valid = None
+ user_ids = list(self.cohort)
+ assert_equal([e.user_id for e in self.editors], user_ids)
+
+ def test_empty_iter(self):
+ self.cohort.validated = False
self.session.commit()
user_ids = list(self.cohort)
- assert_equal(self.editors[0].user_id in user_ids, False)
- assert_equal(self.editors[1].user_id in user_ids, False)
- assert_equal(self.editors[2].user_id in user_ids, True)
- assert_equal(self.editors[3].user_id in user_ids, True)
+ assert_equal(user_ids, [])
+
+ def test_iter_with_invalid(self):
+ wikiusers = self.session.query(WikiUser).all()
+ wikiusers[0].valid = False
+ wikiusers[1].valid = None
+ self.session.commit()
+
+ user_ids = list(self.cohort)
+ assert_equal(wikiusers[0].mediawiki_userid in user_ids, False)
+ assert_equal(wikiusers[1].mediawiki_userid in user_ids, False)
+ assert_equal(wikiusers[2].mediawiki_userid in user_ids, True)
+ assert_equal(wikiusers[3].mediawiki_userid in user_ids, True)
assert_equal(len(user_ids), 2)
def test_group_by_project(self):
- self.editors[0].valid = False
- self.editors[1].valid = None
+ wikiusers = self.session.query(WikiUser).all()
+ print [(w.mediawiki_userid, w.valid, w.mediawiki_username) for w in
wikiusers]
+ wikiusers[0].valid = False
+ wikiusers[1].valid = None
self.session.commit()
- grouped = self.cohort.group_by_project()
- user_ids = list(list(grouped)[0])
- assert_equal(self.editors[0].user_id in user_ids, False)
- assert_equal(self.editors[1].user_id in user_ids, False)
- assert_equal(self.editors[2].user_id in user_ids, True)
- assert_equal(self.editors[3].user_id in user_ids, True)
+ user_ids = []
+ for project, uids in self.cohort.group_by_project():
+ user_ids += list(uids)
+
+ assert_equal(wikiusers[0].mediawiki_userid in user_ids, False)
+ assert_equal(wikiusers[1].mediawiki_userid in user_ids, False)
+ assert_equal(wikiusers[2].mediawiki_userid in user_ids, True)
+ assert_equal(wikiusers[3].mediawiki_userid in user_ids, True)
assert_equal(len(user_ids), 2)
diff --git a/tests/test_models/test_run_report.py
b/tests/test_models/test_run_report.py
index eb6010a..908dcce 100644
--- a/tests/test_models/test_run_report.py
+++ b/tests/test_models/test_run_report.py
@@ -55,6 +55,8 @@
self.session.commit()
for name, metric in metric_classes.iteritems():
+ if not metric.show_in_ui: continue
+
desired_responses = [{
'name': '{0} - test'.format(name),
'cohort': {
@@ -74,11 +76,11 @@
}]
jr = RunReport(desired_responses, user_id=self.owner_user_id)
celery_task = jr.task.delay(jr)
- # return value is not used from this .get() call
- celery_task.get()
- error_message = '{0} ran with invalid cohort'.format(name)
- assert_equals(celery_task.ready(), True, error_message)
- assert_equals(celery_task.failed(), True, error_message)
+ results = celery_task.get()
+ assert_true(
+ results['FAILURE'].find('ran with invalid cohort') >= 0,
+ '{0} ran with invalid cohort'.format(name)
+ )
def test_aggregated_response_namespace_edits(self):
desired_responses = [{
diff --git a/wikimetrics/config/db_config.yaml
b/wikimetrics/config/db_config.yaml
index 2be115e..4a22149 100644
--- a/wikimetrics/config/db_config.yaml
+++ b/wikimetrics/config/db_config.yaml
@@ -1,4 +1,4 @@
-SQL_ECHO : True
+SQL_ECHO : False
#WIKIMETRICS_ENGINE_URL : 'sqlite:///test.db'
#MEDIAWIKI_ENGINE_URL_TEMPLATE : 'sqlite:///{0}.db'
# For testing with mysql locally (useful for manual connection survival tests)
diff --git a/wikimetrics/controllers/cohorts.py
b/wikimetrics/controllers/cohorts.py
index 83d1e29..ab7173e 100644
--- a/wikimetrics/controllers/cohorts.py
+++ b/wikimetrics/controllers/cohorts.py
@@ -3,7 +3,9 @@
from flask import url_for, flash, render_template, redirect, request
from flask.ext.login import current_user
from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
-from ..utils import json_response, json_error, json_redirect,
deduplicate_by_key
+from ..utils import (
+ json_response, json_error, json_redirect, deduplicate_by_key, Unauthorized
+)
from ..configurables import app, db
from ..models import (
Cohort, CohortUser, CohortUserRole,
@@ -28,8 +30,9 @@
.join(CohortUser)\
.join(User)\
.filter(User.id == current_user.id)\
- .filter(CohortUser.role.in_([CohortUserRole.OWNER,
CohortUserRole.VIEWER]))\
+ .filter(CohortUser.role.in_(CohortUserRole.SAFE_ROLES))\
.filter(Cohort.enabled)\
+ .filter(Cohort.validated)\
.all()
db_session.close()
@@ -54,61 +57,43 @@
full_detail = request.args.get('full_detail', 0)
cohort = None
- if str(name_or_id).isdigit():
- cohort = get_cohort_by_id(int(name_or_id))
- else:
- cohort = get_cohort_by_name(name_or_id)
-
- if cohort:
- limit = None if full_detail == 'true' else 3
- cohort_with_wikiusers = populate_cohort_wikiusers(cohort, limit)
- return json_response(cohort_with_wikiusers)
-
- return '{}', 404
-
-
-def get_cohort_query():
- allowed_roles = [CohortUserRole.OWNER, CohortUserRole.VIEWER]
db_session = db.get_session()
- return (
- db_session.query(Cohort)
- .join(CohortUser)
- .join(User)
- .filter(User.id == current_user.id)
- .filter(CohortUser.role.in_(allowed_roles))
- .filter(Cohort.enabled),
- db_session
- )
-
-
-def get_cohort_by_id(id):
try:
- query, db_session = get_cohort_query()
- cohort = query.filter(Cohort.id == id).one()
+ if str(name_or_id).isdigit():
+ cohort = Cohort.get_safely(db_session, current_user.id,
by_id=int(name_or_id))
+ else:
+ cohort = Cohort.get_safely(db_session, current_user.id,
by_name=name_or_id)
+ except Unauthorized:
+ return 'You are not allowed to access this Cohort', 401
+ except NoResultFound:
+ return 'Could not find this Cohort', 404
+ finally:
db_session.close()
- return cohort
- except (MultipleResultsFound, NoResultFound):
- return None
+
+ limit = None if full_detail == 'true' else 3
+ cohort_with_wikiusers = populate_cohort_wikiusers(cohort, limit)
+ return json_response(cohort_with_wikiusers)
def get_cohort_by_name(name):
+ """
+ Gets a cohort by name, without checking access or worrying about duplicates
+ """
try:
- query, db_session = get_cohort_query()
- cohort = query.filter(Cohort.name == name).one()
+ db_session = db.get_session()
+ return db_session.query(Cohort).filter(Cohort.name == name).first()
+ finally:
db_session.close()
- return cohort
- except (MultipleResultsFound, NoResultFound):
- return None
def populate_cohort_wikiusers(cohort, limit):
+ """
+ Fetches up to <limit> WikiUser records belonging to <cohort>
+ """
db_session = db.get_session()
- wikiusers = db_session.query(WikiUser)\
- .join(CohortWikiUser)\
- .filter(CohortWikiUser.cohort_id == cohort.id)\
- .limit(limit)\
- .all()
-
+ wikiusers = cohort.filter_wikiuser_query(
+ db_session.query(WikiUser)
+ ).limit(limit).all()
db_session.close()
cohort_dict = cohort._asdict()
cohort_dict['wikiusers'] = [wu._asdict() for wu in wikiusers]
diff --git a/wikimetrics/models/cohort.py b/wikimetrics/models/cohort.py
index 86edd83..e8a3b30 100644
--- a/wikimetrics/models/cohort.py
+++ b/wikimetrics/models/cohort.py
@@ -46,13 +46,11 @@
def __iter__(self):
""" returns list of user_ids """
db_session = db.get_session()
- tuples_with_ids = db_session\
- .query(WikiUser.mediawiki_userid)\
- .join(CohortWikiUser)\
- .filter(CohortWikiUser.cohort_id == self.id)\
- .all()
+ wikiusers = self.filter_wikiuser_query(
+ db_session.query(WikiUser.mediawiki_userid)
+ ).all()
db_session.close()
- return (t[0] for t in tuples_with_ids)
+ return (r.mediawiki_userid for r in wikiusers)
def group_by_project(self):
"""
@@ -68,49 +66,67 @@
into a set of project-homogenous cohorts, which can be
analyzed using a single database connection
"""
-
db_session = db.get_session()
- user_id_projects = db_session\
- .query(WikiUser.mediawiki_userid, WikiUser.project)\
- .join(CohortWikiUser)\
- .filter(CohortWikiUser.cohort_id == self.id)\
- .order_by(WikiUser.project)\
- .all()
+ user_id_projects = self.filter_wikiuser_query(
+ db_session.query(WikiUser.mediawiki_userid, WikiUser.project)
+ ).order_by(WikiUser.project).all()
db_session.close()
# TODO: push this logic into sqlalchemy. The solution
# includes subquery(), but I can't seem to get anything working
groups = itertools.groupby(user_id_projects, key=itemgetter(1))
-
- # note: the below line is more concise but harder to read
- #return ((project, (r[0] for r in users)) for project, users in groups)
- for project, users in groups:
- yield project or self.default_project, (r[0] for r in users)
+
+ return (
+ (project or self.default_project, (r[0] for r in users))
+ for project, users in groups
+ )
+
+ def filter_wikiuser_query(self, wikiusers_query):
+ """
+ Parameters:
+ wikiusers_query : a sqlalchemy query object asking for one or more
+ properties of WikiUser
+
+ Return:
+ the query object passed in, filtered and joined to the
+ appropriate tables, and restricted to this cohort
+ """
+ return wikiusers_query\
+ .join(CohortWikiUser)\
+ .join(Cohort)\
+ .filter(Cohort.id == self.id)\
+ .filter(Cohort.validated)\
+ .filter(WikiUser.valid)
@staticmethod
- def get_safely(db_session, user_id, cohort_id):
+ def get_safely(db_session, user_id, by_id=None, by_name=None):
"""
Gets a cohort but first checks permissions on it
Parameters
db_session : the database session to query
user_id : the user that should have access to the cohort
- cohort_id : the cohort to get
+ by_id : the cohort id to get. <by_id> or <by_name> is True
+ by_name : the cohort name to get. <by_id> or <by_name> is True
Returns
- If found, a Cohort instance with id == cohort_id
+ If found, a Cohort instance with id == cohort_id or name ==
cohort_name
Raises
NoResultFound : cohort did not exist
Unauthorized : user_id is not allowed to access this cohort
"""
- cohort, role = db_session.query(Cohort, CohortUser.role)\
+ query = db_session.query(Cohort, CohortUser.role)\
.join(CohortUser)\
.join(User)\
.filter(User.id == user_id)\
- .filter(Cohort.id == cohort_id)\
- .filter(Cohort.enabled)\
- .one()
+ .filter(Cohort.enabled)
+ if by_id:
+ query = query.filter(Cohort.id == by_id)
+ if by_name:
+ query = query.filter(Cohort.name == by_name)
+
+ cohort, role = query.one()
if role in CohortUserRole.SAFE_ROLES:
return cohort
else:
diff --git a/wikimetrics/models/report_nodes/run_report.py
b/wikimetrics/models/report_nodes/run_report.py
index e7cb01c..f28accd 100644
--- a/wikimetrics/models/report_nodes/run_report.py
+++ b/wikimetrics/models/report_nodes/run_report.py
@@ -9,6 +9,7 @@
from wikimetrics.utils import deduplicate
from report import ReportNode
from aggregate_report import AggregateReport
+from validate_report import ValidateReport
__all__ = ['RunReport']
@@ -44,7 +45,7 @@
# get cohort
cohort_dict = cohort_metric_dict['cohort']
db_session = db.get_session()
- cohort = Cohort.get_safely(db_session, self.user_id,
cohort_dict['id'])
+ cohort = Cohort.get_safely(db_session, self.user_id,
by_id=cohort_dict['id'])
db_session.close()
# construct metric
@@ -54,7 +55,12 @@
metric = metric_class(**metric_dict)
# TODO: don't think csrf can work here, but see if there's another
way
metric.fake_csrf()
- if metric.validate():
+
+ metric_names.append(metric.label)
+ cohort_names.append(cohort.name)
+
+ validate_report = ValidateReport(metric, cohort)
+ if validate_report.valid():
# construct and start RunReport
output_child = AggregateReport(
cohort,
@@ -68,10 +74,8 @@
user_id=self.user_id,
)
children.append(output_child)
- metric_names.append(metric.label)
- cohort_names.append(cohort.name)
else:
- raise Exception('{0} was incorrectly
configured'.format(metric.label))
+ children.append(validate_report)
metric_names = deduplicate(metric_names)
cohort_names = deduplicate(cohort_names)
diff --git a/wikimetrics/models/report_nodes/validate_report.py
b/wikimetrics/models/report_nodes/validate_report.py
new file mode 100644
index 0000000..889387f
--- /dev/null
+++ b/wikimetrics/models/report_nodes/validate_report.py
@@ -0,0 +1,44 @@
+from report import ReportLeaf
+from wikimetrics.utils import stringify
+
+
+class ValidateReport(ReportLeaf):
+ """
+ Checks if a metric and cohort are valid. If they're not, this ReportLeaf
+ can be added to a Report hierarchy and will report the appropriate errors
+ """
+
+ show_in_ui = True
+
+ def __init__(self, metric, cohort):
+ """
+ Parameters
+ metric : an instance of a wikimetrics.metrics.metric.Metric
+ cohort : an instance of a wikimetrics.models.cohort.Cohort
+ """
+ super(ValidateReport, self).__init__(parameters=stringify(metric.data))
+ self.metric_valid = metric.validate()
+ self.cohort_valid = cohort.validated
+ self.metric_label = metric.label
+ self.cohort_name = cohort.name
+
+ def valid(self):
+ return self.metric_valid and self.cohort_valid
+
+ def run(self):
+ """
+ This will get executed if the instance is added into a Report node
hierarchy
+ It outputs failure messages due to any invalid configuration. None of
these
+ failures should happen unless the user tries to hack the system.
+ """
+ message = ''
+ if not self.cohort_valid:
+ message += '{0} ran with invalid cohort {1}\n'.format(
+ self.metric_label,
+ self.cohort_name,
+ )
+ if not self.metric_valid:
+ message += '{0} was incorrectly configured\n'.format(
+ self.metric_label,
+ )
+ return {'FAILURE': message or 'False'}
--
To view, visit https://gerrit.wikimedia.org/r/92581
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I9cdf44864043e60342e1f4113d2fa3310f71b08e
Gerrit-PatchSet: 7
Gerrit-Project: analytics/wikimetrics
Gerrit-Branch: master
Gerrit-Owner: Milimetric <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits