|
@@ -806,8 +806,12 @@ class ReplicatorTestCase(test_base.CoriolisBaseTestCase):
|
|
|
@mock.patch.object(replicator_module.Replicator, '_copy_file')
|
|
@mock.patch.object(replicator_module.Replicator, '_copy_file')
|
|
|
@mock.patch.object(replicator_module.Replicator, 'restart')
|
|
@mock.patch.object(replicator_module.Replicator, 'restart')
|
|
|
@mock.patch.object(replicator_module.Client, '_test_connection')
|
|
@mock.patch.object(replicator_module.Client, '_test_connection')
|
|
|
|
|
+ @mock.patch.object(replicator_module.os, 'close')
|
|
|
|
|
+ @mock.patch.object(replicator_module.os, 'remove')
|
|
|
def test_update_state(
|
|
def test_update_state(
|
|
|
self,
|
|
self,
|
|
|
|
|
+ mock_remove,
|
|
|
|
|
+ mock_close,
|
|
|
mock_test_connection,
|
|
mock_test_connection,
|
|
|
mock_restart,
|
|
mock_restart,
|
|
|
mock_copy_file,
|
|
mock_copy_file,
|
|
@@ -815,18 +819,20 @@ class ReplicatorTestCase(test_base.CoriolisBaseTestCase):
|
|
|
mock_dump,
|
|
mock_dump,
|
|
|
mock_open,
|
|
mock_open,
|
|
|
):
|
|
):
|
|
|
- mock_mkstemp.return_value = (None, mock.sentinel.state)
|
|
|
|
|
|
|
+ mock_mkstemp.return_value = (mock.sentinel.fd, mock.sentinel.state)
|
|
|
mock_dump.return_value = None
|
|
mock_dump.return_value = None
|
|
|
|
|
|
|
|
self.replicator.update_state(mock.sentinel.state, restart=False)
|
|
self.replicator.update_state(mock.sentinel.state, restart=False)
|
|
|
|
|
|
|
|
mock_mkstemp.assert_called_once()
|
|
mock_mkstemp.assert_called_once()
|
|
|
|
|
+ mock_close.assert_called_once_with(mock.sentinel.fd)
|
|
|
mock_open.assert_called_once_with(mock.sentinel.state, 'w')
|
|
mock_open.assert_called_once_with(mock.sentinel.state, 'w')
|
|
|
mock_copy_file.assert_called_once_with(
|
|
mock_copy_file.assert_called_once_with(
|
|
|
self.replicator._ssh,
|
|
self.replicator._ssh,
|
|
|
mock_mkstemp.return_value[1],
|
|
mock_mkstemp.return_value[1],
|
|
|
replicator_module.REPLICATOR_STATE,
|
|
replicator_module.REPLICATOR_STATE,
|
|
|
)
|
|
)
|
|
|
|
|
+ mock_remove.assert_called_once_with(mock.sentinel.state)
|
|
|
mock_restart.assert_not_called()
|
|
mock_restart.assert_not_called()
|
|
|
mock_test_connection.assert_not_called()
|
|
mock_test_connection.assert_not_called()
|
|
|
|
|
|
|
@@ -836,8 +842,12 @@ class ReplicatorTestCase(test_base.CoriolisBaseTestCase):
|
|
|
@mock.patch.object(replicator_module.Replicator, '_copy_file')
|
|
@mock.patch.object(replicator_module.Replicator, '_copy_file')
|
|
|
@mock.patch.object(replicator_module.Replicator, 'restart')
|
|
@mock.patch.object(replicator_module.Replicator, 'restart')
|
|
|
@mock.patch.object(replicator_module.Client, '_test_connection')
|
|
@mock.patch.object(replicator_module.Client, '_test_connection')
|
|
|
|
|
+ @mock.patch.object(replicator_module.os, 'close')
|
|
|
|
|
+ @mock.patch.object(replicator_module.os, 'remove')
|
|
|
def test_update_state_with_restart(
|
|
def test_update_state_with_restart(
|
|
|
self,
|
|
self,
|
|
|
|
|
+ mock_remove,
|
|
|
|
|
+ mock_close,
|
|
|
mock_test_connection,
|
|
mock_test_connection,
|
|
|
mock_restart,
|
|
mock_restart,
|
|
|
mock_copy_file,
|
|
mock_copy_file,
|
|
@@ -845,7 +855,7 @@ class ReplicatorTestCase(test_base.CoriolisBaseTestCase):
|
|
|
mock_dump,
|
|
mock_dump,
|
|
|
mock_open,
|
|
mock_open,
|
|
|
):
|
|
):
|
|
|
- mock_mkstemp.return_value = (None, mock.sentinel.state)
|
|
|
|
|
|
|
+ mock_mkstemp.return_value = (mock.sentinel.fd, mock.sentinel.state)
|
|
|
mock_dump.return_value = None
|
|
mock_dump.return_value = None
|
|
|
|
|
|
|
|
self.replicator._cli._test_connection = mock_test_connection
|
|
self.replicator._cli._test_connection = mock_test_connection
|
|
@@ -853,15 +863,40 @@ class ReplicatorTestCase(test_base.CoriolisBaseTestCase):
|
|
|
self.replicator.update_state(mock.sentinel.state, restart=True)
|
|
self.replicator.update_state(mock.sentinel.state, restart=True)
|
|
|
|
|
|
|
|
mock_mkstemp.assert_called_once()
|
|
mock_mkstemp.assert_called_once()
|
|
|
|
|
+ mock_close.assert_called_once_with(mock.sentinel.fd)
|
|
|
mock_open.assert_called_once_with(mock.sentinel.state, 'w')
|
|
mock_open.assert_called_once_with(mock.sentinel.state, 'w')
|
|
|
mock_copy_file.assert_called_once_with(
|
|
mock_copy_file.assert_called_once_with(
|
|
|
self.replicator._ssh,
|
|
self.replicator._ssh,
|
|
|
mock_mkstemp.return_value[1],
|
|
mock_mkstemp.return_value[1],
|
|
|
replicator_module.REPLICATOR_STATE,
|
|
replicator_module.REPLICATOR_STATE,
|
|
|
)
|
|
)
|
|
|
|
|
+ mock_remove.assert_called_once_with(mock.sentinel.state)
|
|
|
mock_restart.assert_called_once()
|
|
mock_restart.assert_called_once()
|
|
|
mock_test_connection.assert_called_once()
|
|
mock_test_connection.assert_called_once()
|
|
|
|
|
|
|
|
|
|
+ @mock.patch('builtins.open')
|
|
|
|
|
+ @mock.patch.object(replicator_module.json, 'dump')
|
|
|
|
|
+ @mock.patch.object(replicator_module.tempfile, 'mkstemp')
|
|
|
|
|
+ @mock.patch.object(replicator_module.Replicator, '_copy_file')
|
|
|
|
|
+ @mock.patch.object(replicator_module.os, 'close')
|
|
|
|
|
+ @mock.patch.object(replicator_module.os, 'remove')
|
|
|
|
|
+ def test_update_state_removes_temp_file_on_copy_error(
|
|
|
|
|
+ self,
|
|
|
|
|
+ mock_remove,
|
|
|
|
|
+ mock_close,
|
|
|
|
|
+ mock_copy_file,
|
|
|
|
|
+ mock_mkstemp,
|
|
|
|
|
+ mock_dump,
|
|
|
|
|
+ mock_open,
|
|
|
|
|
+ ):
|
|
|
|
|
+ mock_mkstemp.return_value = (mock.sentinel.fd, mock.sentinel.state)
|
|
|
|
|
+ mock_copy_file.side_effect = Exception('copy failed')
|
|
|
|
|
+
|
|
|
|
|
+ self.assertRaises(Exception, self.replicator.update_state, mock.sentinel.state)
|
|
|
|
|
+
|
|
|
|
|
+ mock_close.assert_called_once_with(mock.sentinel.fd)
|
|
|
|
|
+ mock_remove.assert_called_once_with(mock.sentinel.state)
|
|
|
|
|
+
|
|
|
@mock.patch.object(replicator_module.paramiko, 'SSHClient')
|
|
@mock.patch.object(replicator_module.paramiko, 'SSHClient')
|
|
|
def test__get_ssh_client(self, mock_ssh_client):
|
|
def test__get_ssh_client(self, mock_ssh_client):
|
|
|
self._ssh = mock_ssh_client.return_value
|
|
self._ssh = mock_ssh_client.return_value
|