def testTimeEvent4(self):
        """
        Run test with time interval in seconds.
        """
        self._log.debug( "\n\ntestTimeEvent4" )
        loader = EventRouterLoader()
        loader.loadHandlers( getDictFromXmlString(testConfigTime4) )

        loader.start()  # all tasks

        self._router = loader.getEventRouter()

        self.waitNEvents( 1 )
        TestEventLogger.logEvents()

        # first event should be isDark
        self.assert_( len(TestEventLogger._events) > 0)
        self.assertEqual( TestEventLogger._events[0].getType(), u'http://id.webbrick.co.uk/events/time/isDark' )
        self.assertEqual( TestEventLogger._events[0].getSource(), "time/isDark" )

        self.waitNEvents( 5 )
        TestEventLogger.logEvents()
        self.assert_( len(TestEventLogger._events) > 4)
        evt = TestEventLogger._events[1]
        od = evt.getPayload()
        self.assertEqual( len(od["timestr"]),8 )
        self.assertEqual( len(od["datestr"]),10 )
        self.assertEqual( len(od["datetimestr"]),19 )

        loader.stop()  # all tasks
        self.dumpEvents = False
    def testTimeEvent2(self):
        """
        Run test with time interval in seconds.
        """
        self._log.debug( "\ntestTimeEvent2" )
        loader = EventRouterLoader()
        loader.loadHandlers( getDictFromXmlString(testConfigTime2) )

        loader.start()  # all tasks

        self.waitNEvents( 5, 70 )

        # now look for correct url requests
        TestEventLogger.logEvents()
        self.assertEqual( len(TestEventLogger._events), 5)

        # the requests could be in either order.
        seenOne = 0
        seenTwo = 0
        for evnt in TestEventLogger._events:
            if ( evnt.getSource() == "local/BoilerOn" ):
                seenOne += 1
            elif ( evnt.getSource() == "local/HwOn" ):
                seenTwo += 1
            else:
                pass    # error
        self.assertEqual( seenOne, 1 )
        self.assertEqual( seenTwo, 4 )

        loader.stop()  # all tasks
        self.dumpEvents = False
    def testTimeEvent1(self):
        """
        Run test with time interval in minutes.
        """
        self._log.debug( "\n\ntestTimeEvent1" )
        loader = EventRouterLoader()
        loader.loadHandlers( getDictFromXmlString(testConfigTime1) )

        loader.start()  # all tasks

        self._router = loader.getEventRouter()

        self.waitNEvents( 1 )

        # should have isDark or isLight event
        TestEventLogger.logEvents()

        self.assertEqual( len(TestEventLogger._events), 1)
        self.assertEqual( TestEventLogger._events[0].getType(), u'http://id.webbrick.co.uk/events/time/isDark' )
        self.assertEqual( TestEventLogger._events[0].getSource(), "time/isDark" )
        # assume testing during daylight hours
        od = TestEventLogger._events[0].getPayload()
        #self.assertEqual( od["state"], 0 )

        maxTime = 70
        while (TestEventLogger._events[-1].getType() != u'http://id.webbrick.co.uk/events/time/minute') and (maxTime > 0):
            maxTime -= 1
            time.sleep(1)

        TestEventLogger.logEvents()

        # now look for correct url requests
        self.failUnless( len(TestEventLogger._events) >= 2)
        self.assertEqual( TestEventLogger._events[-1].getType(), u'http://id.webbrick.co.uk/events/time/minute' )
        self.assertEqual( TestEventLogger._events[-1].getSource(), "time/minute" )
        od = TestEventLogger._events[-1].getPayload()
        self.failUnless( od.has_key("second") ) 
        self.failUnless( od.has_key("minute") ) 
        self.failUnless( od.has_key("hour") ) 
        self.failUnless( od.has_key("day") ) 
        self.failUnless( od.has_key("date") ) 
        self.failUnless( od.has_key("month") ) 
        self.failUnless( od.has_key("year") ) 
        self.failUnless( od.has_key("week") ) 
        self.failUnless( od.has_key("dayofyear") ) 
        self.failUnless( od.has_key("timestr") ) 
        self.failUnless( od.has_key("datestr") ) 
        self.failUnless( od.has_key("datetimestr") ) 

        loader.stop()  # all tasks
        self.dumpEvents = False
    def testTimeEvent3(self):
        """
        Run test with time interval in seconds.
        """
        self._log.debug( "\n\ntestTimeEvent3" )
        loader = EventRouterLoader()
        loader.loadHandlers( getDictFromXmlString(testConfigTime3) )

        loader.start()  # all tasks

        self._router = loader.getEventRouter()

        self.waitNEvents( 16, 20 )

        TestEventLogger.logEvents()
        self.assert_( len(TestEventLogger._events) > 16)

        loader.stop()  # all tasks
        self.dumpEvents = False
