Attachment 'test_lightTracker.py'

Download

   1 #!/usr/bin/env python
   2 
   3 # Unit Test Suites for pyTracker Project
   4 #
   5 # Using standard unit test framework coming with Python
   6 # To execute the test cases, type:
   7 #    >>python test_pyTracker.py
   8 #
   9 # Written by Alex Dong ( alex.dong at gmail.com)
  10 
  11 
  12 
  13 import urllib2
  14 import unittest
  15 from bencode import bencode, bdecode
  16 from urllib import quote
  17 from models import peer_db
  18 import web as db
  19 from logger import logger
  20 logger = logger('TEST_TRACKER')
  21 
  22 '''
  23 ===== Section: Test Code Structure ==========
  24 1.  There will be two annouce and scrape server pairs to be tested. One will 
  25     be public available track server and the other one will be the 
  26     local pyTracker. 
  27 2.  Every test case will be executed twise. The first time executes against the
  28     public track server to make sure the test case design and implementation
  29     are correct. The second time against the local pyTracker server.
  30 3.  The test code has two layers: 
  31     1)  meta-instruction layer: This layer contains all the low-level 
  32         instructions to deal with tracker server. For example, 
  33         announce('start'), _status_assertions, etc.
  34     2)  test case layer: This layer will be built on top of the 
  35         meta-instruction layer and it contains the main test case 
  36         scenarios and assertions.
  37 '''
  38 def requestURL(url):
  39     fp  = urllib2.urlopen(url)
  40     r   = bdecode(fp.read())
  41     fp.close()
  42     return r
  43 
  44 # Global Constants. Used to build test cases.
  45 public_tracker_url = 'http://tracker.torrentbox.com:2710/'
  46 local_tracker_url  = 'http://127.0.0.1:8080/tracker/'
  47 target_tracker_url = local_tracker_url + "announce"
  48 target_scraper_url = local_tracker_url + "scrape"
  49 
  50 info_hash         = '839be8624144b3f993118240d9332d673bff7523'
  51 peer_id           = 'M4-20-2-e918a1127f32'
  52 port             = 6881
  53 size             = 93989333
  54 torrent_name      = 'Madonna - Confessions on a dance floor'
  55 
  56 
  57 class MetaInstruction(unittest.TestCase):
  58     def __init__(self, url, info_hash, size, peer_id=peer_id, port=port):
  59         self._url           = url
  60         self._info_hash     = info_hash.decode('hex')
  61         self._size          = size
  62         self._peer_id       = peer_id
  63         self._port          = port
  64 
  65     def status_assert(self, cur_status, expectation=None):
  66         (cur_complete, cur_incomplete) = cur_status
  67         
  68         if expectation: 
  69             if expectation['complete']=='down':
  70                 self.assert_(self._last_complete - 1 == cur_complete)
  71             elif expectation['complete']=='up':
  72                 self.assert_(self._last_complete + 1 == cur_complete)
  73             else:
  74                 self.assert_(self._last_complete == cur_complete)
  75                 
  76             if expectation['incomplete']=='down':
  77                 self.assert_(self._last_incomplete - 1 == cur_incomplete)
  78             elif expectation['incomplete']=='up':
  79                 self.assert_(self._last_incomplete + 1 == cur_incomplete)
  80             else:
  81                 self.assert_(self._last_incomplete == cur_incomplete)
  82             
  83         (self._last_complete, self._last_incomplete) = cur_status
  84     
  85     def scrape(self):
  86        r = requestURL("%s?info_hash=%s" % (target_scraper_url, quote(self._info_hash)))
  87        r = r['files'][self._info_hash]
  88        return (r['complete'], r['incomplete'])
  89 
  90     def announce(self, event, downloaded, uploaded, left):
  91         # Make URL
  92         url = "%s?info_hash=%s&peer_id=%s&compact=1&port=%s&event=%s&downloaded=%s&uploaded=%s&left=%s" % \
  93             (self._url, quote(self._info_hash), quote(self._peer_id), str(self._port), event, downloaded, uploaded, left)
  94         r = requestURL(url)
  95         return (r['complete'], r['incomplete'])
  96 
  97 
  98 class ExceptionalTestCases(unittest.TestCase):
  99     
 100     def _has_failure(self, url):
 101         r = requestURL(url)
 102         self.assert_(r['failure reason:'] != None)
 103         
 104     def testMissingInfoHash(self):
 105         self._has_failure("%s?peer_id=%s" % (target_tracker_url, peer_id))
 106         
 107     def testNonExistenceInfoHash(self):
 108         self._has_failure("%s?info_hash=839be8624144b3f993118240d9332d673bf32322&peer_id=%s&port=%s" %
 109             (target_tracker_url, peer_id, port))
 110         
 111     def testInvalidPort(self):
 112         self._has_failure("%s?info_hash=%s&peer_id=%s&port=68810976" % 
 113             (target_tracker_url, info_hash, peer_id))
 114         
 115     def testInvalidEVent(self):
 116         self._has_failure("%s?info_hash=%s&peer_id=%s&port=%s&event=Unknown" % 
 117             (target_tracker_url, info_hash, peer_id, port))
 118     
 119     def testInvalidLeftAndEvent(self):
 120         self._has_failure("%s?info_hash=%s&peer_id=%s&port=%s&event=Completed&left=25" % 
 121             (target_tracker_url, info_hash, peer_id, port))
 122     
 123         
 124 class MultipleClientsDownloadMultipleTorrentsTestCases(unittest.TestCase):
 125     def setUp(self):
 126         self._ut_tor_1 = MetaInstruction(target_tracker_url, '101c9d63211c3c570ffbadd49c5649d3fb497273',93989333, "UT000000000000000001", 21056)
 127         self._ut_tor_2 = MetaInstruction(target_tracker_url, '09bb5bb38283e111a5b830243525659e077d7f24',93989333, "UT000000000000000001", 21056)
 128         self._ml_tor_1 = MetaInstruction(target_tracker_url, '101c9d63211c3c570ffbadd49c5649d3fb497273', 93989333, "Mainline000000000001", 61099)
 129         self._ml_tor_2 = MetaInstruction(target_tracker_url, '09bb5bb38283e111a5b830243525659e077d7f24', 93989333, "Mainline000000000001", 61099)
 130         peer_db.truncate()
 131 
 132     def testOneClientMultipleTorrent(self):
 133         pass
 134 
 135     def testTwoClientsOneTorrent(self):
 136         """'Mainline' seeding and 'UT' downloading"""
 137         self._ml_tor_1.status_assert(self._ml_tor_1.announce('started', 93989333, 93989333, 0))
 138         self._ml_tor_1.status_assert(self._ut_tor_1.announce('started', 93989333, 2342, 234231), {'complete':'equal', 'incomplete':'up'})
 139         self._ml_tor_1.status_assert(self._ut_tor_1.announce('completed', 93989333, 93989333, 0), {'complete':'up', 'incomplete':'down'})
 140 
 141     def testTwoClientsReceiveCorrectLocationInfo(self):
 142         pass
 143 
 144 class OneClientDownloadsMultipleTorrentsTestCases(unittest.TestCase):        
 145     def setUp(self):
 146         self._mi_1 = MetaInstruction(target_tracker_url, '101c9d63211c3c570ffbadd49c5649d3fb497273',93989333)
 147         self._mi_2 = MetaInstruction(target_tracker_url, '09bb5bb38283e111a5b830243525659e077d7f24', 93989333)
 148 
 149     def testTwoTorrentsAtSameOrder(self):
 150         self._mi_1.status_assert(self._mi_1.announce('started', 93989333, 93989333, 0))
 151         self._mi_2.status_assert(self._mi_2.announce('started', 93989333, 93989333, 0))
 152         self._mi_2.status_assert(self._mi_2.announce('stopped', 93989333, 93989333, 0), {'complete':'down', 'incomplete':'equal'})
 153         self._mi_1.status_assert(self._mi_1.announce('stopped', 93989333, 93989333, 0), {'complete':'down', 'incomplete':'equal'})
 154 
 155     def testTwoTorrentsRequests(self):
 156         self._mi_1.status_assert(self._mi_1.announce('started', 93989333, 93989333, 0))
 157         self._mi_2.status_assert(self._mi_2.announce('started', 93989333, 93989333, 0))
 158         self._mi_2.status_assert(self._mi_2.announce('stopped', 93989333, 93989333, 0), {'complete':'down', 'incomplete':'equal'})
 159         self._mi_1.status_assert(self._mi_1.announce('stopped', 93989333, 93989333, 0), {'complete':'down', 'incomplete':'equal'})
 160 
 161     def testTwoTorrentsRandomOrder(self):
 162         self._mi_1.status_assert(self._mi_1.announce('started', 93989333, 93989333, 233345))        
 163         self._mi_1.status_assert(self._mi_1.announce('completed', 93989333, 93989333, 0), {'complete':'up', 'incomplete':'down'})
 164 
 165         self._mi_2.status_assert(self._mi_2.announce('started', 93989333, 93989333, 334234))        
 166         self._mi_2.status_assert(self._mi_2.announce('stopped', 93989333, 93989333, 0), {'complete':'equal', 'incomplete':'down'})
 167         self._mi_2.status_assert(self._mi_2.announce('started', 93989333, 93989333, 234234), {'complete':'equal', 'incomplete':'up'})
 168 
 169         self._mi_1.status_assert(self._mi_1.announce('completed', 93989333, 93989333, 0), {'complete':'equal', 'incomplete':'equal'})
 170         self._mi_1.status_assert(self._mi_1.announce('stopped', 93989333, 93989333, 0), {'complete':'down', 'incomplete':'equal'})
 171 
 172         self._mi_2.status_assert(self._mi_2.announce('completed', 93989333, 93989333, 0), {'complete':'up', 'incomplete':'down'})
 173         self._mi_2.status_assert(self._mi_2.announce('stopped', 93989333, 93989333, 0), {'complete':'down', 'incomplete':'equal'})
 174     
 175 class SmokeTestCases(unittest.TestCase):    
 176     def setUp(self):
 177         self._url = target_tracker_url
 178         self._info_hash = info_hash
 179         self._size = size
 180         self._torrent_name = torrent_name
 181         self._mi = MetaInstruction(self._url, self._info_hash, self._size)
 182         peer_db.truncate()
 183 
 184     def testInitialIncompleteStartup(self):
 185         init = self._mi.scrape()
 186         curr = self._mi.announce('started', 93989333, 93989333, 333)
 187         self.assert_(init[0]==curr[0])
 188         self.assert_(init[1]+1==curr[1])
 189 
 190     def testInitialCompleteStartup(self):
 191         init = self._mi.scrape()
 192         curr = self._mi.announce('started', 93989333, 93989333, 0)
 193         self.assert_(init[0]+1==curr[0])          # complete
 194         self.assert_(init[1]==curr[1])        # incomplete
 195 
 196     def testInitialSeeding(self):
 197         self._mi.status_assert(self._mi.announce('started', 93989333, 93989333, 0))
 198         self._mi.status_assert(self._mi.announce('stopped', 93989333, 93989333, 0), {'complete':'down', 'incomplete':'equal'})                
 199                     
 200     def testDownloaderRequests(self):
 201         self._mi.status_assert(self._mi.announce('started', 93989333, 93989333, 32424))        
 202         self._mi.status_assert(self._mi.announce('started', 93989333, 93989333, 322), {'complete':'equal', 'incomplete':'equal'})
 203         
 204     def testDuplicatedCompeteRequests(self):
 205         self._mi.status_assert(self._mi.announce('started', 93989333, 93989333, 32424))        
 206         self._mi.status_assert(self._mi.announce('completed', 93989333, 93989333, 0), {'complete':'up', 'incomplete':'down'})
 207         self._mi.status_assert(self._mi.announce('completed', 93989333, 93989333, 0), {'complete':'equal', 'incomplete':'equal'})
 208         self._mi.status_assert(self._mi.announce('stopped', 93989333, 93989333, 0), {'complete':'down', 'incomplete':'equal'})                
 209         
 210     def testDuplicatedStartedRequests(self):
 211         self._mi.status_assert(self._mi.announce('started', 93989333, 93989333, 0))        
 212         self._mi.status_assert(self._mi.announce('started', 93989333, 93989333, 0), {'complete':'equal', 'incomplete':'equal'})
 213         self._mi.status_assert(self._mi.announce('started', 93989333, 93989333, 0), {'complete':'equal', 'incomplete':'equal'})  
 214         self._mi.status_assert(self._mi.announce('stopped', 93989333, 93989333, 0), {'complete':'down', 'incomplete':'equal'})  
 215         
 216     def testDuplicatedStoppedRequests(self):
 217         self._mi.status_assert(self._mi.announce('started', 93989333, 93989333, 23420))        
 218         self._mi.status_assert(self._mi.announce('stopped', 93989333, 93989333, 2342), {'complete':'equal', 'incomplete':'down'})
 219         self._mi.status_assert(self._mi.announce('stopped', 93989333, 93989333, 2342), {'complete':'equal', 'incomplete':'equal'})
 220         
 221     def testResumeWorkflow(self):
 222         self._mi.status_assert(self._mi.announce('started', 93989333, 93989333, 234320))        
 223         self._mi.status_assert(self._mi.announce('stopped', 93989333, 93989333, 234230), {'complete':'equal', 'incomplete':'down'}) 
 224         self._mi.status_assert(self._mi.announce('started', 93989333, 93989333, 234230), {'complete':'equal', 'incomplete':'up'})  
 225         self._mi.status_assert(self._mi.announce('completed', 93989333, 93989333, 0), {'complete':'up', 'incomplete':'down'})    
 226         self._mi.status_assert(self._mi.announce('stopped', 93989333, 93989333, 0), {'complete':'down', 'incomplete':'equal'})
 227     
 228     def testNormalWorkflow(self):
 229         self._mi.status_assert(self._mi.announce('started', 93989333, 93989333, 234230))        
 230         self._mi.status_assert(self._mi.announce('completed', 93989333, 93989333, 0), {'complete':'up', 'incomplete':'down'})
 231         self._mi.status_assert(self._mi.announce('stopped', 93989333, 93989333, 0), {'complete':'down', 'incomplete':'equal'})
 232 
 233 if __name__ == '__main__':
 234     db.db_parameters = dict(dbn='mysql', user='root', pw='root', db='bitspace')
 235     db.load()
 236     unittest.main()

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2021-05-11 08:51:49, 18.9 KB) [[attachment:lightTracker.py]]
  • [get | view] (2021-05-11 08:51:49, 12.2 KB) [[attachment:test_lightTracker.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.