def test_commit(mock_write_batches, mock_get_message, fake_publish, db): # Construct task that would be generated by caller. task = _task(fake_publish.id) # Construct dramatiq message that would be generated by caller. mock_get_message.return_value = mock.MagicMock( message_id=task.id, kwargs={"publish_id": fake_publish.id} ) # Simulate successful write of items by write_batches. mock_write_batches.return_value = True db.add(fake_publish) db.add(task) # Caller would've set publish state to COMMITTING. fake_publish.state = "COMMITTING" db.commit() worker.commit(str(fake_publish.id), fake_publish.env, NOW_UTC) # It should've set task state to COMPLETE. db.refresh(task) assert task.state == "COMPLETE" # It should've set publish state to COMMITTED. db.refresh(fake_publish) assert fake_publish.state == "COMMITTED" # It should've called write_batches for items and entry point items. mock_write_batches.assert_has_calls( calls=[ mock.call("test", mock.ANY, NOW_UTC), mock.call("test", mock.ANY, NOW_UTC), ] )
def test_commit_empty_publish( mock_write_batches, mock_get_message, fake_publish, db, caplog ): caplog.set_level(logging.DEBUG, "exodus-gw") # Construct task that would be generated by caller. task = _task(fake_publish.id) # Construct dramatiq message that would be generated by caller. mock_get_message.return_value = mock.MagicMock( message_id=task.id, kwargs={"publish_id": fake_publish.id} ) # Empty the publish. fake_publish.items = [] db.add(fake_publish) db.add(task) # Caller would've set publish state to COMMITTING. fake_publish.state = "COMMITTING" db.commit() worker.commit(str(fake_publish.id), fake_publish.env, NOW_UTC) # It should've logged a message. assert "No items to write for publish %s" % fake_publish.id in caplog.text # It should've set task state to COMPLETE. db.refresh(task) assert task.state == "COMPLETE" # It should've set publish state to COMMITTED. db.refresh(fake_publish) assert fake_publish.state == "COMMITTED" # It should not have called write_batches. mock_write_batches.assert_not_called()
def test_commit_completed_publish( mock_write_batches, mock_get_message, fake_publish, db, caplog ): # Construct task that would be generated by caller. task = _task(fake_publish.id) # Construct dramatiq message that would be generated by caller. mock_get_message.return_value = mock.MagicMock( message_id=task.id, kwargs={"publish_id": fake_publish.id} ) db.add(task) db.add(fake_publish) # Simulate prior completion of publish. fake_publish.state = "COMPLETE" db.commit() worker.commit(str(fake_publish.id), fake_publish.env, NOW_UTC) # It should've logged a warning message. assert ( "Publish %s in unexpected state, 'COMPLETE'" % fake_publish.id in caplog.text ) # It should not have called write_batches. mock_write_batches.assert_not_called()
def test_commit_completed_task( mock_write_batches, mock_get_message, db, caplog ): # Construct task that would be generated by caller. task = _task(publish_id=uuid.UUID("123e4567-e89b-12d3-a456-426614174000")) # Construct dramatiq message that would be generated by caller. mock_get_message.return_value = mock.MagicMock( message_id=task.id, kwargs={"publish_id": task.publish_id} ) db.add(task) # Simulate prior completion of task. task.state = "COMPLETE" db.commit() worker.commit(str(task.publish_id), "test", NOW_UTC) # It should've logged a warning message. assert "Task %s in unexpected state, 'COMPLETE'" % task.id in caplog.text # It should not have called write_batches. mock_write_batches.assert_not_called()
def test_commit_write_items_fail( mock_write_batches, mock_get_message, fake_publish, db, caplog ): # Construct task that would be generated by caller. task = _task(fake_publish.id) # Construct dramatiq message that would be generated by caller. mock_get_message.return_value = mock.MagicMock( message_id=task.id, kwargs={"publish_id": fake_publish.id} ) # Simulate failed write of items. mock_write_batches.side_effect = [RuntimeError(), None] db.add(fake_publish) db.add(task) # Caller would've set publish state to COMMITTING. fake_publish.state = "COMMITTING" db.commit() worker.commit(str(fake_publish.id), fake_publish.env, NOW_UTC) # It should've failed write_batches and recalled to roll back. mock_write_batches.assert_has_calls( calls=[ mock.call("test", mock.ANY, NOW_UTC), mock.call("test", mock.ANY, NOW_UTC, delete=True), ], any_order=False, ) # It should've logged messages. assert ( "Task 8d8a4692-c89b-4b57-840f-b3f0166148d2 encountered an error" in caplog.text ) assert "Rolling back 2 item(s) due to error" in caplog.text # It should've set task state to FAILED. db.refresh(task) assert task.state == "FAILED" # It should've set publish state to FAILED. db.refresh(fake_publish) assert fake_publish.state == "FAILED"
def test_commit_write_entry_point_items_fail( mock_write_batches, mock_get_message, fake_publish, db, caplog ): # Construct task that would be generated by caller. task = _task(fake_publish.id) # Construct dramatiq message that would be generated by caller. mock_get_message.return_value = mock.MagicMock( message_id=task.id, kwargs={"publish_id": fake_publish.id} ) # Simulate successful write of items, failed write of entry point items # and then successful deletion of items. mock_write_batches.side_effect = [None, RuntimeError(), None] db.add(fake_publish) db.add(task) # Caller would've set publish state to COMMITTING. fake_publish.state = "COMMITTING" db.commit() worker.commit(str(fake_publish.id), fake_publish.env, NOW_UTC) # It should've called write_batches for items, entry point items # and then deletion of written items. mock_write_batches.assert_has_calls( calls=[ mock.call("test", mock.ANY, NOW_UTC), mock.call("test", mock.ANY, NOW_UTC), mock.call("test", mock.ANY, NOW_UTC, delete=True), ], any_order=False, ) # It should've logged a message. assert "Rolling back 3 item(s) due to error" in caplog.text # It should've set task state to FAILED. db.refresh(task) assert task.state == "FAILED" # It should've set publish state to FAILED. db.refresh(fake_publish) assert fake_publish.state == "FAILED"