def test_raises_invalid_cohort_for_any_metric(self):
        self.cohort.validated = False
        self.session.commit()

        for name, metric in metric_classes.iteritems():
            if not metric.show_in_ui:
                continue

            parameters = {
                'name': '{0} - test'.format(name),
                'cohort': {
                    'id': self.cohort.id,
                    'name': self.cohort.name,
                },
                'metric': {
                    'name': name,
                    'namespaces': [0, 1, 2],
                    'start_date': '2013-01-01 00:00:00',
                    'end_date': '2013-01-02 00:00:00',
                    'individualResults': True,
                    'aggregateResults': False,
                    'aggregateSum': False,
                    'aggregateAverage': False,
                    'aggregateStandardDeviation': False,
                },
            }
            try:
                RunReport(parameters, user_id=self.owner_user_id)
            except InvalidCohort:
                continue
            assert_true(False)
    def test_user_id_assigned_properly(self):
        parameters = {
            'name': 'Bytes - test',
            'cohort': {
                'id': self.cohort.id,
                'name': self.cohort.name,
            },
            'metric': {
                'name': 'BytesAdded',
                'namespaces': '0,1,2',
                'start_date': '2013-01-01 00:00:00',
                'end_date': '2013-01-02 00:00:00',
                'individualResults': True,
                'aggregateResults': True,
                'aggregateSum': True,
                'aggregateAverage': False,
                'aggregateStandardDeviation': False,
            },
        }

        jr = RunReport(parameters, user_id=self.owner_user_id)
        jr.task.delay(jr).get()
        self.session.commit()
        # executing directly the code that will be run by the scheduler
        recurring_reports()

        # make sure all report nodes have a user_id
        no_user_id = self.session.query(func.count(ReportStore)) \
            .filter(ReportStore.user_id == None) \
            .one()[0]
        assert_equals(no_user_id, 0)
예제 #3
0
 def test_basic_response(self):
     desired_responses = [{
         'name': 'Edits - test',
         'cohort': {
             'id': self.test_cohort_id,
         },
         'metric': {
             'name': 'NamespaceEdits',
             'namespaces': [0, 1, 2],
             'start_date': '2013-06-01',
             'end_date': '2013-09-01',
             'individualResults': True,
             'aggregateResults': False,
             'aggregateSum': False,
             'aggregateAverage': False,
             'aggregateStandardDeviation': False,
         },
     }]
     jr = RunReport(desired_responses, user_id=self.test_user_id)
     results = jr.task.delay(jr).get()
     result_key = self.session.query(PersistentReport)\
         .filter(PersistentReport.id == jr.children[0].persistent_id)\
         .one()\
         .result_key
     results = results[result_key]
     # TODO: figure out why one of the resulting wiki_user_ids is None here
     assert_equals(
         results[Aggregation.IND][0][self.test_mediawiki_user_id]['edits'],
         2,
     )
    def test_aggregated_response_bytes_added(self):
        parameters = {
            'name': 'Edits - test',
            'cohort': {
                'id': self.cohort.id,
                'name': self.cohort.name,
            },
            'metric': {
                'name': 'BytesAdded',
                'namespaces': [0],
                'start_date': '2013-01-01 00:00:00',
                'end_date': '2013-01-03 00:00:00',
                'individualResults': True,
                'aggregateResults': True,
                'aggregateSum': True,
                'aggregateAverage': False,
                'aggregateStandardDeviation': False,
            },
        }
        jr = RunReport(parameters, user_id=self.owner_user_id)
        results = jr.task.delay(jr).get()
        self.session.commit()
        result_key = self.session.query(ReportStore) \
            .get(jr.persistent_id) \
            .result_key
        results = results[result_key]
        assert_equals(
            results[Aggregation.IND][self.editor(0)]['net_sum'],
            -90,
        )

        assert_equals(
            results[Aggregation.SUM]['positive_only_sum'],
            140,
        )
 def test_basic_response(self):
     parameters = {
         'name': 'Edits - test',
         'cohort': {
             'id': self.cohort.id,
             'name': self.cohort.name,
         },
         'metric': {
             'name': 'NamespaceEdits',
             'namespaces': [0, 1, 2],
             'start_date': '2013-01-01 00:00:00',
             'end_date': '2013-01-02 00:00:00',
             'individualResults': True,
             'aggregateResults': False,
             'aggregateSum': False,
             'aggregateAverage': False,
             'aggregateStandardDeviation': False,
         },
     }
     jr = RunReport(parameters, user_id=self.owner_user_id)
     results = jr.task.delay(jr).get()
     self.session.commit()
     result_key = self.session.query(ReportStore) \
         .get(jr.persistent_id) \
         .result_key
     results = results[result_key]
     # TODO: figure out why one of the resulting wiki_user_ids is None here
     assert_equals(
         results[Aggregation.IND][self.editor(0)]['edits'],
         2,
     )
