import os

#Test a few threads against both the same and other databases



from Ft.Ods.StorageManager.Adapters import Constants

SLEEP_MAX = .5

odl_string = '''
module Test{
class Foo
{
	attribute string data;
};
};
'''
#'

try:
    import threading
    HAVE_THREADS=1
except ImportError:
    HAVE_THREADS = 0


NUM_THREADS = 10

from Ft.Ods import Database
import time

g_gate = 1

g_dbName = ''

DBNAME=os.environ.get("ODS_TEST_DB","ods:test")

import sys, test_util
from Ft.Ods import Database
from Ft.Ods.StorageManager.Adapters import Constants

def Test(tester):
    if tester.test_data['driver'] == 'Dbm':
        tester.startTest("Not Supported")
        tester.warning("Multithreaded tested not supported for Dbm driver")
        tester.testDone()
        return
    if not HAVE_THREADS:
        tester.startTest("Not Supported")
        tester.warning("Multithreaded not supported on this platform.")
        tester.testDone()
        return
        
    try:
        _Test(tester)
    finally:
        if os.path.exists('Test'):
            from distutils import dir_util
            dir_util.remove_tree('Test')

    
def _Test(tester):

    tester.startGroup("mthread test %s Driver" % tester.test_data['driver'])

    test_util.DbInit(DBNAME,odl_string)

    global g_dbName
    g_dbName = DBNAME

    db = Database.Database()
    db.open(g_dbName)

    try:
        tester.startTest("Create Threads")

        threads = []
        for ctr in range(NUM_THREADS):
            t = threading.Thread(None,test_thread,"Thread-%i"%ctr,(db,ctr,))
            t.start()
            threads.append(t)

        tester.testDone()
        global g_gate
        g_gate = 0

        tester.startTest("Run Threads")
        left = filter(lambda x:x.isAlive(),threads)
        while len(left):
            time.sleep(1)
            left = filter(lambda x:x.isAlive(),left)
        tester.testDone()
        tester.groupDone()
    finally:
        db.close()



def test_thread(db,threadNum):
    
    sleepTime = 0
    sTime = time.time()

    tx = db.new()
    tx.begin()

    from Test import Foo
    reload(Foo)

    for ctr in range(10):
        f = Foo.new(db)
        sleepTime = sleepTime + rSleep()
        db.bind(f,"Foo %i %i" % (threadNum,ctr))

    tx.commit()

    tx = db.new()
    tx.begin()

    for ctr in range(10):
        f = db.lookup("Foo %i %i" % (threadNum,ctr))
        f.data = "1"
        sleepTime = sleepTime + rSleep()
    tx.commit()

    tx = db.new()
    tx.begin()

    for ctr in range(10):
        f = db.lookup("Foo %i %i" % (threadNum,ctr))
        f.delete()
        sleepTime = sleepTime + rSleep()
    tx.commit()

    
    eTime = time.time()

import whrandom
generator = whrandom.whrandom()

def rSleep():
    global generator
    sTime = generator.random() * SLEEP_MAX
    time.sleep(sTime)
    return sTime

