示例#1
0
    def test_save_public_report(self):
        fake_path = "fake_path"
        file_manager = PublicReportFileManager(self.logger,
                                               '/some/fake/absolute/path')
        file_manager.write_data = Mock()
        file_manager.remove_file = Mock()
        file_manager.get_public_report_path = MagicMock(return_value=fake_path)

        with file_manager_set(app, file_manager):

            desired_responses = [{
                'name': 'Edits - test',
                'cohort': {
                    'id': self.cohort.id,
                    'name': self.cohort.name,
                },
                'metric': {
                    'name': 'NamespaceEdits',
                    'timeseries': 'month',
                    'namespaces': [0, 1, 2],
                    'start_date': '2013-01-01 00:00:00',
                    'end_date': '2013-05-01 00:00:00',
                    'individualResults': True,
                    'aggregateResults': True,
                    'aggregateSum': False,
                    'aggregateAverage': True,
                    'aggregateStandardDeviation': False,
                },
            }]
            json_to_post = json.dumps(desired_responses)

            response = self.client.post('/reports/create/',
                                        data=dict(responses=json_to_post))

            # Wait a second for the task to get processed
            time.sleep(1)

            # Check that the task has been created
            response = self.client.get('/reports/list/')
            parsed = json.loads(response.data)
            result_key = parsed['reports'][-1]['result_key']
            task, report = get_celery_task(result_key)
            assert_true(task and report)

            # Make the report publically accessible (save it to static/public)
            response = self.client.post('/reports/set-public/{}'.format(
                report.id))
            assert_true(response.status_code == 200)
            assert_equal(file_manager.write_data.call_count, 1)

            # Now make the report private (remove it from static/public)
            response = self.client.post('/reports/unset-public/{}'.format(
                report.id))
            assert_true(response.status_code == 200)
            file_manager.remove_file.assert_called_with(fake_path)
            assert_equal(file_manager.remove_file.call_count, 1)
    def test_save_public_report(self):
        fake_path = "fake_path"
        file_manager = PublicReportFileManager(self.logger, '/some/fake/absolute/path')
        file_manager.write_data = Mock()
        file_manager.remove_file = Mock()
        file_manager.get_public_report_path = MagicMock(return_value=fake_path)

        with file_manager_set(app, file_manager):

            desired_responses = [{
                'name': 'Edits - test',
                'cohort': {
                    'id': self.cohort.id,
                    'name': self.cohort.name,
                },
                'metric': {
                    'name': 'NamespaceEdits',
                    'timeseries': 'month',
                    'namespaces': [0, 1, 2],
                    'start_date': '2013-01-01 00:00:00',
                    'end_date': '2013-05-01 00:00:00',
                    'individualResults': True,
                    'aggregateResults': True,
                    'aggregateSum': False,
                    'aggregateAverage': True,
                    'aggregateStandardDeviation': False,
                },
            }]
            json_to_post = json.dumps(desired_responses)

            response = self.client.post('/reports/create/', data=dict(
                responses=json_to_post
            ))

            # Wait a second for the task to get processed
            time.sleep(1)

            # Check that the task has been created
            response = self.client.get('/reports/list/')
            parsed = json.loads(response.data)
            result_key = parsed['reports'][-1]['result_key']
            task, report = get_celery_task(result_key)
            assert_true(task and report)

            # Make the report publically accessible (save it to static/public)
            response = self.client.post('/reports/set-public/{}'.format(report.id))
            assert_true(response.status_code == 200)
            assert_equal(file_manager.write_data.call_count, 1)

            # Now make the report private (remove it from static/public)
            response = self.client.post('/reports/unset-public/{}'.format(report.id))
            assert_true(response.status_code == 200)
            file_manager.remove_file.assert_called_with(fake_path)
            assert_equal(file_manager.remove_file.call_count, 1)