예제 #6
0
 def test_aggregated_response_bytes_added(self):
     desired_responses = [{
         'name': 'Edits - test',
         'cohort': {
             'id': self.test_cohort_id,
         },
         'metric': {
             'name': 'BytesAdded',
             'namespaces': [0, 1, 2],
             'start_date': '2013-06-01',
             'end_date': '2013-09-01',
             'individualResults': True,
             'aggregateResults': True,
             'aggregateSum': True,
             'aggregateAverage': False,
             'aggregateStandardDeviation': False,
         },
     }]
     jr = RunReport(desired_responses, user_id=self.test_user_id)
     results = jr.task.delay(jr).get()
     result_key = self.session.query(PersistentReport)\
         .filter(PersistentReport.id == jr.children[0].persistent_id)\
         .one()\
         .result_key
     results = results[result_key]
     assert_equals(
         results[Aggregation.IND][0][self.test_mediawiki_user_id]['net_sum'],
         6,
     )
     
     assert_equals(
         results[Aggregation.SUM]['positive_only_sum'],
         150,
     )
 def test_empty_response(self):
     """
     Case where user tries to submit form with no cohorts / metrics
     should be handled client side server side an exception will be
     thrown if RunReport object cannot be created
     """
     RunReport({}, user_id=self.owner_user_id)
    def inject_and_fetch_recurrent_run(self):
        parameters = {
            'name': 'Edits - test',
            'cohort': {
                'id': self.cohort.id,
                'name': self.cohort.name,
            },
            'metric': {
                'name': 'NamespaceEdits',
                'namespaces': [0, 1, 2],
                'start_date': '2013-01-01 00:00:00',
                'end_date': '2013-01-03 00:00:00',
                'individualResults': True,
                'aggregateResults': False,
                'aggregateSum': False,
                'aggregateAverage': False,
                'aggregateStandardDeviation': False,
            },
            'recurrent': True,
        }

        jr = RunReport(parameters, user_id=self.owner_user_id)
        jr.task.delay(jr).get()
        self.session.commit()

        # executing directly the code that will be run by the scheduler
        recurring_reports()
        recurrent_runs = self.session.query(ReportStore) \
            .filter(ReportStore.recurrent_parent_id == jr.persistent_id) \
            .all()

        return recurrent_runs
