OpenStack Database As A Service (Trove)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

run_tests.py 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. # Copyright 2013 OpenStack Foundation
  2. # Copyright 2013 Rackspace Hosting
  3. # Copyright 2013 Hewlett-Packard Development Company, L.P.
  4. # All Rights Reserved.
  5. #
  6. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  7. # not use this file except in compliance with the License. You may obtain
  8. # a copy of the License at
  9. #
  10. # http://www.apache.org/licenses/LICENSE-2.0
  11. #
  12. # Unless required by applicable law or agreed to in writing, software
  13. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  14. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  15. # License for the specific language governing permissions and limitations
  16. # under the License.
  17. #
  18. import functools
  19. import gettext
  20. import os
  21. import sys
  22. import traceback
  23. import eventlet
  24. from oslo_log import log as logging
  25. import proboscis
  26. import six
  27. from six.moves import urllib
  28. import wsgi_intercept
  29. from wsgi_intercept.httplib2_intercept import install as wsgi_install
  30. from trove.common import cfg
  31. from trove.common.rpc import service as rpc_service
  32. from trove.common.rpc import version as rpc_version
  33. from trove.common import utils
  34. from trove import rpc
  35. from trove.tests.config import CONFIG
  36. from trove.tests import root_logger
  37. eventlet.monkey_patch(thread=False)
  38. CONF = cfg.CONF
  39. original_excepthook = sys.excepthook
  40. def add_support_for_localization():
  41. """Adds support for localization in the logging.
  42. If ../nova/__init__.py exists, add ../ to Python search path, so that
  43. it will override what happens to be installed in
  44. /usr/(local/)lib/python...
  45. """
  46. path = os.path.join(os.path.abspath(sys.argv[0]), os.pardir, os.pardir)
  47. possible_topdir = os.path.normpath(path)
  48. if os.path.exists(os.path.join(possible_topdir, 'nova', '__init__.py')):
  49. sys.path.insert(0, possible_topdir)
  50. if six.PY2:
  51. gettext.install('nova', unicode=1)
  52. else:
  53. gettext.install('nova')
  54. def initialize_trove(config_file):
  55. from trove.common import pastedeploy
  56. root_logger.DefaultRootLogger()
  57. cfg.CONF(args=[],
  58. project='trove',
  59. default_config_files=[config_file])
  60. logging.setup(CONF, None)
  61. topic = CONF.taskmanager_queue
  62. rpc.init(CONF)
  63. taskman_service = rpc_service.RpcService(
  64. CONF.taskmanager_rpc_encr_key, topic=topic,
  65. rpc_api_version=rpc_version.RPC_API_VERSION,
  66. manager='trove.taskmanager.manager.Manager')
  67. taskman_service.start()
  68. return pastedeploy.paste_deploy_app(config_file, 'trove', {})
  69. def datastore_init():
  70. # Adds the datastore for mysql (needed to make most calls work).
  71. from trove.configuration.models import DatastoreConfigurationParameters
  72. from trove.datastore import models
  73. models.DBDatastore.create(
  74. id=CONFIG.dbaas_datastore_id, name=CONFIG.dbaas_datastore,
  75. default_version_id=CONFIG.dbaas_datastore_version_id)
  76. models.DBDatastore.create(id=utils.generate_uuid(),
  77. name=CONFIG.dbaas_datastore_name_no_versions,
  78. default_version_id=None)
  79. main_dsv = models.DBDatastoreVersion.create(
  80. id=CONFIG.dbaas_datastore_version_id,
  81. datastore_id=CONFIG.dbaas_datastore_id,
  82. name=CONFIG.dbaas_datastore_version,
  83. manager="mysql",
  84. image_id='c00000c0-00c0-0c00-00c0-000c000000cc',
  85. packages='test packages',
  86. active=1)
  87. models.DBDatastoreVersion.create(
  88. id="d00000d0-00d0-0d00-00d0-000d000000dd",
  89. datastore_id=CONFIG.dbaas_datastore_id,
  90. name='mysql_inactive_version', manager="mysql",
  91. image_id='c00000c0-00c0-0c00-00c0-000c000000cc',
  92. packages=None, active=0)
  93. def add_parm(name, data_type, max_size, min_size=0, restart_required=0):
  94. DatastoreConfigurationParameters.create(
  95. datastore_version_id=main_dsv.id,
  96. name=name,
  97. restart_required=restart_required,
  98. max_size=max_size,
  99. min_size=0,
  100. data_type=data_type,
  101. deleted=0,
  102. deleted_at=None)
  103. add_parm('key_buffer_size', 'integer', 4294967296)
  104. add_parm('connect_timeout', 'integer', 65535)
  105. add_parm('join_buffer_size', 'integer', 4294967296)
  106. add_parm('local_infile', 'integer', 1)
  107. add_parm('collation_server', 'string', None, None)
  108. add_parm('innodb_buffer_pool_size', 'integer', 57671680,
  109. restart_required=1)
  110. def initialize_database():
  111. from trove.db import get_db_api
  112. from trove.db.sqlalchemy import session
  113. db_api = get_db_api()
  114. db_api.drop_db(CONF) # Destroys the database, if it exists.
  115. db_api.db_sync(CONF)
  116. session.configure_db(CONF)
  117. datastore_init()
  118. db_api.configure_db(CONF)
  119. def initialize_fakes(app):
  120. # Set up WSGI interceptor. This sets up a fake host that responds each
  121. # time httplib tries to communicate to localhost, port 8779.
  122. def wsgi_interceptor(*args, **kwargs):
  123. def call_back(env, start_response):
  124. path_info = env.get('PATH_INFO')
  125. if path_info:
  126. env['PATH_INFO'] = urllib.parse.unquote(path_info)
  127. return app.__call__(env, start_response)
  128. return call_back
  129. wsgi_intercept.add_wsgi_intercept('localhost',
  130. CONF.bind_port,
  131. wsgi_interceptor)
  132. from trove.tests.util import event_simulator
  133. event_simulator.monkey_patch()
  134. from trove.tests.fakes import taskmanager
  135. taskmanager.monkey_patch()
  136. def parse_args_for_test_config():
  137. test_conf = 'etc/tests/localhost.test.conf'
  138. repl = False
  139. new_argv = []
  140. for index in range(len(sys.argv)):
  141. arg = sys.argv[index]
  142. print(arg)
  143. if arg[:14] == "--test-config=":
  144. test_conf = arg[14:]
  145. elif arg == "--repl":
  146. repl = True
  147. else:
  148. new_argv.append(arg)
  149. sys.argv = new_argv
  150. return test_conf, repl
  151. def run_tests(repl):
  152. """Runs all of the tests."""
  153. if repl:
  154. # Actually show errors in the repl.
  155. sys.excepthook = original_excepthook
  156. def no_thanks(exit_code):
  157. print("Tests finished with exit code %d." % exit_code)
  158. sys.exit = no_thanks
  159. proboscis.TestProgram().run_and_exit()
  160. if repl:
  161. import code
  162. code.interact()
  163. def import_tests():
  164. # F401 unused imports needed for tox tests
  165. from trove.tests.api import backups # noqa
  166. from trove.tests.api import configurations # noqa
  167. from trove.tests.api import databases # noqa
  168. from trove.tests.api import datastores # noqa
  169. from trove.tests.api import flavors # noqa
  170. from trove.tests.api import header # noqa
  171. from trove.tests.api import instances as rd_instances # noqa
  172. from trove.tests.api import instances_actions as rd_actions # noqa
  173. from trove.tests.api import instances_delete # noqa
  174. from trove.tests.api import instances_mysql_down # noqa
  175. from trove.tests.api import instances_resize # noqa
  176. from trove.tests.api import limits # noqa
  177. from trove.tests.api.mgmt import accounts # noqa
  178. from trove.tests.api.mgmt import admin_required # noqa
  179. from trove.tests.api.mgmt import hosts # noqa
  180. from trove.tests.api.mgmt import instances as mgmt_instances # noqa
  181. from trove.tests.api.mgmt import instances_actions as mgmt_actions # noqa
  182. from trove.tests.api.mgmt import malformed_json # noqa
  183. from trove.tests.api.mgmt import storage # noqa
  184. from trove.tests.api import replication # noqa
  185. from trove.tests.api import root # noqa
  186. from trove.tests.api import root_on_create # noqa
  187. from trove.tests.api import user_access # noqa
  188. from trove.tests.api import users # noqa
  189. from trove.tests.api import versions # noqa
  190. from trove.tests.db import migrations # noqa
  191. def main(import_func):
  192. try:
  193. wsgi_install()
  194. add_support_for_localization()
  195. # Load Trove app
  196. # Paste file needs absolute path
  197. config_file = os.path.realpath('etc/trove/trove.conf.test')
  198. # 'etc/trove/test-api-paste.ini'
  199. app = initialize_trove(config_file)
  200. # Initialize sqlite database.
  201. initialize_database()
  202. # Swap out WSGI, httplib, and other components with test doubles.
  203. initialize_fakes(app)
  204. # Initialize the test configuration.
  205. test_config_file, repl = parse_args_for_test_config()
  206. CONFIG.load_from_file(test_config_file)
  207. import_func()
  208. from trove.tests.util import event_simulator
  209. event_simulator.run_main(functools.partial(run_tests, repl))
  210. except Exception as e:
  211. # Printing the error manually like this is necessary due to oddities
  212. # with sys.excepthook.
  213. print("Run tests failed: %s" % e)
  214. traceback.print_exc()
  215. raise
  216. if __name__ == "__main__":
  217. main(import_tests)