示例#3
0
    def __init__(self, report_id, created, results, file_manager=None):
        """
        TODO: Add dependency injection for the file_manager,
        we are passing it on the constructor for easier testing
        but the object should come from the application context
        
        Parameters:
            report_id   : identifier of the report, needed to find
                          directory to write to if report is recurrent
            created     : date report was created, used to identify a single run of
                          a recurrent report
            results     : data to write to disk
            file_manager: PublicReportFileManager, adding to constructor
                          for easy testing.
        """

        self.report_id = report_id
        self.created_string = format_date_for_public_report_file(created)
        self.results = json_string(results)

        self.file_manager = file_manager or PublicReportFileManager(
            task_logger, get_absolute_path())

        # there should not be a need to call these functions more than once
        self.path = self.file_manager.get_public_report_path(self.report_id,
                                                             recurrent=True,
                                                             create=True)

        # TODO use file manager to get function when function is available
        self.filepath = os.path.join(self.path, self.created_string)
 def test_public_report_state_change_error(self):
     """
     Persistent Report should propagate IO errors from
     PublicReportFileManager
     """
     self.app = Mock()
     
     self.logger = Mock(spec=RootLogger)
     
     file_manager = PublicReportFileManager(self.logger, '/some/fake/absolute/path')
     file_manager.write_data = Mock(side_effect=PublicReportIOError('Boom!'))
     # do not write anything to disk
     file_manager.get_public_report_path = Mock()
     ReportStore.make_report_public(
         self.reports[0].id, self.reports[0].user_id, file_manager, 'testing data'
     )
示例#5
0
    def test_public_report_state_change_error(self):
        """
        Persistent Report should propagate IO errors from
        PublicReportFileManager
        """
        self.app = Mock()

        self.logger = Mock(spec=RootLogger)

        file_manager = PublicReportFileManager(self.logger,
                                               '/some/fake/absolute/path')
        file_manager.write_data = Mock(
            side_effect=PublicReportIOError('Boom!'))
        # do not write anything to disk
        file_manager.get_public_report_path = Mock()
        ReportStore.make_report_public(self.reports[0].id,
                                       self.reports[0].user_id, file_manager,
                                       'testing data')
class PublicReportFileMangerTest(unittest.TestCase):
    """
    Tests should have no side effects. i.e. should not create any files on disk
    
    If there is a reason why they would they should be cleaned up after
    
    Assumes /public/static directory is existing, puppet must have created it
    """
    
    def setUp(self):
        # setup mock logger
        self.logger = Mock(spec=RootLogger)
        self.api = PublicReportFileManager(self.logger, './wikimetrics/')
    
    def tearDown(self):
        pass
    
    def test_get_public_report_path(self):
        """
        Path should be constructed acording to protocol
        """
        absolute_report_path = self.api.get_public_report_path('fake-report-id')
        fake_path = 'static/public/fake-report-id.json'
        # should end with 'static/public/fake-report-id.json'
        l = len(fake_path)
        path_len = len(absolute_report_path)
        substr = absolute_report_path[path_len - l:path_len]
        assert_equals(substr, fake_path)
    
    @raises(PublicReportIOError)
    def test_cannot_write_file(self):
        """
        Correct exception is raised when we cannot write to the
        given path.
        """
        self.api.write_data('/some-fake/path/to-create-file/', 'some-string')
    
    @raises(PublicReportIOError)
    def test_cannot_remove_file(self):
        """
        Correct exception is raised when we cannot delete a given report
        """
        self.api.remove_file('/some-fake/path/to-delete-file.json')
示例#7
0
 def setUp(self):
     logger = Mock(spec=RootLogger)
     self.results = {'results': 'good'}
     self.fake_path = '/fake/fake/path/'
     file_manager = PublicReportFileManager(logger, '/some/fake/absolute/path')
     file_manager.write_data = Mock()
     file_manager.remove_file = Mock()
     file_manager.get_public_report_path = MagicMock(return_value=self.fake_path)
     file_manager.coalesce_recurrent_reports = MagicMock(return_value=self.results)
     file_manager.remove_old_report_files = MagicMock()
     self.file_manager = file_manager
