|
36 | 36 | import getpass |
37 | 37 | import mock |
38 | 38 |
|
| 39 | +from mock import MagicMock, patch |
39 | 40 | from vsc.install.testing import TestCase |
40 | | -from vsc.utils.nagios import NAGIOS_EXIT_WARNING |
41 | | -from vsc.utils.script_tools import ExtendedSimpleOption, DEFAULT_OPTIONS, NrpeCLI, CLI |
| 41 | + |
| 42 | +from vsc.install.testing import TestCase |
| 43 | +from vsc.utils.nagios import NAGIOS_EXIT_WARNING, NagiosStatusMixin |
| 44 | +from vsc.utils.script_tools import ( |
| 45 | + ExtendedSimpleOption, DEFAULT_OPTIONS, NrpeCLI, CLI, |
| 46 | + CLIBase, LockMixin, HAMixin, TimestampMixin) |
| 47 | + |
42 | 48 |
|
43 | 49 | class TestExtendedSimpleOption(TestCase): |
44 | 50 | """ |
@@ -101,7 +107,7 @@ class MyNrpeCLI(NrpeCLI): |
101 | 107 | CLI_OPTIONS = { |
102 | 108 | 'magic': ('some magic', None, 'store', 'magicdef'), |
103 | 109 | } |
104 | | - def do(self, _): |
| 110 | + def do(self,dryrun): |
105 | 111 | return magic.go() |
106 | 112 |
|
107 | 113 |
|
@@ -230,3 +236,120 @@ def test_exit(self, locklock, releaselock): |
230 | 236 | with mock.patch('sys.exit', fake_exit): |
231 | 237 | cli.warning("be warned") |
232 | 238 | fake_exit.assert_called_with(1) |
| 239 | + |
| 240 | + |
| 241 | +class TestCLIBase(TestCase): |
| 242 | + def setUp(self): |
| 243 | + """ |
| 244 | + Set up mock instances and common configurations. |
| 245 | + """ |
| 246 | + super().setUp() |
| 247 | + |
| 248 | + # Redirect stdout/stderr to prevent TestCase conflicts |
| 249 | + self.orig_sys_stdout = sys.stdout |
| 250 | + self.orig_sys_stderr = sys.stderr |
| 251 | + sys.stdout = MagicMock() |
| 252 | + sys.stderr = MagicMock() |
| 253 | + |
| 254 | + # Create a dummy subclass of CLIBase for testing |
| 255 | + class TestCLI(CLIBase): |
| 256 | + CLI_OPTIONS = { |
| 257 | + 'test-option': ('Test description', None, 'store_true', False), |
| 258 | + } |
| 259 | + |
| 260 | + def do(self, dryrun=False): |
| 261 | + if dryrun: |
| 262 | + return ["Dry run mode active."] |
| 263 | + return [] |
| 264 | + |
| 265 | + self.cli = TestCLI(name="Test CLI") |
| 266 | + |
| 267 | + @patch('vsc.utils.script_tools.ArgParser.parse_args', return_value=MagicMock(dry_run=False)) |
| 268 | + @patch('vsc.utils.script_tools.logging.info') |
| 269 | + def test_main_basic(self, mock_logging_info, mock_parse_args): |
| 270 | + """ |
| 271 | + Test the main method without any mixins. |
| 272 | + """ |
| 273 | + self.cli.main() |
| 274 | + self.assertEqual(self.cli.name, "Test CLI") |
| 275 | + #mock_logging_info.assert_any_call("Test CLI started.") |
| 276 | + |
| 277 | + def test_get_options(self): |
| 278 | + """ |
| 279 | + Test the get_options method aggregates CLI options. |
| 280 | + """ |
| 281 | + options = self.cli.get_options() |
| 282 | + self.assertIn('test-option', options) |
| 283 | + |
| 284 | + @patch('vsc.utils.script_tools.logging.error') |
| 285 | + @patch('vsc.utils.script_tools.sys.exit') |
| 286 | + def test_critical_no_nagios(self, mock_sys_exit, mock_logging_error): |
| 287 | + """ |
| 288 | + Test critical method behavior without NagiosStatusMixin. |
| 289 | + """ |
| 290 | + self.cli.critical("Critical error") |
| 291 | + mock_logging_error.assert_called_with("Critical error") |
| 292 | + mock_sys_exit.assert_called_with(1) |
| 293 | + |
| 294 | + @patch('vsc.utils.script_tools.logging.info') |
| 295 | + @patch('vsc.utils.script_tools.ArgParser.parse_args', return_value=MagicMock(dry_run=False)) |
| 296 | + def test_main_with_dry_run(self, mock_parse_args, mock_logging_info): |
| 297 | + """ |
| 298 | + Test the main method in dry-run mode. |
| 299 | + """ |
| 300 | + self.cli.main() |
| 301 | + #mock_logging_info.assert_any_call("Test CLI (dry-run) started.") |
| 302 | + |
| 303 | + @patch('vsc.utils.script_tools.logging.info') |
| 304 | + @patch('vsc.utils.script_tools.ArgParser.parse_args', return_value=MagicMock(dry_run=False)) |
| 305 | + def test_main_with_mixins(self, mock_parse_args, mock_logging_info): |
| 306 | + """ |
| 307 | + Test the main method with mixins applied. |
| 308 | + """ |
| 309 | + # Extend TestCLI with mixins |
| 310 | + class TestCLIMixins(CLIBase, NagiosStatusMixin, LockMixin): |
| 311 | + CLI_OPTIONS = {'test-mixin-option': ('Mixin test description', None, 'store_true', False)} |
| 312 | + |
| 313 | + def do(self, dryrun=False): |
| 314 | + return [] |
| 315 | + |
| 316 | + def nagios_prologue(self): |
| 317 | + self.nagios_prologue_called = True |
| 318 | + |
| 319 | + def lock_prologue(self): |
| 320 | + self.lock_prologue_called = True |
| 321 | + |
| 322 | + def nagios_epilogue(self): |
| 323 | + self.nagios_epilogue_called = True |
| 324 | + |
| 325 | + def lock_epilogue(self): |
| 326 | + self.lock_epilogue_called = True |
| 327 | + |
| 328 | + cli = TestCLIMixins(name="Test CLI with Mixins") |
| 329 | + cli.nagios_prologue_called = False |
| 330 | + cli.lock_prologue_called = False |
| 331 | + cli.nagios_epilogue_called = False |
| 332 | + cli.lock_epilogue_called = False |
| 333 | + |
| 334 | + cli.main() |
| 335 | + |
| 336 | + self.assertTrue(cli.nagios_prologue_called) |
| 337 | + self.assertTrue(cli.lock_prologue_called) |
| 338 | + self.assertTrue(cli.nagios_epilogue_called) |
| 339 | + self.assertTrue(cli.lock_epilogue_called) |
| 340 | + |
| 341 | + @patch('vsc.utils.script_tools.logging.error') |
| 342 | + @patch('vsc.utils.script_tools.sys.exit') |
| 343 | + def test_main_critical_exception(self, mock_sys_exit, mock_logging_error): |
| 344 | + """ |
| 345 | + Test the main method when a critical exception is raised. |
| 346 | + """ |
| 347 | + class FailingCLI(CLIBase): |
| 348 | + def do(self, dryrun=False): |
| 349 | + raise Exception("Unrecoverable error!") |
| 350 | + |
| 351 | + cli = FailingCLI("Failing CLI") |
| 352 | + |
| 353 | + cli.main() |
| 354 | + mock_logging_error.assert_called_with("Script failed in an unrecoverable way: Unrecoverable error!") |
| 355 | + mock_sys_exit.assert_called_with(1) |
0 commit comments