示例#5
0
class TestBackupHandler(unittest.TestCase):

    def clearDirectory(self, dname):
        for fn in os.listdir( dname ):
            fnf = "%s/%s" % (dname,fn)
            if isfile(fnf):
                _log.debug( "remove %s", fnf )
                os.remove( fnf )

    def setUp(self):
        _log.debug( "setup" )

        self.router = None
        self.loader = None

        ClearDirectory(workDir)
        ClearDirectory(outputDir)
        CopyDirectory(sourceDir, workDir)

        return

    def tearDown(self):

        if self.loader:
            self.loader.stop()  # all tasks
            self.loader = None
        self.router = None

        if isfile(testdata3):
            os.remove( testdata3 )

        return

    def waitForFile(self, fname, timeout=1.0 ):
        wait = timeout
        while wait > 0 and not isfile(fname):
            wait = wait - 0.1
            time.sleep(0.1)
            

    # Actual tests follow
    def testSingleFileLocal(self):
        """
        Initial single file backup
        """
        _log.debug( "\ntestSingleFileLocal" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigSingleFile) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(fname01sd)

        self.loader.stop()  # all tasks
        self.loader = None

        # now verify file exists.
        self.failUnless( isfile( fname01sd ) )
        self.failUnless( zipfile.is_zipfile( fname01sd ) )
        # read zip info.
        zf = zipfile.ZipFile(fname01sd, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 1 ) # one entry
        self.assertEqual( zfi[0].filename, "work/file1.txt" ) # one entry
        zf.close()

    def testSingleFileLocalCleanUp(self):
        """
        Initial single file backup
        """
        _log.debug( "\ntestSingleFileLocalCleanUp" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigSingleFileCleanUp) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1)    # do initial backup
        self.waitForFile(fname01sd)
                
        # now verify file exists.
        self.failUnless( isfile( fname01sd ) )
        self.failUnless( zipfile.is_zipfile( fname01sd ) )
        # read zip info.

        now = time.time()
        
        # change the timestamp of the file to make it appear to be 6 days old  days old
        past6 = now - 3600*24*6
        os.utime(fname01sd, (past6, past6))
        # invoke cleanup
        self.router.publish( EventAgent("TestBackup"), Events.evtMinute2 )
        time.sleep(0.5)
        # verify file still exists.
        self.failUnless( isfile( fname01sd ) )
        
        # change the timestamp of the file to make it appear to be 6 days old  days old
        past8 = now - 3600*24*8
        os.utime(fname01sd, (past8, past8))
        # invoke cleanup
        self.router.publish( EventAgent("TestBackup"), Events.evtMinute2 )
        time.sleep(0.5)
        # verify file has been deleted
        self.failIf( isfile( fname01sd ) )
        
        self.loader.stop()  # all tasks
        self.loader = None

    def testSingleFileLocalDelete(self):
        """
        Initial single file backup
        """
        _log.debug( "\ntestSingleFileLocalDelete" )

        copyfile( testdata1, testdata3 )
        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigSingleFileDelete) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(fname01)

        self.loader.stop()  # all tasks
        self.loader = None

        # now verify file exists.
        self.failUnless( isfile( fname01 ) )
        self.failUnless( zipfile.is_zipfile( fname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(fname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 1 ) # one entry
        self.assertEqual( zfi[0].filename, "work/file1_delete.txt" )
        self.failIf( isfile( testdata3 ) )  # should be deleted
        zf.close()
    
    def testSingleDirectoryLocal(self):
        _log.debug( "\ntestSingleDirectoryLocal" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigSingleDirectory) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(fname01)

        self.loader.stop()  # all tasks
        self.loader = None

        # now verify file exists.
        self.failUnless( isfile( fname01 ) )
        self.failUnless( zipfile.is_zipfile( fname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(fname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 2 ) # two entrys
        self.assertEqual( zfi[0].filename, "file1.txt" )
        self.assertEqual( zfi[1].filename, "file2.txt" )
        zf.close()

    def testMultipleFilesLocal(self):
        _log.debug( "\ntestMultipleFilesLocal" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigMultipleFile) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(fname01)

        self.loader.stop()  # all tasks
        self.loader = None

        # now verify file exists.
        self.failUnless( isfile( fname01 ) )
        self.failUnless( zipfile.is_zipfile( fname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(fname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 2 ) # two entrys
        self.assertEqual( zfi[0].filename, "work/file1.txt" )
        self.assertEqual( zfi[1].filename, "work/file2.txt" )
        zf.close()
        
        
    def testMultipleFilesLocalCleanUp(self):
        _log.debug( "\ntestMultipleFilesLocalCleanUp" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigMultipleFileCleanUp) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do backup 1
        self.waitForFile(fname01)

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute2 )    # do backup 2
        self.waitForFile(fname02)

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute3 )    # do backup 3
        self.waitForFile(fname03)

        # now verify file exists.
        self.failUnless( isfile( fname01 ) )
        self.failUnless( isfile( fname02 ) )
        self.failUnless( isfile( fname03 ) )
       
        now = time.time()
        
        # change the timestamp of the file to make it appear to be 6 days old  days old
        past6 = now - 3600*24*6
        os.utime(fname02, (past6, past6))
        # invoke cleanup
        self.router.publish( EventAgent("TestBackup"), Events.evtMinute4 )
        time.sleep(0.5)
        # verify file still exists.
        self.failUnless( isfile( fname02 ) )
        
        # change the timestamp of the file to make it appear to be 6 days old  days old
        past8 = now - 3600*24*8
        os.utime(fname01, (past8, past8))
        os.utime(fname03, (past8, past8))
        # invoke cleanup
        self.router.publish( EventAgent("TestBackup"), Events.evtMinute4 )
        time.sleep(0.5)
        # verify file has been deleted
        self.failIf( isfile( fname01 ) )
        self.failUnless( isfile( fname02 ) )
        self.failIf( isfile( fname03 ) )
       
        self.loader.stop()  # all tasks
        self.loader = None

    def testMultipleDirectorysLocal(self):
        _log.debug( "\ntestMultipleDirectorysLocal" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigMultipleDirectories) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(fname01)

        self.loader.stop()  # all tasks
        self.loader = None

        # now verify file exists.
        self.failUnless( isfile( fname01 ) )
        self.failUnless( zipfile.is_zipfile( fname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(fname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 4 )
        self.assertEqual( zfi[0].filename, "file1.txt" )
        self.assertEqual( zfi[1].filename, "file2.txt" )
        self.assertEqual( zfi[2].filename, "file1.1.txt" )
        self.assertEqual( zfi[3].filename, "file1.2.txt" )
        zf.close()

    def testSingleDirectoryRecursiveLocal(self):
        _log.debug( "\ntestSingleDirectoryRecursiveLocal" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigSingleDirectoryRecursive) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(fname01)

        self.loader.stop()  # all tasks
        self.loader = None

        # now verify file exists.
        self.failUnless( isfile( fname01 ) )
        self.failUnless( zipfile.is_zipfile( fname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(fname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 4 )
        self.assertEqual( zfi[0].filename, "file1.txt" )
        self.assertEqual( zfi[1].filename, "file2.txt" )
        self.assertEqual( zfi[2].filename, "dir2/file1.1.txt" )
        self.assertEqual( zfi[3].filename, "dir2/file1.2.txt" )
        zf.close()

    def testMixedDataSetLocal(self):
        _log.debug( "\ntestMixedDataSetLocal" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigMixed) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(fname01)

        self.loader.stop()  # all tasks
        self.loader = None

        # now verify file exists.
        self.failUnless( isfile( fname01 ) )
        self.failUnless( zipfile.is_zipfile( fname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(fname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 4 )
        self.assertEqual( zfi[0].filename, "work/file1.txt" )
        self.assertEqual( zfi[1].filename, "work/file2.txt" )
        self.assertEqual( zfi[2].filename, "file1.1.txt" )
        self.assertEqual( zfi[3].filename, "file1.2.txt" )
        zf.close()

    def testSingleDirectoryAbsoluteLocal(self):
        _log.debug( "\ntestSingleDirectoryAbsoluteLocal" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigSingleDirectoryAbsolute) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()
        self.waitForFile(fname01)

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(fname01)

        self.loader.stop()  # all tasks
        self.loader = None

        # now verify file exists.
        self.failUnless( isfile( fname01 ) )
        self.failUnless( zipfile.is_zipfile( fname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(fname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 2 ) # two entrys
        self.failUnless( zfi[0].filename.endswith("/work/file1.txt") )
        self.failUnless( zfi[1].filename.endswith("/work/file2.txt") )
        zf.close()

    def testMultipleFilesAbsoluteLocal(self):
        _log.debug( "\ntestMultipleFilesAbsoluteLocal" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigMultipleFileAbsolute) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(fname01)

        self.loader.stop()  # all tasks
        self.loader = None

        # now verify file exists.
        self.failUnless( isfile( fname01 ) )
        self.failUnless( zipfile.is_zipfile( fname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(fname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 2 ) # two entrys
        self.failUnless( zfi[0].filename.endswith("/work/file1.txt") )
        self.failUnless( zfi[1].filename.endswith("/work/file2.txt") )
        zf.close()

    def testSingleDirectoryRecursiveAbsoluteLocal(self):
        _log.debug( "\ntestSingleDirectoryRecursiveAbsoluteLocal" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigSingleDirectoryRecursiveAbsolute) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(fname01)

        self.loader.stop()  # all tasks
        self.loader = None

        # now verify file exists.
        self.failUnless( isfile( fname01 ) )
        self.failUnless( zipfile.is_zipfile( fname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(fname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 4 ) # two entrys
        self.failUnless( zfi[0].filename.endswith("/work/file1.txt") )
        self.failUnless( zfi[1].filename.endswith("/work/file2.txt") )
        self.failUnless( zfi[2].filename.endswith("/work/dir2/file1.1.txt") )
        self.failUnless( zfi[3].filename.endswith("/work/dir2/file1.2.txt") )
        zf.close()

    def testMultipleFileChangeLocal(self):
        """
        single file backup followed by no single file and then single file
        """
        _log.debug( "\ntestMultipleFileChangeLocal" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigMultipleFileChange) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(fname01)

        # now verify file exists.
        self.failUnless( isfile( fname01 ) )
        self.failUnless( zipfile.is_zipfile( fname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(fname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 2 ) # one entry
        self.assertEqual( zfi[0].filename, "work/file1.txt" )
        self.assertEqual( zfi[1].filename, "work/file2.txt" )

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute2 )    # no change should not create file
        time.sleep(0.1)
        self.failIf( exists( fname02 ) )    # should not exist

        file(testdata1, 'wb+').close()  # touch file
        time.sleep(0.1)
        zf.close()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute3 )    # no change should not create file
        self.waitForFile(fname03)
        # read zip info.
        zf = zipfile.ZipFile(fname03, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 2 ) # one entry
        self.assertEqual( zfi[0].filename, "work/file1.txt" )
        self.assertEqual( zfi[1].filename, "work/file2.txt" )

        self.loader.stop()  # all tasks
        self.loader = None
        zf.close()

    def testMixedDataSetChangeLocal(self):
        _log.debug( "\ntestMixedDataSetLocal" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigMixedChange) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(fname01)

        # now verify file exists.
        self.failUnless( isfile( fname01 ) )
        self.failUnless( zipfile.is_zipfile( fname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(fname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 4 )
        self.assertEqual( zfi[0].filename, "work/file1.txt" )
        self.assertEqual( zfi[1].filename, "work/file2.txt" )
        self.assertEqual( zfi[2].filename, "file1.1.txt" )
        self.assertEqual( zfi[3].filename, "file1.2.txt" )
        zf.close()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute2 )    # no change should not create file
        time.sleep(0.2)
        self.failIf( exists( fname02 ) )    # should not exist

        file(testdata2, 'wb+').close()  # touch file
        time.sleep(0.2)   # so clock rolls over

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute3 )    # no change should not create file
        self.waitForFile(fname03)
        # read zip info.
        self.failUnless( zipfile.is_zipfile( fname03 ) )
        zf = zipfile.ZipFile(fname03, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 4 )
        self.assertEqual( zfi[0].filename, "work/file1.txt" )
        self.assertEqual( zfi[1].filename, "work/file2.txt" )
        self.assertEqual( zfi[2].filename, "file1.1.txt" )
        self.assertEqual( zfi[3].filename, "file1.2.txt" )
        zf.close()

        self.loader.stop()  # all tasks
        self.loader = None

    def testMultipleFileDeltaLocal(self):
        """
        single file backup followed by no single file and then single file
        """
        _log.debug( "\ntestMultipleFileDeltaLocal" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigMultipleFileDelta) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(fname01)

        # now verify file exists.
        self.failUnless( isfile( fname01 ) )
        self.failUnless( zipfile.is_zipfile( fname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(fname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 2 ) # one entry
        self.assertEqual( zfi[0].filename, "work/file1.txt" )
        self.assertEqual( zfi[1].filename, "work/file2.txt" )
        zf.close()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute2 )    # no change should not create file
        time.sleep(0.2)
        self.failIf( exists( fname02 ) )    # should not exist

        file(testdata1, 'wb+').close()  # touch file
        time.sleep(0.2)

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute3 )    # no change should not create file
        self.waitForFile(fname03)
        # read zip info.
        zf = zipfile.ZipFile(fname03, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 1 ) # one entry
        self.assertEqual( zfi[0].filename, "work/file1.txt" )
        zf.close()

        self.loader.stop()  # all tasks
        self.loader = None

    def testMixedDataSetDeltaLocal(self):
        _log.debug( "\ntestMixedDataSetDeltaLocal" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigMixedDelta) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(fname01)

        # now verify file exists.
        self.failUnless( isfile( fname01 ) )
        self.failUnless( zipfile.is_zipfile( fname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(fname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 4 )
        self.assertEqual( zfi[0].filename, "work/file1.txt" )
        self.assertEqual( zfi[1].filename, "work/file2.txt" )
        self.assertEqual( zfi[2].filename, "file1.1.txt" )
        self.assertEqual( zfi[3].filename, "file1.2.txt" )
        zf.close()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute2 )    # no change should not create file
        time.sleep(0.2)
        self.failIf( exists( fname02 ) )    # should not exist

        file(testdata2, 'wb+').close()  # touch file
        time.sleep(0.2)   # so clock rolls over

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute3 )    # no change should not create file
        self.waitForFile(fname03)
        # read zip info.
        self.failUnless( zipfile.is_zipfile( fname03 ) )
        zf = zipfile.ZipFile(fname03, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 1 ) # subversion control files get in the way.
        self.assertEqual( zfi[0].filename, "work/file2.txt" )
        zf.close()

        self.loader.stop()  # all tasks
        self.loader = None

    def testSingleDirectoryHttpS(self):
        _log.debug( "\ntestSingleDirectoryHttpS" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigSingleDirectoryHttpS) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(HttpSfname01)

        self.loader.stop()  # all tasks
        self.loader = None

        # now verify file exists.
        self.failUnless( isfile( HttpSfname01 ) )
        self.failUnless( zipfile.is_zipfile( HttpSfname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(HttpSfname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 2 ) # two entrys
        self.assertEqual( zfi[0].filename, "file1.txt" )
        self.assertEqual( zfi[1].filename, "file2.txt" )
        zf.close()

    def testSingleDirectoryFtp(self):
        _log.debug( "\ntestSingleDirectoryFtp" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigFtp) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(Ftpfname01)

        self.loader.stop()  # all tasks
        self.loader = None

        # now verify file exists.
        self.failUnless( isfile( Ftpfname01 ) )
        self.failUnless( zipfile.is_zipfile( Ftpfname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(HttpSfname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 2 ) # two entrys
        self.assertEqual( zfi[0].filename, "file1.txt" )
        self.assertEqual( zfi[1].filename, "file2.txt" )
        zf.close()

    def testCommandLine(self):
        """
        Initial single file backup using command line disposal
        """
        _log.debug( "\ntestCommandLine" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigCommandLine) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.router.publish( EventAgent("TestBackup"), Events.evtMinute1 )    # do initial backup
        self.waitForFile(fname01)

        self.loader.stop()  # all tasks
        self.loader = None

        # now verify file exists.
        self.failUnless( isfile( fname01 ) )
        self.failUnless( zipfile.is_zipfile( fname01 ) )
        # read zip info.
        zf = zipfile.ZipFile(fname01, 'r' ) # read only
        zfi = zf.infolist()
        self.assertEqual( len(zfi), 1 ) # one entry
        self.assertEqual( zfi[0].filename, "work/file1.txt" ) # one entry
        zf.close()
示例#6
0
class Root(controllers.RootController):

    def __init__( self ):
        self.eventloader = None
        self.homeTemplate = None
        
    def start(self):
        log_versions()
        # TODO         validateTemplateDirectory() on WebBrickGateway.templates
        persistFile = turbogears.config.get("client_profiles", None, False, "gateway" )

        ClientProfiles.load( persistFile )

        self.homeTemplate = turbogears.config.get("homepage", None, False, "gateway" )

        cfgStr = turbogears.config.get("templateDirectory", None, False, "gateway" )
        if cfgStr:
            _log.info( "additional template directory %s" % (cfgStr) )
            validateTemplateDirectory( cfgStr )

            #WbConfigSettings.addTemplateDir( cfgStr )
            sys.path.insert( 1, cfgStr )
            import kid
            _log.info( "Kid Paths %s"  % (str(kid.path.paths)) )
            ### tempdir = tempdir[:-(len(tempsuf)-1)]
            kid.path.insert( cfgStr )
            _log.info( "Kid Paths %s"  % (str(kid.path.paths)) )

        cfgStr = turbogears.config.get("network", None, False, "wbcfg" )
        if cfgStr:
            WbConfigBase.addNetwork( cfgStr )

        cfgStr = turbogears.config.get("webbrickDirectory", None, False, "wbcfg" )
        if cfgStr:
            WbConfigSettings.ConfDir = cfgStr
            _log.info( "updated webbrick configuration directory %s" % (cfgStr) )

        userDir = turbogears.config.get("despatchConfig", None, False, "gateway" )
        sysDir = turbogears.config.get("despatchConfigSystem", None, False, "gateway" )
        self.eventloader = EventRouterLoader()
        # system files first.

        self.eventloader.loadFromDirectories( [sysDir, userDir] )

        #print WbConfigSettings_hga.ConfDir
        #print WbConfigSettings.ConfDir
        
        ###self.panel = PanelRenderer.PanelRenderer()

        self.local       = LocalData.LocalData()
        self.userinterface = UserInterface.UserInterface()

        self.nameCache = Webbrick.WebbrickNodeNameCache()
        self.wbsts = Webbrick.WebbrickStatusCache( self.nameCache )
        self.wbcmd = Webbrick.WebbrickCommand( self.nameCache )
        self.eventstate = EventState.EventState( )
        self.discover = DiscoverHandler()
        self.media = Media.Media()

        # need to handle discovery better
        self.wbcnf = WbCfgManagerForm( self.discover )

        # THIS IS FOR ARMOUR gateway config and discovery only 
        if ARMOUR_DEV:
            self.wbgwcnf = WbGwCfgManager()
        
        self.schedule = Schedule.Schedule()
        self.sendevent = SendEvent.SendEventLocal(self.eventloader.getEventRouter())
        self.wbproxy = Webbrick.WebbrickProxy()

        self.eventstate.start(self.eventloader.getEventRouter())
        
        self.nameCache.start(self.eventloader.getEventRouter())
        self.wbsts.start(self.eventloader.getEventRouter())
        self.discover.start(self.eventloader.getEventRouter())
        self.schedule.start()
        self.media.start(self.eventloader.getEventRouter())
        
        # event handlers last
        if self.eventloader:
            self.eventloader.start()
        
        if not self.eventloader.getEventRouter():
            print "EVENT DESPATCH TASK NOT LOADED/FAILED CONFIGURE"

        _log.info( "Sys Paths %s"  % (sys.path) )

        # Now publish the versions
        router = self.eventloader.getEventRouter()
        publish_versions(router)
        
        
        import kid
        _log.info( "Kid Paths %s"  % (str(kid.path.paths)) )
        _log.warning( "**** System Configured ****" )

    def stop(self):
        """
        helper to shut down some class stuff.
        """
        self.schedule.stop()
        self.discover.stop(self.eventloader.getEventRouter())
        self.wbsts.stop( self.eventloader.getEventRouter() )
        self.nameCache.start( self.eventloader.getEventRouter() )
        self.eventloader.stop()
        self.media.stop(self.eventloader.getEventRouter())

    @turbogears.expose(template="WebBrickGateway.templates.welcome")
    def index(self):
        # look up in client profiles to get homePage.
        if self.homeTemplate:
            result = ClientProfiles.makeStandardResponse( cherrypy.request, self.homeTemplate )
        else:
            result = ClientProfiles.makeStandardResponse( cherrypy.request, "welcome" )
        result["now"] = time.ctime()
        return result

    @turbogears.expose(template="WebBrickGateway.templates.quiet")
    def quiet(self):
        result = ClientProfiles.makeStandardResponse( cherrypy.request )
        return result

    @turbogears.expose(template="WebBrickGateway.templates.listpanels")
    def panels(self):
        result = ClientProfiles.makeStandardResponse( cherrypy.request )

        def selectPanelName((_,nam)): 
            return nam[:-4]

        pattern = re.compile( r'^.+\.xml$' )
        c = CollectFiles("../resources/paneldef/",pattern,recursive=False)
        result['baseuri'] = turbogears.url("/")+"panel/"
        result['panels'] = map(selectPanelName,c)
        return result

    # Serve up media control panel
    @turbogears.expose(template="WebBrickGateway.templates.mediapanel")
    def mediapanel(self, **args):
        result = ClientProfiles.makeStandardResponse( cherrypy.request, "mediapanel" )
        # extract any parameters from the URL and add to the dictionary.
        for arg in args:
            result[arg] = args[arg]

        return result

    @turbogears.expose(template="WebBrickGateway.templates.welcome")
    def template(self, *args):
        """
        This function is used to return an arbitrary template used as
        a static page, but wrapped with the common header and footer
        elements.
        """
        # will set tg_template
        result = ClientProfiles.makeStandardResponse( cherrypy.request, string.join(args,'.') )
        if result.has_key("tg_format") and result["tg_format"] == "xml":
            #cherrypy.response.headers['Content-Type'] = "text/xml"
            cherrypy.response.headerMap['Content-Type'] = "text/xml"

        cherrypy.response.headers['Content-Type'] = "text/xml"
        cherrypy.response.headerMap['Content-Type'] = "text/xml"

        return result

    # obsolete, Andy:No actually turns out to be useful for serving files in pure XML format
    @turbogears.expose(template="WebBrickGateway.templates.welcome", format="xml", content_type="text/xml")
    def templatex(self, *args):
        """
        This function is used to return an arbitrary template used as
        a static page, but wrapped with the common header and footer
        elements.
        """
        # will set tg_template
        result = ClientProfiles.makeStandardResponse( cherrypy.request, string.join(args,'.') )

        result["tg_format"] = "xml"
#        result["tg_template"] = 'WebBrickGateway.templates.'+string.join(args,'.')

        cherrypy.response.headerMap['Refresh'] = "30"

        return result
   
    @turbogears.expose(format="manifest", content_type="text/cache-manifest")
    def manifest(self, *args):
        """
        This function is used to return an arbitrary template used as
        a static page, but wrapped with the common header and footer
        elements.
        """
        # get the path where the manifest is stored and serve it as the correct content type
        _log.debug("Requesting manifest for: " + args[0] + "skin")
        manifestpath = pkg_resources.resource_filename("WebBrickRes", "../resources/skins/") + args[0] + "/static/manifest/" + args[0] + ".manifest"
        result = file(manifestpath).read()

        return result
      
    # Serves dataset from siteLogRoot and graph_prop.xml from /static/css
    # as combined Json for use with OpenFlashChart
    # TODO: Move data processing out of controllers
    @turbogears.expose()
    def jsondata(self, logfile = None, propfile = None):
        """
        """
        result = ""
        
        # for debugging only
        # logPath = "/home/webbrick"
        # propPath = "/home/webbrick"
        
        # get the location of log files
        logPath = turbogears.config.get ('siteLogRoot', None, False, 'DEFAULT')
        
        # get the location of css files
        staticRoot = str(turbogears.config.get("static_filter.root", None, False, "global" ))
        staticCss = str(turbogears.config.get("static_filter.dir", None, False, "/static/css" ))
        if staticCss[0] != "/":
            propPath = staticRoot + staticCss
        else:
            propPath = staticCss
        
        
        if logfile and propfile:
            
        
            # does the log folder exist
            if logPath:
                
                # try to read the log file
                try:
                    
                    processeddata = {}
                    
                    xmldatastring = "<entrys>" + "".join(file(logPath + "/" + logfile).readlines()) + "</entrys>"
                    xmldatablob = parseXmlString(xmldatastring)
                    datadict = getDictFromXml(xmldatablob, typecast=True)
                    for item in datadict["entrys"][0]:
                        processeddata[item] = []
                        for entry in datadict["entrys"]:
                            processeddata[item].append(entry[item][0])
                            
                    result = str(processeddata)
                except:
                    _log.error( "log file: %s does not exist on Path: %s" %(logfile, logPath) )    
                
            if propPath:
                
                # try to read the prop file
                try:
                    xmlpropstring = "".join(file(propPath + "/" + propfile).readlines())
                    xmlpropblob = parseXmlString(xmlpropstring)
                    propdict = getDictFromXml(xmlpropblob, typecast=True)
                    propdict = propdict['graphprop']
                    #result = json.dumps(propdict)
                    #result = str(propdict)
                except:
                    _log.error( "log file: %s does not exist on Path: %s" %(propfile, propPath) )
           
            if processeddata and propdict: 
                try:
                    propdict["datasets"] = []
                    for item in processeddata:
                        if item != "time" and item != "date":
                            propdict["datasets"].append({"text": item.replace(".", " "), "values":processeddata.get(item)})
                        elif item == "time":
                            propdict["x_axis"]["labels"]["times"] = processeddata.get(item)
                        elif item == "date":                    
                            propdict["x_axis"]["labels"]["dates"] = processeddata.get(item)
                except:
                    _log.error( "Could not add data to chart" )
                result = json.dumps(propdict)
                
        else:
            _log.error( "Not enough arguments passed to allow processing" )
         
        return result
    
    # Serves dataset from siteLogRoot and graph_prop.xml from /static/css
    # as combined Json for use with OpenFlashChart
    # TODO: Move data processing out of controllers
    @turbogears.expose()
    def jsonfiles(self, filterstr = None):
        """
        """
        result = ""
        
        # get the location of log files
        logPath = turbogears.config.get ('siteLogRoot', None, False, 'DEFAULT')

        filenames = []
        if logPath:
            if filterstr:
                _log.debug( "Filter Filenames using: %s" %(filterstr))
                for filename in listdir(logPath):
                    if filterstr in filename:
                        filenames.append(filename)
            else:
                _log.debug( "No filter string provided - return all filenames")
                for filename in listdir(logPath):
                    filenames.append(filename)
            
            resultdict = {"options":filenames}
            result = json.dumps(resultdict)
        else: 
            _log.error( "No valid siteRootLog" )
        return result                     
        
    
       
    @turbogears.expose()
    def redirect(self,*args):
        """ 
        generalised redirect, so Gateway can manage locations of cameras etc.
        The URLs returned may be changed dependant on whether client on local network or not
        """
        cfgStr = turbogears.config.get(args[0], None, False, "redirect" )
        if cfgStr:
            raise cherrypy.HTTPRedirect(cfgStr)
        return self.index()

    #@turbogears.expose()
    def default(self,*args):
        return self.panels()
示例#7
0
class TestSendEvent(unittest.TestCase):
    def setUp(self):
        self._log = logging.getLogger( "TestSendEvent" )
        self._log.debug( "\n\nsetUp" )

        self.router = None
        self.loader = None

        ClientProfiles.load( "./Output/browser_profiles.xml" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigSendEvent) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        cherrypy.root = TestRoot(self.router)

    def tearDown(self):
        self._log.debug( "\n\ntearDown" )

        if self.loader:
            self.loader.stop()  # all tasks
            self.loader = None
        self.router = None

        time.sleep(1)

    # send a simpel event
    def testSimpleEvent(self):
        self._log.debug( "\ntestSimpleEvent" )

        testutil.create_request("/sendevent/test/event")

        # We should see lots of events here as initial pass.
        self.assertEqual( len(EventHandlers.tests.TestEventLogger._events), 1 )
        self.assertEqual( EventHandlers.tests.TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/uri" )
        self.assertEqual( EventHandlers.tests.TestEventLogger._events[0].getSource(), "test/event" )
        self.assertEqual( EventHandlers.tests.TestEventLogger._events[0].getPayload(), None )

    # send an event with a different event type
    def testAlternateEventType(self):
        self._log.debug( "\ntestAlternateEventType" )

        testutil.create_request("/sendevent/test/event?type=http://id.webbrick.co.uk/test/type")

        self.assertEqual( len(EventHandlers.tests.TestEventLogger._events), 1 )
        self.assertEqual( EventHandlers.tests.TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/test/type" )
        self.assertEqual( EventHandlers.tests.TestEventLogger._events[0].getSource(), "test/event" )
        self.assertEqual( EventHandlers.tests.TestEventLogger._events[0].getPayload(), None )

    # send an event with a different event type
    def testParameters(self):
        self._log.debug( "\ntestParameters" )

        testutil.create_request("/sendevent/test/event?p1=1&p2=2")

        self.assertEqual( len(EventHandlers.tests.TestEventLogger._events), 1 )
        self.assertEqual( EventHandlers.tests.TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/uri" )
        self.assertEqual( EventHandlers.tests.TestEventLogger._events[0].getSource(), "test/event" )
        self.assertEqual( len(EventHandlers.tests.TestEventLogger._events[0].getPayload()), 2 )

    # send an event with a different event type
    def testAlternateEventTypeAndParameters(self):
        self._log.debug( "\ntestAlternateEventTypeAndParameters" )

        testutil.create_request("/sendevent/test/event?type=http://id.webbrick.co.uk/test/type&p1=1&p2=2")

        self.assertEqual( len(EventHandlers.tests.TestEventLogger._events), 1 )
        self.assertEqual( EventHandlers.tests.TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/test/type" )
        self.assertEqual( EventHandlers.tests.TestEventLogger._events[0].getSource(), "test/event" )
        self.assertEqual( len(EventHandlers.tests.TestEventLogger._events[0].getPayload()), 2 )
示例#8
0
class TestHeatmiser(unittest.TestCase):

    def setUp(self):
        _log.debug( "\n\nsetUp" )
        TestEventLogger._events = []  # empty list

        self.router = None
        self.loader = None

    def tearDown(self):
        _log.debug( "\n\ntearDown" )

        if self.loader:
            self.loader.stop()  # all tasks
            self.loader = None
        self.router = None

        #time.sleep(1)

    def testReadParameters(self):
        driver = HeatmiserDriver( serialPort )
        driver.open()
        par = driver.readParameter( heatmiserAdr2 )
        self.assertNotEqual( par, None )
        _log.debug( "%s", par )

        driver.close()

    def testGetStatus(self):
        driver = HeatmiserDriver( serialPort )
        driver.open()
        par = driver.getStatus( heatmiserAdr2 )
        self.assertNotEqual( par, None )
        _log.debug( "%s", par )

        driver.close()

    def testScan(self):
        # locate heatmisers
        driver = HeatmiserDriver( serialPort )
        driver.open()
        for idx in range(32):
            par = driver.getStatus( idx )
            if par:
                _log.info( "Heatmiser %i %s", idx, par )

        driver.close()

    def testReadParameters2(self):
        driver = HeatmiserDriver( serialPort )
        driver.open()

        par = driver.readParameter( heatmiserAdr1 )
        self.assertNotEqual( par, None )
        _log.debug( "%s", par )

        par = driver.readParameter( heatmiserAdr2 )
        self.assertNotEqual( par, None )
        _log.debug( "%s", par )

        driver.close()

    def testWriteParameters(self):
        _log.debug( "\ntestWriteParameters" )
        driver = HeatmiserDriver( serialPort )
        driver.open()
        par = driver.readParameter( heatmiserAdr2 )
        self.assertNotEqual( par, None )
        _log.debug( "%s", par )

        #par["partNr"] = 3
        par["hour"] = 20
        par["minute"] = 30
        par["dayOfWeek"] = 7
        par["tempCal"] = par["roomT"]

        driver.writeParameter( heatmiserAdr2, par )
        _log.debug( "%s", par )

        par = driver.readParameter( heatmiserAdr2 )
        self.assertNotEqual( par, None )
        _log.debug( "%s", par )

        driver.close()

    def testWriteParameters2(self):
        _log.debug( "\ntestWriteParameters2" )
        driver = HeatmiserDriver( serialPort )
        driver.open()

        par = driver.readParameter( heatmiserAdr1 )
        self.assertNotEqual( par, None )
        _log.debug( "%s", par )

        par["tempCal"] = par["roomT"]
        par["hour"] = 20
        par["minute"] = 30
        par["dayOfWeek"] = 7

        driver.writeParameter( heatmiserAdr1, par )
        _log.debug( "%s", par )


        par = driver.readParameter( heatmiserAdr2 )
        self.assertNotEqual( par, None )
        _log.debug( "%s", par )

        par["tempCal"] = par["roomT"]
        par["hour"] = 20
        par["minute"] = 30
        par["dayOfWeek"] = 7

        driver.writeParameter( heatmiserAdr2, par )
        _log.debug( "%s", par )

        driver.close()

    def testResetAll(self):
        # Not so much a test but set heatmiser to known state
        _log.debug( "\ntestResetAll" )
        driver = HeatmiserDriver( serialPort )
        driver.open()
        params = driver.readParameter( heatmiserAdr2 )
        self.failIfEqual( params, None, "no comms" )
        _log.debug( "%s", params )

        params["dayOfWeek"] = 1
        params["hour"] = 23
        params["minute"] = 45
        params["tempCal"] = 18
        params["partNr"]  = 3
        params["differential"] = 1

        params["format"] = "C"
        params["frostMode"] = "disabled"
        params["sensor"] = "internal"
        params["floorLimit"] = "disabled"
        params["frostProt"] = "off"
        params["allKey"] = "unlocked"
        params["state"] = "off"
        params["setT"] = 20
        params["frostT"] = 7
        params["delay"] = 1
        params["preheat"] = 0
        params["floorMaxT"] = 30

        self.assert_( driver.writeParameter( heatmiserAdr2, params ) )

        daySchList = [
            HeatmiserSchEntry( hours=7, minutes=0, setPoint=18 ),
            HeatmiserSchEntry( hours=8, minutes=30, setPoint=14 ),
            HeatmiserSchEntry( hours=16, minutes=0, setPoint=21 ),
            HeatmiserSchEntry( hours=22, minutes=30, setPoint=14 ),
            ]

        wendSchList = [
            HeatmiserSchEntry( hours=7, minutes=0, setPoint=18 ),
            HeatmiserSchEntry( hours=8, minutes=30, setPoint=14 ),
            HeatmiserSchEntry( hours=16, minutes=0, setPoint=21 ),
            HeatmiserSchEntry( hours=22, minutes=30, setPoint=14 ),
            ]
        
        self.assert_( driver.setSchedule( heatmiserAdr2, CMD_SET_HEAT_WEEK_C_SET, MODEL_PRTN, daySchList ) )
        self.assert_( driver.setSchedule( heatmiserAdr2, CMD_SET_HEAT_WEND_C_SET, MODEL_PRTN, wendSchList ) )

        driver.close()

    def testSetClock(self):
        _log.debug( "\ntestSetClock" )

        driver = HeatmiserDriver( serialPort )

        interface = HeatmiserState( None, driver, heatMiserCfg ) # No event router
        driver.open()

        _log.debug( "%s" % interface.readStatus() )    # ensure model initialised

        self.assert_( interface.setClock( 1, 12, 34 ) )

        clk = interface.readClock()
        _log.debug( "%s", clk )

        driver.close()
        self.assertEqual( clk["dayOfWeek"], 1 )
        self.assertEqual( clk["hour"], 12 )
        self.assertEqual( clk["minute"], 34 )

    def testLoadConfig(self):
        _log.debug( "\ntestLoadConfig" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigHeatmiser) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        time.sleep(1)

    def testFirstRead(self):
        _log.debug( "\ntestFirstRead" )
        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigHeatmiser) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        time.sleep(1)

        oldLen = len(TestEventLogger._events)
        # for each schedule entry 4 weekday, 4 weekend
        # send time and day event and set point event
        # 16 events
        # send two current values setpoint and current value
        
        expectedEvents = { 
                    "http://id.webbrick.co.uk/events/config/set" : 
                            [
                                ("schedule/room2/0" , 'time', '07:00:00', 'day', '-MTWtF-'),
                                ("schedule/room2/1" , 'time', '08:30:00', 'day', '-MTWtF-'),
                                ("schedule/room2/2" , 'time', '16:00:00', 'day', '-MTWtF-'),
                                ("schedule/room2/3" , 'time', '22:30:00', 'day', '-MTWtF-'),
                                ("schedule/room2/4" , 'time', '07:00:00', 'day', 'S-----s'),
                                ("schedule/room2/5" , 'time', '08:30:00', 'day', 'S-----s'),
                                ("schedule/room2/6" , 'time', '16:00:00', 'day', 'S-----s'),
                                ("schedule/room2/7" , 'time', '22:30:00', 'day', 'S-----s'),
                                ("schedule/room2/0/room2" , 'val', None),
                                ("schedule/room2/1/room2" , 'val', None),
                                ("schedule/room2/2/room2" , 'val', None),
                                ("schedule/room2/3/room2" , 'val', None),
                                ("schedule/room2/4/room2" , 'val', None),
                                ("schedule/room2/5/room2" , 'val', None),
                                ("schedule/room2/6/room2" , 'val', None),
                                ("schedule/room2/7/room2" , 'val', None),
                            ],
                    "http://id.webbrick.co.uk/events/heatmiser/current":
                            [
                                ("heatmiser/room2/setpoint" , 'val', None ),
                                ("heatmiser/room2/temperature" , 'val', None ),
                            ]
                }

        TestEventLogger.logEvents()
        _log.info( "Expected Events %s " % (expectedEvents) )
        haveErr, excessEvents = Utils.verifyEvents( expectedEvents, TestEventLogger._events )

        _log.info( "Excess Events %s " % (excessEvents) )

        self.assertEqual( haveErr, False, "Incorrect event set" )

    def testSecondRead(self):
        _log.debug( "\ntestSecondRead" )
        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigHeatmiser) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        time.sleep(1)   # allow start
        oldLen = len(TestEventLogger._events)
        self.assertEqual( oldLen, 18 )

        self.router.publish( EventAgent("TestHeatmiser"), Events.evtSecond15 )  # re-read
        time.sleep(1)

        TestEventLogger.logEvents()

        # additional time event
        self.assertEqual( oldLen+1, len(TestEventLogger._events) )

    def testSendConfigure(self):
        _log.debug( "\ntestSendConfigure" )
        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigHeatmiser) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        oldLen = len(TestEventLogger._events)
        self.assertEqual( oldLen, 18 )

        # send command event

        self.router.publish( EventAgent("TestHeatmiser"), Events.evtSecond15 )  # re-read
        time.sleep(1)

        TestEventLogger.logEvents()

        # additional time event
        self.assertEqual( oldLen+1, len(TestEventLogger._events) )

    def testVerifyClock(self):
        _log.debug( "\ntestVerifyClock" )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigHeatmiser) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()
        time.sleep(1)

        self.router.publish( EventAgent("TestHeatmiser"), Events.evtTimexx3030 )   # trigger heatmiser verify of clock.
        time.sleep(3)

        self.loader.stop()  # all tasks
        self.loader = None
        self.router = None

        # re opne to read clock.
        driver = HeatmiserDriver( serialPort )

        interface = HeatmiserState( None, driver, heatMiserCfg ) # No event router
        driver.open()

        _log.debug( "%s" % interface.readStatus() )    # ensure model initialised

        clk = interface.readClock()
        _log.debug( "%s" % clk )

        driver.close()

        nowTime = time.gmtime()
        # nowTime[3] = hour
        # nowTime[4] = minute
        # nowTime[6] = day of week

        self.assertEqual( clk["dayOfWeek"], nowTime[6]+1 )
        self.assertEqual( clk["hour"], nowTime[3] )
        self.assertEqual( clk["minute"], nowTime[4] )

    def testChangeCurSetPoint(self):
        _log.debug( "\ntestChangeCurSetPoint" )
        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigHeatmiser) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        time.sleep(1)
        oldLen = len(TestEventLogger._events)
        self.assertEqual( oldLen, 18 )

        # send command event
        self.router.publish( EventAgent("TestHeatmiser"), evtCurrentConfigure16Degrees )

        self.router.publish( EventAgent("TestHeatmiser"), Events.evtSecond15 )  # re-read

        time.sleep(1)

        TestEventLogger.logEvents()

        # additional time event
        self.assertEqual( oldLen+3, len(TestEventLogger._events) )

    def testChangeSchTime(self):
        _log.debug( "\ntestChangeSchTime" )
        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigHeatmiser) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        time.sleep(1)
        oldLen = len(TestEventLogger._events)
        self.assertEqual( oldLen, 18 )

        # send command event
        self.router.publish( EventAgent("TestHeatmiser"), evtScheduleConfigure1230 )
        time.sleep(1)

        self.router.publish( EventAgent("TestHeatmiser"), Events.evtSecond15 )  # re-read
        time.sleep(1)

        TestEventLogger.logEvents()

        # additional events, control. time, 2  update events.
        self.assertEqual( oldLen+4, len(TestEventLogger._events) )

    def testChangeSchAction(self):
        _log.debug( "\ntestChangeSchAction" )
        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testConfigHeatmiser) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        time.sleep(1)
        oldLen = len(TestEventLogger._events)
        self.assertEqual( oldLen, 18 )

        # send command event
        self.router.publish( EventAgent("TestHeatmiser"), evtScheduleConfigure15Degrees )
        time.sleep(1)

        self.router.publish( EventAgent("TestHeatmiser"), Events.evtSecond15 )  # re-read
        time.sleep(1)

        TestEventLogger.logEvents()

        # additional events, control. time, 1  update events.
        self.assertEqual( oldLen+3, len(TestEventLogger._events) )

    def testDummy(self):
        return
class TestPersistFile(unittest.TestCase):

    def setUp(self):
        self._log = logging.getLogger( "TestPersistFile" )
        self._log.debug( "\nsetUp" )
        self.setCwd = False
        if exists("EventHandlers/tests/resources"):
            self.setCwd = True
            os.chdir("EventHandlers/tests")
            
        if exists(outFile):
            os.unlink( outFile )
        
        if exists(outFile+'.bak'):
            os.unlink( outFile+'.bak' )
            
        if exists(outFile+'.daily'):
            os.unlink( outFile+'.daily' )
        
        self.router = None
        self.loader = None

    def tearDown(self):
        self._log.debug( "\n\ntearDown" )

        if self.loader:
            self.loader.stop()  # all tasks
            self.loader = None
        self.router = None

        time.sleep(1)
        if self.setCwd:
            os.chdir("../..")
            
    def expectNevents(self, cnt ):
        idx = 20
        while (len(TestEventLogger._events) < cnt) and (idx > 0):
            time.sleep(0.05)
            idx = idx - 1

        if ( len(TestEventLogger._events) != cnt):
            TestEventLogger.logEvents()

        self.assertEqual( len(TestEventLogger._events), cnt)

    def sendSeconds ( self ):
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/time/second',
                'time/second',
                {'val':1} ) )
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/time/second',
                'time/second',
                {'val':1} ) )
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/time/second',
                'time/second',
                {'val':1} ) )
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/time/second',
                'time/second',
                {'val':1} ) )
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/time/second',
                'time/second',
                {'val':1} ) )
                

    # Actual tests follow

    def testCreate_fromScratch(self):
        """ NOTE: This will throw an Error, since there is no persist file! This Error is expected and should occur!
        """
        self._log.debug( "\ntestCreate_fromScratch" )
            
        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()
        
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/config/set',
                'test/persist4',
                {'val':4} ) )
        self.expectNevents(2)
        
        # thats all folks.
        self.failUnless( exists(outFile) )

    def testCreate_fromBak(self):
        self._log.debug( "\ntestCreate_fromBak" )
        copyfile( refFile1, outFileBak )
        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        # Only want to know if .bak was copied to outfile
        self.failUnless( exists(outFile) )
        
    def testCreate_fromDaily(self):
        self._log.debug( "\ntestCreate_fromDaily" )
        copyfile( refFile1, outFileDaily )
        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        # Only want to know if .daily was copied to outfile
        self.failUnless( exists(outFile) )
        
        
    def testCreateAndAdd(self):
        """ NOTE: This will throw an Error, since there is no persist file! This Error is expected and should occur!
        """
        self._log.debug( "\ntestCreateAndAdd" )
        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()
        
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/config/set',
                'test/persist4',
                {'val':4} ) )

        self.expectNevents(2)
        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/config/set" )
        self.assertEqual( TestEventLogger._events[0].getSource(), "test/persist4" )
        self.assertEqual( TestEventLogger._events[0].getPayload()['val'], 4 )
        self.assertEqual( TestEventLogger._events[1].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[1].getSource(), "test/persist4" )
        self.assertEqual( TestEventLogger._events[1].getPayload()['val'], 4 )

    def testCreateAndAdd2(self):
        """ NOTE: This will throw an Error, since there is no persist file! This Error is expected and should occur!
        """
        self._log.debug( "\ntestCreateAndAdd2" )
        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg2) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()
        
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/config/set',
                'test/persist4',
                {'val':4} ) )

        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/config/set',
                'test/persist5',
                {'val':5} ) )

        self.expectNevents(4)
        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/config/set" )
        self.assertEqual( TestEventLogger._events[0].getSource(), "test/persist4" )
        self.assertEqual( TestEventLogger._events[0].getPayload()['val'], 4 )
        self.assertEqual( TestEventLogger._events[1].getType(), "http://id.webbrick.co.uk/events/config/set" )
        self.assertEqual( TestEventLogger._events[1].getSource(), "test/persist5" )
        self.assertEqual( TestEventLogger._events[1].getPayload()['val'], 5 )
        self.assertEqual( TestEventLogger._events[2].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[2].getSource(), "test/persist4" )
        self.assertEqual( TestEventLogger._events[2].getPayload()['val'], 4 )
        self.assertEqual( TestEventLogger._events[3].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[3].getSource(), "test/persist5" )
        self.assertEqual( TestEventLogger._events[3].getPayload()['val'], 5 )

    def testStartup(self):
        self._log.debug( "\ntestStartup" )
        copyfile( refFile1, outFile )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()
        self.expectNevents(1)
               
        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[0].getSource(), "test/persist" )

    def testStartup2(self):
        self._log.debug( "\ntestStartup2" )
        copyfile( refFile2, outFile )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        # copy baseline file to working.
        # expect a single event of the only persisted value

        self.expectNevents(2)
        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[0].getSource(), "test/persist2" )
        self.assertEqual( TestEventLogger._events[1].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[1].getSource(), "test/persist" )

    def testStartup3(self):
        self._log.debug( "\ntestStartup3" )
        copyfile( refFile3, outFile )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()
        
        self.router.publish( EventAgent("TestPersistFile"), Events.evtRuntime5)

        # copy baseline file to working.
        # expect a single event of the only persisted value

        self.expectNevents(4)
        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[0].getSource(), "test/persist2" )
        self.assertEqual( TestEventLogger._events[0].getPayload()['val'], '1' )
        self.assertEqual( TestEventLogger._events[0].getPayload()['val2'], '2' )
        self.assertEqual( TestEventLogger._events[1].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[1].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[1].getPayload()['val'], '1' )

    def testStartup4(self):
        self._log.debug( "\ntestStartup" )
        copyfile( refFile1, outFile )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg3) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()
        # expect a single event of the only persisted value

        self.expectNevents(1)
        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[0].getSource(), "test/persist" )

    def testUpdateExist(self):
        self._log.debug( "\ntestUpdateExist" )
        copyfile( refFile1, outFile )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.sendSeconds()

        self.expectNevents(1)
        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[0].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[0].getPayload()['val'], '1' )

        # copy baseline file to working.
        # expect a single event of the only persisted value
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/config/set',
                'test/persist',
                {'val':3} ) )

        self.sendSeconds()

        self.expectNevents(3)
        self.assertEqual( TestEventLogger._events[1].getType(), "http://id.webbrick.co.uk/events/config/set" )
        self.assertEqual( TestEventLogger._events[1].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[1].getPayload()['val'], 3 )
        self.assertEqual( TestEventLogger._events[2].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[2].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[2].getPayload()['val'], 3 )
        


    def testUpdateExist2(self):
        self._log.debug( "\ntestUpdateExist2" )
        copyfile( refFile1, outFile )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg2) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.sendSeconds()

        self.expectNevents(1)
        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[0].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[0].getPayload()['val'], '1' )

        # copy baseline file to working.
        # expect a single event of the only persisted value
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/config/set',
                'test/persist',
                {'val':3} ) )
                
        self.sendSeconds()

        self.expectNevents(3)
        self.assertEqual( TestEventLogger._events[1].getType(), "http://id.webbrick.co.uk/events/config/set" )
        self.assertEqual( TestEventLogger._events[1].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[1].getPayload()['val'], 3 )
        self.assertEqual( TestEventLogger._events[2].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[2].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[2].getPayload()['val'], 3 )

    def testUpdateExistMultiValue(self):
        self._log.debug( "\ntestUpdateExistMultiValue" )
        copyfile( refFile3, outFile )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.sendSeconds()
        
        self.expectNevents(2)
        

        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[0].getSource(), "test/persist2" )
        self.assertEqual( TestEventLogger._events[0].getPayload()['val'], '1' )
        self.assertEqual( TestEventLogger._events[0].getPayload()['val2'], '2' )
        self.assertEqual( TestEventLogger._events[1].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[1].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[1].getPayload()['val'], '1' )

        # expect a single event of the only persisted value
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/config/set',
                'test/persist2',
                {'val2':3} ) )

        self.sendSeconds()
        
        self.expectNevents(4)
        self.assertEqual( TestEventLogger._events[2].getType(), "http://id.webbrick.co.uk/events/config/set" )
        self.assertEqual( TestEventLogger._events[2].getSource(), "test/persist2" )
        self.assertEqual( TestEventLogger._events[2].getPayload()['val2'], 3 )
        self.assertEqual( TestEventLogger._events[3].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[3].getSource(), "test/persist2" )
        self.assertEqual( TestEventLogger._events[3].getPayload()['val'], '1' )
        self.assertEqual( TestEventLogger._events[3].getPayload()['val2'], 3 )
    
    def testDailyExists(self):
        self._log.debug( "\ntestDailyExists" )
        copyfile( refFile1, outFile )
        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        # send in 19.00 time event
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/time/minute',
                'time/minute',
                {'hour':19
                , 'minute': 5} ) )
        time.sleep(1)
        self.expectNevents(1)
        # Only want to know if current xml was coppied to .daily
        self.failUnless( exists(outFileDaily) )
    
    def testWriteNew(self):
        self._log.debug( "\ntestWriteNew" )
        copyfile( refFile1, outFile )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.sendSeconds()

        self.expectNevents(1)
        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[0].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[0].getPayload()['val'], '1' )

        # copy baseline file to working.
        # expect a single event of the only persisted value
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/config/set',
                'test/persist4',
                {'val':4} ) )

        self.sendSeconds()

        self.expectNevents(3)
        self.assertEqual( TestEventLogger._events[1].getType(), "http://id.webbrick.co.uk/events/config/set" )
        self.assertEqual( TestEventLogger._events[1].getSource(), "test/persist4" )
        self.assertEqual( TestEventLogger._events[1].getPayload()['val'], 4 )
        self.assertEqual( TestEventLogger._events[2].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[2].getSource(), "test/persist4" )
        self.assertEqual( TestEventLogger._events[2].getPayload()['val'], 4 )

    def testUpdateReload(self):
        self._log.debug( "\ntestUpdateReload" )
        copyfile( refFile1, outFile )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.sendSeconds()

        self.expectNevents(1)
        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[0].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[0].getPayload()['val'], '1' )

        # copy baseline file to working.
        # expect a single event of the only persisted value
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/config/set',
                'test/persist5',
                {'val':5} ) )

        self.sendSeconds()

        self.expectNevents(3)
        self.assertEqual( TestEventLogger._events[1].getType(), "http://id.webbrick.co.uk/events/config/set" )
        self.assertEqual( TestEventLogger._events[1].getSource(), "test/persist5" )
        self.assertEqual( TestEventLogger._events[1].getPayload()['val'], 5 )
        self.assertEqual( TestEventLogger._events[2].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[2].getSource(), "test/persist5" )
        self.assertEqual( TestEventLogger._events[2].getPayload()['val'], 5 )

        self.loader.stop()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.sendSeconds()

        time.sleep(2)
        self.expectNevents(2)
        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[0].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[0].getPayload()['val'], '1' )
        self.assertEqual( TestEventLogger._events[1].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[1].getSource(), "test/persist5" )
        self.assertEqual( TestEventLogger._events[1].getPayload()['val'], '5' )

    def testPersistFileWrite ( self ):
        """
        A testcase to determine the functionality of the persist file modifications with the countdown timer implementation.        
        """
        
        self._log.debug( "\ntestPersistFileWrite" )
        copyfile( refFile1, outFile )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg3) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.sendSeconds()

        self.expectNevents(1)
        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[0].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[0].getPayload()['val'], '1' )
        
        self.sendSeconds()

        savePath = os.path.join("/usr/lib/python2.5/site-packages/WebBrickLibs-2.0-py2.5.egg/EventHandlers/tests/TestOut/persist.xml")
        content = ""
        fileHandle = open(savePath, 'w')
        fileHandle.write(content)
        fileHandle.close()
        time.sleep(1)

        # expect a single event of the only persisted value
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/config/set',
                'test/persist',
                {'val':57} ) )
                
        self.sendSeconds()

        time.sleep(2)

        i = 0
        for line in open(savePath, "r"):
            self._log.debug("line: " + line)
            i = i + 1

        self.assertEqual(i, 8)

        self.expectNevents(3)
        self.assertEqual( TestEventLogger._events[1].getType(), "http://id.webbrick.co.uk/events/config/set" )
        self.assertEqual( TestEventLogger._events[1].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[1].getPayload()['val'], 57 )
        self.assertEqual( TestEventLogger._events[2].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[2].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[2].getPayload()['val'], 57 )

    def testNoPersistFileWrite ( self ):
        """
        A testcase to determine the functionality of the persist file modifications with the countdown timer implementation.        
        """
        
        self._log.debug( "\ntestPersistFileWrite" )
        copyfile( refFile1, outFile )

        self.loader = EventRouterLoader()
        self.loader.loadHandlers( getDictFromXmlString(testPersistCfg3) )
        self.loader.start()  # all tasks
        self.router = self.loader.getEventRouter()

        self.sendSeconds()

        self.expectNevents(1)
        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[0].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[0].getPayload()['val'], '1' )
        
        self.sendSeconds()

        savePath = os.path.join("/usr/lib/python2.5/site-packages/WebBrickLibs-2.0-py2.5.egg/EventHandlers/tests/TestOut/persist.xml")
        content = ""
        fileHandle = open(savePath, 'w')
        fileHandle.write(content)
        fileHandle.close()
        time.sleep(1)

        # expect a single event of the only persisted value
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/config/set',
                'test/persist',
                {'val':1} ) )
                
        self.sendSeconds()

        time.sleep(2)

        content = ""
        fileHandle = open(savePath, 'w')
        fileHandle.write(content)
        fileHandle.close()
        time.sleep(1)

        # expect a single event of the only persisted value
        self.router.publish( EventAgent("TestPersistFile"), Event( 'http://id.webbrick.co.uk/events/config/set',
                'test/persist',
                {'val':1} ) )

        time.sleep(2)

        i = 0
        for line in open(savePath, "r"):
            self._log.debug("line: " + line)
            i = i + 1



        self.assertEqual(i, 0)

        self.expectNevents(5)
        self.assertEqual( TestEventLogger._events[1].getType(), "http://id.webbrick.co.uk/events/config/set" )
        self.assertEqual( TestEventLogger._events[1].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[1].getPayload()['val'], 1 )
        self.assertEqual( TestEventLogger._events[2].getType(), "http://id.webbrick.co.uk/events/config/get" )
        self.assertEqual( TestEventLogger._events[2].getSource(), "test/persist" )
        self.assertEqual( TestEventLogger._events[2].getPayload()['val'], 1 )



    def testDummy(self):
        return
