"""Tests to see if bufmgr is working correctly. These tests originally came from the U. Wisconsin-Madison Minibase project, which I ported to Java, which I then ported to Python. Note that these tests running to completion does not indicate that your code is correct: you've got to get the output right.""" import bufmgr import utils import array NUMBUF = 20 class TestException(Exception): pass def test1(bufMgr, filename): """Testing pinPage, unpinPage, and whether a dirty page is written to disk""" first = 5 last = first + bufMgr.poolSize() + 5 # Allocate some pages (startId, startPage) = bufMgr.newPage(last+10,filename) bufMgr.unpinPage(startId,filename,False) print "------- Test 1 -------" for i in range(first,last+1): page = bufMgr.pinPage(i,filename) if page == None: raise TestException("Unable to pin page 1st time") print "after pinPage", i data = array.array('c', "This is test 1 for page " + str(i)) page[0:len(data)] = data[:] bufMgr.unpinPage(i,filename,True) print "after unpinPage",i print for i in range(first,last+1): page = bufMgr.pinPage(i,filename) if page == None: raise TestException("Unable to pin page 2nd time") readBack = page.tostring() orig = "This is test 1 for page " + str(i) print "PAGE[", i, "]:", readBack[0:len(orig)] if readBack[0:len(orig)] != orig: raise TestException("Page content incorrect") bufMgr.unpinPage(i,filename,False) def test2(bufMgr, filename): """Testing replacement policy""" print "------- Test 2 -------" # Allocate some pages (startId, startPage) = bufMgr.newPage(5*bufMgr.poolSize(),filename) bufMgr.unpinPage(startId,filename,False) # Pin and unpin a series of pages, the first half are loved, the # latter half are hated. # Pin all pages in the buffer and unpin them in reverse order # Clock will behave as MRU in that case frame = [None]*bufMgr.poolSize() for i in range(bufMgr.poolSize()): page = bufMgr.pinPage(i+5,filename) if page == None: raise TestException("Unable to pin page") frame[i] = bufMgr.findFrame(i+5,filename) if frame[i] < 0 or frame[i] >= bufMgr.poolSize(): raise TestException("Invalid frame returned") print "Page", i+5, "at frame", frame[i], "is pinned." # Try pinning an extra page page = bufMgr.pinPage(bufMgr.poolSize()+6,filename) if page != None: raise TestException("Pinned page in full buffer") # Start unpinning pages for i in range(bufMgr.poolSize()-1, -1 ,-1): bufMgr.unpinPage(i+5,filename,True) print "Page", i+5, "at frame", frame[i], "is unpinned." # Start pinning a new set of pages again. The page frames should # be exactly the same order as the previous one Clock in that case # will resemble MRU for i in range(bufMgr.poolSize(), 2*bufMgr.poolSize()): page = bufMgr.pinPage(i+5,filename) if page == None: raise TestException("Unable to pin page") spot = bufMgr.findFrame(i+5,filename) print "Page", i+5, "pinned in frame", spot if spot != frame[i-bufMgr.poolSize()]: raise TestException("Frame number incorrect") # Unpin half the pages in order for i in range(bufMgr.poolSize(), 2*bufMgr.poolSize(), 2): bufMgr.unpinPage(i+5,filename,True) print "Page", i+5, "at frame", frame[i-bufMgr.poolSize()], \ "is unpinned." # Now, pin a new set of pages # Again, it should resemble the previous sequence # In this case, Clock behaves as LRU for i in range(2*bufMgr.poolSize(), 3*bufMgr.poolSize(), 2): page = bufMgr.pinPage(i+5,filename) if page == None: raise TestException("Unable to pin page") spot = bufMgr.findFrame(i+5,filename) bufMgr.unpinPage(i+5,filename,True) bufMgr.unpinPage(i-bufMgr.poolSize()+6,filename,True) print "Page", i+5, "pinned in frame", spot if spot != frame[i-2*bufMgr.poolSize()]: raise TestException("Frame number incorrect") def test3(bufMgr,filename): """Testing newPage,pinPage, freePage, error protocol""" print "------- Test 3 -------" pageIds = [0]*30 pages = [None]*30 # Allocate 10 pages from database for i in range(10): pair = bufMgr.newPage(1,filename) if pair == None: raise TestException("newPage failed") (pageIds[i],pages[i]) = pair # Pin first 10 pages a second time for i in range(10): print "Pinning page", i, pageIds[i] page = bufMgr.pinPage(pageIds[i],filename) if page == None: raise TestException("Unable to pin page") # Yes, this is checking pointers: after pinning once # (with newPage), and pinning again, pointers should be the # same if page is not pages[i]: raise TestException("Pinning error 2nd time") # Try to free pinned pages for i in range(5,10): print "Freeing page", pageIds[i] succeeded = True try: bufMgr.freePage(pageIds[i],filename) except bufmgr.PagePinnedException: succeeded = False; if succeeded: raise TestException("Pinned page freed") # Now free page 0 thru 9 by first unpinning each page twice for i in range(10): bufMgr.unpinPage(pageIds[i],filename,False) bufMgr.unpinPage(pageIds[i],filename,False) bufMgr.freePage(pageIds[i],filename) print "Freed page", pageIds[i] # Get 14 more pages for i in range(10,24): pair = bufMgr.newPage(1,filename) if pair == None: raise TestException("newPage failed") print "new page", i, ",", pair[0] def test4(bufMgr,filename): """Test newPage,pinPage, unpinPage, and whether a dirty page is written to disk.""" data = array.array('c',"This page is dirty!") print "------- Test 4 -------" pair = bufMgr.newPage(1,filename) if pair == None: raise TestException("newPage failed") (pageId,page) = pair print "newPage successful" # dirty page page[0:len(data)] = data[:] bufMgr.unpinPage(pageId,filename,True) print "Unpinning of page successful" bufMgr.flushAllPages() # Create a new buffer manager to see if it can handle it bufMgr = bufmgr.BufferManager(NUMBUF) page = bufMgr.pinPage(pageId,filename) if page == None: raise TestException("Pinning of page failed") print "Pinning of page successful" readBack = page.tostring() orig = data.tostring() if readBack[0:len(orig)] != orig: raise TestException("Dirtied page not written to disk") print "Dirtied page written to disk" def test5(bufMgr,filename): pageIds = [None]*30 pages = [None]*30 print "------- Test 5 -------" # Allocate 10 pages from database for i in range(10): pair = bufMgr.newPage(1,filename) if pair == None: raise TestException("newPage failed") (pageIds[i],pages[i]) = pair print "Allocated 10 pages successful" # Try to unpin a pinned page twice bufMgr.unpinPage(pageIds[0],filename,False); print "Unpinning of a pinned page successful" # Try to unpin an unpinned page success = True try: bufMgr.unpinPage(pageIds[0],filename,False) except bufmgr.PageNotPinnedException: success = False; if success: raise TestException("Unpinning of an unpinned page successful") print "Unpinning of an unpinned page failed (as it should)" # Pin a nonexistent page success = True try: tmpPage = bufMgr.pinPage(999,filename) except utils.BadPageNumberException: success = False if success: raise TestException("Pinning of a non-existent page succeeded") print "Pinning of a non-existent page failed (as it should)" # Unpin a nonexistent page success = True; try: bufMgr.unpinPage(999,filename,False) except bufmgr.PageNotPinnedException: success = False if success: raise TestException("Unpinning of a non-existent page succeeded") print "Unpinning of a non-existent page failed (as it should)" # Free a page that is still pinned page = bufMgr.pinPage(pageIds[0],filename) if page == None: raise TestException("Unable to pin page") print "Pinning of page successful" success = True try: bufMgr.freePage(pageIds[0],filename) except bufmgr.PagePinnedException: success = False if success: raise TestException("Freeing a pinned page succeeded") print "Freeing a pinned page failed (as it should)" # Free all allocated pages for i in range(10): bufMgr.unpinPage(pageIds[i],filename,False) bufMgr.freePage(pageIds[i],filename) print "Freeing allocated pages successful" # Allocate new buffer manager bufMgr = bufmgr.BufferManager(NUMBUF) # fill up buffer with pinned pages for i in range(NUMBUF): pair = bufMgr.newPage(1,filename) if pair == None: raise TestException("newPage failed") (pageIds[i],pages[i]) = pair print "Allocate pages successful" # Now try to pin one more page pair = bufMgr.newPage(1,filename) if pair != None: raise TestException("Pinning a page in a full buffer succeeded") print "Pinning a page in a full buffer failed (as it should)" # Free all allocated pages for i in range(NUMBUF): bufMgr.unpinPage(pageIds[i],filename,False) bufMgr.freePage(pageIds[i],filename) print "Freeing allocated pages successful" def test6(bufMgr,filename): print "------- Test 6 -------" # Allocate some pages (startId, startPage) = bufMgr.newPage(15,filename) bufMgr.unpinPage(startId,filename,False) for i in range(13): page = bufMgr.pinPage(i,filename) if page == None: raise TestException("Pinning page failed") print "after pinPage", i data = array.array('c',"This is test 6 for page " + str(i)) page[0:len(data)] = data[:] bufMgr.flushPage(i,filename) print "after flushPage", i bufMgr.unpinPage(i,filename,True) for i in range(13): page = bufMgr.pinPage(i,filename) if page == None: raise TestException("Pinning page failed") readBack = page.tostring() orig = "This is test 6 for page " + str(i) print "PAGE[", i, "]:", readBack[0:len(orig)] if readBack[0:len(orig)] != orig: raise TestException("Page content incorrect") bufMgr.unpinPage(i,filename,False) # Try to pin a page in a different file success = False; try: page = bufMgr.pinPage(1,filename+"a") except utils.BadFileException: print "Successfully caught pinning wrong file" success = True if not success: raise TestException("Pinned wrong file") def test7(bufMgr,filename): print "------- Test 7 -------" # Allocate some pages (startId, startPage) = bufMgr.newPage(15,filename) bufMgr.unpinPage(startId,filename,False) for i in range(13): page = bufMgr.pinPage(i,filename) if page == None: raise TestException("Pinning page failed") bufMgr.unpinPage(i,filename,True) bufMgr.flushAllPages() utils.erase(filename) bufMgr.flushAllPages() print "Successfully deleted and flushed again" def test8(bufMgr,filename): print "------- Test 8 -------" # Allocate some pages (startId, startPage) = bufMgr.newPage(bufMgr.poolSize()*2,filename) bufMgr.unpinPage(startId,filename,False) for i in range(bufMgr.poolSize()+1): page = bufMgr.pinPage(i,filename) if page == None: raise TestException("Pinning page failed") print "after pinPage", i data = array.array('c',"This is test 8 for page " + str(i)) page[0:len(data)] = data[:] bufMgr.flushPage(i,filename) print "after flushPage", i bufMgr.unpinPage(i,filename,True) pair = bufMgr.newPage(1,filename) if pair == None: raise TestException("newPage failed") (pageId,page) = pair # Verify that page is empty zero = True for i in range(len(page)): if page[i] != '\0': zero = False break if not zero: print "Test failed: page is not empty." for i in range(len(page)): print page.data[i], print else: print "Successfully completed test 8." def runTest(test): success = True try: utils.create("testfile",0) bufMgr = bufmgr.BufferManager(NUMBUF) test(bufMgr,"testfile") except TestException, e: print 'Test Exception thrown' success = False print e return success; runTest(test1) runTest(test2) runTest(test3) runTest(test4) runTest(test5) runTest(test6) runTest(test7) runTest(test8)