示例#8
0
def setup_filemanager():
    if request.endpoint is not None:
        if request.path.startswith('/reports'):
            file_manager = getattr(g, 'file_manager', None)
            if file_manager is None:
                g.file_manager = PublicReportFileManager(
                    app.logger,
                    app.absolute_path_to_app_root)
        cohort_service = getattr(g, 'cohort_service', None)
        centralauth_service = getattr(g, 'centralauth_service', None)
        if cohort_service is None:
            g.cohort_service = CohortService()
        if centralauth_service is None:
                g.centralauth_service = CentralAuthService()
 def setUp(self):
     # setup mock logger
     self.logger = Mock(spec=RootLogger)
     self.api = PublicReportFileManager(self.logger, './wikimetrics/')
     self.test_report_path = os.path.join(get_absolute_path(), os.pardir, 'tests')
class PublicReportFileMangerTest(unittest.TestCase):
    """
    Tests should have no side effects. i.e. should not create any files on disk

    If there is a reason why they would they should be cleaned up after

    Assumes /public/static directory is existing, puppet must have created it
    """

    def setUp(self):
        # setup mock logger
        self.logger = Mock(spec=RootLogger)
        self.api = PublicReportFileManager(self.logger, './wikimetrics/')
        self.test_report_path = os.path.join(get_absolute_path(), os.pardir, 'tests')

    def tearDown(self):
        pass

    def test_get_public_report_path(self):
        """
        Path should be constructed acording to protocol
        """
        absolute_report_path = self.api.get_public_report_path('fake-report-id')
        fake_path = 'static/public/fake-report-id.json'
        # should end with 'static/public/fake-report-id.json'
        l = len(fake_path)
        path_len = len(absolute_report_path)
        substr = absolute_report_path[path_len - l:path_len]
        assert_equal(substr, fake_path)

    @raises(PublicReportIOError)
    def test_cannot_write_file(self):
        """
        Correct exception is raised when we cannot write to the
        given path.
        """
        self.api.write_data('/some-fake/path/to-create-file/', 'some-string')

    @raises(PublicReportIOError)
    def test_cannot_remove_file(self):
        """
        Correct exception is raised when we cannot delete a given report
        """
        self.api.remove_file('/some-fake/path/to-delete-file.json')

    def test_coalesce_recurrent_reports(self):
        self.api.root_dir = self.test_report_path
        assert_true(os.path.isdir(self.test_report_path))
        test_report_id = '0000'

        test_report_dir = os.sep.join((self.test_report_path, 'static',
                                      'public', test_report_id))
        full_report = self.api.coalesce_recurrent_reports(test_report_id)

        # Confirm the coalesced file has the correct keys (the "Metric_end_date" for each
        # child report, and that the individual reports in the coalesced file match the
        # content of each child report file
        files_to_coalesce = [f for f in os.listdir(test_report_dir) if os.path.isfile(
            os.sep.join((test_report_dir, f))) and f != COALESCED_REPORT_FILE]

        assert_equal(len(files_to_coalesce), 4)

        report_results = []
        users_reported = set()
        dates = set()
        for f in files_to_coalesce:
            with open(os.sep.join((test_report_dir, f))) as json_file:
                try:
                    loaded = json.load(json_file)
                    for u in loaded['result'][Aggregation.IND]:
                        users_reported.add(u)
                    for d in loaded['result'][Aggregation.AVG]['edits']:
                        dates.add(d)
                    report_results.append(loaded)
                except ValueError:
                    pass

        assert_equal(len(report_results), 3)  # There are 3 valid test report files

        assert_equal({k for k in full_report}, {
            'result', 'parameters'
        })
        assert_equal({k for k in full_report['result']}, {
            Aggregation.AVG, Aggregation.IND
        })
        assert_equal({k for k in full_report['result'][Aggregation.IND]}, users_reported)
        assert_equal({k for k in full_report['result'][Aggregation.AVG]['edits']}, dates)

    @raises(PublicReportIOError)
    def test_remove_recurrent_report(self):
        # Attempt to delete a non-existent recurrent report directory
        self.api.root_dir = self.test_report_path
        test_report_id = '0001'
        self.api.remove_recurrent_report(test_report_id)
 def setUp(self):
     # setup mock logger
     self.logger = Mock(spec=RootLogger)
     self.api = PublicReportFileManager(self.logger, './wikimetrics/')
