testing.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. # -*- coding: utf-8 -*-
  2. # SPDX-License-Identifier: AGPL-3.0-or-later
  3. """Shared testing code."""
  4. # pylint: disable=missing-function-docstring,consider-using-with
  5. import os
  6. import subprocess
  7. import traceback
  8. from os.path import dirname, join, abspath, realpath
  9. from splinter import Browser
  10. import aiounittest
  11. class SearxTestLayer:
  12. """Base layer for non-robot tests."""
  13. __name__ = 'SearxTestLayer'
  14. @classmethod
  15. def setUp(cls):
  16. pass
  17. @classmethod
  18. def tearDown(cls):
  19. pass
  20. @classmethod
  21. def testSetUp(cls):
  22. pass
  23. @classmethod
  24. def testTearDown(cls):
  25. pass
  26. class SearxRobotLayer():
  27. """Searx Robot Test Layer"""
  28. def setUp(self):
  29. os.setpgrp() # create new process group, become its leader
  30. # get program paths
  31. webapp = join(abspath(dirname(realpath(__file__))), 'webapp.py')
  32. exe = 'python'
  33. # The Flask app is started by Flask.run(...), don't enable Flask's debug
  34. # mode, the debugger from Flask will cause wired process model, where
  35. # the server never dies. Further read:
  36. #
  37. # - debug mode: https://flask.palletsprojects.com/quickstart/#debug-mode
  38. # - Flask.run(..): https://flask.palletsprojects.com/api/#flask.Flask.run
  39. os.environ['SEARX_DEBUG'] = '0'
  40. # set robot settings path
  41. os.environ['SEARX_SETTINGS_PATH'] = abspath(
  42. dirname(__file__) + '/settings_robot.yml')
  43. # run the server
  44. self.server = subprocess.Popen(
  45. [exe, webapp],
  46. stdout=subprocess.PIPE,
  47. stderr=subprocess.STDOUT
  48. )
  49. if hasattr(self.server.stdout, 'read1'):
  50. print(self.server.stdout.read1(1024).decode())
  51. def tearDown(self):
  52. os.kill(self.server.pid, 9)
  53. # remove previously set environment variable
  54. del os.environ['SEARX_SETTINGS_PATH']
  55. # SEARXROBOTLAYER = SearxRobotLayer()
  56. def run_robot_tests(tests):
  57. print('Running {0} tests'.format(len(tests)))
  58. for test in tests:
  59. with Browser('firefox', headless=True) as browser:
  60. test(browser)
  61. class SearxTestCase(aiounittest.AsyncTestCase):
  62. """Base test case for non-robot tests."""
  63. layer = SearxTestLayer
  64. def setattr4test(self, obj, attr, value):
  65. """
  66. setattr(obj, attr, value)
  67. but reset to the previous value in the cleanup.
  68. """
  69. previous_value = getattr(obj, attr)
  70. def cleanup_patch():
  71. setattr(obj, attr, previous_value)
  72. self.addCleanup(cleanup_patch)
  73. setattr(obj, attr, value)
  74. if __name__ == '__main__':
  75. import sys
  76. # test cases
  77. from tests import robot
  78. base_dir = abspath(join(dirname(__file__), '../tests'))
  79. if sys.argv[1] == 'robot':
  80. test_layer = SearxRobotLayer()
  81. errors = False
  82. try:
  83. test_layer.setUp()
  84. run_robot_tests([getattr(robot, x) for x in dir(robot) if x.startswith('test_')])
  85. except Exception: # pylint: disable=broad-except
  86. errors = True
  87. print('Error occured: {0}'.format(traceback.format_exc()))
  88. test_layer.tearDown()
  89. sys.exit(1 if errors else 0)