@ -15,16 +15,21 @@
import signal
import mock
from oslo_config import cfg
from oslo_config import fixture as oslo_fixture
import octavia . api . drivers . driver_agent . driver_listener
from octavia . cmd import driver_agent
from octavia . tests . unit import base
CONF = cfg . CONF
class TestDriverAgentCMD ( base . TestCase ) :
def setUp ( self ) :
super ( TestDriverAgentCMD , self ) . setUp ( )
self . CONF = self . useFixture ( oslo_fixture . Config ( cfg . CONF ) )
@mock.patch ( ' os.kill ' )
@mock.patch ( ' octavia.cmd.driver_agent.CONF ' )
@ -34,24 +39,118 @@ class TestDriverAgentCMD(base.TestCase):
os_calls = [ mock . call ( 1 , signal . SIGHUP ) , mock . call ( 2 , signal . SIGHUP ) ]
mock_os_kill . assert_has_calls ( os_calls , any_order = True )
def test_check_if_provider_agent_enabled ( self ) :
mock_extension = mock . MagicMock ( )
self . CONF . config ( group = " driver_agent " ,
enabled_provider_agents = [
' spiffy_agent ' , ' super_agent ' ] )
mock_extension . name = ' super_agent '
self . assertTrue (
driver_agent . _check_if_provider_agent_enabled ( mock_extension ) )
mock_extension . name = ' bogus_agent '
self . assertFalse (
driver_agent . _check_if_provider_agent_enabled ( mock_extension ) )
@mock.patch ( ' setproctitle.setproctitle ' )
@mock.patch ( ' signal.signal ' )
def test_process_wrapper ( self , mock_signal , mock_setproctitle ) :
mock_exit_event = mock . MagicMock ( )
mock_function = mock . MagicMock ( )
mock_function . side_effect = [
mock . DEFAULT , Exception ( ' boom ' ) , mock . DEFAULT , Exception ( ' boom ' ) ,
mock . DEFAULT ]
mock_exit_event . is_set . side_effect = [ False , False , True ,
False , False , True ]
signal_calls = [ mock . call ( signal . SIGINT , signal . SIG_IGN ) ,
mock . call ( signal . SIGHUP , driver_agent . _mutate_config ) ]
# With agent_name
driver_agent . _process_wrapper (
mock_exit_event , ' test_proc_name ' , mock_function ,
agent_name = ' test_agent_name ' )
mock_signal . assert_has_calls ( signal_calls )
mock_setproctitle . assert_called_once_with (
' octavia-driver-agent - test_proc_name -- test_agent_name ' )
mock_function . assert_called_once_with ( mock_exit_event )
# With agent_name - With function exception
mock_signal . reset_mock ( )
mock_setproctitle . reset_mock ( )
mock_function . reset_mock ( )
driver_agent . _process_wrapper (
mock_exit_event , ' test_proc_name ' , mock_function ,
agent_name = ' test_agent_name ' )
mock_signal . assert_has_calls ( signal_calls )
mock_setproctitle . assert_called_once_with (
' octavia-driver-agent - test_proc_name -- test_agent_name ' )
mock_function . assert_called_once_with ( mock_exit_event )
# Without agent_name
mock_signal . reset_mock ( )
mock_setproctitle . reset_mock ( )
mock_function . reset_mock ( )
driver_agent . _process_wrapper (
mock_exit_event , ' test_proc_name ' , mock_function )
mock_signal . assert_has_calls ( signal_calls )
mock_setproctitle . assert_called_once_with (
' octavia-driver-agent - test_proc_name ' )
mock_function . assert_called_once_with ( mock_exit_event )
# Without agent_name - With function exception
mock_signal . reset_mock ( )
mock_setproctitle . reset_mock ( )
mock_function . reset_mock ( )
driver_agent . _process_wrapper (
mock_exit_event , ' test_proc_name ' , mock_function )
mock_signal . assert_has_calls ( signal_calls )
mock_setproctitle . assert_called_once_with (
' octavia-driver-agent - test_proc_name ' )
mock_function . assert_called_once_with ( mock_exit_event )
@mock.patch ( ' octavia.cmd.driver_agent.multiprocessing ' )
@mock.patch ( ' stevedore.enabled.EnabledExtensionManager ' )
def test_start_provider_agents ( self , mock_stevedore , mock_multiprocessing ) :
mock_extension = mock . MagicMock ( )
mock_extension . name = ' test_extension '
mock_exit_event = mock . MagicMock ( )
mock_stevedore . return_value = [ mock_extension ]
mock_ext_proc = mock . MagicMock ( )
mock_multiprocessing . Process . return_value = mock_ext_proc
driver_agent . _start_provider_agents ( mock_exit_event )
mock_stevedore . assert_called_once_with (
namespace = ' octavia.driver_agent.provider_agents ' ,
check_func = driver_agent . _check_if_provider_agent_enabled )
mock_multiprocessing . Process . assert_called_once_with (
name = ' test_extension ' , target = driver_agent . _process_wrapper ,
args = ( mock_exit_event , ' provider_agent ' , mock_extension . plugin ) ,
kwargs = { ' agent_name ' : ' test_extension ' } )
mock_ext_proc . start . assert_called_once_with ( )
@mock.patch ( ' os.kill ' )
@mock.patch ( ' octavia.cmd.driver_agent.multiprocessing ' )
@mock.patch ( ' oslo_reports.guru_meditation_report.TextGuruMeditation. '
' setup_autorun ' )
@mock.patch ( ' octavia.common.service.prepare_service ' )
def test_main ( self , mock_prep_srvc , mock_gmr , mock_multiprocessing ,
mock_signal ) :
mock_ kil l) :
mock_exit_event = mock . MagicMock ( )
mock_multiprocessing . Event . return_value = mock_exit_event
mock_status_listener_proc = mock . MagicMock ( )
mock_stats_listener_proc = mock . MagicMock ( )
mock_get_listener_proc = mock . MagicMock ( )
mock_multiprocessing . Process . side_effect = [ mock_status_listener_proc ,
mock_stats_listener_proc ,
mock_get_listener_proc ,
mock_status_listener_proc ,
mock_stats_listener_proc ,
mock_get_listener_proc ]
mock_multiprocessing . Process . side_effect = [
mock_status_listener_proc , mock_stats_listener_proc ,
mock_get_listener_proc ,
mock_status_listener_proc , mock_stats_listener_proc ,
mock_get_listener_proc ,
mock_status_listener_proc , mock_stats_listener_proc ,
mock_get_listener_proc ,
mock_status_listener_proc , mock_stats_listener_proc ,
mock_get_listener_proc ,
mock_status_listener_proc , mock_stats_listener_proc ,
mock_get_listener_proc ]
driver_agent . main ( )
mock_prep_srvc . assert_called_once ( )
mock_gmr . assert_called_once ( )
@ -76,3 +175,40 @@ class TestDriverAgentCMD(base.TestCase):
mock_stats_listener_proc . join . side_effect = [ KeyboardInterrupt , None ]
driver_agent . main ( )
mock_exit_event . set . assert_called_once ( )
# Test keyboard interrupt with provider agents
mock_exit_event . reset_mock ( )
mock_stats_listener_proc . join . side_effect = [ KeyboardInterrupt , None ]
mock_provider_proc = mock . MagicMock ( )
mock_provider_proc . pid = ' not-valid-pid '
mock_provider_proc . exitcode = 1
driver_agent . PROVIDER_AGENT_PROCESSES = [ mock_provider_proc ]
driver_agent . main ( )
mock_exit_event . set . assert_called_once ( )
mock_provider_proc . join . assert_called_once_with (
CONF . driver_agent . provider_agent_shutdown_timeout )
# Test keyboard interrupt with provider agents fails to stop
mock_exit_event . reset_mock ( )
mock_stats_listener_proc . join . side_effect = [ KeyboardInterrupt , None ]
mock_provider_proc = mock . MagicMock ( )
mock_provider_proc . pid = ' not-valid-pid '
mock_provider_proc . exitcode = None
driver_agent . PROVIDER_AGENT_PROCESSES = [ mock_provider_proc ]
driver_agent . main ( )
mock_exit_event . set . assert_called_once ( )
mock_provider_proc . join . assert_called_once_with (
CONF . driver_agent . provider_agent_shutdown_timeout )
mock_kill . assert_called_once_with ( ' not-valid-pid ' , signal . SIGKILL )
# Test keyboard interrupt with provider agents join exception
mock_exit_event . reset_mock ( )
mock_stats_listener_proc . join . side_effect = [ KeyboardInterrupt , None ]
mock_provider_proc = mock . MagicMock ( )
mock_provider_proc . pid = ' not-valid-pid '
mock_provider_proc . join . side_effect = Exception ( ' boom ' )
driver_agent . PROVIDER_AGENT_PROCESSES = [ mock_provider_proc ]
driver_agent . main ( )
mock_exit_event . set . assert_called_once ( )
mock_provider_proc . join . assert_called_once_with (
CONF . driver_agent . provider_agent_shutdown_timeout )