conftest.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. import os
  2. import sys
  3. import urllib
  4. import time
  5. import logging
  6. import json
  7. import shutil
  8. import gc
  9. import pytest
  10. import mock
  11. def pytest_addoption(parser):
  12. parser.addoption("--slow", action='store_true', default=False, help="Also run slow tests")
  13. # Config
  14. if sys.platform == "win32":
  15. PHANTOMJS_PATH = "tools/phantomjs/bin/phantomjs.exe"
  16. else:
  17. PHANTOMJS_PATH = "phantomjs"
  18. SITE_URL = "http://127.0.0.1:43110"
  19. sys.path.insert(0, os.path.abspath(os.path.dirname(__file__) + "/../lib")) # External modules directory
  20. sys.path.insert(0, os.path.abspath(os.path.dirname(__file__) + "/..")) # Imports relative to src dir
  21. from Config import config
  22. config.argv = ["none"] # Dont pass any argv to config parser
  23. config.parse(silent=True) # Plugins need to access the configuration
  24. logging.basicConfig(level=logging.DEBUG, stream=sys.stdout)
  25. from Plugin import PluginManager
  26. PluginManager.plugin_manager.loadPlugins()
  27. config.loadPlugins()
  28. config.parse() # Parse again to add plugin configuration options
  29. config.data_dir = "src/Test/testdata" # Use test data for unittests
  30. config.debug_socket = True # Use test data for unittests
  31. config.verbose = True # Use test data for unittests
  32. config.tor = "disabled" # Don't start Tor client
  33. config.trackers = []
  34. os.chdir(os.path.abspath(os.path.dirname(__file__) + "/../..")) # Set working dir
  35. # Cleanup content.db caches
  36. if os.path.isfile("%s/content.db" % config.data_dir):
  37. os.unlink("%s/content.db" % config.data_dir)
  38. if os.path.isfile("%s-temp/content.db" % config.data_dir):
  39. os.unlink("%s-temp/content.db" % config.data_dir)
  40. import gevent
  41. from gevent import monkey
  42. monkey.patch_all(thread=False)
  43. from Site import Site
  44. from Site import SiteManager
  45. from User import UserManager
  46. from File import FileServer
  47. from Connection import ConnectionServer
  48. from Crypt import CryptConnection
  49. from Ui import UiWebsocket
  50. from Tor import TorManager
  51. from Content import ContentDb
  52. from util import RateLimit
  53. from Db import Db
  54. # SiteManager.site_manager.load = mock.MagicMock(return_value=True) # Don't try to load from sites.json
  55. # SiteManager.site_manager.save = mock.MagicMock(return_value=True) # Don't try to load from sites.json
  56. @pytest.fixture(scope="session")
  57. def resetSettings(request):
  58. open("%s/sites.json" % config.data_dir, "w").write("{}")
  59. open("%s/users.json" % config.data_dir, "w").write("""
  60. {
  61. "15E5rhcAUD69WbiYsYARh4YHJ4sLm2JEyc": {
  62. "certs": {},
  63. "master_seed": "024bceac1105483d66585d8a60eaf20aa8c3254b0f266e0d626ddb6114e2949a",
  64. "sites": {}
  65. }
  66. }
  67. """)
  68. @pytest.fixture(scope="session")
  69. def resetTempSettings(request):
  70. data_dir_temp = config.data_dir + "-temp"
  71. if not os.path.isdir(data_dir_temp):
  72. os.mkdir(data_dir_temp)
  73. open("%s/sites.json" % data_dir_temp, "w").write("{}")
  74. open("%s/users.json" % data_dir_temp, "w").write("""
  75. {
  76. "15E5rhcAUD69WbiYsYARh4YHJ4sLm2JEyc": {
  77. "certs": {},
  78. "master_seed": "024bceac1105483d66585d8a60eaf20aa8c3254b0f266e0d626ddb6114e2949a",
  79. "sites": {}
  80. }
  81. }
  82. """)
  83. def cleanup():
  84. os.unlink("%s/sites.json" % data_dir_temp)
  85. os.unlink("%s/users.json" % data_dir_temp)
  86. request.addfinalizer(cleanup)
  87. @pytest.fixture()
  88. def site(request):
  89. threads_before = [obj for obj in gc.get_objects() if isinstance(obj, gevent.Greenlet)]
  90. # Reset ratelimit
  91. RateLimit.queue_db = {}
  92. RateLimit.called_db = {}
  93. site = Site("1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT")
  94. site.announce = mock.MagicMock(return_value=True) # Don't try to find peers from the net
  95. # Always use original data
  96. assert "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT" in site.storage.getPath("") # Make sure we dont delete everything
  97. shutil.rmtree(site.storage.getPath(""), True)
  98. shutil.copytree(site.storage.getPath("") + "-original", site.storage.getPath(""))
  99. def cleanup():
  100. site.storage.deleteFiles()
  101. site.content_manager.contents.db.deleteSite(site)
  102. del SiteManager.site_manager.sites["1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT"]
  103. site.content_manager.contents.db.close()
  104. db_path = "%s/content.db" % config.data_dir
  105. os.unlink(db_path)
  106. del ContentDb.content_dbs[db_path]
  107. gevent.killall([obj for obj in gc.get_objects() if isinstance(obj, gevent.Greenlet) and obj not in threads_before])
  108. request.addfinalizer(cleanup)
  109. site = Site("1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT") # Create new Site object to load content.json files
  110. if not SiteManager.site_manager.sites:
  111. SiteManager.site_manager.sites = {}
  112. SiteManager.site_manager.sites["1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT"] = site
  113. return site
  114. @pytest.fixture()
  115. def site_temp(request):
  116. threads_before = [obj for obj in gc.get_objects() if isinstance(obj, gevent.Greenlet)]
  117. with mock.patch("Config.config.data_dir", config.data_dir + "-temp"):
  118. site_temp = Site("1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT")
  119. site_temp.announce = mock.MagicMock(return_value=True) # Don't try to find peers from the net
  120. def cleanup():
  121. site_temp.storage.deleteFiles()
  122. site_temp.content_manager.contents.db.deleteSite(site_temp)
  123. site_temp.content_manager.contents.db.close()
  124. db_path = "%s-temp/content.db" % config.data_dir
  125. os.unlink(db_path)
  126. del ContentDb.content_dbs[db_path]
  127. gevent.killall([obj for obj in gc.get_objects() if isinstance(obj, gevent.Greenlet) and obj not in threads_before])
  128. request.addfinalizer(cleanup)
  129. return site_temp
  130. @pytest.fixture(scope="session")
  131. def user():
  132. user = UserManager.user_manager.get()
  133. user.sites = {} # Reset user data
  134. return user
  135. @pytest.fixture(scope="session")
  136. def browser():
  137. try:
  138. from selenium import webdriver
  139. browser = webdriver.PhantomJS(executable_path=PHANTOMJS_PATH, service_log_path=os.path.devnull)
  140. browser.set_window_size(1400, 1000)
  141. except Exception, err:
  142. raise pytest.skip("Test requires selenium + phantomjs: %s" % err)
  143. return browser
  144. @pytest.fixture(scope="session")
  145. def site_url():
  146. try:
  147. urllib.urlopen(SITE_URL).read()
  148. except Exception, err:
  149. raise pytest.skip("Test requires zeronet client running: %s" % err)
  150. return SITE_URL
  151. @pytest.fixture(scope="session")
  152. def file_server(request):
  153. request.addfinalizer(CryptConnection.manager.removeCerts) # Remove cert files after end
  154. file_server = FileServer("127.0.0.1", 1544)
  155. gevent.spawn(lambda: ConnectionServer.start(file_server))
  156. # Wait for port opening
  157. for retry in range(10):
  158. time.sleep(0.1) # Port opening
  159. try:
  160. conn = file_server.getConnection("127.0.0.1", 1544)
  161. conn.close()
  162. break
  163. except Exception, err:
  164. print err
  165. assert file_server.running
  166. def stop():
  167. file_server.stop()
  168. request.addfinalizer(stop)
  169. return file_server
  170. @pytest.fixture()
  171. def ui_websocket(site, file_server, user):
  172. class WsMock:
  173. def __init__(self):
  174. self.result = None
  175. def send(self, data):
  176. self.result = json.loads(data)["result"]
  177. ws_mock = WsMock()
  178. ui_websocket = UiWebsocket(ws_mock, site, file_server, user, None)
  179. def testAction(action, *args, **kwargs):
  180. func = getattr(ui_websocket, "action%s" % action)
  181. func(0, *args, **kwargs)
  182. return ui_websocket.ws.result
  183. ui_websocket.testAction = testAction
  184. return ui_websocket
  185. @pytest.fixture(scope="session")
  186. def tor_manager():
  187. try:
  188. tor_manager = TorManager()
  189. assert tor_manager.connect()
  190. tor_manager.startOnions()
  191. except Exception, err:
  192. raise pytest.skip("Test requires Tor with ControlPort: %s, %s" % (config.tor_controller, err))
  193. return tor_manager
  194. @pytest.fixture()
  195. def db(request):
  196. db_path = "%s/zeronet.db" % config.data_dir
  197. schema = {
  198. "db_name": "TestDb",
  199. "db_file": "%s/zeronet.db" % config.data_dir,
  200. "maps": {
  201. "data.json": {
  202. "to_table": [
  203. "test",
  204. {"node": "test", "table": "test_importfilter", "import_cols": ["test_id", "title"]}
  205. ]
  206. }
  207. },
  208. "tables": {
  209. "test": {
  210. "cols": [
  211. ["test_id", "INTEGER"],
  212. ["title", "TEXT"],
  213. ["json_id", "INTEGER REFERENCES json (json_id)"]
  214. ],
  215. "indexes": ["CREATE UNIQUE INDEX test_id ON test(test_id)"],
  216. "schema_changed": 1426195822
  217. },
  218. "test_importfilter": {
  219. "cols": [
  220. ["test_id", "INTEGER"],
  221. ["title", "TEXT"],
  222. ["json_id", "INTEGER REFERENCES json (json_id)"]
  223. ],
  224. "indexes": ["CREATE UNIQUE INDEX test_importfilter_id ON test_importfilter(test_id)"],
  225. "schema_changed": 1426195822
  226. }
  227. }
  228. }
  229. if os.path.isfile(db_path):
  230. os.unlink(db_path)
  231. db = Db(schema, db_path)
  232. db.checkTables()
  233. def stop():
  234. db.close()
  235. os.unlink(db_path)
  236. request.addfinalizer(stop)
  237. return db