make timer test working
authorFelix Domke <tmbinc@elitedvb.net>
Mon, 26 Mar 2007 16:00:10 +0000 (16:00 +0000)
committerFelix Domke <tmbinc@elitedvb.net>
Mon, 26 Mar 2007 16:00:10 +0000 (16:00 +0000)
tests/README [new file with mode: 0644]
tests/enigma.py
tests/fake_time.py
tests/test_timer.py

diff --git a/tests/README b/tests/README
new file mode 100644 (file)
index 0000000..63f8369
--- /dev/null
@@ -0,0 +1,42 @@
+enigma2 test environment
+
+
+The goal is to test as much components of enigma2 with as less dependencies
+as possible. So we create an environment which emulates "all" runtime
+dependencies with fixed value. 
+
+Only python is tested, all c++ stuff is re-implemented in python (usually as
+dummy functions).
+
+When testing components, they should be kept seperated. If this is not
+possible, you can try overriding imports, for example you can replace
+Notification support with dummy notifications to prevent the whole GUI from
+loading...
+
+If even that doesn't help, the component is bad, and should be fixed. Please
+try to seperate changes to the test system from changes from components.
+Please don't add specific test functionality into the components. If they
+are not remote controllable, the component is badly writen anyway.
+
+Usually, all dummy functions are implemented to not fail. They emit special
+events to signal what has been done. These results will be compared to the
+expected test results, so they should be consistent with each run. If you
+want to test failures, you need to install "fault hooks", where you can
+inject faults.
+
+For example:
+
+The timer test initializes
+ - the "real" navigation stuff,
+ - the real record config,
+ - the real parental control,
+ - inserts a fake null-notification handler,
+
+then it installs a timer, and runs the enigma mainloop (enigma.run()).
+Core events happening during the duration of the test (like "record prepare,
+record start, record stop") will be recorded, and compared after the test.
+
+(compare is not yet implemented)
+
+Starting these tests must currently done with
+PYTHONPATH=.:..:../lib/python/ python test_timer.py
index 97fcdb9..2f6acc6 100644 (file)
@@ -17,6 +17,8 @@ timers = set()
 
 import time
 
+from events import eventfnc
+
 ##################### ENIGMA BASE
 
 class eTimer:
@@ -30,7 +32,7 @@ class eTimer:
                self.singleshot = singleshot
                timers.add(self)
        
-       def stop():
+       def stop(self):
                timers.remove(self)
 
        def __repr__(self):
@@ -40,14 +42,12 @@ class eTimer:
                if self.singleshot:
                        self.stop()
                self.next_activation += self.msec / 1000.0
-               print "next activation now %d " % self.next_activation
                self.timeout()
 
 def runIteration():
        running_timers = list(timers)
        assert len(running_timers), "no running timers, so nothing will ever happen!"
        running_timers.sort(key=lambda x: x.next_activation)
-       print running_timers
        
        next_timer = running_timers[0]
 
@@ -66,12 +66,11 @@ stopped = False
 
 def stop():
        global stopped
-       print "STOP NOW"
        stopped = True
 
-def run():
+def run(duration = 1000):
        stoptimer = eTimer()
-       stoptimer.start(10000)
+       stoptimer.start(duration * 1000.0)
        stoptimer.timeout.get().append(stop)
        while not stopped:
                runIteration()
@@ -93,9 +92,44 @@ eWindowStyleSkinned = None
 eButton = None
 eListboxPythonStringContent = None
 eListbox = None
-eEPGCache = None
+
+class eEPGCache:
+       @classmethod
+       def getInstance(self):
+               return self.instance
+
+       instance = None
+
+       def __init__(self):
+               eEPGCache.instance = self
+
+       def lookupEventTime(self, ref, query):
+               return None
+
+eEPGCache()
+
 getBestPlayableServiceReference = None
 
+class pNavigation:
+       def __init__(self):
+               self.m_event = slot()
+               self.m_record_event = slot()
+
+       @eventfnc
+       def recordService(self, service):
+               return iRecordableService(service)
+
+       @eventfnc
+       def stopRecordService(self, service):
+               service.stop()
+
+       @eventfnc
+       def playService(self, service):
+               return None
+
+eRCInput = None
+getPrevAsciiCode = None
+
 class eServiceReference:
 
        isDirectory=1
@@ -112,11 +146,118 @@ class eServiceReference:
                self.ref = ref
                self.flags = 0
 
-iRecordableService = None
+       def toString(self):
+               return self.ref
+
+       def __repr__(self):
+               return self.toString()
+
+class iRecordableService:
+       def __init__(self, ref):
+               self.ref = ref
+
+       @eventfnc
+       def prepare(self, filename, begin, end, event_id):
+               return 0
+       
+       @eventfnc
+       def start(self):
+               return 0
+
+       @eventfnc
+       def stop(self):
+               return 0
+       
+       def __repr__(self):
+               return "iRecordableService(%s)" % repr(self.ref)
+
 quitMainloop = None
-eAVSwitch = None
+
+class eAVSwitch:
+       @classmethod
+       def getInstance(self):
+               return self.instance
+
+       instance = None
+
+       def __init__(self):
+               eAVSwitch.instance = self
+
+       def setColorFormat(self, value):
+               print "[eAVSwitch] color format set to %d" % value
+
+       def setAspectRatio(self, value):
+               print "[eAVSwitch] aspect ratio set to %d" % value
+
+       def setWSS(self, value):
+               print "[eAVSwitch] wss set to %d" % value
+
+       def setSlowblank(self, value):
+               print "[eAVSwitch] wss set to %d" % value
+
+       def setVideomode(self, value):
+               print "[eAVSwitch] wss set to %d" % value
+
+       def setInput(self, value):
+               print "[eAVSwitch] wss set to %d" % value
+
+eAVSwitch()
+
 eDVBVolumecontrol = None
-eDBoxLCD = None
+
+class eRFmod:
+       @classmethod
+       def getInstance(self):
+               return self.instance
+
+       instance = None
+
+       def __init__(self):
+               eRFmod.instance = self
+
+       def setFunction(self, value):
+               print "[eRFmod] set function to %d" % value
+
+       def setTestmode(self, value):
+               print "[eRFmod] set testmode to %d" % value
+
+       def setSoundFunction(self, value):
+               print "[eRFmod] set sound function to %d" % value
+
+       def setSoundCarrier(self, value):
+               print "[eRFmod] set sound carrier to %d" % value
+
+       def setChannel(self, value):
+               print "[eRFmod] set channel to %d" % value
+
+       def setFinetune(self, value):
+               print "[eRFmod] set finetune to %d" % value
+
+eRFmod()
+
+
+class eDBoxLCD:
+       @classmethod
+       def getInstance(self):
+               return self.instance
+       
+       instance = None
+       
+       def __init__(self):
+               eDBoxLCD.instance = self
+
+       def setLCDBrightness(self, value):
+               print "[eDBoxLCD] set brightness to %d" % value
+
+       def setLCDContrast(self, value):
+               print "[eDBoxLCD] set contrast to %d" % value
+
+       def setInverted(self, value):
+               print "[eDBoxLCD] set inverted to %d" % value
+
+eDBoxLCD();
+
+Misc_Options = None
 
 class eServiceCenter:
        @classmethod
@@ -161,3 +302,49 @@ class eActionMap:
                pass
 
 
+##################### ENIGMA STARTUP:
+
+def init_nav():
+       import Navigation, NavigationInstance
+       NavigationInstance.instance = Navigation.Navigation()
+
+def init_record_config():
+       import Components.RecordingConfig
+       Components.RecordingConfig.InitRecordingConfig()
+
+def init_parental_control():
+       from Components.ParentalControl import InitParentalControl
+       InitParentalControl()
+
+def init_all():
+       # this is stuff from mytest.py
+       init_nav()
+       
+       init_record_config()
+       init_parental_control()
+       
+       import Components.InputDevice
+       Components.InputDevice.InitInputDevices()
+
+       import Components.AVSwitch
+       Components.AVSwitch.InitAVSwitch()
+
+       import Components.UsageConfig
+       Components.UsageConfig.InitUsageConfig()
+
+       import Components.Network
+       Components.Network.InitNetwork()
+
+       import Components.Lcd
+       Components.Lcd.InitLcd()
+
+       import Components.SetupDevices
+       Components.SetupDevices.InitSetupDevices()
+
+       import Components.RFmod
+       Components.RFmod.InitRFmod()
+
+       import Components.NimManager
+
+       import Screens.Ci
+       Screens.Ci.InitCiConfig()
index 09f88b4..3c77ded 100644 (file)
@@ -1,10 +1,31 @@
 import time
 
-real_time = time.time
+real_time = None
+time_offset = 0
 
-time_offset = real_time()
+def setRealtime():
+       global real_time
+       real_time = time.time
+
+def setIdealtime():
+       global real_time
+       real_time = lambda: 0
+
+def setTime(now):
+       global time_offset
+       time_offset = real_time() - now
+
+setIdealtime()
+setTime(0)
 
 def my_time():
        return real_time() - time_offset
 
 time.time = my_time
+
+def my_sleep(sleep):
+       global time_offset
+       time_offset -= sleep
+       print "(faking %f seconds)" % sleep
+
+time.sleep = my_sleep
index 4745030..2ee76f1 100644 (file)
@@ -1,28 +1,79 @@
 import enigma
+import sys
+import time
 
-import RecordTimer
+#enigma.reset()
+def test_timer(repeat = 0, timer_start = 10, timer_length = 100):
+       import RecordTimer
+       
+       at = time.time()
+       
+       t = RecordTimer.RecordTimer()
 
-t = RecordTimer.RecordTimer()
+       # generate a timer to test
+       import xml.dom.minidom
 
-# generate a timer to test
-import xml.dom.minidom
+       timer = RecordTimer.createTimer(xml.dom.minidom.parseString(
+       """
+               <timer 
+                       begin="%d" 
+                       end="%d"
+                       serviceref="1:0:1:6DD2:44D:1:C00000:0:0:0:" 
+                       repeated="%d" 
+                       name="Test Event Name" 
+                       description="Test Event Description" 
+                       afterevent="nothing" 
+                       eit="56422" 
+                       disabled="0" 
+                       justplay="0">
+       </timer>""" % (at + timer_start, at + timer_start + timer_length, repeat)
+       ).childNodes[0])
 
-timer = RecordTimer.createTimer(xml.dom.minidom.parseString(
-"""
-       <timer 
-               begin="10" 
-               end="200"
-               serviceref="1:0:1:6DD2:44D:1:C00000:0:0:0:" 
-               repeated="0" 
-               name="Test Event Name" 
-               description="Test Event Description" 
-               afterevent="nothing" 
-               eit="56422" 
-               disabled="0" 
-               justplay="0">
-</timer>""").childNodes[0])
+       t.record(timer)
 
-t.record(timer)
+       # run virtual environment
+       enigma.run(4 * 86400)
+       
+       print "done."
+       
+       timers = t.processed_timers  + t.timer_list
+       
+       print "start: %s" % (time.ctime(at + 10))
+       
+       assert len(timers) == 1
+       
+       for t in timers:
+               print "begin=%d, end=%d, repeated=%d, state=%d" % (t.begin - at, t.end - at, t.repeated, t.state)
+               print "begin: %s" % (time.ctime(t.begin))
+               print "end: %s" % (time.ctime(t.end))
 
-# run virtual environment
-enigma.run()
+       # if repeat, check if the calculated repeated time of day matches the initial time of day
+       if repeat:
+               t_initial = time.localtime(at + timer_start)
+               t_repeated = time.localtime(timers[0].begin)
+               print t_initial
+               print t_repeated
+               
+#              assert t_initial[3:6] == t_repeated[3:6], "repeated timer time of day does not match"
+
+# required stuff for timer (we try to keep this minimal)
+enigma.init_nav()
+enigma.init_record_config()
+enigma.init_parental_control()
+
+
+import FakeNotifications
+sys.modules["Notifications"] = FakeNotifications
+
+from events import log
+
+import calendar
+
+
+import os
+# we are operating in CET/CEST
+os.environ['TZ'] = 'CET'
+time.tzset()
+
+log(test_timer, base_time = calendar.timegm((2007, 3, 24, 12, 0, 0)), repeat=0x7f)
+#log(test_timer, base_time = calendar.timegm((2007, 03, 20, 0, 0, 0)), repeat=0x7f)