PageRenderTime 136ms CodeModel.GetById 41ms app.highlight 75ms RepoModel.GetById 15ms app.codeStats 0ms

/test_apiary/sqllog.py

https://bitbucket.org/lindenlab/apiary/
Python | 361 lines | 330 code | 7 blank | 24 comment | 2 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
 26from StringIO import StringIO
 27import unittest
 28
 29from apiary.mysql.sqllog import *
 30from apiary.tools.timestamp import TimeStamp
 31    
 32
 33TestSource = 'unittest'
 34FakeJobs = [str(n) for n in range(111, 1000, 111)]
 35FakeJob = FakeJobs[-1]
 36
 37
 38class TestEvent(unittest.TestCase):
 39
 40    def testEventStr(self):
 41        e = Event(123456.789, FakeJobs[0], TestSource, 'QueryStart', 'SELECT * FROM foo')
 42        self.assertEqual(str(e), """\
 43123456.789000\t%s\t%s\tQueryStart
 44SELECT * FROM foo
 45**************************************
 46""" % (FakeJobs[0], TestSource))
 47
 48    def testOrdering(self):
 49        e1 = Event(10001.700, FakeJob, TestSource, 'QueryStart', 'SELECT')
 50        e2 = Event(10001.717, FakeJob, TestSource, 'QueryResponse', 'SELECT')
 51        e3 = Event(10001.717, FakeJob, TestSource, 'Quit', 'Quit')
 52        e4 = Event(10001.729, FakeJobs[0], TestSource, 'QueryStart', 'SELECT')
 53        
 54        self.assert_(e1 < e2)
 55        self.assert_(e1 < e3)
 56        self.assert_(e1 < e4)
 57        self.assert_(e2 < e3)
 58        self.assert_(e2 < e4)
 59        self.assert_(e3 < e4)
 60
 61
 62class TestParsing(unittest.TestCase):
 63
 64    def testSimpleStanza(self):
 65        f = StringIO("""\
 661237237351.064861\t10.0.0.1:40784\t%s\tQueryResponse
 67SELECT column1, column2 FROM some_table WHERE column1='foo'
 68**************************************
 691237237351.065393\t10.0.0.2:39706\t%s\tQueryStart
 70SELECT t1.column1, t2.column2, t1.column3  FROM table1 t1, table2 t2  WHERE t1.column1 = '00000000-0000-0000-0000-000000000000'  AND t2.column2 = t1.column4
 71**************************************
 72""" % (TestSource, TestSource))
 73        s = parse_stanza(f)
 74        self.assert_(s is not None)
 75        self.assertEqual(s.time, TimeStamp(1237237351.064861))
 76        self.assertEqual(s.id, '10.0.0.1:40784')
 77        self.assertEqual(s.state, 'QueryResponse')
 78        self.assertEqual(s.body, """\
 79SELECT column1, column2 FROM some_table WHERE column1='foo'
 80""")
 81
 82    def disabled_testMkQueryLogSyntax(self):
 83        f = StringIO("""\
 84# administrator command: Connect;
 85# Time: 091022 12:43:08.898136
 86# User@Host: user[user] @ 10.0.0.1 []
 87# Client: 10.0.0.1:40737
 88# Thread_id: 10000000
 89# Query_time: 0  Lock_time: 0  Rows_sent: 0  Rows_examined: 0
 90use some_table;
 91SELECT foo FROM bar WHERE column1 = 'some_uid' AND column2 = 'another_uid' AND column3 = 1;
 92""")
 93        s = parse_stanza(f)
 94        self.assert_(s is not None)
 95        self.assertEqual(s.time, TimeStamp(1256215388.898136))
 96        self.assertEqual(s.id, '10.0.0.1:40737:10000000')
 97        self.assertEqual(s.body, """\
 98use some_table;
 99SELECT foo FROM bar WHERE column1 = 'some_uid' AND column2 = 'another_uid' AND column3 = 1;
100""")
101
102    def testEmptyStanza(self):
103        f = StringIO('')
104        s = parse_stanza(f)
105        self.assert_(s is None)
106    
107    def testMissingStanzaEnd(self):
108        f = StringIO("""\
1091237237351.064861\t10.0.0.1:40784\t%s\tQueryResponse
110SELECT column1, column2 FROM table1 WHERE column3='foo'
111""" % TestSource)
112        s = parse_stanza(f)
113        self.assert_(s is not None)
114        self.assertEqual(s.time, TimeStamp(1237237351.064861))
115        self.assertEqual(s.id, '10.0.0.1:40784')
116        self.assertEqual(s.state, 'QueryResponse')
117        self.assertEqual(s.body, """\
118SELECT column1, column2 FROM table1 WHERE column3='foo'
119""")
120
121    def testJunkLeadInStanza(self):
122        f = StringIO("""\
123SELECT t1.column1, t2.column2, t1.column3 FROM table1 t1, table2 t2  WHERE t1.column4 = 'foo'  AND t2.column5 = u.column6
124**************************************
1251237237351.064861\t10.0.0.1:40784\t%s\tQueryResponse
126SELECT column1, column2 FROM table1 WHERE column3='foo'
127**************************************
128""" % TestSource)
129        s = parse_stanza(f)
130        self.assert_(s is not None)
131        self.assertEqual(s.time, TimeStamp(1237237351.064861))
132        self.assertEqual(s.id, '10.0.0.1:40784')
133        self.assertEqual(s.state, 'QueryResponse')
134        self.assertEqual(s.body, """\
135SELECT column1, column2 FROM table1 WHERE column3='foo'
136""")
137
138
139class TestSequence(unittest.TestCase):
140
141    def testTime(self):
142        seq = Sequence()
143        seq.note(Event(10001.700, FakeJob, TestSource, 'QueryStart', 'SELECT'))
144        seq.note(Event(10001.703, FakeJob, TestSource, 'QueryResult', 'SELECT'))
145        seq.note(Event(10001.717, FakeJob, TestSource, 'Quit', 'Quit'))
146        
147        self.assertEqual(seq.count(), 3)
148        self.assertEqual(seq.time(), TimeStamp(0.017))
149    
150    def testQuit(self):
151        seq = Sequence()
152        seq.note(Event(10001.700, FakeJob, TestSource, 'QueryStart', 'SELECT'))
153        self.assert_(not seq.ended())
154        seq.note(Event(10001.703, FakeJob, TestSource, 'QueryResult', 'SELECT'))
155        self.assert_(not seq.ended())
156        seq.note(Event(10001.717, FakeJob, TestSource, 'Quit', 'Quit'))
157        self.assert_(seq.ended())
158    
159    def testGenerateEnd(self):
160        seq = Sequence()
161        seq.note(Event(10001.700, FakeJob, TestSource, 'QueryStart', 'SELECT'))
162        seq.note(Event(10001.703, FakeJob, TestSource, 'QueryResult', 'SELECT'))
163        self.assert_(not seq.ended())
164        e = seq.generateEnd()
165        self.assertEqual(e.time, TimeStamp(10001.703))
166        self.assertEqual(e.id, FakeJob)
167        self.assertEqual(e.state, 'Quit')
168    
169    def testTimeTo(self):
170        seq = Sequence()
171        e1 = Event(10001.700, FakeJob, TestSource, 'QueryStart', 'SELECT')
172        e2 = Event(10001.717, FakeJob, TestSource, 'Quit', 'Quit')
173        
174        self.assert_(seq.timeto(e1) is None)
175        
176        seq.note(e1)
177        self.assertEqual(seq.timeto(e1), TimeStamp(0))
178        self.assertEqual(seq.timeto(e2), TimeStamp(0.017))
179        
180
181
182class SimpleCoalesce(CoalesceSequences):
183    def __init__(self):
184        CoalesceSequences.__init__(self)
185        self.sequences = []
186        
187    def fullSequence(self, e):
188        self.sequences.append(e)
189        
190class TestCoalesce(unittest.TestCase):
191
192    def assertEvent(self, e, time, id, state, body=None):
193        self.assertEqual(e.source, TestSource)
194        if time is not None:
195            if not isinstance(time, TimeStamp):
196                time = TimeStamp(time)
197            self.assertEqual(e.time, time)
198        if id is not None:
199            self.assertEqual(e.id, id)
200        if state is not None:
201            self.assertEqual(e.state, state)
202        if body is not None:
203            self.assertEqual(e.body, body)
204            
205    def testOne(self):
206        c = CoalescedEvent()
207        c.add(Event(10001.500, FakeJob, TestSource, 'QueryStart', 'SELECT "foo"'))
208        c.add(Event(10001.600, FakeJob, TestSource, 'QueryStart', 'SELECT "bar"'))
209        c.add(Event(10001.700, FakeJob, TestSource, 'Quit', 'Quit'))
210        
211        self.assertEvent(c, 10001.500, FakeJob, 'Sequence',
212            '10001.500000:SELECT "foo"\n+++\n'
213            '10001.600000:SELECT "bar"\n+++\n'
214            '10001.700000:Quit\n+++\n')
215
216    def testTwoSequential(self):
217        l = []
218        l.append(Event(10001.500, FakeJob, TestSource, 'QueryStart', 'SELECT "foo"'))
219        l.append(Event(10001.600, FakeJob, TestSource, 'QueryStart', 'SELECT "bar"'))
220        l.append(Event(10001.700, FakeJob, TestSource, 'Quit', 'Quit'))
221        l.append(Event(10002.500, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "oof"'))
222        l.append(Event(10002.600, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "rab"'))
223        l.append(Event(10002.700, FakeJobs[0], TestSource, 'Quit', 'Quit'))
224        
225        sc = SimpleCoalesce()
226        sc.replay(l)
227        
228        self.assertEqual(len(sc.sequences), 2)
229        self.assertEvent(sc.sequences[0], 10001.500, FakeJob, 'Sequence',
230            '10001.500000:SELECT "foo"\n+++\n'
231            '10001.600000:SELECT "bar"\n+++\n'
232            '10001.700000:Quit\n+++\n')
233        self.assertEvent(sc.sequences[1], 10002.500, FakeJobs[0], 'Sequence',
234            '10002.500000:SELECT "oof"\n+++\n'
235            '10002.600000:SELECT "rab"\n+++\n'
236            '10002.700000:Quit\n+++\n')
237        
238    def testTwoInterleaved(self):
239        l = []
240        l.append(Event(10001.500, FakeJob, TestSource, 'QueryStart', 'SELECT "foo"'))
241        l.append(Event(10001.520, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "oof"'))
242        l.append(Event(10001.600, FakeJob, TestSource, 'QueryStart', 'SELECT "bar"'))
243        l.append(Event(10001.620, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "rab"'))
244        l.append(Event(10001.700, FakeJob, TestSource, 'Quit', 'Quit'))
245        l.append(Event(10001.720, FakeJobs[0], TestSource, 'Quit', 'Quit'))
246        
247        sc = SimpleCoalesce()
248        sc.replay(l)
249        
250        self.assertEqual(len(sc.sequences), 2)
251        self.assertEvent(sc.sequences[0], 10001.500, FakeJob, 'Sequence',
252            '10001.500000:SELECT "foo"\n+++\n'
253            '10001.600000:SELECT "bar"\n+++\n'
254            '10001.700000:Quit\n+++\n')
255        self.assertEvent(sc.sequences[1], 10001.520, FakeJobs[0], 'Sequence',
256            '10001.520000:SELECT "oof"\n+++\n'
257            '10001.620000:SELECT "rab"\n+++\n'
258            '10001.720000:Quit\n+++\n')
259        
260    def testTwoNested(self):
261        l = []
262        l.append(Event(10001.500, FakeJob, TestSource, 'QueryStart', 'SELECT "foo"'))
263        l.append(Event(10002.500, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "oof"'))
264        l.append(Event(10002.600, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "rab"'))
265        l.append(Event(10002.700, FakeJobs[0], TestSource, 'Quit', 'Quit'))
266        l.append(Event(10003.600, FakeJob, TestSource, 'QueryStart', 'SELECT "bar"'))
267        l.append(Event(10003.700, FakeJob, TestSource, 'Quit', 'Quit'))
268        
269        sc = SimpleCoalesce()
270        sc.replay(l)
271        
272        self.assertEqual(len(sc.sequences), 2)
273        self.assertEvent(sc.sequences[0], 10001.500, FakeJob, 'Sequence',
274            '10001.500000:SELECT "foo"\n+++\n'
275            '10003.600000:SELECT "bar"\n+++\n'
276            '10003.700000:Quit\n+++\n')
277        self.assertEvent(sc.sequences[1], 10002.500, FakeJobs[0], 'Sequence',
278            '10002.500000:SELECT "oof"\n+++\n'
279            '10002.600000:SELECT "rab"\n+++\n'
280            '10002.700000:Quit\n+++\n')
281        
282    def testManyNested(self):
283        l = []
284        l.append(Event(10001.500, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "one"'))
285        l.append(Event(10002.500, FakeJobs[1], TestSource, 'QueryStart', 'SELECT "two"'))
286        l.append(Event(10002.700, FakeJobs[1], TestSource, 'Quit', 'Quit'))
287        l.append(Event(10003.500, FakeJobs[2], TestSource, 'QueryStart', 'SELECT "three"'))
288        l.append(Event(10003.700, FakeJobs[2], TestSource, 'Quit', 'Quit'))
289        l.append(Event(10004.500, FakeJobs[3], TestSource, 'QueryStart', 'SELECT "four"'))
290        l.append(Event(10004.700, FakeJobs[3], TestSource, 'Quit', 'Quit'))
291        l.append(Event(10005.500, FakeJobs[4], TestSource, 'QueryStart', 'SELECT "five"'))
292        l.append(Event(10005.700, FakeJobs[0], TestSource, 'Quit', 'Quit'))
293        l.append(Event(10006.500, FakeJobs[5], TestSource, 'QueryStart', 'SELECT "six"'))
294        l.append(Event(10006.700, FakeJobs[5], TestSource, 'Quit', 'Quit'))
295        l.append(Event(10007.500, FakeJobs[6], TestSource, 'QueryStart', 'SELECT "seven"'))
296        l.append(Event(10007.700, FakeJobs[6], TestSource, 'Quit', 'Quit'))
297        l.append(Event(10008.500, FakeJobs[7], TestSource, 'QueryStart', 'SELECT "eight"'))
298        l.append(Event(10008.700, FakeJobs[7], TestSource, 'Quit', 'Quit'))
299        l.append(Event(10009.700, FakeJobs[4], TestSource, 'Quit', 'Quit'))
300
301        sc = SimpleCoalesce()
302        sc.replay(l)
303
304        self.assertEqual(len(sc.sequences), 8)
305        self.assertEqual(sc.sequences[0].id, FakeJobs[0])
306        self.assertEqual(sc.sequences[1].id, FakeJobs[1])
307        self.assertEqual(sc.sequences[2].id, FakeJobs[2])
308        self.assertEqual(sc.sequences[3].id, FakeJobs[3])
309        self.assertEqual(sc.sequences[4].id, FakeJobs[4])
310        self.assertEqual(sc.sequences[5].id, FakeJobs[5])
311        self.assertEqual(sc.sequences[6].id, FakeJobs[6])
312        self.assertEqual(sc.sequences[7].id, FakeJobs[7])
313    
314    def testMissingEnd(self):
315        l = []
316        l.append(Event(10001.500, FakeJobs[0], TestSource, 'QueryStart', 'SELECT "one"'))
317        l.append(Event(10002.500, FakeJobs[1], TestSource, 'QueryStart', 'SELECT "two"'))
318        l.append(Event(10002.700, FakeJobs[1], TestSource, 'Quit', 'Quit'))
319        l.append(Event(10003.500, FakeJobs[2], TestSource, 'QueryStart', 'SELECT "three"'))
320    
321        sc = SimpleCoalesce()
322        sc.replay(l)
323        self.assertEqual(len(sc.sequences), 3)
324        self.assertEqual(sc.sequences[0].id, FakeJobs[0])
325        self.assertEqual(sc.sequences[1].id, FakeJobs[1])
326        self.assertEqual(sc.sequences[2].id, FakeJobs[2])
327
328        es = sc.sequences[0].events()
329        self.assertEqual(len(es), 2)
330        self.assertEvent(es[0], 10001.500, FakeJobs[0], Event.Query, 'SELECT "one"')
331        self.assertEvent(es[1], 10001.500, FakeJobs[0], Event.End)
332        es = sc.sequences[1].events()
333        self.assertEqual(len(es), 2)
334        self.assertEvent(es[0], 10002.500, FakeJobs[1], Event.Query, 'SELECT "two"')
335        self.assertEvent(es[1], 10002.700, FakeJobs[1], Event.End)
336        es = sc.sequences[2].events()
337        self.assertEqual(len(es), 2)
338        self.assertEvent(es[0], 10003.500, FakeJobs[2], Event.Query, 'SELECT "three"')
339        self.assertEvent(es[1], 10003.500, FakeJobs[2], Event.End)
340
341    def testSplitApart(self):
342        c = CoalescedEvent()
343        c.add(Event(10001.500, FakeJob, TestSource, 'QueryStart', 'SELECT "foo"'))
344        c.add(Event(10001.600, FakeJob, TestSource, 'QueryStart', 'SELECT "bar"\n'))
345        c.add(Event(10001.700, FakeJob, TestSource, 'QueryStart', '\nSELECT "baz"'))
346        c.add(Event(10001.800, FakeJob, TestSource, 'Quit', 'Quit'))
347        
348        e = parse_stanza(StringIO(str(c)))
349        self.assertEqual(e.id, FakeJob)
350        self.assertEqual(e.state, CoalescedEvent.Sequence)
351
352        es = e.events();
353        self.assertEqual(len(es), 4)
354        
355        self.assertEvent(es[0], 10001.500, FakeJob, Event.Query, 'SELECT "foo"')
356        self.assertEvent(es[1], 10001.600, FakeJob, Event.Query, 'SELECT "bar"\n')
357        self.assertEvent(es[2], 10001.700, FakeJob, Event.Query, '\nSELECT "baz"')
358        self.assertEvent(es[3], 10001.800, FakeJob, Event.End)
359
360if __name__ == '__main__':
361    unittest.main()