class TestEventRouterLoad(unittest.TestCase):

    def setUp(self):
        _log.debug( "\n\nsetUp" )
        self._loader = None
        self._router = None
        self.setCwd = False
        if exists("EventHandlers/tests/resources"):
            self.setCwd = True
            os.chdir("EventHandlers/tests")

    def tearDown(self):
        _log.debug( "\n\ntearDown" )

        if self._loader:
            self._loader.stop()
            self._loader = None
        self._router = None
        time.sleep(1)
        if self.setCwd:
            os.chdir("../..")

    # Actual tests follow

    def testTestEventLogger(self):
        """
        Test loading the test event logger
        """
        _log.debug( "\ntestTestEventLogger" )
        self._loader = EventRouterLoader()
        self._loader.loadHandlers( getDictFromXmlString(testConfigTestEventLogger) )

        self._loader.start()  # all tasks

        self._router = self._loader.getEventRouter()

        self._router.publish( EventAgent("TestEventRouterLoad"), Events.evtTD0 )
        self._router.publish( EventAgent("TestEventRouterLoad"), Events.evtTD1 )
        
        if len(TestEventLogger._events) < 2 :
            time.sleep(1)   # allow threading to catch up.

        # now look for correct events requests
        TestEventLogger.logEvents()

        self.assertEqual( len(TestEventLogger._events), 2)
        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/webbrick/TD" )
        self.assertEqual( TestEventLogger._events[0].getSource(), "webbrick/100/TD/0" )
        self.assertEqual( TestEventLogger._events[1].getType(), "http://id.webbrick.co.uk/events/webbrick/TD" )
        self.assertEqual( TestEventLogger._events[1].getSource(), "webbrick/100/TD/1" )

    def doSimpleTest(self):

        self._router.publish( EventAgent("TestEventRouterLoad"), Events.evtDO_0_off )
        self._router.publish( EventAgent("TestEventRouterLoad"), Events.evtDO_1_off )
        self._router.publish( EventAgent("TestEventRouterLoad"), Events.evtDO_1_on )

        if len(TestEventLogger._events) < 8 :
            time.sleep(1)   # allow threading to catch up.

        # now look for correct events requests
        TestEventLogger.logEvents()

        self.assertEqual( len(TestEventLogger._events), 5)
        base = 0