예제 #9
0
 def test_invalid_metric(self):
     run_report = RunReport()
     run_report.parse_request([{
         'name': 'Edits - test',
         'cohort': {
             'id': self.test_cohort_id,
         },
         'metric': {
             'name': 'NamespaceEdits',
             'namespaces': 'blah blah',
         },
     }])
 def test_run_report_repr(self):
     run_report = RunReport(
         {
             'name': 'Edits - test',
             'cohort': {
                 'id': self.cohort.id,
                 'name': self.cohort.name,
             },
             'metric': {
                 'name': 'NamespaceEdits',
             },
         },
         user_id=self.owner_user_id)
     assert_true(str(run_report).find('RunReport') >= 0)
 def test_run_report_finish(self):
     run_report = RunReport(
         {
             'name': 'Edits - test',
             'cohort': {
                 'id': self.cohort.id,
                 'name': self.cohort.name,
             },
             'metric': {
                 'name': 'NamespaceEdits',
             },
         },
         user_id=self.owner_user_id)
     result = run_report.finish(['aggregate_result'])
     assert_equals(result[run_report.result_key], 'aggregate_result')
    def test_lots_of_concurrent_requests(self):
        parameters = {
            'name': 'Edits - test',
            'cohort': {
                'id': self.cohort.id,
                'name': self.cohort.name,
            },
            'metric': {
                'name': 'BytesAdded',
                'namespaces': '0,1,2',
                'start_date': '2013-01-01 00:00:00',
                'end_date': '2013-01-02 00:00:00',
                'individualResults': True,
                'aggregateResults': True,
                'aggregateSum': True,
                'aggregateAverage': False,
                'aggregateStandardDeviation': False,
            },
        }
        reports = []
        # NOTE: you can make this loop as much as you'd like if celery
        # is allowed enough concurrent workers, set via CELERYD_CONCURRENCY
        trials = 3
        for i in range(trials):
            jr = RunReport(parameters, user_id=self.owner_user_id)
            reports.append((jr, jr.task.delay(jr)))

        successes = 0
        for jr, delayed in reports:
            try:
                results = delayed.get()
                self.session.commit()
                result_key = self.session.query(ReportStore) \
                    .get(jr.persistent_id) \
                    .result_key
                results = results[result_key]
                if results[Aggregation.SUM]['positive_only_sum'] == 140:
                    successes += 1
            except SoftTimeLimitExceeded:
                print('Timeout expired during this task.')
            except Exception:
                print('An exception occurred during this task.')
                raise

        print('Successes: {0}'.format(successes))
        assert_true(successes == trials, 'all of the trials must succeed')
    def test_aggregated_response_namespace_edits_with_timeseries(self):
        parameters = {
            'name': 'Edits - test',
            'cohort': {
                'id': self.cohort.id,
                'name': self.cohort.name,
            },
            'metric': {
                'name': 'NamespaceEdits',
                'namespaces': [0, 1, 2],
                'start_date': '2013-01-01 00:20:00',
                'end_date': '2013-03-01 00:00:00',
                'timeseries': TimeseriesChoices.MONTH,
                'individualResults': True,
                'aggregateResults': True,
                'aggregateSum': True,
                'aggregateAverage': False,
                'aggregateStandardDeviation': False,
            },
        }
        jr = RunReport(parameters, user_id=self.owner_user_id)
        results = jr.task.delay(jr).get()
        self.session.commit()
        result_key = self.session.query(ReportStore) \
            .get(jr.persistent_id) \
            .result_key
        results = results[result_key]

        key = results[Aggregation.IND][self.editor(0)]['edits'].items()[0][0]
        assert_equals(key, '2013-01-01 00:20:00')

        assert_equals(
            results[Aggregation.SUM]['edits'].items()[0][0],
            '2013-01-01 00:20:00',
        )

        assert_equals(
            results[Aggregation.SUM]['edits']['2013-01-01 00:20:00'],
            8,
        )
        assert_equals(
            results[Aggregation.SUM]['edits']['2013-02-01 00:00:00'],
            2,
        )
    def test_wiki_cohort_runs(self):
        self.create_wiki_cohort()
        # give the WikiCohort all the users of self.cohort, for easy testing
        self.session.execute(WikiUserStore.__table__.update().values(
            validating_cohort=self.basic_wiki_cohort.id).where(
                WikiUserStore.validating_cohort == self.cohort.id))
        self.session.execute(CohortWikiUserStore.__table__.update().values(
            cohort_id=self.basic_wiki_cohort.id).where(
                CohortWikiUserStore.cohort_id == self.cohort.id))
        self.cohort = self.basic_wiki_cohort
        parameters = {
            'name': 'Edits - test',
            'cohort': {
                'id': self.cohort.id,
                'name': self.cohort.name,
            },
            'metric': {
                'name': 'NamespaceEdits',
                'namespaces': [0, 1, 2],
                'start_date': '2013-01-01 00:00:00',
                'end_date': '2013-01-02 00:00:00',
                'individualResults': True,
                'aggregateResults': True,
                'aggregateSum': True,
                'aggregateAverage': False,
                'aggregateStandardDeviation': False,
            },
        }
        jr = RunReport(parameters, user_id=self.owner_user_id)
        results = jr.task.delay(jr).get()
        self.session.commit()
        result_key = self.session.query(ReportStore) \
            .get(jr.persistent_id) \
            .result_key
        results = results[result_key]
        assert_equals(
            results[Aggregation.IND][self.editor(0)]['edits'],
            2,
        )

        assert_equals(
            results[Aggregation.SUM]['edits'],
            4,
        )
    def test_many_parallel_runs(self):
        parameters = {
            'name': 'Edits - test',
            'cohort': {
                'id': self.cohort.id,
                'name': self.cohort.name,
            },
            'metric': {
                'name': 'NamespaceEdits',
                'namespaces': [0, 1, 2],
                'start_date': '2013-01-01 00:00:00',
                'end_date': '2013-01-03 00:00:00',
                'individualResults': True,
                'aggregateResults': False,
                'aggregateSum': False,
                'aggregateAverage': False,
                'aggregateStandardDeviation': False,
            },
            'recurrent': True,
        }

        jr = RunReport(parameters,
                       user_id=self.owner_user_id,
                       created=datetime.today() -
                       timedelta(days=self.total_runs))
        jr.task.delay(jr).get()
        self.session.commit()

        # executing directly the code that will be run by the scheduler
        recurring_reports()

        recurrent_runs = self.session.query(ReportStore) \
            .filter(ReportStore.recurrent_parent_id == jr.persistent_id) \
            .all()

        successful_runs = filter(lambda x: x.status == 'SUCCESS',
                                 recurrent_runs)

        # make sure we have one and no more than one recurrent run
        assert_equal(len(successful_runs), self.total_runs)
    def test_invalid_metric(self):
        jr = RunReport(
            {
                'name': 'Edits - test',
                'cohort': {
                    'id': self.cohort.id,
                },
                'metric': {
                    'name': 'NamespaceEdits',
                    'start_date': 'blah',
                },
            },
            user_id=self.owner_user_id)

        results = jr.task.delay(jr).get()
        print results
        self.session.commit()
        result_key = self.session.query(ReportStore) \
            .get(jr.persistent_id) \
            .result_key
        assert_true(
            results[result_key]['FAILURE'].find(
                'Edits was incorrectly configured') >= 0, )
