"""Tests to test the test framework"""

import sys
import unittest

import eventlet.timeout

from neutron.tests import base


class BrokenExceptionHandlerTestCase(base.DietTestCase):
    # Embedded to hide from the regular test discovery
    class MyTestCase(base.DietTestCase):
        def setUp(self):
            super(BrokenExceptionHandlerTestCase.MyTestCase, self).setUp()
            self.addOnException(self._diag_collect)

        def _diag_collect(self, exc_info):
            raise ValueError('whoopsie daisy')

        def runTest(self):
            raise IndexError("Thou shalt not pass by reference")

    def test_broken_exception_handler(self):
        result = self.MyTestCase().run()
        # ensure both exceptions are logged
        self.assertIn('Thou shalt', result.errors[0][1])
        self.assertIn('whoopsie', result.errors[0][1])
        self.assertFalse(result.wasSuccessful())


class SystemExitTestCase(base.DietTestCase):
    # Embedded to hide from the regular test discovery
    class MyTestCase(base.DietTestCase):
        def __init__(self, exitcode):
            super(SystemExitTestCase.MyTestCase, self).__init__()
            self.exitcode = exitcode

        def runTest(self):
            if self.exitcode is not None:
                sys.exit(self.exitcode)

    def test_no_sysexit(self):
        result = self.MyTestCase(exitcode=None).run()
        self.assertTrue(result.wasSuccessful())

    def test_sysexit(self):
        expectedFails = [self.MyTestCase(exitcode) for exitcode in (0, 1)]

        suite = unittest.TestSuite(tests=expectedFails)
        result = self.defaultTestResult()
        try:
            suite.run(result)
        except SystemExit:
            self.fail('SystemExit escaped!')

        self.assertEqual([], result.errors)
        self.assertCountEqual(set(id(t) for t in expectedFails),
                              set(id(t) for (t, traceback) in result.failures))


class CatchTimeoutTestCase(base.DietTestCase):
    # Embedded to hide from the regular test discovery
    class MyTestCase(base.DietTestCase):
        def test_case(self):
            raise eventlet.Timeout()

        def runTest(self):
            return self.test_case()

    def test_catch_timeout(self):
        try:
            result = self.MyTestCase().run()
            self.assertFalse(result.wasSuccessful())
        except eventlet.Timeout:
            self.fail('Timeout escaped!')
