test_ssl_compat.py 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. # -*- coding: utf-8 -*-
  2. import sys
  3. import unittest
  4. from unittest.mock import patch
  5. """
  6. test_ssl_compat.py
  7. websocket - WebSocket client library for Python
  8. Copyright 2025 engn33r
  9. Licensed under the Apache License, Version 2.0 (the "License");
  10. you may not use this file except in compliance with the License.
  11. You may obtain a copy of the License at
  12. http://www.apache.org/licenses/LICENSE-2.0
  13. Unless required by applicable law or agreed to in writing, software
  14. distributed under the License is distributed on an "AS IS" BASIS,
  15. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. See the License for the specific language governing permissions and
  17. limitations under the License.
  18. """
  19. class SSLCompatTest(unittest.TestCase):
  20. def test_ssl_available(self):
  21. """Test that SSL is available in normal conditions"""
  22. import websocket._ssl_compat as ssl_compat
  23. # In normal conditions, SSL should be available
  24. self.assertTrue(ssl_compat.HAVE_SSL)
  25. self.assertIsNotNone(ssl_compat.ssl)
  26. # SSL exception classes should be available
  27. self.assertTrue(hasattr(ssl_compat, "SSLError"))
  28. self.assertTrue(hasattr(ssl_compat, "SSLEOFError"))
  29. self.assertTrue(hasattr(ssl_compat, "SSLWantReadError"))
  30. self.assertTrue(hasattr(ssl_compat, "SSLWantWriteError"))
  31. def test_ssl_not_available(self):
  32. """Test fallback behavior when SSL is not available"""
  33. # Remove ssl_compat from modules to force reimport
  34. if "websocket._ssl_compat" in sys.modules:
  35. del sys.modules["websocket._ssl_compat"]
  36. # Mock the ssl module to not be available
  37. import builtins
  38. original_import = builtins.__import__
  39. def mock_import(name, *args, **kwargs):
  40. if name == "ssl":
  41. raise ImportError("No module named 'ssl'")
  42. return original_import(name, *args, **kwargs)
  43. with patch("builtins.__import__", side_effect=mock_import):
  44. import websocket._ssl_compat as ssl_compat
  45. # SSL should not be available
  46. self.assertFalse(ssl_compat.HAVE_SSL)
  47. self.assertIsNone(ssl_compat.ssl)
  48. # Fallback exception classes should be available and functional
  49. self.assertTrue(issubclass(ssl_compat.SSLError, Exception))
  50. self.assertTrue(issubclass(ssl_compat.SSLEOFError, Exception))
  51. self.assertTrue(issubclass(ssl_compat.SSLWantReadError, Exception))
  52. self.assertTrue(issubclass(ssl_compat.SSLWantWriteError, Exception))
  53. # Test that exceptions can be instantiated
  54. ssl_error = ssl_compat.SSLError("test error")
  55. self.assertIsInstance(ssl_error, Exception)
  56. self.assertEqual(str(ssl_error), "test error")
  57. ssl_eof_error = ssl_compat.SSLEOFError("test eof")
  58. self.assertIsInstance(ssl_eof_error, Exception)
  59. ssl_want_read = ssl_compat.SSLWantReadError("test read")
  60. self.assertIsInstance(ssl_want_read, Exception)
  61. ssl_want_write = ssl_compat.SSLWantWriteError("test write")
  62. self.assertIsInstance(ssl_want_write, Exception)
  63. def tearDown(self):
  64. """Clean up after tests"""
  65. # Ensure ssl_compat is reimported fresh for next test
  66. if "websocket._ssl_compat" in sys.modules:
  67. del sys.modules["websocket._ssl_compat"]
  68. if __name__ == "__main__":
  69. unittest.main()