示例#12
0
 def setUp(self):
     # setup mock logger
     self.logger = Mock(spec=RootLogger)
     self.api = PublicReportFileManager(self.logger, './wikimetrics/')
     self.test_report_path = os.path.join(get_absolute_path(), os.pardir,
                                          'tests')
示例#13
0
class PublicReportFileMangerTest(unittest.TestCase):
    """
    Tests should have no side effects. i.e. should not create any files on disk

    If there is a reason why they would they should be cleaned up after

    Assumes /public/static directory is existing, puppet must have created it
    """
    def setUp(self):
        # setup mock logger
        self.logger = Mock(spec=RootLogger)
        self.api = PublicReportFileManager(self.logger, './wikimetrics/')
        self.test_report_path = os.path.join(get_absolute_path(), os.pardir,
                                             'tests')

    def tearDown(self):
        pass

    def test_get_public_report_path(self):
        """
        Path should be constructed acording to protocol
        """
        absolute_report_path = self.api.get_public_report_path(
            'fake-report-id')
        fake_path = 'static/public/fake-report-id.json'
        # should end with 'static/public/fake-report-id.json'
        l = len(fake_path)
        path_len = len(absolute_report_path)
        substr = absolute_report_path[path_len - l:path_len]
        assert_equal(substr, fake_path)

    @raises(PublicReportIOError)
    def test_cannot_write_file(self):
        """
        Correct exception is raised when we cannot write to the
        given path.
        """
        self.api.write_data('/some-fake/path/to-create-file/', 'some-string')

    @raises(PublicReportIOError)
    def test_cannot_remove_file(self):
        """
        Correct exception is raised when we cannot delete a given report
        """
        self.api.remove_file('/some-fake/path/to-delete-file.json')

    def test_coalesce_recurrent_reports(self):
        self.api.root_dir = self.test_report_path
        assert_true(os.path.isdir(self.test_report_path))
        test_report_id = '0000'

        test_report_dir = os.sep.join(
            (self.test_report_path, 'static', 'public', test_report_id))
        full_report = self.api.coalesce_recurrent_reports(test_report_id)

        # Confirm the coalesced file has the correct keys (the "Metric_end_date" for each
        # child report, and that the individual reports in the coalesced file match the
        # content of each child report file
        files_to_coalesce = [
            f for f in os.listdir(test_report_dir)
            if os.path.isfile(os.sep.join((test_report_dir,
                                           f))) and f != COALESCED_REPORT_FILE
        ]

        assert_equal(len(files_to_coalesce), 4)

        report_results = []
        users_reported = set()
        dates = set()
        for f in files_to_coalesce:
            with open(os.sep.join((test_report_dir, f))) as json_file:
                try:
                    loaded = json.load(json_file)
                    for u in loaded['result'][Aggregation.IND]:
                        users_reported.add(u)
                    for d in loaded['result'][Aggregation.AVG]['edits']:
                        dates.add(d)
                    report_results.append(loaded)
                except ValueError:
                    pass

        assert_equal(len(report_results),
                     3)  # There are 3 valid test report files

        assert_equal({k for k in full_report}, {'result', 'parameters'})
        assert_equal({k
                      for k in full_report['result']},
                     {Aggregation.AVG, Aggregation.IND})
        assert_equal({k
                      for k in full_report['result'][Aggregation.IND]},
                     users_reported)
        assert_equal(
            {k
             for k in full_report['result'][Aggregation.AVG]['edits']}, dates)

    @raises(PublicReportIOError)
    def test_remove_recurrent_report(self):
        # Attempt to delete a non-existent recurrent report directory
        self.api.root_dir = self.test_report_path
        test_report_id = '0001'
        self.api.remove_recurrent_report(test_report_id)