#        self.assertEqual( len(TestEventLogger._events), 8)
#        self.assertEqual( TestEventLogger._events[0].getType(), "http://id.webbrick.co.uk/events/subscribe" )
#        self.assertEqual( TestEventLogger._events[1].getType(), "http://id.webbrick.co.uk/events/subscribe" )
#        self.assertEqual( TestEventLogger._events[2].getType(), "http://id.webbrick.co.uk/events/subscribe" )
#        base = 3

        #
        # artifact of simple router is that the event logger may see new events before triggering events.
        #
        # type, source and space for a parameter

        expectedEvents = { 
                    "local/url" : 
                            [
                                ("local/BoilerOn",),
                                ("local/HwOn",),
                            ],
                    "http://id.webbrick.co.uk/events/webbrick/DO" : 
                            [   
                                ("webbrick/100/DO/0",),
                                ("webbrick/100/DO/1",),
                                ("webbrick/100/DO/1",),
                            ],
                     }
        _log.debug( "Received Events %s " % (TestEventLogger._events) )

        haveErr, excessEvents = Utils.verifyEvents( expectedEvents, TestEventLogger._events )

        _log.debug( "Excess Events %s " % (excessEvents) )

        self.assertEqual( haveErr, False, "Incorrect event set" )

    def testConfigureDefault(self):
        """
        Test loading a single event handler
        """
        _log.debug( "\ntestConfigureDefault" )
        self._loader = EventRouterLoader()
        self._loader.loadHandlers( getDictFromXmlString(testConfigDefault) )

        self._loader.start()  # all tasks

        self._router = self._loader.getEventRouter()
        self.doSimpleTest()

    def testConfigureThreaded(self):
        """
        Test loading a single event handler
        """
        _log.debug( "\ntestConfigureThreaded" )
        self._loader = EventRouterLoader()
        self._loader.loadHandlers( getDictFromXmlString(testConfigThreaded) )

        self._loader.start()  # all tasks

        self._router = self._loader.getEventRouter()
        self.doSimpleTest()

    def testConfigureRouter(self):
        """
        Test loading a single event handler
        """
        _log.debug( "\ntestConfigureRouter" )
        self._loader = EventRouterLoader()
        self._loader.loadHandlers( getDictFromXmlString(testConfigRouter) )

        self._loader.start()  # all tasks

        self._router = self._loader.getEventRouter()
        self.doSimpleTest()

        self._loader.stop()  # all tasks

    def testConfigurePubSub(self):
        """
        Test loading a single event handler
        """
        _log.debug( "\ntestConfigurePubSub" )
        self._loader = EventRouterLoader()
        self._loader.loadHandlers( getDictFromXmlString(testConfigPubSub) )

        self._loader.start()  # all tasks

        self._router = self._loader.getEventRouter()
        self.doSimpleTest()

    def testFileConfigure(self):
        _log.debug( "\ntestDirectoryConfigure" )

        self._loader = EventRouterLoader()
        self._loader.loadFromFile( "./resources/testEventRouterLoad/fromFile.xml" )

        self._loader.start()  # all tasks

        self._router = self._loader.getEventRouter()

        self.doSimpleTest()

    def testDirectoryConfigure(self):
        _log.debug( "\ntestDirectoryConfigure" )

        self._loader = EventRouterLoader()
        self._loader.loadFromDirectories( "./resources/testEventRouterLoad/fromDirLoad" )

        self._loader.start()  # all tasks

        self._router = self._loader.getEventRouter()

        self.doSimpleTest()

    def testDirectoriesConfigure(self):
        _log.debug( "\ntestDirectoryConfigure" )

        self._loader = EventRouterLoader()
        self._loader.loadFromDirectories( "./resources/testEventRouterLoad/fromDirLoad1:./resources/testEventRouterLoad/fromDirLoad2" )

        self._loader.start()  # all tasks

        self._router = self._loader.getEventRouter()

        self.doSimpleTest()

    def testConfigureMultiple(self):
        """
        Test loading a single event handler
        """
        _log.debug( "\ntestConfigureMultiple" )
        self._loader = EventRouterLoader()
        self._loader.loadHandlers( getDictFromXmlString(testConfigMultiple1) )
        self._loader.loadHandlers( getDictFromXmlString(testConfigMultiple2) )

        self._loader.start()  # all tasks

        self._router = self._loader.getEventRouter()
        self.doSimpleTest()

    def testDummy(self):
        return