#!/usr/bin/env python
#@+leo-ver=4
#@+node:@file tests.py
#@@first
#
#    Copyright (C) 2004  Richard Jones  <richard followed by funny at sign then jones then a dot then name>
#
#    GmailFS Test Cases
#
#    ./test.py mountpoint blocksize 
#    e.g. ./tests.py /gmailfs 5242880
#
#    This program can be distributed under the terms of the GNU GPL.
#    See the file COPYING.
#

"""
GmailFS Test Cases provides some tests to the author shooting himself in the foot between releases.
"""

import os,traceback,sys,md5
from stat import *
from os import *

#@+node:mainline
class TestFS:
    """
    Class containing test cases for gmail filesystem
    """
    
    def __init__(self,mountpath,blocksize):
        self.mountpath = mountpath
        self.blocksize = blocksize

    def check(self,passed,testname):
        if passed==1:
            print "passed "+testname
        else:
            print "failed "+testname
            

    def create_1(self,path,file1):
        try:
            pathname = os.path.join(self.mountpath,path)
            print 'pathname='+pathname+' path:'+path
            if not os.access(pathname,F_OK):
                os.makedirs(pathname)
            pathname = os.path.join(pathname,file1)
            f = file(pathname,"w")
            writestr = 'hello world\n'
            f.write(writestr)
            f.close()
            f = file(pathname,"r")
            readstr = f.read()
            if readstr != writestr:
                print 'readstr: '+readstr+' not equal to writestr:'+writestr
                return 0
        except:
            traceback.print_exc(file=sys.stdout)
            return 0

        return 1

    def create_big_1(self,path,file1,writelen):
        try:
            pathname = os.path.join(self.mountpath,path)
            if not os.access(pathname,F_OK):
                os.makedirs(pathname)
            pathname = os.path.join(pathname,file1)
            f = file(pathname,'w')
            count = 0
            num = 0
            m = md5.new()
            while count<writelen:
               numstr = str(num)
               f.write(numstr)
               num+=1
               if num>9:
                   num=0
               m.update(numstr)
               count+=1

            md5orig = m.digest()
            
            f.close()
            f = file(pathname,"r")
            md5check = md5.new(f.read()).digest()
            if  md5orig != md5check:
                print 'readstr: '+readstr+' not equal to writestr:'+writestr
                return 0
        except:
            traceback.print_exc(file=sys.stdout)
            return 0

        return 1

    def link_1(self,path1,path2,sym):
        pathname1 = os.path.join(self.mountpath,path1)
        pathname2 = os.path.join(self.mountpath,path2)

        try:
            if (sym):
                symlink(pathname1,pathname2)
            else:
                link(pathname1,pathname2)
                
            if not os.access(pathname2,F_OK):
                os.remove(pathname2)
                return 0

        except:
            traceback.print_exc(file=sys.stdout)
            return 0

        os.remove(pathname2)
        return 1


    def deletedir_1(self,path):
        pathname = os.path.join(self.mountpath,path)
        try:
            os.rmdir(pathname)
        except:
            traceback.print_exc(file=sys.stdout)
            return 0

        if os.access(pathname,F_OK):
            return 0

        return 1

    def delete_1(self,path):
        pathname = os.path.join(self.mountpath,path)
        print "test delete_1 deleting pathname:"+pathname
        try:
            os.unlink(pathname)
        except:
            traceback.print_exc(file=sys.stdout)
            return 0

        if os.access(pathname,F_OK):
            return 0

        return 1
        
    def mkdir_1(self,path):
        pathname = os.path.join(self.mountpath,path)
        print 'pathname='+pathname+' path:'+path
        try:
            os.makedirs(pathname)
       
            if not os.access(pathname,F_OK):
                os.removedirs(pathname)
                return 0
            
            mode = os.stat(pathname)[ST_MODE]
            if not S_ISDIR(mode):
                os.removedirs(pathname)
                return 0
            
        except:
            traceback.print_exc(file=sys.stdout)
            return 0

        os.removedirs(pathname)
        return 1

    

if __name__ == '__main__':
    tester = TestFS(sys.argv[1],int(sys.argv[2]))
    print "start tests"
    tester.check(tester.mkdir_1("test1"),"mkdir test1")
        
    tester.check(tester.mkdir_1("test1/test2"),"mkdir test1/test2")
    tester.check(tester.create_1("","file1"),"create /file1")
    tester.check(tester.create_1("dir1","file1"),"create /dir1/file1")
    tester.check(tester.create_1("dir1/dir2","file1"),"create dir1/dir2/file1")
    tester.check(tester.create_big_1("dir3","bigfile1",tester.blocksize-1),"create dir3/bigfile1 with size:"+str(tester.blocksize))
    tester.check(tester.delete_1("dir3/bigfile1"),"delete dir3/bigfile1")
    tester.check(tester.create_big_1("dir3","bigfile1",tester.blocksize),"create dir3/bigfile1 with size:"+str(tester.blocksize))
    tester.check(tester.delete_1("dir3/bigfile1"),"delete dir3/bigfile1")
    tester.check(tester.create_big_1("dir3","bigfile1",tester.blocksize+1),"create dir3/bigfile1 with size:"+str(tester.blocksize+1))
    tester.check(tester.delete_1("dir3/bigfile1"),"delete dir3/bigfile1")
    tester.check(tester.create_big_1("dir3","bigfile1",(tester.blocksize*2+1)),"create dir3/bigfile1 with size:"+str(tester.blocksize*2+1))
    tester.check(tester.delete_1("dir3/bigfile1"),"delete dir3/bigfile1")
    tester.check(tester.deletedir_1("dir3"),"delete dir3")

#    tester.check(tester.link_1("/bin/df","testfile2",1),"symlink testfile2 to /bin/df")
#    tester.check(tester.link_1("dir1/file1","testfile2",0),"hardlink testfile2 to dir1/file1")
#    tester.check(tester.link_1("file1","testfile2",0),"hardlink testfile2 to file1")
    tester.check(tester.link_1("dir1/dir2/file1","testfile2",0),"hardlink testfile2 to dir1/dir2/file1")
    tester.check(tester.delete_1("file1"),"delete file1")
    tester.check(tester.delete_1("dir1/file1"),"delete dir1/file1")
    tester.check(tester.delete_1("dir1/dir2/file1"),"delete dir1/dir2/file1")
    tester.check(tester.deletedir_1("dir1/dir2"),"delete dir1/dir2")
    tester.check(tester.deletedir_1("dir1"),"delete dir1")

    
    print "finished tests"
#@-node:mainline
#@-node:@file gmailfs.py
#@-leo
