def test_make_local_config(self): """ Test that making the local config looks like it is expected to """ input_dictionary = OrderedDict([ ('first_value', 1), ('first_word', 'word one'), ('second_value', 2.0), ('second_word', 'word two') ]) expected_text = 'first_value = 1\nfirst_word = \'word one\'\n' \ 'second_value = 2.0\nsecond_word = \'word two\'' actual_text = IntegrationTestWorker.make_local_config(input_dictionary) self.assertEqual(expected_text, actual_text)
def test_workflow_of_integration_worker(self, mock_run_test): """ General work flow of the integration worker from receiving a packet, to finishing with a packet. """ # Worker receives a packet, most likely from the deploy worker # Example packet: # # { # 'application': 'staging', # 'service': 'adsws', # 'release': '', # 'config': {}, # } # # example_packet = { 'application': 'staging', 'service': 'adsws', 'tag': 'v1.0.0', 'commit': 'gf9gd8f', 'config': {}, 'action': 'test' } expected_packet = example_packet.copy() expected_packet['tested'] = True # Override the run test returned value. This means the logic of the test # does not have to be mocked mock_run_test.return_value = expected_packet with MiniRabbit(RABBITMQ_URL) as w: w.publish(route='in', exchange='test', payload=json.dumps(example_packet)) # Worker runs the tests params = { 'RABBITMQ_URL': RABBITMQ_URL, 'exchange': 'test', 'subscribe': 'in', 'publish': 'out', 'status': 'database', 'TEST_RUN': True } test_worker = IntegrationTestWorker(params=params) test_worker.run() test_worker.connection.close() # Worker sends a packet to the next worker with MiniRabbit(RABBITMQ_URL) as w: m_in = w.message_count(queue='in') m_out = w.message_count(queue='out') p = w.get_packet(queue='out') self.assertEqual(m_in, 0) self.assertEqual(m_out, 1) # Remove values that are not in the starting packet self.assertTrue(p.pop('tested')) self.assertEqual( p, example_packet )
def test_db_writes_on_test_pass(self, mocked_run_test): """ Check that the database is being written to when a test passes """ # Stub data packet = { 'application': 'adsws', 'environment': 'staging', 'tag': 'v1.0.0', 'commit': 'gf9gd8f', } expected_packet = packet.copy() expected_packet['tested'] = True mocked_run_test.return_value = expected_packet # Start the IntegrationTester worker params = { 'RABBITMQ_URL': RABBITMQ_URL, 'exchange': 'test', 'subscribe': 'in', 'publish': 'out', 'status': 'database', 'TEST_RUN': True } # Push to rabbitmq with MiniRabbit(RABBITMQ_URL) as w: w.publish(route='in', exchange='test', payload=json.dumps(packet)) test_worker = IntegrationTestWorker(params=params) test_worker.run() test_worker.connection.close() # Assert there is a packet on the publish queue with MiniRabbit(RABBITMQ_URL) as w: self.assertEqual(w.message_count('out'), 1) self.assertEqual(w.message_count('database'), 1) # Start the DB Writer worker params = { 'RABBITMQ_URL': RABBITMQ_URL, 'exchange': 'test', 'subscribe': 'database', 'TEST_RUN': True } db_worker = DatabaseWriterWorker(params=params) db_worker.app = self.app db_worker.run() db_worker.connection.close() with self.app.session_scope() as session: all_deployments = session.query(Deployment).all() self.assertEqual( len(all_deployments), 1, msg='More (or less) than 1 deployment entry: {}' .format(all_deployments) ) deployment = all_deployments[0] for key in packet: self.assertEqual( packet[key], getattr(deployment, key) ) self.assertEqual(deployment.tested, True)
def test_worker_running_test(self, mocked_publish, mocked_clone, mocked_subprocess, mocked_rmtree, mocked_cd, mocked_isdir, mocked_open): """ Test that the integration worker follows the expected workflow: """ # Mock responses # 1. File object file_instance = mocked_open.return_value file_instance.__enter__.return_value = file_instance file_instance.__exit__.return_value = None # 2. Change Directory instance_cd = mocked_cd.return_value instance_cd.__enter__.return_value = instance_cd instance_cd.__exit__.return_value = None # 3. Subprocess process = mock.Mock() process.communicate.return_value = '10 passed', '' mocked_subprocess.Popen.return_value = process # 4. Others mocked_isdir.return_value = True mocked_publish.return_value = None mocked_clone.return_value = None example_payload = { 'application': 'staging', 'service': 'adsws', 'release': 'v1.0.0', 'config': {}, 'action': 'test' } worker = IntegrationTestWorker() result = worker.run_test(example_payload) # The worker downloads the repository that contains the integration # tests mocked_clone.assert_has_calls( [mock.call('https://github.com/adsabs/adsrex.git', '/tmp/adsrex', branch='develop')] ) # Test that the local config gets produced mocked_open.assert_has_calls( [mock.call('/tmp/adsrex/v1/local_config.py', 'w')] ) # The worker changes into the directory and runs the tests using # a bash script mocked_subprocess.Popen.assert_has_calls( [mock.call(['py.test'], stdin=mocked_subprocess.PIPE, stdout=mocked_subprocess.PIPE)] ) # The test repository should also no longer exist mocked_rmtree.assert_has_calls( [mock.call('/tmp/adsrex')] ) # The test passes and it forwards a packet on to the relevant worker, # with the updated keyword for test pass example_payload['tested'] = True self.assertEqual( example_payload, result )
def test_git_raises_error(self, mocked_publish, mocked_clone, mocked_subprocess, mocked_rmtree, mocked_cd, mocked_isdir, mocked_open): """ Test that nothing breaks if git pull fails """ # Mock responses # 1. File object file_instance = mocked_open.return_value file_instance.__enter__.return_value = file_instance file_instance.__exit__.return_value = None # 2. Change Directory instance_cd = mocked_cd.return_value instance_cd.__enter__.return_value = instance_cd instance_cd.__exit__.return_value = None # 3. Subprocess process = mock.Mock() process.communicate.return_value = '10 passed', '' mocked_subprocess.Popen.return_value = process # 4. Others mocked_isdir.return_value = True mocked_publish.return_value = None mocked_clone.side_effect = ValueError('ValueError') example_payload = { 'application': 'staging', 'service': 'adsws', 'release': 'v1.0.0', 'config': {}, 'action': 'test' } worker = IntegrationTestWorker() result = worker.run_test(example_payload.copy()) # The worker downloads the repository that contains the integration # tests mocked_clone.assert_has_calls( [mock.call('https://github.com/adsabs/adsrex.git', '/tmp/adsrex', branch='develop')] ) # Test that the local config does not get produced self.assertFalse(mocked_open.called) # Subprocess should not be called self.assertFalse(mocked_subprocess.called) # Regardless, rmtree should still be called to cleanup any folders mocked_rmtree.assert_has_calls( [mock.call('/tmp/adsrex')] ) # The test passes and it forwards a packet on to the relevant worker, # with the updated keyword for test pass example_payload['tested'] = False self.assertEqual( example_payload, result )