#!/usr/bin/env python

##-----------------------------------------------------------------------
##
## DTest - A Distributed test framework
##
## Copyright (c) 2006-2008 Eric NOULARD, Lionel DUROYON and Frederik DEWEERDT 
##
## This library is free software; you can redistribute it and/or
## modify it under the terms of the GNU Lesser General Public
## License as published by the Free Software Foundation; either
## version 2.1 of the License, or (at your option) any later version.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public
## License along with this library; if not, write to the Free Software
## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
##
##-----------------------------------------------------------------------


import dtest
import time
import logging

# Here begins the test
dtest.DTestMaster.logger.setLevel(level=logging.ERROR)
dtest.DTester.logger.setLevel(level=logging.ERROR)

def myCustomStep(dtester, *args, **kwargs):
    return True
   
def myInvalidCustomStep(bla, blo):
   print "myInvalidCustomStep"

def mySleepStep(dtester):
   time.sleep(6)

# Create as many DTester as you need
tester1     = dtest.DTester("DTester1")
tester2     = dtest.DTester("DTester2")

# Describe the run step(s)
tester1.addRunStep("barrier","aBarrier")
tester2.addRunStep("barrier","aBarrier")
tester2.addRunStep("ok",True,"SKIPPED test",skip="--SKIPPED step--")
tester2.addRunStep("ok",False,"here is a failure")
# You may add a run step using different syntax
# 1- use a string as method name
# 2- use an unbound method from a class
# 3- use a bound method

# 1- use a string as method name
#    then DTest will lookup a method "ok" in class
#    corresponding to object instance
#    calling addRunStep (i.e. tester2.__class__ in this case)
tester2.addRunStep("ok",True,"ok step using 'string' ok name")
# 2- use an unbound method from a class
#    then DTest will use the method and provides "self" as first arg
tester2.addRunStep(dtest.DTester.ok,True,"ok step using 'DTester.ok' unbound method")
# 2bis- use an unbound method taken from the class
#       using the __class__ attribute of the object
tester2.addRunStep(tester2.__class__.ok,True,"ok step using 'tester2.__class__.ok' unbound method")
# 3- use a bound method
#
tester2.addRunStep(tester2.ok,True,"ok step using 'tester2.ok' bound method")
# 5- use a custom step
#    then DTest will check that first arg is either self or dtester
#    and will provider the "self" caller as first arg
tester1.addRunStep(myCustomStep)
tester1.addRunStep("ok",tester1.getFutureLastStepStatus,"myCustomStep")
try:
   tester1.addRunStep(myInvalidCustomStep)
except dtest.DTester.InvalidStepFunctionException, e:
   print "## OK not adding the run step:", repr(myInvalidCustomStep)
   print "## Since it raises : ", repr(e)   

tester2.addRunStep("barrier","anotherBarrier")
tester2.addRunStep("ok",True,"TODO step",todo="--TODO step--")

# Thoses step will make tester2 timeout for sure
tester1.addRunStep("barrier","wait4me4ever")
tester2.addRunStep("barrier","wait4me4ever")
tester1.addRunStep("waitDuring",6)
tester1.addRunStep("barrier","timedBarrier",10.6)
tester2.addRunStep("barrier","timedBarrier",1.5)
tester2.addRunStep("ok",True,"--END step--")

# Add some trace Handlers
traceManager = dtest.TraceManager()
# TAP goes to stdout
traceManager.register(dtest.TAPTraceHandler())
# MSC goes to file MSC-trace
traceManager.register(dtest.MSCTraceHandler(output="MSC-trace"))
traceManager.register(dtest.PromelaTraceHandler(output="PML-trace"))

# To generate a message sequence chart trace of one possible execution but without executing the steps
# set pseudoexec to 1
pseudoexec=0

myDTestMaster = dtest.DTestMaster("First Sequence")
myDTestMaster.registerTraceManager(traceManager)
if (pseudoexec):
    myDTestMaster.setPseudoExec(1)
myDTestMaster.register(tester1)
myDTestMaster.register(tester2)
myDTestMaster.startTestSequence()
myDTestMaster.waitTestSequenceEnd()

tester3     = dtest.DTester("DTester3")
tester3.addRunStep("ok",True,"an OK step")
tester3.addRunStep("barrier","aBarrier")
tester3.addRunStep("ok",False,"an NOK step")
myDTestMaster = dtest.DTestMaster("Second Sequence")
myDTestMaster.registerTraceManager(traceManager)
myDTestMaster.register(tester3)
myDTestMaster.startTestSequence()
myDTestMaster.waitTestSequenceEnd()

tester4     = dtest.DTester("DTester3")
tester4.addRunStep("ok",True,"an OK step")
tester4.addRunStep("barrier","aBarrier")
tester4.addRunStep("ok",True,"anther OK step")
myDTestMaster = dtest.DTestMaster("Third Sequence")
myDTestMaster.registerTraceManager(traceManager)
myDTestMaster.register(tester4)
myDTestMaster.startTestSequence()
myDTestMaster.waitTestSequenceEnd()

traceManager.finalize()
