abstract_database.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import abc
  2. import re
  3. import shlex
  4. import subprocess
  5. from toolset.utils.popen import PopenTimeout
  6. class AbstractDatabase:
  7. '''
  8. Abstract Database Class.
  9. To be derived for defining a new concrete Database type
  10. '''
  11. #margin of tolerance on the results (rows read or updated only)
  12. margin = 1.011
  13. @classmethod
  14. @abc.abstractmethod
  15. def get_connection(cls, config):
  16. '''
  17. Establishes and returns a connection to the database.
  18. '''
  19. pass
  20. @classmethod
  21. @abc.abstractmethod
  22. def get_current_world_table(cls, config):
  23. '''
  24. Returns a JSON object containing all 10,000 World items as they currently
  25. exist in the database. This is used for verifying that entries in the
  26. database have actually changed during an Update verification test.
  27. '''
  28. pass
  29. @classmethod
  30. @abc.abstractmethod
  31. def test_connection(cls, config):
  32. '''
  33. Tests the connection and returns true if it is established.
  34. '''
  35. pass
  36. @classmethod
  37. @abc.abstractmethod
  38. def get_queries(cls, config):
  39. '''
  40. Returns the number of db queries (all types).
  41. '''
  42. pass
  43. @classmethod
  44. @abc.abstractmethod
  45. def get_rows(cls, config):
  46. '''
  47. Returns the number of db rows read.
  48. '''
  49. pass
  50. @classmethod
  51. @abc.abstractmethod
  52. def get_rows_updated(cls, config):
  53. '''
  54. Return the number of updated db rows.
  55. '''
  56. pass
  57. @classmethod
  58. @abc.abstractmethod
  59. def reset_cache(cls, config):
  60. '''
  61. Reset the query cache.
  62. '''
  63. pass
  64. @classmethod
  65. def verify_queries(cls, config, table_name, url, concurrency=512, count=2, check_updates=False):
  66. '''
  67. Verify query and row numbers for table_name.
  68. Retrieve from the database statistics of the number of queries made, the number of rows read, eventually the number of updated rows.
  69. Run 2 repetitions of http requests at the concurrency level 512 with siege.
  70. Retrieve statistics again, calculate the number of queries made and the number of rows read.
  71. '''
  72. trans_failures = 0
  73. rows_updated = None
  74. cls.tbl_name = table_name # used for Postgres and mongodb
  75. queries = int(cls.get_queries(config))
  76. rows = int(cls.get_rows(config))
  77. if check_updates:
  78. rows_updated = int(cls.get_rows_updated(config))
  79. cls.reset_cache(config)
  80. #Start siege requests with timeout (20s)
  81. path = config.db_root
  82. process = PopenTimeout(shlex.split("siege -c %s -r %s %s -R %s/.siegerc" % (concurrency, count, url, path)), stdout = subprocess.PIPE, stderr = subprocess.STDOUT, timeout=20)
  83. output, _ = process.communicate()
  84. #Search for failed transactions
  85. match = re.search('Failed transactions:.*?(\d+)\n', output, re.MULTILINE)
  86. if match:
  87. trans_failures = int(match.group(1))
  88. print output
  89. else:
  90. trans_failures = concurrency * count#Failed transactions: 100%
  91. queries = int(cls.get_queries(config)) - queries
  92. rows = int(cls.get_rows(config)) - rows
  93. if check_updates:
  94. rows_updated = int(cls.get_rows_updated(config)) - rows_updated
  95. return queries, rows, rows_updated, cls.margin, trans_failures