예제 #17
0
def reports_request():
    """
    Renders a page that facilitates kicking off a new report
    """

    if request.method == 'GET':
        return render_template('report.html')
    else:
        desired_responses = json.loads(request.form['responses'])
        recurrent = json.loads(request.form.get('recurrent', 'false'))

        for parameters in desired_responses:
            parameters['recurrent'] = recurrent
            # NOTE: this is not a mistake.  Currently recurrent => public on creation
            parameters['public'] = recurrent
            # Encode cohort description for the case it contains special characters
            if ('description' in parameters['cohort'] and
                    parameters['cohort']['description'] is not None):
                encoded_description = parameters['cohort']['description'].encode('utf-8')
                parameters['cohort']['description'] = encoded_description
            jr = RunReport(parameters, user_id=current_user.id)
            jr.task.delay(jr)

        return json_redirect(url_for('reports_index'))
예제 #18
0
 def test_empty_response(self):
     # TODO: handle case where user tries to submit form with no cohorts / metrics
     jr = RunReport([], user_id=self.test_user_id)
     result = jr.task.delay(jr).get()
     assert_equals(result, [])
예제 #19
0
 def test_run_report_repr(self):
     run_report = RunReport([])
     assert_true(str(run_report).find('RunReport') >= 0)
예제 #20
0
 def test_run_report_finish(self):
     run_report = RunReport([])
     result = run_report.finish([])
     assert_equals(result[run_report.result_key], 'Finished')
 def test_invalid_report(self):
     RunReport({})