def setUp(self, mock_config, mock_parser, mock_log): path = os.path.dirname(os.path.realpath(__file__ + '../../../')) self._path = os.path.join(path, os.path.join('tests', 'conf')) mock_config.return_value = [self._path] mock_parser.return_value = [] mock_log.return_value = None Logger._instance = mock_log Configuration(filename='config_sections.json') self._thread_manager = ThreadManager()
def test_adding_filter_ignores_argument_validation_error_and_adds_to_self(self, mock_query, mock_load, mock_jira_client): mock_query.side_effect = ArgumentValidationError('1st', 'append', 'pyccata.core.filter.Filter', 'object') mock_jira_client.return_value = DataProviders._get_client() with patch('pyccata.core.configuration.Configuration.manager', new_callable=PropertyMock) as mock_manager: with patch('pyccata.core.configuration.Configuration._configuration', new_callable=PropertyMock) as mock_config: mock_config.return_value = DataProviders._get_config_for_test() mock_manager.return_value = 'jira' manager = ThreadManager() manager.append(TestObservableThread()) self.assertEquals(1, len(manager))
def test_adding_filter_adds_project_manager(self, mock_load, mock_jira_client): mock_jira_client.return_value = DataProviders._get_client() with patch('pyccata.core.configuration.Configuration.manager', new_callable=PropertyMock) as mock_manager: with patch('pyccata.core.configuration.Configuration._configuration', new_callable=PropertyMock) as mock_config: mock_config.return_value = DataProviders._get_config_for_test() mock_manager.return_value = 'jira' manager = ThreadManager() self.assertIsInstance(manager.projectmanager, ProjectManager) self.assertIsInstance(manager.querymanager, QueryManager) self.assertIsInstance(manager.configuration, Configuration) mock_filter = Filter('assignee = "Foo"') manager.append(mock_filter) self.assertIsInstance(mock_filter.projectmanager, ProjectManager)
def setUp(self, mock_config, mock_parser, mock_log): self.tearDown() mock_log.return_value = None Logger._instance = mock_log path = os.path.dirname(os.path.realpath(__file__ + '../../../../')) self._path = os.path.join(path, os.path.join('tests', 'conf')) mock_config.return_value = [self._path] mock_parser.return_value = [] config = None with patch('argparse.ArgumentParser.add_argument'): config = Configuration(filename='valid_config.json') config.check = True self._report_manager = ReportManager() self._thread_manager = ThreadManager()
def setup(self, extractor, index, queries, results, primary_dataset, unique_columns): """ Set up the partition runner :param pyccata.core.classes.DataExtraction: extractor :param int: index :param list: queries :param list: results :param string: primary_dataset :param list|string: unique_columns queries is a list of ``pyccata.core.parser.ExtractedResults`` objects results is a list of ``pandas.DataFrame`` objects primary_dataset dictates which frame to use for the left side of the join unique_columns determines which column to use for the join """ # pylint: disable=arguments-differ,too-many-arguments self._extractor = extractor self._index = index self._queries = queries self._results = results self._names = [item.name for item in results] alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' short_names = [letter for letter in alphabet[:len(self._results)]] self._mappings = { name: short for short, name in zip(short_names, self._names) } self._primary_dataset = primary_dataset self._unique_columns = unique_columns ThreadManager().append(self)
def threadmanager(self): """ Load the threadmanager """ try: if self._thread_manager is None: return ThreadManager() except (ImportError, AttributeError, NotImplementedError, RequiredKeyError) as exception: ControllerAbstract._raise_and_terminate('ThreadManager', exception) return self._thread_manager
def setup(self, merge_table, query, unique_columns): """ Set up a new data-filter as a threaded object :param merge_table: pandas.DataFrame object :param query: string """ # pylint: disable=arguments-differ self._data = merge_table self._query = query self._unique_columns = unique_columns ThreadManager().append(self)
def test_execute_batches_pool_size_and_logs_on_error(self, mock_query, mock_load, mock_jira_client): mock_query.side_effect = ArgumentValidationError('1st', 'append', 'pyccata.core.filter.Filter', 'object') mock_jira_client.return_value = DataProviders._get_client() with patch('pyccata.core.configuration.Configuration.manager', new_callable=PropertyMock) as mock_manager: with patch('pyccata.core.configuration.Configuration._configuration', new_callable=PropertyMock) as mock_config: mock_config.return_value = DataProviders._get_config_for_test() mock_manager.return_value = 'jira' manager = ThreadManager() test_threads = DataProviders.some_threads_explode() for thread in test_threads: manager.append(thread) manager.start()
def test_execute_batches_pool_size_and_fills_on_complete(self, mock_query, mock_load, mock_jira_client): mock_query.side_effect = ArgumentValidationError('1st', 'append', 'pyccata.core.filter.Filter', 'object') mock_jira_client.return_value = DataProviders._get_client() with patch('pyccata.core.configuration.Configuration.manager', new_callable=PropertyMock) as mock_manager: with patch('pyccata.core.configuration.Configuration._configuration', new_callable=PropertyMock) as mock_config: mock_config.return_value = DataProviders._get_config_for_test() mock_manager.return_value = 'jira' manager = ThreadManager() # start with 100 threads... for i in range(100): manager.append(ViableTestThread()) manager.start()
def test_execute_adds_to_failures_when_all_observers_fail(self, mock_load, mock_jira_client): mock_jira_client.return_value = None with patch('pyccata.core.configuration.Configuration.manager', new_callable=PropertyMock) as mock_manager: with patch('pyccata.core.configuration.Configuration._configuration', new_callable=PropertyMock) as mock_config: mock_config.return_value = DataProviders._get_config_for_test() mock_manager.return_value = 'jira' mock_broken = BrokenConnectionFilter('assignee = "Bob"') mock_filter = BrokenConnectionFilter('assignee = "Bob"') manager = ThreadManager() manager.append(mock_broken) manager.append(mock_filter) self.assertEquals(1, len(manager)) self.assertEquals(1, len(manager[0]._observers)) manager.start() self.assertEquals(1, len(manager._failed_threads))
class TestList(TestCase): _report_manager = None _thread_manager = None @patch('pyccata.core.log.Logger.log') @patch('argparse.ArgumentParser.parse_args') @patch('pyccata.core.configuration.Configuration._get_locations') def setUp(self, mock_config, mock_parser, mock_log): path = os.path.dirname(os.path.realpath(__file__ + '../../../../')) self._path = os.path.join(path, os.path.join('tests', 'conf')) mock_config.return_value = [self._path] mock_parser.return_value = [] mock_log.return_value = None Logger._instance = mock_log Configuration(filename='config_sections.json') self._report_manager = ReportManager() self._thread_manager = ThreadManager() def tearDown(self): if ThreadManager._instance is not None: ThreadManager._instance = None if Configuration._instance is not None: Configuration._instance = None Configuration.NAMESPACE = 'pyccata.core' def test_get_item_raises_error_if_content_is_filter_and_filter_results_is_empty( self): list_contents = Filter('project=mssportal', max_results=5, fields=['id', 'description', 'priority']) Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) unordered = List(self._thread_manager, config) with self.assertRaises(IndexError): item = unordered[0] def test_get_item_raises_error_if_content_is_list_and_results_is_none( self): list_contents = [] Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) unordered = List(self._thread_manager, config) with self.assertRaises(IndexError): item = unordered[0] def test_set_item_raises_error_if_content_is_filter_and_filter_results_is_none( self): list_contents = Filter('project=mssportal', max_results=5, fields=['id', 'description', 'priority']) Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) unordered = List(self._thread_manager, config) with self.assertRaises(IndexError): unordered[0] = 'hello world' def test_set_item_raises_error_if_content_is_list_and_results_is_none( self): list_contents = [] Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) unordered = List(self._thread_manager, config) with self.assertRaises(IndexError): unordered[0] = 'hello world' def test_get_len_returns_length_of_self_if_content_is_list(self): list_contents = ['test 1', 'test 2', 'test 3'] Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) unordered = List(self._thread_manager, config) self.assertEqual(3, len(unordered)) @patch('pyccata.core.managers.project.ProjectManager.search_issues') def test_get_len_returns_length_of_filter_results_if_content_is_filter( self, mock_manager): result_list = DataProviders( ).get_results_for_list_init_with_single_query_in_config() list_contents = Filter('project=msportal', max_results=5, fields=['id', 'description', 'priority']) mock_manager.return_value = result_list Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) unordered = List(self._thread_manager, config) self._thread_manager.execute() self.assertEquals(5, len(unordered)) def test_delete_item_if_content_is_list(self): list_contents = ['test 1', 'test 2', 'test 3'] Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) unordered = List(self._thread_manager, config) del unordered[2] self.assertEquals(2, len(unordered)) @patch('pyccata.core.managers.project.ProjectManager.search_issues') def test_delete_item_if_content_is_filter(self, mock_manager): result_list = DataProviders( ).get_results_for_list_init_with_single_query_in_config() list_contents = Filter('project=msportal', max_results=5, fields=['id', 'description', 'priority']) mock_manager.return_value = result_list Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) unordered = List(self._thread_manager, config) self._thread_manager.execute() del unordered[1] self.assertEquals(4, len(unordered)) def test_reverse_list_if_content_is_list(self): list_contents = ['test 1', 'test 2', 'test 3'] Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) unordered = List(self._thread_manager, config) unordered = list(reversed(unordered)) self.assertEquals('test 3', unordered[0]) self.assertEquals('test 2', unordered[1]) self.assertEquals('test 1', unordered[2]) @patch('pyccata.core.managers.project.ProjectManager.search_issues') def test_reverse_list_if_content_is_filter(self, mock_manager): result_list = DataProviders( ).get_results_for_list_init_with_single_query_in_config() list_contents = Filter('project=msportal', max_results=5, fields=['id', 'description', 'priority']) mock_manager.return_value = result_list Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) unordered = List(self._thread_manager, config) self._thread_manager.execute() unordered = list(reversed(unordered)) self.assertEquals('This is test item 5', unordered[0].description) self.assertEquals('This is test item 4', unordered[1].description) self.assertEquals('This is test item 3', unordered[2].description) self.assertEquals('This is test item 2', unordered[3].description) self.assertEquals('This is test item 1', unordered[4].description) def test_list_contains_item_if_content_is_list(self): list_contents = ['test 1', 'test 2', 'test 3'] Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) unordered = List(self._thread_manager, config) self.assertTrue(('test 1' in unordered)) @patch('pyccata.core.managers.project.ProjectManager.search_issues') def test_list_contains_item_if_content_is_filter(self, mock_manager): result_list = DataProviders( ).get_results_for_list_init_with_single_query_in_config() list_contents = Filter('project=msportal', max_results=5, fields=['id', 'description', 'priority']) mock_manager.return_value = result_list Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) unordered = List(self._thread_manager, config) self._thread_manager.execute() self.assertTrue((result_list[3] in unordered)) def test_setup_raises_argument_validation_error_if_style_is_invalid(self): Config = namedtuple('Config', 'content style field prepend') config = Config(content=[], style='IAmInvalid', field='', prepend=None) with self.assertRaises(ArgumentValidationError): unordered = List(self._thread_manager, config) @patch('pyccata.core.managers.report.ReportManager.add_list') def test_init_creates_list(self, mock_list): list_contents = ['test item 1', 'test item 2', 'test item 3'] Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='', prepend=None) calls = [call(item, style='ListBullet') for item in list_contents] unordered = List(self._thread_manager, config) unordered.run() unordered.render(self._report_manager) mock_list.assert_has_calls(calls) @patch('pyccata.core.managers.project.ProjectManager.search_issues') @patch('pyccata.core.managers.report.ReportManager.add_list') def test_init_using_list_of_queries_creates_list(self, mock_list, mock_manager): result_list = DataProviders( ).get_results_for_list_init_with_list_of_queries_in_config() list_contents = [ Filter('project=mssportal', max_results=5, fields=['id', 'description', 'priority']), Filter('project=svcdesk', max_results=5, fields=['id', 'description', 'priority']), Filter('project=mvs', max_results=5, fields=['id', 'description', 'priority']), ] mock_manager.side_effect = result_list Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) calls = [ call(item[0].description, style='ListBullet') for item in result_list ] unordered = List(self._thread_manager, config) self._thread_manager.execute() unordered.render(self._report_manager) mock_list.assert_has_calls(calls) @patch('pyccata.core.managers.project.ProjectManager.search_issues') @patch('pyccata.core.managers.report.ReportManager.add_list') def test_init_using_list_of_queries_and_strings_creates_list( self, mock_list, mock_manager): result_list = DataProviders( ).get_results_for_list_init_with_list_of_queries_and_strings_in_config( ) list_contents = [ Filter('project=msportal', max_results=5, fields=['id', 'description', 'priority']), "This is a string entry", Filter('project=svdesk', max_results=5, fields=['id', 'description', 'priority']), Filter('project=mvp', max_results=5, fields=['id', 'description', 'priority']), "This is another string entry" ] effect = [item for item in result_list if isinstance(item, ResultList)] mock_manager.side_effect = effect Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) calls = [ call(item[0].description if isinstance(item, list) else item, style='ListBullet') for item in result_list ] unordered = List(self._thread_manager, config) self._thread_manager.execute() unordered.render(self._report_manager) mock_list.assert_has_calls(calls) @patch('pyccata.core.managers.project.ProjectManager.search_issues') @patch('pyccata.core.managers.report.ReportManager.add_list') def test_init_using_single_query_creates_list(self, mock_list, mock_manager): result_list = DataProviders( ).get_results_for_list_init_with_single_query_in_config() list_contents = Filter('project=msportal', max_results=5, fields=['id', 'description', 'priority']) mock_manager.return_value = result_list Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) calls = [ call(item.description, style='ListBullet') for item in result_list ] unordered = List(self._thread_manager, config) self._thread_manager.execute() unordered.render(self._report_manager) mock_list.assert_has_calls(calls) @patch('pyccata.core.managers.project.ProjectManager.search_issues') @patch('pyccata.core.managers.report.ReportManager.add_list') def test_init_using_list_of_queries_and_strings_continues_if_query_errors( self, mock_list, mock_manager): result_list = DataProviders( ).get_results_for_list_init_with_list_of_queries_and_strings_continues( ) list_contents = [ Filter('project=msportal', max_results=5, fields=['id', 'description', 'priority']), "This is a string entry", Filter('project=svdesk', max_results=5, fields=['id', 'description', 'priority']), Filter('project=mvp', max_results=5, fields=['id', 'description', 'priority']), "This is another string entry" ] effect = [item for item in result_list if isinstance(item, ResultList)] effect[1] = InvalidQueryError('The query you have provided is invalid') mock_manager.side_effect = effect Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) calls = [ call(item[0].description if isinstance(item, list) else item, style='ListBullet') for item in result_list ] del calls[2] unordered = List(self._thread_manager, config) self._thread_manager.execute() unordered.render(self._report_manager) mock_list.assert_has_calls(calls) @patch('pyccata.core.managers.project.ProjectManager.search_issues') def test_list_contains_item_if_content_is_tuple(self, mock_manager): result_list = DataProviders( ).get_results_for_list_init_with_single_query_in_config() ListContents = namedtuple('ListContents', 'query fields') list_contents = ListContents('project=msportal', fields=['id', 'description', 'priority']) mock_manager.return_value = result_list Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) unordered = List(self._thread_manager, config) self._thread_manager.execute() self.assertTrue((result_list[3] in unordered)) @patch('pyccata.core.managers.project.ProjectManager.search_issues') def test_list_fails_if_content_is_invalid_tuple(self, mock_manager): result_list = DataProviders( ).get_results_for_list_init_with_single_query_in_config() Filter = namedtuple('Filter', 'bob fields') list_contents = Filter('project=msportal', fields=['id', 'description', 'priority']) mock_manager.return_value = result_list Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) with self.assertRaises(ArgumentValidationError): unordered = List(self._thread_manager, config) def test_run_completes_if_filter_delays_in_completing(self): ListContents = namedtuple('ListContents', 'query fields') list_contents = ListContents('project=msportal', fields=['id', 'description', 'priority']) Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) with patch('pyccata.core.filter.Filter.complete', new_callable=PropertyMock) as mock_thread_complete: unordered = List(self._thread_manager, config) mock_thread_complete.side_effect = [False, False, True] unordered.run() self.assertTrue(unordered._complete) def test_run_completes_if_thread_fails(self): ListContents = namedtuple('ListContents', 'query fields') list_contents = ListContents('project=msportal', fields=['id', 'description', 'priority']) Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) with patch('pyccata.core.threading.Threadable.complete', new_callable=PropertyMock) as mock_thread_complete: unordered = List(self._thread_manager, config) mock_thread_complete.return_value = True unordered._content._failure = InvalidQueryError( 'Your JQL contains an error before Pipeline') unordered.run() self.assertTrue(unordered._complete) @patch('pyccata.core.managers.project.ProjectManager.search_issues') @patch('pyccata.core.managers.report.ReportManager.add_list') def test_init_using_list_of_queries_and_strings_continues_if_query_is_delayed( self, mock_list, mock_manager): result_list = DataProviders( ).get_results_for_list_init_with_list_of_queries_and_strings_continues( ) list_contents = [ "This is a string entry", Filter('project=msportal', max_results=5, fields=['id', 'description', 'priority']) ] effect = [item for item in result_list if isinstance(item, ResultList)] effect[1] = InvalidQueryError('The query you have provided is invalid') mock_manager.side_effect = effect Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) with patch('pyccata.core.filter.Filter.complete', new_callable=PropertyMock) as mock_thread_complete: mock_thread_complete.side_effect = [False, False, True] unordered = List(self._thread_manager, config) unordered.run() self.assertTrue(unordered._complete) @patch('pyccata.core.filter.Filter.results', new_callable=PropertyMock) @patch('pyccata.core.managers.report.ReportManager.add_list') def test_init_using_single_query_creates_list_of_items( self, mock_list, mock_results): results = ["test 1", "test 2", "test 3", "test 4", "test 5"] resultset = Issue() resultset.pipelines = results list_contents = Filter('project=msportal', max_results=5, fields=['id', 'description', 'priority']) Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='pipelines', prepend=None) calls = [call(item, style='ListBullet') for item in results] with patch('pyccata.core.filter.Filter.complete', new_callable=PropertyMock): unordered = List(self._thread_manager, config) mock_results.return_value = [resultset] list_contents.complete.return_value = True unordered.run() unordered.render(self._report_manager) mock_list.assert_has_calls(calls) @patch('pyccata.core.managers.project.ProjectManager.search_issues') def test_list_completes_if_content_filter_fails(self, mock_manager): result_list = DataProviders( ).get_results_for_list_init_with_single_query_in_config() list_contents = Filter('project=msportal', max_results=5, fields=['id', 'description', 'priority']) mock_manager.return_value = result_list Config = namedtuple('Config', 'content style field prepend') config = Config(content=list_contents, style='unordered', field='description', prepend=None) unordered = List(self._thread_manager, config) with patch('pyccata.core.filter.Filter.failure', new_callable=PropertyMock) as mock_failure: mock_failure.return_value = RuntimeError('I blew up') self._thread_manager.execute()
class TestTable(TestCase): _report_manager = None _thread_manager = None @patch('pyccata.core.log.Logger.log') @patch('argparse.ArgumentParser.parse_args') @patch('pyccata.core.configuration.Configuration._get_locations') def setUp(self, mock_config, mock_parser, mock_log): path = os.path.dirname(os.path.realpath(__file__ + '../../../../')) self._path = os.path.join(path, os.path.join('tests', 'conf')) mock_config.return_value = [self._path] mock_parser.return_value = [] mock_log.return_value = None Logger._instance = mock_log Configuration(filename='config_sections.json') self._report_manager = ReportManager() self._thread_manager = ThreadManager() def tearDown(self): if ThreadManager._instance is not None: ThreadManager._instance = None if Configuration._instance is not None: Configuration._instance = None Configuration.NAMESPACE = 'pyccata.core' @patch('pyccata.core.managers.report.ReportManager.add_table') def test_run_creates_table(self, mock_manager): Config = namedtuple('Config', 'rows columns style') rows = [] for i in range(6): rows.append( ['Row ' + str((i + 1)), 'Test description ' + str((i + 1))]) columns = ['Name', 'Description'] config = Config(rows=rows, columns=columns, style='Light heading 1') table = Table(self._thread_manager, config) self._thread_manager.execute() table.render(self._report_manager) calls = [call(headings=columns, data=rows, style='Light heading 1')] mock_manager.assert_has_calls(calls) @patch('pyccata.core.managers.report.ReportManager.add_table') def test_create_table_manages_exception_if_filter_cannot_be_created( self, mock_manager): Config = namedtuple('Config', 'rows columns style') Filter = namedtuple('SubFilter', 'search_for bob') rows = Filter(search_for='project=mssportal', bob='fish') columns = ['Name', 'Description'] config = Config(rows=rows, columns=columns, style='Light heading 1') table = Table(self._thread_manager, config) def test_run_completes_if_filter_fails(self): mock_filter = Filter('bob', max_results=5, fields=None, namespace='pyccata.core') mock_filter._failure = InvalidQueryError('query is wrong') Config = namedtuple('Config', 'rows columns style') config = Config(rows=[['My search', mock_filter]], columns=['Test column', 'Test Results'], style=None) table = Table(self._thread_manager, config) table.run() self.assertTrue(table._complete) def test_run_completes_if_filter_delays_in_completing(self): mock_filter = Filter('bob', max_results=5, fields=None, namespace='pyccata.core') Config = namedtuple('Config', 'rows columns style') config = Config(rows=[['My search', mock_filter]], columns=['Test column', 'Test Results'], style=None) with patch('pyccata.core.threading.Threadable.complete', new_callable=PropertyMock) as mock_thread: table = Table(self._thread_manager, config) mock_thread.side_effect = [False, False, True] table.run() self.assertTrue(table._complete) @patch('pyccata.core.managers.report.ReportManager.add_table') @patch('pyccata.core.managers.report.ReportManager.add_heading') def test_table_doesnt_render_with_empty_filter_results( self, mock_heading, mock_table): self.tearDown() Config = namedtuple('Config', 'rows columns style') Filter = namedtuple('Filter', 'query max_results namespace') rows = Filter(query='project=mssportal', max_results=5, namespace='pyccata.core') columns = ['Name', 'Description'] config = Config(rows=rows, columns=columns, style='Light heading 1') table = Table(self._thread_manager, config) document = ReportManager() table.render(document) mock_table.assert_not_called() mock_heading.assert_not_called() @patch('pyccata.core.managers.report.ReportManager.add_table') @patch('pyccata.core.managers.report.ReportManager.add_heading') def test_table_renders_filter_results(self, mock_heading, mock_table): self.tearDown() Config = namedtuple('Config', 'rows columns style') with patch('pyccata.core.filter.Filter.results', new_callable=PropertyMock) as mock_results: ResultsList = namedtuple('ResultsList', 'total results') Result = namedtuple('Result', 'key release_text business_representative') mock_results.return_value = ResultsList( total=1, results=[ Result(key='testproj-123', release_text='I am test text', business_representative='Bob Smith') ]) Filter = namedtuple('Filter', 'query max_results namespace') rows = Filter(query='project=mssportal', max_results=5, namespace='pyccata.core') columns = ['Name', 'Description'] config = Config(rows=rows, columns=columns, style='Light heading 1') table = Table(self._thread_manager, config) document = ReportManager() table.render(document) self.assertEquals(1, mock_table.call_count) mock_heading.assert_not_called() @patch('pyccata.core.managers.report.ReportManager.add_table') @patch('pyccata.core.managers.report.ReportManager.add_heading') def test_table_renders_filter_results_from_cell_query( self, mock_heading, mock_table): self.tearDown() Config = namedtuple('Config', 'rows columns style') with patch('pyccata.core.filter.Filter.results', new_callable=PropertyMock) as mock_results: ResultsList = namedtuple('ResultsList', 'total results') Result = namedtuple('Result', 'key release_text business_representative') mock_results.return_value = ResultsList( total=1, results=[ Result(key='testproj-123', release_text='I am test text', business_representative='Bob Smith') ]) Filter = namedtuple('Filter', 'query max_results namespace') rows = Filter(query='project=mssportal', max_results=5, namespace='pyccata.core') columns = ['Name', 'Description'] config = Config(rows=[['Data', rows]], columns=columns, style='Light heading 1') table = Table(self._thread_manager, config) table.title = 'Test Title' document = ReportManager() table.render(document) self.assertEquals(1, mock_table.call_count) self.assertEquals(1, mock_heading.call_count) mock_heading.assert_called_with('Test Title', 3) @patch('pyccata.core.managers.report.ReportManager.add_table') @patch('pyccata.core.managers.report.ReportManager.add_heading') def test_table_renders_filter_results_from_cell_query_continues_if_filter_errors( self, mock_heading, mock_table): self.tearDown() Config = namedtuple('Config', 'rows columns style') with patch('pyccata.core.filter.Filter.results', new_callable=PropertyMock) as mock_results: ResultsList = namedtuple('ResultsList', 'total results') Result = namedtuple('Result', 'key release_text business_representative') mock_results.return_value = ResultsList( total=1, results=[ Result(key='testproj-123', release_text='I am test text', business_representative='Bob Smith') ]) Filter = namedtuple('Filter', 'max_results namespace') rows = Filter(max_results=5, namespace='pyccata.core') columns = ['Name', 'Description'] config = Config(rows=[['Data', rows]], columns=columns, style='Light heading 1') table = Table(self._thread_manager, config) table.title = 'Test Title' document = ReportManager() table.render(document) self.assertEquals(1, mock_table.call_count) self.assertEquals(1, mock_heading.call_count) mock_heading.assert_called_with('Test Title', 3) @patch('pyccata.core.managers.report.ReportManager.add_table') @patch('pyccata.core.managers.report.ReportManager.add_heading') def test_table_renders_filter_results_multi_results_with_combine( self, mock_heading, mock_table): self.tearDown() Config = namedtuple('Config', 'rows columns style') with patch('pyccata.core.filter.Filter.results', new_callable=PropertyMock) as mock_results: results_set_one = ResultList(name='test results') result_issue = Issue() result_issue.description = 'This is a test item' results_set_one.append(result_issue) results_set_two = ResultList(name='another set of tests') another_result_issue = Issue() another_result_issue.description = 'This is a test item' results_set_two.append(another_result_issue) multi_results = MultiResultList() multi_results.combine = True multi_results.append(results_set_one) multi_results.append(results_set_two) mock_results.return_value = multi_results Filter = namedtuple('Filter', 'query max_results namespace') rows = Filter(query='project=mssportal', max_results=5, namespace='pyccata.core') columns = ['Name', 'Description'] config = Config(rows=rows, columns=columns, style='Light heading 1') table = Table(self._thread_manager, config) document = ReportManager() table.render(document) self.assertEquals(1, mock_table.call_count) mock_heading.assert_not_called() @patch('pyccata.core.managers.report.ReportManager.add_table') @patch('pyccata.core.managers.report.ReportManager.add_heading') def test_table_renders_filter_results_multi_results_without_combine( self, mock_heading, mock_table): self.tearDown() Config = namedtuple('Config', 'rows columns style') with patch('pyccata.core.filter.Filter.results', new_callable=PropertyMock) as mock_results: results_set_one = ResultList(name='test results') result_issue = Issue() result_issue.description = 'This is a test item' results_set_one.append(result_issue) results_set_two = ResultList(name='another set of tests') another_result_issue = Issue() another_result_issue.description = 'This is a test item' results_set_two.append(another_result_issue) multi_results = MultiResultList() multi_results.combine = False multi_results.append(results_set_one) multi_results.append(results_set_two) mock_results.return_value = multi_results Filter = namedtuple('Filter', 'query max_results namespace') rows = Filter(query='project=mssportal', max_results=5, namespace='pyccata.core') columns = ['Name', 'Description'] config = Config(rows=rows, columns=columns, style='Light heading 1') table = Table(self._thread_manager, config) document = ReportManager() table.render(document) self.assertEquals(2, mock_table.call_count) self.assertEquals(2, mock_heading.call_count)
def test_we_only_accept_threadable_objects(self, mock_load, mock_jira_client): with self.assertRaises(ArgumentValidationError): manager = ThreadManager() manager.append(object())
class TestThreadableCommand(TestCase): @patch('pyccata.core.log.Logger.log') @patch('argparse.ArgumentParser.parse_args') @patch('pyccata.core.configuration.Configuration._get_locations') def setUp(self, mock_config, mock_parser, mock_log): path = os.path.dirname(os.path.realpath(__file__ + '../../../')) self._path = os.path.join(path, os.path.join('tests', 'conf')) mock_config.return_value = [self._path] mock_parser.return_value = [] mock_log.return_value = None Logger._instance = mock_log Configuration(filename='config_sections.json') self._thread_manager = ThreadManager() def tearDown(self): if Configuration._instance is not None: Configuration._instance = None Configuration.NAMESPACE = 'pyccata.core' self._thread_manager.clear() self._thread_manager._instance = None del self._thread_manager @data( [ "sed 's/24/25/g'", { 'command':'sed', 'args':['s/24/25/g'] } ], [ "sed 's/24/25/g' &>/dev/null", { 'command':'sed', 'args':['s/24/25/g'], 'redirects': {'0': '/dev/null', '2':'/dev/null'} } ], [ "sed 's/24/25/g' 1>&2", { 'command':'sed', 'args':['s/24/25/g'], 'redirects': {'0':'1'} } ], [ "sed 's/24/25/g' 2>&1 1>/dev/null", { 'command':'sed', 'args':['s/24/25/g'], 'redirects': {'0': '/dev/null', '1':'0'} } ], [ "sed 's/24/25/g' &>/dev/null < infile.txt", { 'command':'sed', 'args':['s/24/25/g'], 'redirects': {'0': '/dev/null', '1':'/dev/null'} } ], [ "grep -rin --col 'i < 24\|b>19' > /dev/null", { 'command':'grep', 'args':['-rin', '--col', 'i < 24\|b>19'], 'redirects': {'0': '/dev/null'} } ], [ "grep -rin --col 'i < 24\|b>19' 3>/dev/null", { 'command':'grep', 'args':['-rin', '--col', 'i < 24\|b>19'], 'redirects': {'0': '0'} } ], [ "grep -rin --col 'i < 24\|b>19' 3>4", { 'command':'grep', 'args':['-rin', '--col', 'i < 24\|b>19'], 'redirects': {'0': '0'} } ] ) @unpack def test_build_command_with_simple_commands(self, command, expected_return): configuration = namedtuple('Config', 'name command input_directory output_directory wait_for') config = configuration( name='Test command', command=command, input_directory='/tmp', output_directory='/tmp', wait_for=None ) threadable = ThreadableCommand(self._thread_manager, config) commands = threadable._commands for command in commands: self.assertEquals(command.command, expected_return['command']) self.assertEquals(command.arguments, expected_return['args']) if not 'redirects' in expected_return.keys(): continue for key in expected_return['redirects'].keys(): for redirect in command.redirects: if str(redirect.redirect_input) == str(int(key)-1): out = redirect.redirect_output if isinstance(redirect.redirect_output, str) else str(redirect.redirect_output) self.assertEquals(out, expected_return['redirects'][key]) @data( "sed 's/24/25/g", "sed 's/24/ > /g' &>/dev/null" ) def test_build_command_raises_error_if_command_wont_parse(self, command): configuration = namedtuple('Config', 'name command input_directory output_directory wait_for') config = configuration( name='Test command', command=command, input_directory='/tmp', output_directory='/tmp', wait_for=None ) with self.assertRaises(ValueError): threadable = ThreadableCommand(self._thread_manager, config) """ def test_build_command_assigns_observer_to_threadable(self): configuration = namedtuple('Config', 'name command input_directory output_directory wait_for') config_observing = configuration( name='Observing', command="sed 's/24/25/g'", input_directory='/tmp', output_directory='/tmp', wait_for=None ) observing = ThreadableCommand(self._thread_manager, config_observing) config_observer = configuration( name='Observer', command="grep -rin --col 'bobjones'", input_directory='/tmp', output_directory='/tmp', wait_for=observing ) observer = ThreadableCommand(self._thread_manager, config_observer) self.assertTrue(observing.hasobservers) self.assertEquals(1, len(observing.observers)) """ def test_run_method_forms_a_pipe_and_reads_output(self): configuration = namedtuple('Config', 'name command input_directory output_directory wait_for') config = configuration( name='GrepForTestsAndReplaceWithBuild', command="grep -rin --col 'def test_*' tests | sed 's/test/build/g'", input_directory=os.getcwd(), output_directory='/tmp', wait_for=None ) thread = ThreadableCommand(self._thread_manager, config) self._thread_manager.append(thread) self._thread_manager.execute() self.assertGreater(len(thread.results), 0) def test_run_with_redirect(self): configuration = namedtuple('Config', 'name command input_directory output_directory wait_for') config = configuration( name='GrepForTestsAndReplaceWithBuild', command="grep 2>&1", input_directory=os.getcwd(), output_directory='/tmp', wait_for=None ) thread = ThreadableCommand(self._thread_manager, config) self._thread_manager.append(thread) self._thread_manager.execute() self.assertGreater(len(thread.results), 0) def test_run_raises_error_on_stderr(self): configuration = namedtuple('Config', 'name command input_directory output_directory wait_for') config = configuration( name='GrepForTestsAndReplaceWithBuild', command="grep", input_directory=os.getcwd(), output_directory='/tmp', wait_for=None ) thread = ThreadableCommand(self._thread_manager, config) self._thread_manager.append(thread) with self.assertRaises(ThreadFailedError): self._thread_manager.execute() @patch('builtins.open', create=True) @data( "grep -rin --col 'def test_*' tests | sed 's/test/build/g' 1>/tmp/test", "grep -rin --col 'def test_*' tests | sed 's/test/build/g' &>/tmp/test", "grep -rin --col 'def test_*' tests | sed 's/test/build/g' 2>/tmp/test", "grep -rin --col 'def test_*' tests | sed 's/test/build/g' 2>/tmp/test 1>&2" ) def test_run_with_redirect_to_file(self, command, mock_open): mock_open.return_value = None configuration = namedtuple('Config', 'name command input_directory output_directory wait_for') config = configuration( name='GrepForTestsAndReplaceWithBuild', command=command, input_directory=os.getcwd(), output_directory='/tmp', wait_for=None ) Configuration._instance = None thread = ThreadableCommand(self._thread_manager, config) self._thread_manager.append(thread) self._thread_manager.execute() if (len(thread._commands[1].redirects) == 2): self.assertEquals(thread._commands[1].stdout, thread._commands[1].stderr) self.assertGreater(mock_open.call_count, 0) mock_open.assert_called_with('/tmp/test', mode='a')
class TestSection(TestCase): _thread_manager = None @patch('argparse.ArgumentParser.parse_args') @patch('pyccata.core.log.Logger.log') @patch('pyccata.core.configuration.Configuration._get_locations') def setUp(self, mock_config, mock_log, mock_parser): path = os.path.dirname(os.path.realpath(__file__ + '../../../../')) self._path = os.path.join(path, os.path.join('tests', 'conf')) mock_config.return_value = [self._path] mock_log.return_value = None mock_parser.return_value = [] Logger._instance = mock_log Configuration('config_sections.json') self._thread_manager = ThreadManager() def tearDown(self): if Configuration._instance is not None: Configuration._instance = None Configuration.NAMESPACE = 'pyccata.core' if DocumentPartFactory._instance is not None: DocumentPartFactory._instance = None if ThreadManager._instance is not None: ThreadManager._instance = None def test_init_raises_argument_mismatch_error_if_keyword_args_differ(self): Config = namedtuple('Config', 'title, abstract config') config = Config(title='hello world', abstract='This is a test paragraph', config=['bob', 'marley', 'jimmy', 'hendrix']) with self.assertRaisesRegexp( ArgumentMismatchError, 'Invalid arguments provided to .*\. Got .* expected .*'): Section(self._thread_manager, config) @patch('pyccata.core.parts.section.Section._parse_structure') def test_threadable_init_calls_section_setup(self, mock_parse): mock_parse.return_value = [] Config = namedtuple('Config', 'title, abstract level structure') config = Config(title='hello world', abstract='This is a test paragraph', level=0, structure=None) section = Section(self._thread_manager, config) self.assertEquals('hello world', section._title) self.assertEquals('This is a test paragraph', section._abstract._content[0]) def test_parse_structure_returns_empty_list_if_structure_is_none(self): Config = namedtuple('Config', 'title, abstract level structure') config = Config(title='hello world', abstract='This is a test paragraph', level=0, structure=None) section = Section(self._thread_manager, config) self.assertIsInstance(section._structure, list) self.assertEquals(0, len(section._structure)) def test_threadable_document_init_resets_priority_if_greater_than_max( self): Paragraph = namedtuple('Paragraph', 'text') Config = namedtuple('Config', 'title, abstract level structure') config = Config(title='hello world', abstract='This is a test paragraph', level=0, structure=None) section = Section(self._thread_manager, config) self.assertIsInstance(section._structure, list) self.assertEquals(0, len(section._structure)) section._structure.append( InvalidPriority(self._thread_manager, Paragraph(text='hello world'))) self.assertEquals( ThreadableDocument.MAX_DOCUMENT_PRIORITY, section._structure[len(section._structure) - 1].PRIORITY) def test_parse_structure_returns_list_of_paragraphs(self): config = DataProviders.get_paragraph_config_for_section() section = Section(self._thread_manager, config) self.assertEquals(4, len(section._structure)) for item in section._structure: self.assertIsInstance(item, Paragraph) def test_section_abstract_reads_abstract_from_file(self): Configuration._instance = DataProviders._get_config_for_test() Config = namedtuple('Config', 'title, abstract level structure') config = Config(title='hello world', abstract='section_test_text', level=0, structure=None) section = Section(self._thread_manager, config) self.assertEquals('hello world', section._title) self.assertEquals(3, len(section._abstract._content)) @patch('pyccata.core.managers.report.ReportManager.add_paragraph') def test_section_render(self, mock_paragraph): Config = namedtuple('Config', 'title, abstract level structure') config = Config(title='hello world', abstract='section_test_text', level=0, structure=None) section = Section(self._thread_manager, config) section.render(ReportManager()) @patch('pyccata.core.managers.report.ReportManager.add_paragraph') def test_render_calls_report_manager_add_methods(self, mock_paragraph): Configuration.report_text = 'tests/pyccata.core/data' config = DataProviders.get_paragraph_config_for_section() section = Section(self._thread_manager, config) self.assertEquals(4, len(section._structure)) for item in section._structure: self.assertIsInstance(item, Paragraph) section.render(ReportManager()) calls = [ call('This is paragraph number 1'), call('This is paragraph number 3'), call('This is paragraph number 4'), call('This is paragraph number 5') ] mock_paragraph.assert_has_calls(calls) @patch('pyccata.core.managers.clients.jira.Jira._client') @patch('pyccata.core.configuration.Configuration._load') def test_render_returns_if_section_contains_empty_table( self, mock_load, mock_jira_client): Rows = namedtuple('Row', 'query fields') row_config = Rows(query="project=bob and issuetype=Bug", fields=["key", "description", "priority"]) #rows = Filter(row_config.query, fields=row_config.fields) #self._thread_manager.append(rows) columns = ['Name', 'Description'] TableConfig = namedtuple('TableConfig', 'rows columns style') table_config = TableConfig(rows=row_config, columns=columns, style='Light heading 1') StructureConfig = namedtuple('StructureConfig', 'type title content') structure_config = StructureConfig(type='table', title='Hello world', content=table_config) SectionConfig = namedtuple('SectionConfig', 'title abstract level structure') section_config = SectionConfig( title='Test', abstract='This is a test for empty tables', level=1, structure=[structure_config]) mock_jira_client.return_value = None with patch('pyccata.core.configuration.Configuration.manager', new_callable=PropertyMock) as mock_manager: with patch( 'pyccata.core.configuration.Configuration._configuration', new_callable=PropertyMock) as mock_config: mock_config.return_value = DataProviders._get_config_for_test() mock_manager.return_value = 'jira' section = Section(self._thread_manager, section_config) rows = section._structure[0].rows rows._thread_manager = self._thread_manager rows._project_manager = ProjectManager() rows.projectmanager._client._client = DataProviders._get_client_without_results( ) document = ReportManager() self._thread_manager.execute() section.render(document) self.assertEquals(0, rows.results.total)
class TestAttachments(TestCase): _report_manager = None _thread_manager = None @patch('pyccata.core.log.Logger.log') @patch('argparse.ArgumentParser.parse_args') @patch('pyccata.core.configuration.Configuration._get_locations') def setUp(self, mock_config, mock_parser, mock_log): self.tearDown() mock_log.return_value = None Logger._instance = mock_log path = os.path.dirname(os.path.realpath(__file__ + '../../../../')) self._path = os.path.join(path, os.path.join('tests', 'conf')) mock_config.return_value = [self._path] mock_parser.return_value = [] config = None with patch('argparse.ArgumentParser.add_argument'): config = Configuration(filename='valid_config.json') config.check = True self._report_manager = ReportManager() self._thread_manager = ThreadManager() def tearDown(self): if ThreadManager._instance is not None: ThreadManager._instance = None if Configuration._instance is not None: del Configuration._instance Configuration._instance = None Configuration.NAMESPACE = 'pyccata.core' if Replacements._instance is not None: del Replacements._instance Replacements._instance = None @data( ('zip', 1, '/tmp/28/Jul/2016/AnotherTestApplication.zip'), ('sql', 1, '/tmp/28/Jul/2016/TestApplication.sql'), ('zip,sql', 2, ['/tmp/28/Jul/2016/AnotherTestApplication.zip', '/tmp/28/Jul/2016/TestApplication.sql']) ) @patch('builtins.open', create=True) @patch('jira.client.JIRA.__init__') @patch('jira.client.JIRA.search_issues') @patch('pyccata.core.configuration.Configuration._get_locations') @unpack def test_setup_and_run( self, collation, result_count, result_filename, mock_config_list, mock_results, mock_jira_client, mock_open ): mock_jira_client.return_value = None mock_config_list.return_value = [self._path] Configuration.NAMESPACE = 'pyccata.core' report = ReportManager() mock_results.return_value = DataProviders._test_data_for_attachments() report.add_callback('attachments', getattr(DataProviders, 'test_callback')) self.assertIsInstance(Configuration().replacements, Replacements) Config = namedtuple('Config', 'query fields collate output_path') config = Config( query='project=test and attachments is not empty', fields=[ 'key', 'attachments' ], collate=collation, output_path='/tmp/{FIX_VERSION}' ) Replacements().find('FIX_VERSION').value = '28/Jul/2016' attachments = None with patch('os.makedirs') as mock_os: attachments = Attachments(self._thread_manager, config) mock_os.assert_called_with('/tmp/28/Jul/2016') self._thread_manager.append(attachments) with patch('pycurl.Curl') as mock_curl: with patch('pycurl.Curl.setopt') as mock_setopt: with patch('pycurl.Curl.perform') as mock_perform: with patch('pycurl.Curl.close') as mock_close: Curl = namedtuple('Curl', 'URL WRITEDATA setopt perform close getinfo') mock_curl.return_value = Curl( URL=None, WRITEDATA=None, setopt=mock_setopt, perform=mock_perform, close=mock_close, getinfo=lambda x: 200 ) self._thread_manager.execute() self.assertEquals(result_count, len(attachments._content)) self.assertEquals((3 * result_count), mock_setopt.call_count) self.assertEquals((1 * result_count), mock_perform.call_count) self.assertEquals((1 * result_count), mock_close.call_count) self.assertEquals((1 * result_count), mock_open.call_count) calls = [] if isinstance(result_filename, list): for filename in result_filename: calls.append(call(filename, 'wb')) else: calls.append(call(result_filename, 'wb')) mock_open.assert_has_calls(calls, any_order=True) with patch('pyccata.core.managers.report.ReportManager.add_paragraph') as mock_paragraph: with patch('pyccata.core.managers.report.ReportManager.add_list') as mock_list: attachments.render(report) mock_paragraph.assert_called_with('The following file(s) have been attached to this document:') mock_list.assert_called_with('TestFile.zip') @data( ('zip', 1, '/tmp/28/Jul/2016/AnotherTestApplication.zip'), ('sql', 1, '/tmp/28/Jul/2016/TestApplication.sql'), ('zip,sql', 2, ['/tmp/28/Jul/2016/AnotherTestApplication.zip', '/tmp/28/Jul/2016/TestApplication.sql']) ) @patch('builtins.open', create=True) @patch('jira.client.JIRA.__init__') @patch('jira.client.JIRA.search_issues') @patch('pyccata.core.configuration.Configuration._get_locations') @unpack def test_setup_and_run_without_callback( self, collation, result_count, result_filename, mock_config_list, mock_results, mock_jira_client, mock_open ): mock_jira_client.return_value = None mock_config_list.return_value = [self._path] Configuration.NAMESPACE = 'pyccata.core' report = ReportManager() report.add_callback('attachments', None) mock_results.return_value = DataProviders._test_data_for_attachments() self.assertIsInstance(Configuration().replacements, Replacements) Config = namedtuple('Config', 'query fields collate output_path') config = Config( query='project=test and attachments is not empty', fields=[ 'key', 'attachments' ], collate=collation, output_path='/tmp/{FIX_VERSION}' ) Replacements().find('FIX_VERSION').value = '28/Jul/2016' attachments = None with patch('os.makedirs') as mock_os: attachments = Attachments(self._thread_manager, config) mock_os.assert_called_with('/tmp/28/Jul/2016') self._thread_manager.append(attachments) with patch('pycurl.Curl') as mock_curl: with patch('pycurl.Curl.setopt') as mock_setopt: with patch('pycurl.Curl.perform') as mock_perform: with patch('pycurl.Curl.close') as mock_close: Curl = namedtuple('Curl', 'URL WRITEDATA setopt perform close getinfo') mock_curl.return_value = Curl( URL=None, WRITEDATA=None, setopt=mock_setopt, perform=mock_perform, close=mock_close, getinfo=lambda x: 200 ) self._thread_manager.execute() self.assertEquals(result_count, len(attachments._content)) self.assertEquals((3 * result_count), mock_setopt.call_count) self.assertEquals((1 * result_count), mock_perform.call_count) self.assertEquals((1 * result_count), mock_close.call_count) self.assertEquals((1 * result_count), mock_open.call_count) calls = [] if isinstance(result_filename, list): for filename in result_filename: calls.append(call(filename, 'wb')) else: calls.append(call(result_filename, 'wb')) mock_open.assert_has_calls(calls, any_order=True) with patch('pyccata.core.managers.report.ReportManager.add_paragraph') as mock_paragraph: with patch('pyccata.core.managers.report.ReportManager.add_list') as mock_list: attachments.render(report) mock_paragraph.assert_not_called() mock_list.assert_not_called() @data( ('zip', 1, '/tmp/28/Jul/2016/AnotherTestApplication.zip'), ('sql', 1, '/tmp/28/Jul/2016/TestApplication.sql'), ('zip,sql', 2, ['/tmp/28/Jul/2016/AnotherTestApplication.zip', '/tmp/28/Jul/2016/TestApplication.sql']) ) @patch('builtins.open', create=True) @patch('jira.client.JIRA.__init__') @patch('jira.client.JIRA.search_issues') @patch('pyccata.core.configuration.Configuration._get_locations') @unpack def test_setup_and_run_where_callback_returns_string( self, collation, result_count, result_filename, mock_config_list, mock_results, mock_jira_client, mock_open ): mock_jira_client.return_value = None mock_config_list.return_value = [self._path] Configuration.NAMESPACE = 'pyccata.core' report = ReportManager() mock_results.return_value = DataProviders._test_data_for_attachments() report.add_callback('attachments', lambda x,y: 'TestFile.zip') self.assertIsInstance(Configuration().replacements, Replacements) Config = namedtuple('Config', 'query fields collate output_path') config = Config( query='project=test and attachments is not empty', fields=[ 'key', 'attachments' ], collate=collation, output_path='/tmp/{FIX_VERSION}' ) Replacements().find('FIX_VERSION').value = '28/Jul/2016' attachments = None with patch('os.makedirs') as mock_os: attachments = Attachments(self._thread_manager, config) mock_os.assert_called_with('/tmp/28/Jul/2016') self._thread_manager.append(attachments) with patch('pycurl.Curl') as mock_curl: with patch('pycurl.Curl.setopt') as mock_setopt: with patch('pycurl.Curl.perform') as mock_perform: with patch('pycurl.Curl.close') as mock_close: Curl = namedtuple('Curl', 'URL WRITEDATA setopt perform close getinfo') mock_curl.return_value = Curl( URL=None, WRITEDATA=None, setopt=mock_setopt, perform=mock_perform, close=mock_close, getinfo=lambda x: 200 ) self._thread_manager.execute() self.assertEquals(result_count, len(attachments._content)) self.assertEquals((3 * result_count), mock_setopt.call_count) self.assertEquals((1 * result_count), mock_perform.call_count) self.assertEquals((1 * result_count), mock_close.call_count) self.assertEquals((1 * result_count), mock_open.call_count) calls = [] if isinstance(result_filename, list): for filename in result_filename: calls.append(call(filename, 'wb')) else: calls.append(call(result_filename, 'wb')) mock_open.assert_has_calls(calls, any_order=True) with patch('pyccata.core.managers.report.ReportManager.add_paragraph') as mock_paragraph: with patch('pyccata.core.managers.report.ReportManager.add_list') as mock_list: attachments.render(report) mock_paragraph.assert_called_with('The following file(s) have been attached to this document:') mock_list.assert_called_with('TestFile.zip') @data( ('zip,sql', 2, []) ) @patch('builtins.open', create=True) @patch('jira.client.JIRA.__init__') @patch('jira.client.JIRA.search_issues') @patch('pyccata.core.configuration.Configuration._get_locations') @unpack def test_setup_and_run_doesnt_download_if_attachments_is_empty( self, collation, result_count, result_filename, mock_config_list, mock_results, mock_jira_client, mock_open ): mock_jira_client.return_value = None mock_config_list.return_value = [self._path] Configuration.NAMESPACE = 'pyccata.core' report = ReportManager() mock_results.return_value = [] report.add_callback('attachments', lambda x,y: '') self.assertIsInstance(Configuration().replacements, Replacements) Config = namedtuple('Config', 'query fields collate output_path') config = Config( query='project=test and attachments is not empty', fields=[ 'key', 'attachments' ], collate=collation, output_path='/tmp/{FIX_VERSION}' ) Replacements().find('FIX_VERSION').value = '28/Jul/2016' attachments = None with patch('os.makedirs') as mock_os: attachments = Attachments(self._thread_manager, config) mock_os.assert_called_with('/tmp/28/Jul/2016') with patch('pyccata.core.parts.attachments.Attachments._download_attachments') as mock_download: self._thread_manager.execute() mock_download.assert_not_called() @patch('pyccata.core.filter.Filter.failure', new_callable=PropertyMock) @patch('argparse.ArgumentParser.parse_args') @patch('pyccata.core.configuration.Configuration._get_locations') def test_setup_and_run_handles_exception(self, mock_config_list, mock_parser, mock_failure): mock_parser.return_value = [] mock_config_list.return_value = [self._path] Configuration.NAMESPACE = 'pyccata.core' report = ReportManager() # never actually thrown from the filter but useful for testing and coverage ;-) mock_failure.return_value = InvalidFilenameError('The specified file does not exist') report.add_callback('test', 'test_callback') self.assertEquals('test_callback', report.get_callback('test')) self.assertIsInstance(Configuration().replacements, Replacements) Config = namedtuple('Config', 'query fields collate output_path') config = Config( query='project=test and attachments is not empty', fields=[ 'key', 'attachments' ], collate='zip', output_path='/tmp/{FIX_VERSION}' ) Replacements().find('FIX_VERSION').value = '28/Jul/2016' attachments = None with patch('os.makedirs') as mock_os: attachments = Attachments(self._thread_manager, config) mock_os.assert_called_with('/tmp/28/Jul/2016') with patch('pyccata.core.filter.Filter.failed', return_value=True): attachments.run() self.assertEquals(str(attachments._content.failure), 'The specified file does not exist') @patch('builtins.open', create=True) @patch('jira.client.JIRA.__init__') @patch('jira.client.JIRA.search_issues') @patch('pyccata.core.managers.clients.jira.Jira.server', new_callable=PropertyMock) @patch('pyccata.core.configuration.Configuration._get_locations') @unpack def test_run_raises_type_error_if_attachments_callback_function_is_not_set( self, mock_config_list, mock_results, mock_jira_results, mock_jira_client, mock_open ): mock_jira_client.return_value = None mock_config_list.return_value = [self._path] Configuration.NAMESPACE = 'pyccata.core' report = ReportManager() report.add_callback('attachments', None) mock_jira_results.return_value = DataProviders._test_data_for_attachments() server = namedtuple('Server', 'server_address attachments') mock_results.return_value = server(server_address=None, attachments=None) self.assertIsInstance(Configuration().replacements, Replacements) Config = namedtuple('Config', 'query fields collate output_path') config = Config( query='project=test and attachments is not empty', fields=[ 'key', 'attachments' ], collate='zip', output_path='/tmp/{FIX_VERSION}' ) attachments = None with patch('os.path.exists') as mock_exists: mock_exists.return_value = False with patch('os.makedirs') as mock_os: attachments = Attachments(self._thread_manager, config) mock_os.assert_called_with('/tmp/' + Configuration().replacements.replace('{FIX_VERSION}')) self._thread_manager.append(attachments) with patch('pycurl.Curl') as mock_curl: with patch('pycurl.Curl.setopt') as mock_setopt: with patch('pycurl.Curl.perform') as mock_perform: with patch('pycurl.Curl.close') as mock_close: Curl = namedtuple('Curl', 'URL WRITEDATA setopt perform close getinfo') mock_curl.return_value = Curl( URL=None, WRITEDATA=None, setopt=mock_setopt, perform=mock_perform, close=mock_close, getinfo=lambda x: 200 ) with self.assertRaises(InvalidCallbackError): self._thread_manager.execute() self.assertIsInstance(attachments.failure, InvalidCallbackError) mock_setopt.assert_not_called() mock_perform.assert_not_called() mock_close.assert_not_called() mock_open.assert_not_called()