2 # -*- coding: utf-8 -*-
4 # Copyright 2010-2011, Carl Gherardi
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ########################################################################
33 pp
= pprint
.PrettyPrinter(indent
=4)
39 def __init__(self
, sitename
):
45 def error_report(self
, filename
, hand
, stat
, ghash
, testhash
, player
):
46 print "Regression Test Error:"
47 print "\tFile: %s" % filename
48 print "\tStat: %s" % stat
49 print "\tPlayer: %s" % player
50 if filename
in self
.histogram
:
51 self
.histogram
[filename
] += 1
53 self
.histogram
[filename
] = 1
55 if stat
in self
.statcount
:
56 self
.statcount
[stat
] += 1
58 self
.statcount
[stat
] = 1
61 def print_histogram(self
):
62 print "%s:" % self
.site
63 for f
in self
.histogram
:
64 idx
= f
.find('regression')
65 print "(%3d) : %s" %(self
.histogram
[f
], f
[idx
:])
67 def compare_gametypes_file(filename
, importer
, errors
):
68 hashfilename
= filename
+ '.gt'
70 in_fh
= codecs
.open(hashfilename
, 'r', 'utf8')
71 whole_file
= in_fh
.read()
74 testhash
= eval(whole_file
)
76 hhc
= importer
.getCachedHHC()
77 handlist
= hhc
.getProcessedHands()
81 1:'Gametype: currency',
87 7:'Gametype: Small Blind',
88 8:'Gametype: Big Blind',
89 9:'Gametype: Small Bet',
90 10:'Gametype: Big Bet',
91 11:'Gametype: maxSeats',
96 ghash
= hand
.gametyperow
97 for i
in range(len(ghash
)):
98 #print "DEBUG: about to compare: '%s' and '%s'" %(ghash[i], testhash[i])
99 if ghash
[i
] == testhash
[i
]:
100 # The stats match - continue
103 errors
.error_report(filename
, hand
, lookup
[i
], ghash
, testhash
, None)
106 def compare_handsplayers_file(filename
, importer
, errors
):
107 hashfilename
= filename
+ '.hp'
109 in_fh
= codecs
.open(hashfilename
, 'r', 'utf8')
110 whole_file
= in_fh
.read()
113 testhash
= eval(whole_file
)
115 hhc
= importer
.getCachedHHC()
116 handlist
= hhc
.getProcessedHands()
117 #We _really_ only want to deal with a single hand here.
118 for hand
in handlist
:
119 ghash
= hand
.stats
.getHandsPlayers()
121 #print "DEBUG: player: '%s'" % p
123 teststat
= testhash
[p
]
126 #print "pstat[%s][%s]: %s == %s" % (p, stat, pstat[stat], teststat[stat])
128 if pstat
[stat
] == teststat
[stat
]:
129 # The stats match - continue
132 if stat
== 'tourneyTypeId' or stat
== 'tourneysPlayersIds' or stat
== 'showed':
136 errors
.error_report(filename
, hand
, stat
, ghash
, testhash
, p
)
138 errors
.error_report(filename
, False, "KeyError: '%s'" % stat
, False, False, p
)
140 def compare_hands_file(filename
, importer
, errors
):
141 hashfilename
= filename
+ '.hands'
143 in_fh
= codecs
.open(hashfilename
, 'r', 'utf8')
144 whole_file
= in_fh
.read()
147 testhash
= eval(whole_file
)
149 hhc
= importer
.getCachedHHC()
150 handlist
= hhc
.getProcessedHands()
152 for hand
in handlist
:
153 ghash
= hand
.stats
.getHands()
154 # Delete unused data from hash
163 #print "DEBUG: hand: '%s'" % datum
165 if ghash
[datum
] == testhash
[datum
]:
166 # The stats match - continue
170 if (datum
== "gametypeId"
171 or datum
== 'sessionId'
172 or datum
== 'tourneyId'
173 or datum
== 'gameSessionId'
175 or datum
== 'runItTwice'):
176 # Not an error. gametypeIds are dependent on the order added to the db.
177 #print "DEBUG: Skipping mismatched gamtypeId"
180 errors
.error_report(filename
, hand
, datum
, ghash
, testhash
, None)
182 errors
.error_report(filename
, False, "KeyError: '%s'" % datum
, False, False, None)
185 def compare(leaf
, importer
, errors
, site
):
187 #print "DEBUG: fileanme: %s" % filename
189 # Test if this is a hand history file
190 if filename
.endswith('.txt'):
191 # test if there is a .hp version of the file
192 if DEBUG
: print "Site: %s" % site
193 if DEBUG
: print "Filename: %s" % filename
194 importer
.addBulkImportImportFileOrDir(filename
, site
=site
)
195 (stored
, dups
, partial
, errs
, ttime
) = importer
.runImport()
198 errors
.error_report(filename
, False, "Parse", False, False, False)
200 if os
.path
.isfile(filename
+ '.hp'):
201 compare_handsplayers_file(filename
, importer
, errors
)
202 if os
.path
.isfile(filename
+ '.hands'):
203 compare_hands_file(filename
, importer
, errors
)
204 if os
.path
.isfile(filename
+ '.gt'):
205 compare_gametypes_file(filename
, importer
, errors
)
207 importer
.clearFileList()
211 def walk_testfiles(dir, function
, importer
, errors
, site
):
212 """Walks a directory, and executes a callback on each file """
213 dir = os
.path
.abspath(dir)
215 for file in [file for file in os
.listdir(dir) if not file in [".",".."]]:
216 nfile
= os
.path
.join(dir,file)
217 if os
.path
.isdir(nfile
):
218 walk_testfiles(nfile
, compare
, importer
, errors
, site
)
220 function(nfile
, importer
, errors
, site
)
221 except OSError as (errno
, strerror
):
223 # Error 20 is 'not a directory'
224 function(dir, importer
, errors
, site
)
226 raise OSError(errno
, strerror
)
230 print "Run all tests:"
231 print "\t./TestHandsPlayers.py"
232 print "Run tests for a sinlge site:"
233 print "\t./TestHandsPlayers -s <Sitename>"
234 print "Run tests for a sinlge file in a site:"
235 print "\t./TestHandsPlayers -s <Sitename> -f <filename>"
242 (options
, argv
) = Options
.fpdb_options()
244 test_all_sites
= True
246 if options
.usage
== True:
249 single_file_test
= False
252 options
.sitename
= Options
.site_alias(options
.sitename
)
253 if options
.sitename
== False:
256 print "Testing single hand: '%s'" % options
.filename
257 single_file_test
= True
259 print "Only regression testing '%s' files" % (options
.sitename
)
260 test_all_sites
= False
262 config
= Configuration
.Config(file = "HUD_config.test.xml")
263 db
= Database
.Database(config
)
264 sql
= SQL
.Sql(db_server
= 'sqlite')
266 settings
.update(config
.get_db_parameters())
267 settings
.update(config
.get_import_parameters())
268 settings
.update(config
.get_default_paths())
270 importer
= fpdb_import
.Importer(False, settings
, config
, None)
271 importer
.setDropIndexes("don't drop")
272 importer
.setFailOnError(True)
273 importer
.setThreads(-1)
274 importer
.setCallHud(False)
275 importer
.setFakeCacheHHC(True)
277 PacificPokerErrors
= FpdbError('PacificPoker')
278 PokerStarsErrors
= FpdbError('PokerStars')
279 FTPErrors
= FpdbError('Full Tilt Poker')
280 PartyPokerErrors
= FpdbError('Party Poker')
281 BetfairErrors
= FpdbError('Betfair')
282 OnGameErrors
= FpdbError('OnGame')
283 AbsoluteErrors
= FpdbError('Absolute Poker')
284 UltimateBetErrors
= FpdbError('Ultimate Bet')
285 EverleafErrors
= FpdbError('Everleaf Poker')
286 EverestErrors
= FpdbError('Everest Poker')
287 CarbonErrors
= FpdbError('Carbon')
288 PKRErrors
= FpdbError('PKR')
289 iPokerErrors
= FpdbError('iPoker')
290 Win2dayErrors
= FpdbError('Win2day')
291 WinamaxErrors
= FpdbError('Winamax')
294 PacificPokerErrors
, PokerStarsErrors
, FTPErrors
, PartyPokerErrors
,
295 BetfairErrors
, OnGameErrors
, AbsoluteErrors
,
296 EverleafErrors
, CarbonErrors
, PKRErrors
,
297 iPokerErrors
, WinamaxErrors
, UltimateBetErrors
,
298 Win2dayErrors
, EverestErrors
,
302 'PacificPoker' : False,
303 'PokerStars' : False,
304 'Full Tilt Poker' : False,
305 'PartyPoker' : False,
309 'UltimateBet' : False,
319 if test_all_sites
== True:
323 sites
[options
.sitename
] = True
325 if sites
['PacificPoker'] == True and not single_file_test
:
326 walk_testfiles("regression-test-files/cash/PacificPoker/", compare
, importer
, PacificPokerErrors
, "PacificPoker")
327 elif sites
['PacificPoker'] == True and single_file_test
:
328 walk_testfiles(options
.filename
, compare
, importer
, PacificPokerErrors
, "PacificPoker")
330 if sites
['PokerStars'] == True and not single_file_test
:
331 walk_testfiles("regression-test-files/cash/Stars/", compare
, importer
, PokerStarsErrors
, "PokerStars")
332 walk_testfiles("regression-test-files/tour/Stars/", compare
, importer
, PokerStarsErrors
, "PokerStars")
333 elif sites
['PokerStars'] == True and single_file_test
:
334 walk_testfiles(options
.filename
, compare
, importer
, PokerStarsErrors
, "PokerStars")
336 if sites
['Full Tilt Poker'] == True and not single_file_test
:
337 walk_testfiles("regression-test-files/cash/FTP/", compare
, importer
, FTPErrors
, "Full Tilt Poker")
338 walk_testfiles("regression-test-files/tour/FTP/", compare
, importer
, FTPErrors
, "Full Tilt Poker")
339 elif sites
['Full Tilt Poker'] == True and single_file_test
:
340 walk_testfiles(options
.filename
, compare
, importer
, FTPErrors
, "Full Tilt Poker")
341 if sites
['PartyPoker'] == True and not single_file_test
:
342 walk_testfiles("regression-test-files/cash/PartyPoker/", compare
, importer
, PartyPokerErrors
, "PartyPoker")
343 walk_testfiles("regression-test-files/tour/PartyPoker/", compare
, importer
, PartyPokerErrors
, "PartyPoker")
344 elif sites
['PartyPoker'] == True and single_file_test
:
345 walk_testfiles(options
.filename
, compare
, importer
, PartyPokerErrors
, "PartyPoker")
346 if sites
['Betfair'] == True and not single_file_test
:
347 walk_testfiles("regression-test-files/cash/Betfair/", compare
, importer
, BetfairErrors
, "Betfair")
348 elif sites
['Betfair'] == True and single_file_test
:
349 walk_testfiles(options
.filename
, compare
, importer
, BetfairErrors
, "Betfair")
350 if sites
['OnGame'] == True and not single_file_test
:
351 walk_testfiles("regression-test-files/cash/OnGame/", compare
, importer
, OnGameErrors
, "OnGame")
352 walk_testfiles("regression-test-files/tour/ongame/", compare
, importer
, OnGameErrors
, "OnGame")
353 elif sites
['OnGame'] == True and single_file_test
:
354 walk_testfiles(options
.filename
, compare
, importer
, OnGameErrors
, "OnGame")
355 if sites
['Absolute'] == True and not single_file_test
:
356 walk_testfiles("regression-test-files/cash/Absolute/", compare
, importer
, AbsoluteErrors
, "Absolute")
357 walk_testfiles("regression-test-files/tour/Absolute/", compare
, importer
, AbsoluteErrors
, "Absolute")
358 elif sites
['Absolute'] == True and single_file_test
:
359 walk_testfiles(options
.filename
, compare
, importer
, AbsoluteErrors
, "Absolute")
360 if sites
['UltimateBet'] == True and not single_file_test
:
361 walk_testfiles("regression-test-files/cash/UltimateBet/", compare
, importer
, UltimateBetErrors
, "Absolute")
362 elif sites
['UltimateBet'] == True and single_file_test
:
363 walk_testfiles(options
.filename
, compare
, importer
, UltimateBetErrors
, "Absolute")
364 if sites
['Everleaf'] == True and not single_file_test
:
365 walk_testfiles("regression-test-files/cash/Everleaf/", compare
, importer
, EverleafErrors
, "Everleaf")
366 walk_testfiles("regression-test-files/tour/Everleaf/", compare
, importer
, EverleafErrors
, "Everleaf")
367 elif sites
['Everleaf'] == True and single_file_test
:
368 walk_testfiles(options
.filename
, compare
, importer
, EverleafErrors
, "Everleaf")
369 if sites
['Everest'] == True and not single_file_test
:
370 walk_testfiles("regression-test-files/cash/Everest/", compare
, importer
, EverestErrors
, "Everest")
371 elif sites
['Everest'] == True and single_file_test
:
372 walk_testfiles(options
.filename
, compare
, importer
, EverestErrors
, "Everest")
373 if sites
['Carbon'] == True and not single_file_test
:
374 walk_testfiles("regression-test-files/cash/Carbon/", compare
, importer
, CarbonErrors
, "Carbon")
375 elif sites
['Carbon'] == True and single_file_test
:
376 walk_testfiles(options
.filename
, compare
, importer
, CarbonErrors
, "Carbon")
377 #if sites['PKR'] == True and not single_file_test:
378 # walk_testfiles("regression-test-files/cash/PKR/", compare, importer, PKRErrors, "PKR")
379 if sites
['iPoker'] == True and not single_file_test
:
380 walk_testfiles("regression-test-files/cash/iPoker/", compare
, importer
, iPokerErrors
, "iPoker")
381 elif sites
['iPoker'] == True and single_file_test
:
382 walk_testfiles(options
.filename
, compare
, importer
, iPokerErrors
, "iPoker")
383 if sites
['Winamax'] == True and not single_file_test
:
384 walk_testfiles("regression-test-files/cash/Winamax/", compare
, importer
, WinamaxErrors
, "Winamax")
385 walk_testfiles("regression-test-files/tour/Winamax/", compare
, importer
, WinamaxErrors
, "Winamax")
386 elif sites
['Winamax'] == True and single_file_test
:
387 walk_testfiles(options
.filename
, compare
, importer
, WinamaxErrors
, "Winamax")
388 if sites
['Win2day'] == True and not single_file_test
:
389 walk_testfiles("regression-test-files/cash/Win2day/", compare
, importer
, Win2dayErrors
, "Win2day")
390 elif sites
['Win2day'] == True and single_file_test
:
391 walk_testfiles(options
.filename
, compare
, importer
, Win2dayErrors
, "Win2day")
395 for i
, site
in enumerate(ErrorsList
):
396 totalerrors
+= ErrorsList
[i
].errorcount
398 for i
, site
in enumerate(ErrorsList
):
399 ErrorsList
[i
].print_histogram()
401 # Merge the dicts of stats from the various error objects
403 for i
, site
in enumerate(ErrorsList
):
404 tmp
= ErrorsList
[i
].statcount
407 statdict
[stat
] += tmp
[stat
]
409 statdict
[stat
] = tmp
[stat
]
412 print "---------------------"
413 print "Errors by stat:"
414 print "---------------------"
415 #for stat in statdict:
416 # print "(%3d) : %s" %(statdict[stat], stat)
418 sortedstats
= sorted([(value
,key
) for (key
,value
) in statdict
.items()])
419 for num
, stat
in sortedstats
:
420 print "(%3d) : %s" %(num
, stat
)
422 print "---------------------"
423 print "Total Errors: %d" % totalerrors
424 print "---------------------"
426 if __name__
== '__main__':