PageRenderTime 42ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/test_apiary/sqllog.py

https://bitbucket.org/lindenlab/apiary/
Python | 361 lines | 330 code | 7 blank | 24 comment | 1 complexity | 93b69bccd612119f86fa9733672a59db MD5 | raw file
  1. #
  2. # $LicenseInfo:firstyear=2010&license=mit$
  3. #
  4. # Copyright (c) 2010, Linden Research, Inc.
  5. #
  6. # Permission is hereby granted, free of charge, to any person obtaining a copy
  7. # of this software and associated documentation files (the "Software"), to deal
  8. # in the Software without restriction, including without limitation the rights
  9. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. # copies of the Software, and to permit persons to whom the Software is
  11. # furnished to do so, subject to the following conditions:
  12. #
  13. # The above copyright notice and this permission notice shall be included in
  14. # all copies or substantial portions of the Software.
  15. #
  16. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. # THE SOFTWARE.
  23. # $/LicenseInfo$
  24. #
  25. from StringIO import StringIO
  26. import unittest
  27. from apiary.mysql.sqllog import *
  28. from apiary.tools.timestamp import TimeStamp
  29. TestSource = 'unittest'
  30. FakeJobs = [str(n) for n in range(111, 1000, 111)]
  31. FakeJob = FakeJobs[-1]
  32. class TestEvent(unittest.TestCase):
  33. def testEventStr(self):
  34. e = Event(123456.789, FakeJobs[0], TestSource, 'QueryStart', 'SELECT * FROM foo')
  35. self.assertEqual(str(e), """\
  36. 123456.789000\t%s\t%s\tQueryStart
  37. SELECT * FROM foo
  38. **************************************
  39. """ % (FakeJobs[0], TestSource))
  40. def testOrdering(self):
  41. e1 = Event(10001.700, FakeJob, TestSource, 'QueryStart', 'SELECT')
  42. e2 = Event(10001.717, FakeJob, TestSource, 'QueryResponse', 'SELECT')
  43. e3 = Event(10001.717, FakeJob, TestSource, 'Quit', 'Quit')
  44. e4 = Event(10001.729, FakeJobs[0], TestSource, 'QueryStart', 'SELECT')
  45. self.assert_(e1 < e2)
  46. self.assert_(e1 < e3)
  47. self.assert_(e1 < e4)
  48. self.assert_(e2 < e3)
  49. self.assert_(e2 < e4)
  50. self.assert_(e3 < e4)
  51. class TestParsing(unittest.TestCase):
  52. def testSimpleStanza(self):
  53. f = StringIO("""\
  54. 1237237351.064861\t10.0.0.1:40784\t%s\tQueryResponse
  55. SELECT column1, column2 FROM some_table WHERE column1='foo'
  56. **************************************
  57. 1237237351.065393\t10.0.0.2:39706\t%s\tQueryStart
  58. SELECT t1.column1, t2.column2, t1.column3 FROM table1 t1, table2 t2 WHERE t1.column1 = '00000000-0000-0000-0000-000000000000' AND t2.column2 = t1.column4
  59. **************************************
  60. """ % (TestSource, TestSource))
  61. s = parse_stanza(f)
  62. self.assert_(s is not None)
  63. self.assertEqual(s.time, TimeStamp(1237237351.064861))
  64. self.assertEqual(s.id, '10.0.0.1:40784')
  65. self.assertEqual(s.state, 'QueryResponse')
  66. self.assertEqual(s.body, """\
  67. SELECT column1, column2 FROM some_table WHERE column1='foo'
  68. """)
  69. def disabled_testMkQueryLogSyntax(self):
  70. f = StringIO("""\
  71. # administrator command: Connect;
  72. # Time: 091022 12:43:08.898136
  73. # User@Host: user[user] @ 10.0.0.1 []
  74. # Client: 10.0.0.1:40737
  75. # Thread_id: 10000000
  76. # Query_time: 0 Lock_time: 0 Rows_sent: 0 Rows_examined: 0
  77. use some_table;
  78. SELECT foo FROM bar WHERE column1 = 'some_uid' AND column2 = 'another_uid' AND column3 = 1;
  79. """)
  80. s = parse_stanza(f)
  81. self.assert_(s is not None)
  82. self.assertEqual(s.time, TimeStamp(1256215388.898136))
  83. self.assertEqual(s.id, '10.0.0.1:40737:10000000')
  84. self.assertEqual(s.body, """\
  85. use some_table;
  86. SELECT foo FROM bar WHERE column1 = 'some_uid' AND column2 = 'another_uid' AND column3 = 1;
  87. """)
  88. def testEmptyStanza(self):
  89. f = StringIO('')
  90. s = parse_stanza(f)
  91. self.assert_(s is None)
  92. def testMissingStanzaEnd(self):
  93. f = StringIO("""\
  94. 1237237351.064861\t10.0.0.1:40784\t%s\tQueryResponse
  95. SELECT column1, column2 FROM table1 WHERE column3='foo'
  96. """ % TestSource)
  97. s = parse_stanza(f)
  98. self.assert_(s is not None)
  99. self.assertEqual(s.time, TimeStamp(1237237351.064861))
  100. self.assertEqual(s.id, '10.0.0.1:40784')
  101. self.assertEqual(s.state, 'QueryResponse')
  102. self.assertEqual(s.body, """\
  103. SELECT column1, column2 FROM table1 WHERE column3='foo'
  104. """)
  105. def testJunkLeadInStanza(self):
  106. f = StringIO("""\
  107. SELECT t1.column1, t2.column2, t1.column3 FROM table1 t1, table2 t2 WHERE t1.column4 = 'foo' AND t2.column5 = u.column6
  108. **************************************
  109. 1237237351.064861\t10.0.0.1:40784\t%s\tQueryResponse
  110. SELECT column1, column2 FROM table1 WHERE column3='foo'
  111. **************************************
  112. """ % TestSource)
  113. s = parse_stanza(f)
  114. self.assert_(s is not None)
  115. self.assertEqual(s.time, TimeStamp(1237237351.064861))
  116. self.assertEqual(s.id, '10.0.0.1:40784')
  117. self.assertEqual(s.state, 'QueryResponse')
  118. self.assertEqual(s.body, """\
  119. SELECT column1, column2 FROM table1 WHERE column3='foo'
  120. """)
  121. class TestSequence(unittest.TestCase):
  122. def testTime(self):
  123. seq = Sequence()
  124. seq.note(Event(10001.700, FakeJob, TestSource, 'QueryStart', 'SELECT'))
  125. seq.note(Event(10001.703, FakeJob, TestSource, 'QueryResult', 'SELECT'))
  126. seq.note(Event(10001.717, FakeJob, TestSource, 'Quit', 'Quit'))
  127. self.assertEqual(seq.count(), 3)
  128. self.assertEqual(seq.time(), TimeStamp(0.017))
  129. def testQuit(self):
  130. seq = Sequence()
  131. seq.note(Event(10001.700, FakeJob, TestSource, 'QueryStart', 'SELECT'))
  132. self.assert_(not seq.ended())
  133. seq.note(Event(10001.703, FakeJob, TestSource, 'QueryResult', 'SELECT'))
  134. self.assert_(not seq.ended())
  135. seq.note(Event(10001.717, FakeJob, TestSource, 'Quit', 'Quit'))
  136. self.assert_(seq.ended())
  137. def testGenerateEnd(self):
  138. seq = Sequence()
  139. seq.note(Event(10001.700, FakeJob, TestSource, 'QueryStart', 'SELECT'))
  140. seq.note(Event(10001.703, FakeJob, TestSource, 'QueryResult', 'SELECT'))
  141. self.assert_(not seq.ended())
  142. e = seq.generateEnd()
  143. self.assertEqual(e.time, TimeStamp(10001.703))
  144. self.assertEqual(e.id, FakeJob)
  145. self.assertEqual(e.state, 'Quit')
  146. def testTimeTo(self):
  147. seq = Sequence()
  148. e1 = Event(10001.700, FakeJob, TestSource, 'QueryStart', 'SELECT')
  149. e2 = Event(10001.717, FakeJob, TestSource, 'Quit', 'Quit')
  150. self.assert_(seq.timeto(e1) is None)
  151. seq.note(e1)
  152. self.assertEqual(seq.timeto(e1), TimeStamp(0))
  153. self.assertEqual(seq.timeto(e2), TimeStamp(0.017))
  154. class SimpleCoalesce(CoalesceSequences):
  155. def __init__(self):
  156. CoalesceSequences.__init__(self)
  157. self.sequences = []
  158. def fullSequence(self, e):
  159. self.sequences.append(e)
  160. class TestCoalesce(unittest.TestCase):
  161. def assertEvent(self, e, time, id, state, body=None):
  162. self.assertEqual(e.source, TestSource)
  163. if time is not None:
  164. if not isinstance(time, TimeStamp):
  165. time = TimeStamp(time)
  166. self.assertEqual(e.time, time)
  167. if id is not None:
  168. self.assertEqual(e.id, id)
  169. if state is not None:
  170. self.assertEqual(e.state, state)
  171. if body is not None:
  172. self.assertEqual(e.body, body)
  173. def testOne(self):
  174. c = CoalescedEvent()
  175. c.add(Event(10001.500, FakeJob, TestSource, 'QueryStart', 'SELECT "foo"'))
  176. c.add(Event(10001.600, FakeJob, TestSource, 'QueryStart', 'SELECT "bar"'))
  177. c.add(Event(10001.700, FakeJob, TestSource, 'Quit', 'Quit'))
  178. self.assertEvent(c, 10001.500, FakeJob, 'Sequence',
  179. '10001.500000:SELECT "foo"\n+++\n'
  180. '10001.600000:SELECT "bar"\n+++\n'
  181. '10001.700000:Quit\n+++\n')
  182. def testTwoSequential(self):
  183. l = []
  184. l.append(Event(10001.500, FakeJob, TestSource, 'QueryStart', 'SELECT "foo"'))
  185. l.append(Event(10001.600, FakeJob, TestSource, 'QueryStart', 'SELECT "bar"'))
  186. l.append(Event(10001.700, FakeJob, TestSource, 'Quit', 'Quit'))
  187. l.append(Event(10002.500, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "oof"'))
  188. l.append(Event(10002.600, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "rab"'))
  189. l.append(Event(10002.700, FakeJobs[0], TestSource, 'Quit', 'Quit'))
  190. sc = SimpleCoalesce()
  191. sc.replay(l)
  192. self.assertEqual(len(sc.sequences), 2)
  193. self.assertEvent(sc.sequences[0], 10001.500, FakeJob, 'Sequence',
  194. '10001.500000:SELECT "foo"\n+++\n'
  195. '10001.600000:SELECT "bar"\n+++\n'
  196. '10001.700000:Quit\n+++\n')
  197. self.assertEvent(sc.sequences[1], 10002.500, FakeJobs[0], 'Sequence',
  198. '10002.500000:SELECT "oof"\n+++\n'
  199. '10002.600000:SELECT "rab"\n+++\n'
  200. '10002.700000:Quit\n+++\n')
  201. def testTwoInterleaved(self):
  202. l = []
  203. l.append(Event(10001.500, FakeJob, TestSource, 'QueryStart', 'SELECT "foo"'))
  204. l.append(Event(10001.520, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "oof"'))
  205. l.append(Event(10001.600, FakeJob, TestSource, 'QueryStart', 'SELECT "bar"'))
  206. l.append(Event(10001.620, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "rab"'))
  207. l.append(Event(10001.700, FakeJob, TestSource, 'Quit', 'Quit'))
  208. l.append(Event(10001.720, FakeJobs[0], TestSource, 'Quit', 'Quit'))
  209. sc = SimpleCoalesce()
  210. sc.replay(l)
  211. self.assertEqual(len(sc.sequences), 2)
  212. self.assertEvent(sc.sequences[0], 10001.500, FakeJob, 'Sequence',
  213. '10001.500000:SELECT "foo"\n+++\n'
  214. '10001.600000:SELECT "bar"\n+++\n'
  215. '10001.700000:Quit\n+++\n')
  216. self.assertEvent(sc.sequences[1], 10001.520, FakeJobs[0], 'Sequence',
  217. '10001.520000:SELECT "oof"\n+++\n'
  218. '10001.620000:SELECT "rab"\n+++\n'
  219. '10001.720000:Quit\n+++\n')
  220. def testTwoNested(self):
  221. l = []
  222. l.append(Event(10001.500, FakeJob, TestSource, 'QueryStart', 'SELECT "foo"'))
  223. l.append(Event(10002.500, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "oof"'))
  224. l.append(Event(10002.600, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "rab"'))
  225. l.append(Event(10002.700, FakeJobs[0], TestSource, 'Quit', 'Quit'))
  226. l.append(Event(10003.600, FakeJob, TestSource, 'QueryStart', 'SELECT "bar"'))
  227. l.append(Event(10003.700, FakeJob, TestSource, 'Quit', 'Quit'))
  228. sc = SimpleCoalesce()
  229. sc.replay(l)
  230. self.assertEqual(len(sc.sequences), 2)
  231. self.assertEvent(sc.sequences[0], 10001.500, FakeJob, 'Sequence',
  232. '10001.500000:SELECT "foo"\n+++\n'
  233. '10003.600000:SELECT "bar"\n+++\n'
  234. '10003.700000:Quit\n+++\n')
  235. self.assertEvent(sc.sequences[1], 10002.500, FakeJobs[0], 'Sequence',
  236. '10002.500000:SELECT "oof"\n+++\n'
  237. '10002.600000:SELECT "rab"\n+++\n'
  238. '10002.700000:Quit\n+++\n')
  239. def testManyNested(self):
  240. l = []
  241. l.append(Event(10001.500, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "one"'))
  242. l.append(Event(10002.500, FakeJobs[1], TestSource, 'QueryStart', 'SELECT "two"'))
  243. l.append(Event(10002.700, FakeJobs[1], TestSource, 'Quit', 'Quit'))
  244. l.append(Event(10003.500, FakeJobs[2], TestSource, 'QueryStart', 'SELECT "three"'))
  245. l.append(Event(10003.700, FakeJobs[2], TestSource, 'Quit', 'Quit'))
  246. l.append(Event(10004.500, FakeJobs[3], TestSource, 'QueryStart', 'SELECT "four"'))
  247. l.append(Event(10004.700, FakeJobs[3], TestSource, 'Quit', 'Quit'))
  248. l.append(Event(10005.500, FakeJobs[4], TestSource, 'QueryStart', 'SELECT "five"'))
  249. l.append(Event(10005.700, FakeJobs[0], TestSource, 'Quit', 'Quit'))
  250. l.append(Event(10006.500, FakeJobs[5], TestSource, 'QueryStart', 'SELECT "six"'))
  251. l.append(Event(10006.700, FakeJobs[5], TestSource, 'Quit', 'Quit'))
  252. l.append(Event(10007.500, FakeJobs[6], TestSource, 'QueryStart', 'SELECT "seven"'))
  253. l.append(Event(10007.700, FakeJobs[6], TestSource, 'Quit', 'Quit'))
  254. l.append(Event(10008.500, FakeJobs[7], TestSource, 'QueryStart', 'SELECT "eight"'))
  255. l.append(Event(10008.700, FakeJobs[7], TestSource, 'Quit', 'Quit'))
  256. l.append(Event(10009.700, FakeJobs[4], TestSource, 'Quit', 'Quit'))
  257. sc = SimpleCoalesce()
  258. sc.replay(l)
  259. self.assertEqual(len(sc.sequences), 8)
  260. self.assertEqual(sc.sequences[0].id, FakeJobs[0])
  261. self.assertEqual(sc.sequences[1].id, FakeJobs[1])
  262. self.assertEqual(sc.sequences[2].id, FakeJobs[2])
  263. self.assertEqual(sc.sequences[3].id, FakeJobs[3])
  264. self.assertEqual(sc.sequences[4].id, FakeJobs[4])
  265. self.assertEqual(sc.sequences[5].id, FakeJobs[5])
  266. self.assertEqual(sc.sequences[6].id, FakeJobs[6])
  267. self.assertEqual(sc.sequences[7].id, FakeJobs[7])
  268. def testMissingEnd(self):
  269. l = []
  270. l.append(Event(10001.500, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "one"'))
  271. l.append(Event(10002.500, FakeJobs[1], TestSource, 'QueryStart', 'SELECT "two"'))
  272. l.append(Event(10002.700, FakeJobs[1], TestSource, 'Quit', 'Quit'))
  273. l.append(Event(10003.500, FakeJobs[2], TestSource, 'QueryStart', 'SELECT "three"'))
  274. sc = SimpleCoalesce()
  275. sc.replay(l)
  276. self.assertEqual(len(sc.sequences), 3)
  277. self.assertEqual(sc.sequences[0].id, FakeJobs[0])
  278. self.assertEqual(sc.sequences[1].id, FakeJobs[1])
  279. self.assertEqual(sc.sequences[2].id, FakeJobs[2])
  280. es = sc.sequences[0].events()
  281. self.assertEqual(len(es), 2)
  282. self.assertEvent(es[0], 10001.500, FakeJobs[0], Event.Query, 'SELECT "one"')
  283. self.assertEvent(es[1], 10001.500, FakeJobs[0], Event.End)
  284. es = sc.sequences[1].events()
  285. self.assertEqual(len(es), 2)
  286. self.assertEvent(es[0], 10002.500, FakeJobs[1], Event.Query, 'SELECT "two"')
  287. self.assertEvent(es[1], 10002.700, FakeJobs[1], Event.End)
  288. es = sc.sequences[2].events()
  289. self.assertEqual(len(es), 2)
  290. self.assertEvent(es[0], 10003.500, FakeJobs[2], Event.Query, 'SELECT "three"')
  291. self.assertEvent(es[1], 10003.500, FakeJobs[2], Event.End)
  292. def testSplitApart(self):
  293. c = CoalescedEvent()
  294. c.add(Event(10001.500, FakeJob, TestSource, 'QueryStart', 'SELECT "foo"'))
  295. c.add(Event(10001.600, FakeJob, TestSource, 'QueryStart', 'SELECT "bar"\n'))
  296. c.add(Event(10001.700, FakeJob, TestSource, 'QueryStart', '\nSELECT "baz"'))
  297. c.add(Event(10001.800, FakeJob, TestSource, 'Quit', 'Quit'))
  298. e = parse_stanza(StringIO(str(c)))
  299. self.assertEqual(e.id, FakeJob)
  300. self.assertEqual(e.state, CoalescedEvent.Sequence)
  301. es = e.events();
  302. self.assertEqual(len(es), 4)
  303. self.assertEvent(es[0], 10001.500, FakeJob, Event.Query, 'SELECT "foo"')
  304. self.assertEvent(es[1], 10001.600, FakeJob, Event.Query, 'SELECT "bar"\n')
  305. self.assertEvent(es[2], 10001.700, FakeJob, Event.Query, '\nSELECT "baz"')
  306. self.assertEvent(es[3], 10001.800, FakeJob, Event.End)
  307. if __name__ == '__main__':
  308. unittest.main()