Exemple #1
0
class EventConnectionTest(unittest.TestCase):

    def setUp(self):
        self.platform = getPlatform()
        self.translator = Mock()
        self.domainCache = Mock()
        self.settings = MythSettings(self.platform, self.translator)
        
        privateConfig = OnDemandConfig()
        self.settings.put('mysql_host', privateConfig.get('mysql_host'))
        self.settings.put('mysql_port', privateConfig.get('mysql_port'))
        self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
        self.settings.setMySqlUser(privateConfig.get('mysql_user'))  
        self.settings.put('mysql_password', privateConfig.get('mysql_password'))
        self.settings.put('paths_recordedprefix', privateConfig.get('paths_recordedprefix'))
        
        self.db = MythDatabase(self.settings, self.translator, self.domainCache)
        self.bus = EventBus()
        self.conn = EventConnection(self.settings, self.translator, self.platform, self.bus, self.db)

    def tearDown(self):
        self.conn.close()

    def test_read_a_system_event(self):
        x  = 1
        if 'MYTH_SNIFFER' in os.environ:
            x = 9999999
        for i in xrange(x):
            msg = self.conn.readEvent()
            print(msg)
            log.debug(msg)
Exemple #2
0
    def setUp(self):
        self.platform = getPlatform()
        self.translator = Mock()
        self.settings = MythSettings(self.platform, self.translator)

        privateConfig = OnDemandConfig()
        self.settings.put('mysql_host', privateConfig.get('mysql_host'))
        self.settings.put('mysql_port', privateConfig.get('mysql_port'))
        self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
        self.settings.setMySqlUser(privateConfig.get('mysql_user'))
        self.settings.put('mysql_password',
                          privateConfig.get('mysql_password'))
        self.settings.put('paths_recordedprefix',
                          privateConfig.get('paths_recordedprefix'))
        self.bus = EventBus()
        self.domainCache = Mock()
        pools['dbPool'] = Pool(
            MythDatabaseFactory(settings=self.settings,
                                translator=self.translator,
                                domainCache=self.domainCache))
        pools['connPool'] = Pool(
            ConnectionFactory(settings=self.settings,
                              translator=self.translator,
                              platform=self.platform,
                              bus=self.bus))
Exemple #3
0
 def test_verifyRecordingDirs_InvalidDirThrowsSettingsException(self):
     try:
         MythSettings.verifyRecordingDirs(
             os.path.join('someBogusDir', 'anotherBogusDir'))
         self.fail('expected failure')
     except SettingsException, se:
         log.debug('PASS: %s' % se)
Exemple #4
0
class MythEventPublisherTest(unittest.TestCase):

    def setUp(self):
        self.platform = getPlatform()
        self.translator = Mock()
        self.settings = MythSettings(self.platform, self.translator)
        
        privateConfig = OnDemandConfig()
        self.settings.put('mysql_host', privateConfig.get('mysql_host'))
        self.settings.put('mysql_port', privateConfig.get('mysql_port'))
        self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
        self.settings.setMySqlUser(privateConfig.get('mysql_user'))  
        self.settings.put('mysql_password', privateConfig.get('mysql_password'))
        self.settings.put('paths_recordedprefix', privateConfig.get('paths_recordedprefix'))
        self.bus = EventBus()
        self.domainCache = Mock()
        pools['dbPool']   = Pool(MythDatabaseFactory(settings=self.settings, translator=self.translator, domainCache=self.domainCache))
        pools['connPool'] = Pool(ConnectionFactory(settings=self.settings, translator=self.translator, platform=self.platform, bus=self.bus))
        
    def tearDown(self):
        pools['connPool'].shutdown()
        pools['dbPool'].shutdown()

    def test_event_publisher(self):
        publisher = MythEventPublisher(settings=self.settings, translator=self.translator, platform=self.platform, bus=self.bus)
        publisher.startup()
        time.sleep(5)
        publisher.shutdown()
Exemple #5
0
class EventConnectionTest(unittest.TestCase):
    def setUp(self):
        self.platform = getPlatform()
        self.translator = Mock()
        self.domainCache = Mock()
        self.settings = MythSettings(self.platform, self.translator)

        privateConfig = OnDemandConfig()
        self.settings.put('mysql_host', privateConfig.get('mysql_host'))
        self.settings.put('mysql_port', privateConfig.get('mysql_port'))
        self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
        self.settings.setMySqlUser(privateConfig.get('mysql_user'))
        self.settings.put('mysql_password',
                          privateConfig.get('mysql_password'))
        self.settings.put('paths_recordedprefix',
                          privateConfig.get('paths_recordedprefix'))

        self.db = MythDatabase(self.settings, self.translator,
                               self.domainCache)
        self.bus = EventBus()
        self.conn = EventConnection(self.settings, self.translator,
                                    self.platform, self.bus, self.db)

    def tearDown(self):
        self.conn.close()

    def test_read_a_system_event(self):
        x = 1
        if 'MYTH_SNIFFER' in os.environ:
            x = 9999999
        for i in xrange(x):
            msg = self.conn.readEvent()
            print(msg)
            log.debug(msg)
Exemple #6
0
 def test_getRecordingDirs_ManyDirectories(self):
     when(self.platform).getScriptDataDir().thenReturn(self.sandbox)
     settings = MythSettings(self.platform, self.translator)
     settings.put("paths_recordedprefix", os.pathsep.join(["a", "b", "c"]))
     log.debug("Recording prefix = %s" % settings.get("paths_recordedprefix"))
     dirs = settings.getRecordingDirs()
     self.assertEquals(3, len(dirs))
     self.assertEquals(["a", "b", "c"], dirs)
Exemple #7
0
 def test_verifyRecordingDirs_OneInvalidOutOfManyOKThrowsSettingsException(self):
     try:
         MythSettings.verifyRecordingDirs(
             tempfile.gettempdir() + os.pathsep + "someBogusDir" + os.pathsep + os.getcwd()
         )
         self.fail("expected failure")
     except SettingsException, se:
         log.debug("PASS: %s" % se)
Exemple #8
0
 def test_getRecordingDirs_SingleDirectory(self):
     when(self.platform).getScriptDataDir().thenReturn(self.sandbox)
     settings = MythSettings(self.platform, self.translator)
     settings.put("paths_recordedprefix", "/mnt/mythtv")
     log.debug("Recording prefix = %s" % settings.get("paths_recordedprefix"))
     dirs = settings.getRecordingDirs()
     self.assertEquals(1, len(dirs))
     self.assertEquals("/mnt/mythtv", dirs[0])
Exemple #9
0
 def test_verifyBoolean_AllValuesThatShouldRaiseException(self):
     badValues = ('true', 'false', '', '2', 'crap')
     for b in badValues:
         try:
             MythSettings.verifyBoolean(b, 'blah')
             self.fail('should have throws SettingsException')
         except SettingsException, se:
             log.debug('PASS: %s %s' % (b, se))
Exemple #10
0
 def test_saveSettings_LoadedDefaultsCreatesNewSettingsFile(self):
     filename = "settings.xml"
     filepath = os.path.join(self.sandbox, filename)
     when(self.platform).getScriptDataDir().thenReturn(self.sandbox)
     self.assertFalse(os.path.exists(filepath))
     s = MythSettings(self.platform, self.translator)
     s.save()
     self.assertTrue(os.path.exists(filepath))
Exemple #11
0
 def test_verifyBoolean_AllValuesThatShouldRaiseException(self):
     badValues = ("true", "false", "", "2", "crap")
     for b in badValues:
         try:
             MythSettings.verifyBoolean(b, "blah")
             self.fail("should have throws SettingsException")
         except SettingsException, se:
             log.debug("PASS: %s %s" % (b, se))
Exemple #12
0
 def test_saveSettings_LoadedDefaultsCreatesNewSettingsFile(self):
     filename = 'settings.xml'
     filepath = os.path.join(self.sandbox, filename)
     when(self.platform).getScriptDataDir().thenReturn(self.sandbox)
     self.assertFalse(os.path.exists(filepath))
     s = MythSettings(self.platform, self.translator)
     s.save()
     self.assertTrue(os.path.exists(filepath))
Exemple #13
0
 def test_verifyRecordingDirs_OneInvalidOutOfManyOKThrowsSettingsException(
         self):
     try:
         MythSettings.verifyRecordingDirs(tempfile.gettempdir() +
                                          os.pathsep + 'someBogusDir' +
                                          os.pathsep + os.getcwd())
         self.fail('expected failure')
     except SettingsException, se:
         log.debug('PASS: %s' % se)
Exemple #14
0
    def test_When_existing_setting_changed_to_different_value_Then_event_published_to_bus(self):
        # Setup
        when(self.platform).getScriptDataDir().thenReturn(self.sandbox)
        s = MythSettings(self.platform, self.translator, bus=self.bus)

        # Test
        s.get("mysql_host")
        s.put("mysql_host", "foo")

        # Verify
        verify(self.bus, 1).publish(any(dict))
Exemple #15
0
 def setUp(self):
     translator = mockito.Mock()
     platform = mockito.Mock()
     bus = mockito.Mock()
     settings = MythSettings(platform, translator)
     privateConfig = OnDemandConfig()
     settings.put('mysql_host', privateConfig.get('mysql_host'))
     settings.put('mysql_password', privateConfig.get('mysql_password'))
     settings.put('mysql_database', privateConfig.get('mysql_database'))
     self.db = MythDatabase(settings, translator)
     self.conn = Connection(settings, translator, platform, bus, self.db)
     self.brain = FileLiveTvBrain(self.conn, self.db)
 def setUp(self):
     p = Platform()
     langInfo = util_mock.XBMCLangInfo(p)
     translator = util_mock.Translator(p, langInfo)
     settings = MythSettings(p, translator)
     domainCache = Mock()
     
     privateConfig = OnDemandConfig()
     settings.put('mysql_host', privateConfig.get('mysql_host'))
     settings.put('mysql_database', privateConfig.get('mysql_database'))
     settings.put('mysql_user', privateConfig.get('mysql_user'))  
     settings.put('mysql_password', privateConfig.get('mysql_password'))
     
     self.dbPool = pool.pools['dbPool'] = pool.Pool(MythDatabaseFactory(settings=settings, translator=translator, domainCache=domainCache))
Exemple #17
0
class MythDatabaseTest(unittest.TestCase):
    def setUp(self):
        self.platform = Platform()

        # self.translator = Mock()
        self.langInfo = util_mock.XBMCLangInfo(self.platform)
        self.translator = util_mock.Translator(self.platform, self.langInfo)

        self.bus = Mock()
        self.domainCache = Mock()
        self.settings = MythSettings(self.platform, self.translator)

        privateConfig = OnDemandConfig()
        self.settings.put("mysql_host", privateConfig.get("mysql_host"))
        self.settings.put("mysql_database", privateConfig.get("mysql_database"))
        self.settings.put("mysql_password", privateConfig.get("mysql_password"))

        self.db = MythDatabase(self.settings, self.translator, self.domainCache)
        self.conn = Connection(self.settings, self.translator, self.platform, self.bus, self.db)

    def tearDown(self):
        # self.db.close()
        self.conn.close()

    def test_saveSchedule_NewSchedule(self):
        now = datetime.datetime.now()
        programs = self.db.getTVGuideDataFlattened(now, now, self.db.getChannels())
        if len(programs) == 0:
            log.warn("Cannot run unit tests without program listings in the database")
            return

        schedule = RecordingSchedule.fromProgram(programs[0], self.translator)
        log.debug("Test schedule = %s" % schedule)
        result = self.db.saveSchedule(schedule)
        log.debug("Save schedule result = %s" % result)

    def test_addJob_UserJob1(self):
        recordings = self.conn.getAllRecordings()
        if not recordings:
            log.warn("Cannot run unit tests without program listings in the database")
            return

        job = Job.fromProgram(recordings[-1], JobType.USERJOB & JobType.USERJOB1)
        log.debug(job)

        self.assertIsNone(job.id)
        self.db.addJob(job)
        log.debug(job)
        self.assertIsNotNone(job.id)
Exemple #18
0
    def test_When_setting_has_a_unicode_value_Then_saving_and_loading_should_still_work(
            self):
        when(self.platform).getScriptDataDir().thenReturn(self.sandbox)
        s = MythSettings(self.platform, self.translator)
        unicodeStr = u'Königreich der Himmel'
        s.put('recordings_selected_group', unicodeStr)
        s.save()

        s2 = MythSettings(self.platform, self.translator)
        actualStr = s2.get('recordings_selected_group')
        self.assertTrue(unicodeStr == actualStr)
        self.assertTrue(isinstance(unicodeStr, unicode))
Exemple #19
0
class MythThumbnailResolverTest(unittest.TestCase):
    def setUp(self):
        self.platform = getPlatform()
        self.translator = Mock()
        self.domainCache = Mock()
        self.settings = MythSettings(self.platform, self.translator)

        privateConfig = OnDemandConfig()
        self.settings.setMySqlHost(privateConfig.get('mysql_host'))
        self.settings.setMySqlPort(privateConfig.get('mysql_port'))
        self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
        self.settings.setMySqlUser(privateConfig.get('mysql_user'))
        self.settings.setMySqlPassword(privateConfig.get('mysql_password'))

        log.debug('%s' % self.settings)

        self.db = MythDatabase(self.settings, self.translator,
                               self.domainCache)
        self.bus = EventBus()
        self.conn = Connection(self.settings, self.translator, self.platform,
                               self.bus, self.db)

    def tearDown(self):
        self.conn.close()

    def test_store_download_thumbnail(self):
        # Setup
        recordings = self.conn.getRecordings()
        self.assertTrue(recordings, 'Recordings needed in to run test')
        downloader = MythThumbnailResolver(self.conn, self.db)
        dest = os.path.sep.join([
            tempfile.gettempdir(),
            'thumbnail_' + str(random.randint(1, 999999)) + '.png'
        ])

        # Test
        downloader.store(recordings[-1], dest)

        # Verify
        log.debug('Downloaded %s to %s' %
                  (safe_str(recordings[-1].title()), dest))
        self.assertTrue(os.path.exists(dest))
        self.assertTrue(os.path.isfile(dest))
        self.assertTrue(os.path.getsize(dest) > 0)

        # Cleanup
        os.remove(dest)
Exemple #20
0
 def setUp(self):
     self.platform = getPlatform()
     self.translator = Mock()
     self.domainCache = Mock()
     self.settings = MythSettings(self.platform, self.translator)
     
     privateConfig = OnDemandConfig()
     self.settings.put('mysql_host', privateConfig.get('mysql_host'))
     self.settings.put('mysql_port', privateConfig.get('mysql_port'))
     self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
     self.settings.setMySqlUser(privateConfig.get('mysql_user'))  
     self.settings.put('mysql_password', privateConfig.get('mysql_password'))
     self.settings.put('paths_recordedprefix', privateConfig.get('paths_recordedprefix'))
     
     self.db = MythDatabase(self.settings, self.translator, self.domainCache)
     self.bus = EventBus()
     self.conn = EventConnection(self.settings, self.translator, self.platform, self.bus, self.db)
Exemple #21
0
 def setUp(self):
     self.platform = Platform()
     self.langInfo = util_mock.XBMCLangInfo(self.platform)
     self.translator = util_mock.Translator(self.platform, self.langInfo)
     self.settings = MythSettings(self.platform, self.translator)
     self.protocol = protocol.Protocol56()
     privateConfig = OnDemandConfig()
     self.settings.put('mysql_host', privateConfig.get('mysql_host'))
     self.settings.put('mysql_port', privateConfig.get('mysql_port'))
     self.settings.put('mysql_database',
                       privateConfig.get('mysql_database'))
     self.settings.put('mysql_user', privateConfig.get('mysql_user'))
     self.settings.put('mysql_password',
                       privateConfig.get('mysql_password'))
     self.domainCache = Mock()
     self.db = MythDatabase(self.settings, self.translator,
                            self.domainCache)
Exemple #22
0
 def test_constructor_NonExistentSettingsFilesLoadsDefaults(self):
     when(self.platform).getScriptDataDir().thenReturn(self.sandbox)
     s = MythSettings(self.platform, self.translator)
     self.assertEquals('localhost', s.get('mysql_host'))
     self.assertEquals('3306', s.get('mysql_port'))
     self.assertEquals('mythconverg', s.get('mysql_database'))
     self.assertEquals('mythtv', s.get('mysql_user'))
     self.assertEquals('change_me', s.get('mysql_password'))
Exemple #23
0
class MythThumbnailResolverTest(unittest.TestCase):

    def setUp(self):
        self.platform = getPlatform()
        self.translator = Mock()
        self.domainCache = Mock()
        self.settings = MythSettings(self.platform, self.translator)
        
        privateConfig = OnDemandConfig()
        self.settings.setMySqlHost(privateConfig.get('mysql_host'))
        self.settings.setMySqlPort(privateConfig.get('mysql_port'))
        self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
        self.settings.setMySqlUser(privateConfig.get('mysql_user'))  
        self.settings.setMySqlPassword(privateConfig.get('mysql_password'))
        
        log.debug('%s' % self.settings)
        
        self.db = MythDatabase(self.settings, self.translator, self.domainCache)
        self.bus = EventBus()
        self.conn = Connection(self.settings, self.translator, self.platform, self.bus, self.db)

    def tearDown(self):
        self.conn.close()

    def test_store_download_thumbnail(self):
        # Setup
        recordings = self.conn.getRecordings()
        self.assertTrue(recordings, 'Recordings needed in to run test')
        downloader = MythThumbnailResolver(self.conn, self.db)
        dest = os.path.sep.join([tempfile.gettempdir(), 'thumbnail_' + str(random.randint(1, 999999)) + '.png'])

        # Test
        downloader.store(recordings[-1], dest)
         
        # Verify
        log.debug('Downloaded %s to %s' % (safe_str(recordings[-1].title()), dest))
        self.assertTrue(os.path.exists(dest))
        self.assertTrue(os.path.isfile(dest))
        self.assertTrue(os.path.getsize(dest) > 0)
                
        # Cleanup
        os.remove(dest)        
Exemple #24
0
    def setUp(self):
        self.platform = getPlatform()
        self.translator = Mock()
        self.domainCache = Mock()
        self.settings = MythSettings(self.platform, self.translator)

        privateConfig = OnDemandConfig()
        self.settings.setMySqlHost(privateConfig.get('mysql_host'))
        self.settings.setMySqlPort(privateConfig.get('mysql_port'))
        self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
        self.settings.setMySqlUser(privateConfig.get('mysql_user'))
        self.settings.setMySqlPassword(privateConfig.get('mysql_password'))

        log.debug('%s' % self.settings)

        self.db = MythDatabase(self.settings, self.translator,
                               self.domainCache)
        self.bus = EventBus()
        self.conn = Connection(self.settings, self.translator, self.platform,
                               self.bus, self.db)
Exemple #25
0
class MythEventPublisherTest(unittest.TestCase):
    def setUp(self):
        self.platform = getPlatform()
        self.translator = Mock()
        self.settings = MythSettings(self.platform, self.translator)

        privateConfig = OnDemandConfig()
        self.settings.put('mysql_host', privateConfig.get('mysql_host'))
        self.settings.put('mysql_port', privateConfig.get('mysql_port'))
        self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
        self.settings.setMySqlUser(privateConfig.get('mysql_user'))
        self.settings.put('mysql_password',
                          privateConfig.get('mysql_password'))
        self.settings.put('paths_recordedprefix',
                          privateConfig.get('paths_recordedprefix'))
        self.bus = EventBus()
        self.domainCache = Mock()
        pools['dbPool'] = Pool(
            MythDatabaseFactory(settings=self.settings,
                                translator=self.translator,
                                domainCache=self.domainCache))
        pools['connPool'] = Pool(
            ConnectionFactory(settings=self.settings,
                              translator=self.translator,
                              platform=self.platform,
                              bus=self.bus))

    def tearDown(self):
        pools['connPool'].shutdown()
        pools['dbPool'].shutdown()

    def test_event_publisher(self):
        publisher = MythEventPublisher(settings=self.settings,
                                       translator=self.translator,
                                       platform=self.platform,
                                       bus=self.bus)
        publisher.startup()
        time.sleep(5)
        publisher.shutdown()
Exemple #26
0
class MythDatabaseTest(unittest.TestCase):
    def setUp(self):
        self.platform = Platform()

        #self.translator = Mock()
        self.langInfo = util_mock.XBMCLangInfo(self.platform)
        self.translator = util_mock.Translator(self.platform, self.langInfo)

        self.bus = Mock()
        self.domainCache = Mock()
        self.settings = MythSettings(self.platform, self.translator)

        privateConfig = OnDemandConfig()
        self.settings.put('mysql_host', privateConfig.get('mysql_host'))
        self.settings.put('mysql_database',
                          privateConfig.get('mysql_database'))
        self.settings.put('mysql_password',
                          privateConfig.get('mysql_password'))

        self.db = MythDatabase(self.settings, self.translator,
                               self.domainCache)
        self.conn = Connection(self.settings, self.translator, self.platform,
                               self.bus, self.db)

    def tearDown(self):
        #self.db.close()
        self.conn.close()

    def test_saveSchedule_NewSchedule(self):
        now = datetime.datetime.now()
        programs = self.db.getTVGuideDataFlattened(now, now,
                                                   self.db.getChannels())
        if len(programs) == 0:
            log.warn(
                'Cannot run unit tests without program listings in the database'
            )
            return

        schedule = RecordingSchedule.fromProgram(programs[0], self.translator)
        log.debug('Test schedule = %s' % schedule)
        result = self.db.saveSchedule(schedule)
        log.debug('Save schedule result = %s' % result)

    def test_addJob_UserJob1(self):
        recordings = self.conn.getAllRecordings()
        if not recordings:
            log.warn(
                'Cannot run unit tests without program listings in the database'
            )
            return

        job = Job.fromProgram(recordings[-1],
                              JobType.USERJOB & JobType.USERJOB1)
        log.debug(job)

        self.assertIsNone(job.id)
        self.db.addJob(job)
        log.debug(job)
        self.assertIsNotNone(job.id)
Exemple #27
0
    def setUp(self):
        self.platform = Platform()

        #self.translator = Mock()
        self.langInfo = util_mock.XBMCLangInfo(self.platform)
        self.translator = util_mock.Translator(self.platform, self.langInfo)

        self.bus = Mock()
        self.domainCache = Mock()
        self.settings = MythSettings(self.platform, self.translator)

        privateConfig = OnDemandConfig()
        self.settings.put('mysql_host', privateConfig.get('mysql_host'))
        self.settings.put('mysql_database',
                          privateConfig.get('mysql_database'))
        self.settings.put('mysql_password',
                          privateConfig.get('mysql_password'))

        self.db = MythDatabase(self.settings, self.translator,
                               self.domainCache)
        self.conn = Connection(self.settings, self.translator, self.platform,
                               self.bus, self.db)
Exemple #28
0
    def test_When_setting_has_a_unicode_value_Then_saving_and_loading_should_still_work(self):
        when(self.platform).getScriptDataDir().thenReturn(self.sandbox)
        s = MythSettings(self.platform, self.translator)
        unicodeStr = u"Königreich der Himmel"
        s.put("recordings_selected_group", unicodeStr)
        s.save()

        s2 = MythSettings(self.platform, self.translator)
        actualStr = s2.get("recordings_selected_group")
        self.assertTrue(unicodeStr == actualStr)
        self.assertTrue(isinstance(unicodeStr, unicode))
Exemple #29
0
 def test_constructor_NonExistentSettingsFilesLoadsDefaults(self):
     when(self.platform).getScriptDataDir().thenReturn(self.sandbox)
     s = MythSettings(self.platform, self.translator)
     self.assertEquals("localhost", s.get("mysql_host"))
     self.assertEquals("3306", s.get("mysql_port"))
     self.assertEquals("mythconverg", s.get("mysql_database"))
     self.assertEquals("mythtv", s.get("mysql_user"))
     self.assertEquals("change_me", s.get("mysql_password"))
Exemple #30
0
 def setUp(self):
     self.data = { 
         'title'       : 'Bonanza', 
         'subtitle'    : 'The Shootout',
         'description' : 'Yee haw!',
         'starttime'   : datetime.datetime(2008, 11, 21, 14),
         'endtime'     : datetime.datetime(2008, 11, 21, 14),
         'channum'     : '23',
         'hdtv'        : True
     }
     self.translator = Mock() 
     self.platform = Platform()
     self.protocol = TEST_PROTOCOL
     self.settings = MythSettings(self.platform, self.translator)
Exemple #31
0
 def setUp(self):
     self.platform = Platform()
     self.langInfo = util_mock.XBMCLangInfo(self.platform)
     self.translator = util_mock.Translator(self.platform, self.langInfo)
     self.settings = MythSettings(self.platform, self.translator)
     self.protocol = protocol.Protocol56()
     privateConfig = OnDemandConfig()
     self.settings.put('mysql_host', privateConfig.get('mysql_host'))
     self.settings.put('mysql_port', privateConfig.get('mysql_port'))
     self.settings.put('mysql_database', privateConfig.get('mysql_database'))
     self.settings.put('mysql_user', privateConfig.get('mysql_user'))  
     self.settings.put('mysql_password', privateConfig.get('mysql_password'))
     self.domainCache = Mock()
     self.db = MythDatabase(self.settings, self.translator, self.domainCache)
Exemple #32
0
 def test_getRecordingDirs_SingleDirectory(self):
     when(self.platform).getScriptDataDir().thenReturn(self.sandbox)
     settings = MythSettings(self.platform, self.translator)
     settings.put('paths_recordedprefix', '/mnt/mythtv')
     log.debug("Recording prefix = %s" %
               settings.get('paths_recordedprefix'))
     dirs = settings.getRecordingDirs()
     self.assertEquals(1, len(dirs))
     self.assertEquals('/mnt/mythtv', dirs[0])
Exemple #33
0
 def test_getRecordingDirs_ManyDirectories(self):
     when(self.platform).getScriptDataDir().thenReturn(self.sandbox)
     settings = MythSettings(self.platform, self.translator)
     settings.put('paths_recordedprefix', os.pathsep.join(['a', 'b', 'c']))
     log.debug("Recording prefix = %s" %
               settings.get('paths_recordedprefix'))
     dirs = settings.getRecordingDirs()
     self.assertEquals(3, len(dirs))
     self.assertEquals(['a', 'b', 'c'], dirs)
Exemple #34
0
 def setUp(self):
     self.platform = getPlatform()
     self.translator = Mock()
     self.domainCache = Mock()
     self.settings = MythSettings(self.platform, self.translator)
     
     privateConfig = OnDemandConfig()
     self.settings.setMySqlHost(privateConfig.get('mysql_host'))
     self.settings.setMySqlPort(privateConfig.get('mysql_port'))
     self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
     self.settings.setMySqlUser(privateConfig.get('mysql_user'))  
     self.settings.setMySqlPassword(privateConfig.get('mysql_password'))
     
     self.db = MythDatabase(self.settings, self.translator, self.domainCache)
     self.bus = EventBus()
     self.conn = Connection(self.settings, self.translator, self.platform, self.bus, self.db)
Exemple #35
0
 def setUp(self):
     self.platform = getPlatform()
     self.translator = Mock()
     self.settings = MythSettings(self.platform, self.translator)
     
     privateConfig = OnDemandConfig()
     self.settings.put('mysql_host', privateConfig.get('mysql_host'))
     self.settings.put('mysql_port', privateConfig.get('mysql_port'))
     self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
     self.settings.setMySqlUser(privateConfig.get('mysql_user'))  
     self.settings.put('mysql_password', privateConfig.get('mysql_password'))
     self.settings.put('paths_recordedprefix', privateConfig.get('paths_recordedprefix'))
     self.bus = EventBus()
     self.domainCache = Mock()
     pools['dbPool']   = Pool(MythDatabaseFactory(settings=self.settings, translator=self.translator, domainCache=self.domainCache))
     pools['connPool'] = Pool(ConnectionFactory(settings=self.settings, translator=self.translator, platform=self.platform, bus=self.bus))
Exemple #36
0
    def test_constructor_LoadExistingSettingsFile(self):
        # Setup
        settingsDir = os.path.join('resources', 'test')
        settingsFile = 'test_mythtv_settings.xml'
        when(self.platform).getScriptDataDir().thenReturn(settingsDir)

        # Test
        s = MythSettings(self.platform, self.translator, settingsFile)

        # Verify
        self.assertEquals('test_host', s.get('mysql_host'))
        self.assertEquals('9999', s.get('mysql_port'))
        self.assertEquals('test_database', s.get('mysql_database'))
        self.assertEquals('test_user', s.get('mysql_user'))
        self.assertEquals('test_password', s.get('mysql_password'))
Exemple #37
0
    def test_When_existing_setting_changed_to_different_value_Then_event_published_to_bus(
            self):
        # Setup
        when(self.platform).getScriptDataDir().thenReturn(self.sandbox)
        s = MythSettings(self.platform, self.translator, bus=self.bus)

        # Test
        s.get('mysql_host')
        s.put('mysql_host', 'foo')

        # Verify
        verify(self.bus, 1).publish(any(dict))
Exemple #38
0
 def setUp(self):
     translator = mockito.Mock()
     platform = mockito.Mock()
     bus = mockito.Mock()
     settings = MythSettings(platform, translator)
     privateConfig = OnDemandConfig()
     settings.put('mysql_host', privateConfig.get('mysql_host'))
     settings.put('mysql_password', privateConfig.get('mysql_password'))
     settings.put('mysql_database', privateConfig.get('mysql_database'))
     self.db = MythDatabase(settings, translator)
     self.conn = Connection(settings, translator, platform, bus, self.db)
     self.brain = FileLiveTvBrain(self.conn, self.db)
Exemple #39
0
    def setUp(self):
        self.platform = Platform()

        # self.translator = Mock()
        self.langInfo = util_mock.XBMCLangInfo(self.platform)
        self.translator = util_mock.Translator(self.platform, self.langInfo)

        self.bus = Mock()
        self.domainCache = Mock()
        self.settings = MythSettings(self.platform, self.translator)

        privateConfig = OnDemandConfig()
        self.settings.put("mysql_host", privateConfig.get("mysql_host"))
        self.settings.put("mysql_database", privateConfig.get("mysql_database"))
        self.settings.put("mysql_password", privateConfig.get("mysql_password"))

        self.db = MythDatabase(self.settings, self.translator, self.domainCache)
        self.conn = Connection(self.settings, self.translator, self.platform, self.bus, self.db)
Exemple #40
0
 def setUp(self):
     self.platform = getPlatform()
     self.translator = Mock()
     self.domainCache = Mock()
     self.settings = MythSettings(self.platform, self.translator)
     self.settings.put('streaming_enabled', 'False')
     
     privateConfig = OnDemandConfig()
     self.settings.put('mysql_host', privateConfig.get('mysql_host'))
     self.settings.put('mysql_port', privateConfig.get('mysql_port'))
     self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
     self.settings.setMySqlUser(privateConfig.get('mysql_user'))  
     self.settings.put('mysql_password', privateConfig.get('mysql_password'))
     self.settings.put('paths_recordedprefix', privateConfig.get('paths_recordedprefix'))
     
     self.db = MythDatabase(self.settings, self.translator, self.domainCache)
     self.bus = EventBus()
     self.conn = Connection(self.settings, self.translator, self.platform, self.bus, self.db)
Exemple #41
0
    def test_constructor_LoadExistingSettingsFile(self):
        # Setup
        settingsDir = os.path.join("resources", "test")
        settingsFile = "test_mythtv_settings.xml"
        when(self.platform).getScriptDataDir().thenReturn(settingsDir)

        # Test
        s = MythSettings(self.platform, self.translator, settingsFile)

        # Verify
        self.assertEquals("test_host", s.get("mysql_host"))
        self.assertEquals("9999", s.get("mysql_port"))
        self.assertEquals("test_database", s.get("mysql_database"))
        self.assertEquals("test_user", s.get("mysql_user"))
        self.assertEquals("test_password", s.get("mysql_password"))
Exemple #42
0
 def test_verifyMySQLUser_OK(self):
     MythSettings.verifyMySQLUser("someUser")
Exemple #43
0
class MythChannelIconResolverTest(unittest.TestCase):

    def setUp(self):
        self.platform = getPlatform()
        self.translator = Mock()
        self.domainCache = Mock()
        self.settings = MythSettings(self.platform, self.translator)
        
        privateConfig = OnDemandConfig()
        self.settings.setMySqlHost(privateConfig.get('mysql_host'))
        self.settings.setMySqlPort(privateConfig.get('mysql_port'))
        self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
        self.settings.setMySqlUser(privateConfig.get('mysql_user'))  
        self.settings.setMySqlPassword(privateConfig.get('mysql_password'))
        
        self.db = MythDatabase(self.settings, self.translator, self.domainCache)
        self.bus = EventBus()
        self.conn = Connection(self.settings, self.translator, self.platform, self.bus, self.db)

    def tearDown(self):
        self.conn.close()

    def test_store_When_channel_has_icon_Then_download_icon(self):
        # Setup
        channels = filter(lambda x: x.getIconPath(), self.db.getChannels()) # filter out channels that don't have an icon
        self.assertTrue(len(channels) > 0, 'Channels with icon needed in db to run test')
        downloader = MythChannelIconResolver(self.conn)
         
        # Test - download icons for first 5 channels
        for channel in channels[:min(5, len(channels))]:
            if channel.getIconPath():
                dest = os.path.sep.join([tempfile.gettempdir(), 'channel_' + str(channel.getChannelId()) + channel.getCallSign() + str(time.time()) + '.png'])
                downloader.store(channel, dest)
        
                # Verify
                log.debug('Downloaded %s to %s' % (channel.getIconPath(), dest))
                self.assertTrue(os.path.exists(dest))
                self.assertTrue(os.path.isfile(dest))
                self.assertTrue(os.path.getsize(dest) > 0)
                
                # Cleanup
                os.remove(dest)        
    
    def test_store_When_channel_has_no_icon_Then_do_nothing(self):
        # Setup
        channel = Channel({'name':'Bogus Channel', 'icon':None, 'chanid': '9', 'callsign': 'WXYZ'})
        conn = Mock()
        downloader = MythChannelIconResolver(conn)
         
        # Test 
        downloader.store(channel, 'bogusDestDir')
    
        # Verify
        verifyZeroInteractions(conn)

    def test_store_When_channel_has_iconpath_but_filename_misspelled_Then_do_nothing(self):
        # Setup
        channel = Channel({'name':'Bogus Channel', 'icon': 'bogusIcon.png', 'chanid': '9', 'callsign': 'WXYZ'})
        downloader = MythChannelIconResolver(self.conn)
         
        # Test - download icons for first 5 channels
        dest = os.path.sep.join([tempfile.gettempdir(), str(channel.getChannelId()) + channel.getCallSign() + str(time.time()) + ".png"])
        downloader.store(channel, dest)

        # Verify
        self.assertFalse(os.path.exists(dest))
Exemple #44
0
 def test_verifyRecordingDirs_OKManyDirectories(self):
     MythSettings.verifyRecordingDirs(
         self.sandbox + os.pathsep + os.getcwd() + os.pathsep + self.sandbox + os.pathsep + os.getcwd()
     )
Exemple #45
0
 def test_verifyBoolean_AllValuesThatShouldNotRaiseException(self):
     MythSettings.verifyBoolean('True', 'blah')
     MythSettings.verifyBoolean('False', 'blah')
     MythSettings.verifyBoolean('1', 'blah')
     MythSettings.verifyBoolean('0', 'blah')
Exemple #46
0
    def bootstrapSettings(self):
        self.stage = 'Initializing Settings'
        from mythbox.settings import MythSettings
        self.settings = MythSettings(self.platform, self.translator,
                                     'settings.xml', self.bus)

        #from fanart import FanArt
        #self.log.debug('Settings = \n %s' % self.settings)

        class DelayedInstantiationProxy(object):
            '''Could use a little introspection to sort this out but eh...'''
            def __init__(self, *args, **kwargs):
                self.args = args
                self.kwargs = kwargs
                self.fanArt = None

            def requireDelegate(self):
                if self.fanArt is None:
                    from fanart import FanArt
                    self.fanArt = FanArt(*self.args, **self.kwargs)

            def getSeasonAndEpisode(self, program):
                self.requireDelegate()
                return self.fanArt.getSeasonAndEpisode(program)

            def getRandomPoster(self, program):
                self.requireDelegate()
                return self.fanArt.getRandomPoster(program)

            def getPosters(self, program):
                self.requireDelegate()
                return self.fanArt.getPosters(program)

            def hasPosters(self, program):
                self.requireDelegate()
                return self.fanArt.hasPosters(program)

            def clear(self):
                self.requireDelegate()
                self.fanArt.clear()

            def shutdown(self):
                self.requireDelegate()
                self.fanArt.shutdown()

            def configure(self, settings):
                self.requireDelegate()
                self.fanArt.configure(settings)

            def onEvent(self, event):
                self.requireDelegate()
                self.fanArt.onEvent(event)

        from fanart import FanArt
        self.fanArt = FanArt(self.platform, self.httpCache, self.settings,
                             self.bus)
        #self.fanArt = DelayedInstantiationProxy(self.platform, self.httpCache, self.settings, self.bus)

        try:
            import socket
            socket.setdefaulttimeout(float(os.getenv('MYTHBOX_TIMEOUT', '30')))
        except:
            self.log.exception('Error setting socket timeout')

        self.bus.register(self)

        # Generate fake event to reflect value in settings.xml instead of mythbox_log.ini
        from bus import Event
        self.onEvent({
            'id': Event.SETTING_CHANGED,
            'tag': 'logging_enabled',
            'old': 'DontCare',
            'new': self.settings.get('logging_enabled')
        })
Exemple #47
0
class MythDatabaseTest(unittest.TestCase):

    def setUp(self):
        self.platform = Platform()
        self.langInfo = util_mock.XBMCLangInfo(self.platform)
        self.translator = util_mock.Translator(self.platform, self.langInfo)
        self.settings = MythSettings(self.platform, self.translator)
        self.protocol = protocol.Protocol56()
        privateConfig = OnDemandConfig()
        self.settings.put('mysql_host', privateConfig.get('mysql_host'))
        self.settings.put('mysql_port', privateConfig.get('mysql_port'))
        self.settings.put('mysql_database', privateConfig.get('mysql_database'))
        self.settings.put('mysql_user', privateConfig.get('mysql_user'))  
        self.settings.put('mysql_password', privateConfig.get('mysql_password'))
        self.domainCache = Mock()
        self.db = MythDatabase(self.settings, self.translator, self.domainCache)

    def tearDown(self):
        try:
            self.db.close()
        except:
            pass
        
    def test_constructor(self):
        self.assertTrue(self.db)

    def test_toBackend(self):
        master = self.db.getMasterBackend()
        self.assertEqual(master, self.db.toBackend(master.hostname))
        self.assertEqual(master, self.db.toBackend(master.ipAddress))
        self.assertTrue(master,   self.db.toBackend('bogus'))
        self.assertEqual(master, self.db.toBackend(master.hostname.upper()))
        self.assertEqual(master, self.db.toBackend(master.hostname.lower()))
        
    def test_getBackends(self):
        bes = self.db.getBackends()
        self.assertTrue(len(bes) >= 1)
        
    def test_getMasterBackend(self):
        mbe = self.db.getMasterBackend()
        log.debug(mbe)        
        self.assertTrue(mbe.hostname)
        self.assertTrue(mbe.ipAddress)
        self.assertTrue(mbe.port)
        self.assertTrue(mbe.master)
        self.assertFalse(mbe.slave)
    
    def test_getSlaveBackends(self):
        slaves = self.db.getSlaveBackends()
        for slave in slaves:
            log.debug(slave)
            self.assertFalse(slave.master)
            self.assertTrue(slave.slave)
        
    def test_getChannels(self):
        channels = self.db.getChannels()
        for i, channel in enumerate(channels):
            log.debug("%d - %s"%(i+1, channel))
            self.assertTrue('Expected int but was %s' % type(channel.getChannelId()), isinstance(channel.getChannelId(), int))
            self.assertTrue('Expected str but was %s' % type(channel.getChannelNumber()), isinstance(channel.getChannelNumber(), str))
            self.assertTrue('Expected str but was %s' % type(channel.getCallSign()), isinstance(channel.getCallSign(), str))
            self.assertTrue('Expected str but was %s' % type(channel.getChannelName()), isinstance(channel.getChannelName(), str))
            self.assertTrue('Expected str but was %s' % type(channel.getIconPath()), isinstance(channel.getIconPath(), str))
            self.assertTrue('Expected int but was %s' % type(channel.getTunerId()), isinstance(channel.getTunerId(), int))

    def test_getRecordingProfileNames(self):
        self.assertTrue(self.db.getRecordingProfileNames())
                
    def test_getRecordingGroups(self):
        groups = self.db.getRecordingGroups()
        self.assertTrue('Default' in groups)

    def test_getRecordingTitles_InAllGroups(self):
        titles = self.db.getRecordingTitles('All Groups')
        self.assertTrue(len(titles) > 0)
        total = titles[0][1]
        for i, title in enumerate(titles):
            titleName = title[0]
            titleCount = title[1]
            log.debug('%d - %s x %s' %(i+1, titleCount, titleName))

    def test_getRecordingTitles_ForNonExistantRecordingGroupReturnsAllShowsWithCountOfZero(self):
        titles = self.db.getRecordingTitles('bogus group')
        self.assertEquals(1, len(titles))
        self.assertEquals('All Shows', titles[0][0])
        self.assertEquals(0, titles[0][1])

    def test_getRecordingTitles_ForDeletedRecordingsGroup(self):
        deleted = self.db.getRecordingTitles('Deleted')
        for i, title in enumerate(deleted):
            titleName = title[0]
            titleCount = title[1]
            log.debug('%d - Deleted recording %s recorded %s times' % (i+1, titleName, titleCount))
        self.assertTrue(len(deleted) > 0)

    def test_getTuners(self):
        tuners = self.db.getTuners()
        self.assertTrue(len(tuners) > 0, 'No tuners found')
        for i, tuner in enumerate(tuners):
            log.debug('%d - %s' %(i+1, tuner))
            self.assertIsNotNone(tuner.tunerId)
            self.assertIsNotNone(tuner.hostname)
            self.assertIsNotNone(tuner.signalTimeout)
            self.assertIsNotNone(tuner.channelTimeout)
            self.assertIsNotNone(tuner.domainCache)
            
    def test_getMythSetting_KeyOnly_Found(self):
        s = self.db.getMythSetting('mythfilldatabaseLastRunStatus')
        log.debug('mythfillstatus = %s' % s)
        self.assertFalse(s is None)

    def test_getMythSetting_KeyOnly_NotFound(self):
        s = self.db.getMythSetting('blahblah')
        self.assertTrue(s is None)

    def test_getMythSetting_KeyWithHostname_Found(self):
        # TODO
        pass

    def test_getMythSetting_KeyWithHostname_NotFound(self):
        s = self.db.getMythSetting('blahblah', 'foobar')
        self.assertTrue(s is None)
    
    def test_getRecordingSchedules_All(self):
        schedules = self.db.getRecordingSchedules()
        for i, s in enumerate(schedules):
            log.debug('%d - %s' % (i+1, s))
        self.assertTrue(schedules)
        
    def test_getRecordingSchedules_By_Channel(self):
        # TODO
        pass
    
    def test_getRecordingSchedules_By_ScheduleId(self):
        # Setup
        schedules = self.db.getRecordingSchedules()
        if len(schedules) == 0:
            self.fail('Need schedules to run test')
        expectedSchedule = schedules.pop()
        
        # Test
        actualSchedules = self.db.getRecordingSchedules(scheduleId=expectedSchedule.getScheduleId())
        
        # Verify
        self.assertEquals(1, len(actualSchedules))
        self.assertEquals(expectedSchedule.getScheduleId(), actualSchedules.pop().getScheduleId())

    def test_getJobs_All(self):
        when(self.domainCache).getUserJobs().thenReturn(self.db.getUserJobs())
        jobs = self.db.getJobs()
        self.assertTrue(jobs is not None)
        for index, job in enumerate(jobs):
            log.debug('job %d = %s' % (index, job))
            
    def test_getJobs_ForProgram(self):
        # Setup
        when(self.domainCache).getUserJobs().thenReturn(self.db.getUserJobs())
        jobs = self.db.getJobs()
        if len(jobs) == 0:
            log.warn('No jobs in database to test with. Test skipped...')
            return 
        job = jobs[-1]  # last job
        data = [''] * self.protocol.recordSize()
        data[4]  = job.channelId
        data[11] = time.mktime(job.startTime.timetuple()) 
        program = RecordedProgram(data=data, settings=Mock(), translator=Mock(), platform=Mock(), protocol=self.protocol, conn=Mock())
    
        # Test
        jobs = self.db.getJobs(program=program)
    
        # Verify
        self.assertTrue(len(jobs) > 0)
        for index, actual in enumerate(jobs):
            log.debug('job %d = %s' % (index, actual))
            self.assertEquals(job.channelId, actual.channelId)
            self.assertEquals(job.startTime, actual.startTime)

    def test_getJobs_ByJobType(self):
        # Setup
        when(self.domainCache).getUserJobs().thenReturn(self.db.getUserJobs())
        jobs = self.db.getJobs()
        if len(jobs) == 0:
            log.warn('No jobs in database to test with. Test skipped...')
            return
        job = jobs[0]
    
        # Test
        jobs = self.db.getJobs(jobType=job.jobType)
    
        # Verify
        self.assertTrue(len(jobs) > 0)
        for index, j2 in enumerate(jobs):
            log.debug('job %d = %s' % (index, j2))
            self.assertEquals(job.jobType, j2.jobType)
        
    def test_getJobs_ForProgram_ByJobType(self):
        # Setup
        when(self.domainCache).getUserJobs().thenReturn(self.db.getUserJobs())
        jobs = self.db.getJobs()
        if len(jobs) == 0:
            log.warn('No jobs in database to test with. Test skipped...')
            return 
        job = jobs[-1] # last job
        data = [''] * self.protocol.recordSize()
        data[4]  = job.channelId
        data[11] = time.mktime(job.startTime.timetuple()) 
        program = RecordedProgram(data=data, settings=Mock(), translator=Mock(), platform=Mock(), protocol=self.protocol, conn=Mock())
    
        # Test
        jobs = self.db.getJobs(program=program, jobType=job.jobType)
    
        # Verify
        self.assertTrue(len(jobs) > 0)
        for index, actual in enumerate(jobs):
            log.debug('job %d = %s' % (index, actual))
            self.assertEquals(job.channelId, actual.channelId)
            self.assertEquals(job.startTime, actual.startTime)
            self.assertEquals(job.jobType, actual.jobType)
            
    def test_getUserJobs(self):
        userJobs = self.db.getUserJobs()
        for j in userJobs:
            log.debug(j)
        self.assertEqual(4, len(userJobs))

    def test_getTVGuideDataFlattened(self):
        # TODO: Convert to mocks w/ assertions
        channels = self.db.getChannels()[:2]
        programs = self.db.getTVGuideDataFlattened(
            datetime.datetime.now(), 
            datetime.datetime.now() + datetime.timedelta(hours=4), 
            channels)
        
        for p in programs:
            log.debug(p)
            
    def test_getFramerate(self):
        from mythbox.mythtv.conn import Connection
        from mythbox.util import safe_str
        from mythbox.mythtv.enums import RecordingStatus
        
        conn = Connection(settings=self.settings, translator=Mock(), platform=Mock(), bus=Mock(), db=self.db)
        try:
            recordings = conn.getAllRecordings()[-10:]
            for r in recordings:
                if r.isCommFlagged() and r.getRecordingStatus() == RecordingStatus.RECORDED:
                    fps  = self.db.getFramerate(r)
                    log.debug('%s - %s - %s %d' % (safe_str(r.title()), safe_str(r.subtitle()), fps, r.getRecordingStatus()))
                    self.assertGreaterEqual(fps, 0.0, fps)
        finally:
            conn.close()
            
Exemple #48
0
    def bootstrapSettings(self):
        self.stage = 'Initializing Settings'
        from mythbox.settings import MythSettings
        self.settings = MythSettings(self.platform, self.translator, 'settings.xml', self.bus)

        #from fanart import FanArt
        #self.log.debug('Settings = \n %s' % self.settings)

        class DelayedInstantiationProxy(object):
            '''Could use a little introspection to sort this out but eh...'''
            
            def __init__(self, *args, **kwargs):
                self.args = args
                self.kwargs = kwargs
                self.fanArt = None
                
            def requireDelegate(self):
                if self.fanArt is None:
                    from fanart import FanArt
                    self.fanArt = FanArt(*self.args, **self.kwargs)
            
            def getSeasonAndEpisode(self, program):
                self.requireDelegate()
                return self.fanArt.getSeasonAndEpisode(program)
            
            def getRandomPoster(self, program):
                self.requireDelegate()
                return self.fanArt.getRandomPoster(program)
            
            def getPosters(self, program):
                self.requireDelegate()
                return self.fanArt.getPosters(program)
        
            def hasPosters(self, program):
                self.requireDelegate()
                return self.fanArt.hasPosters(program)
            
            def clear(self):
                self.requireDelegate()
                self.fanArt.clear() 
        
            def shutdown(self):
                self.requireDelegate()
                self.fanArt.shutdown()
                
            def configure(self, settings):
                self.requireDelegate()
                self.fanArt.configure(settings)
            
            def onEvent(self, event):
                self.requireDelegate()
                self.fanArt.onEvent(event)
                    
        from fanart import FanArt
        self.fanArt = FanArt(self.platform, self.httpCache, self.settings, self.bus)
        #self.fanArt = DelayedInstantiationProxy(self.platform, self.httpCache, self.settings, self.bus)
        
        try:
            import socket
            socket.setdefaulttimeout(float(os.getenv('MYTHBOX_TIMEOUT', '30')))
        except:
            self.log.exception('Error setting socket timeout')
            
        self.bus.register(self)

        # Generate fake event to reflect value in settings.xml instead of mythbox_log.ini
        from bus import Event
        self.onEvent({'id': Event.SETTING_CHANGED, 'tag':'logging_enabled', 'old':'DontCare', 'new':self.settings.get('logging_enabled')})
Exemple #49
0
class MythChannelIconResolverTest(unittest.TestCase):
    def setUp(self):
        self.platform = getPlatform()
        self.translator = Mock()
        self.domainCache = Mock()
        self.settings = MythSettings(self.platform, self.translator)

        privateConfig = OnDemandConfig()
        self.settings.setMySqlHost(privateConfig.get('mysql_host'))
        self.settings.setMySqlPort(privateConfig.get('mysql_port'))
        self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
        self.settings.setMySqlUser(privateConfig.get('mysql_user'))
        self.settings.setMySqlPassword(privateConfig.get('mysql_password'))

        self.db = MythDatabase(self.settings, self.translator,
                               self.domainCache)
        self.bus = EventBus()
        self.conn = Connection(self.settings, self.translator, self.platform,
                               self.bus, self.db)

    def tearDown(self):
        self.conn.close()

    def test_store_When_channel_has_icon_Then_download_icon(self):
        # Setup
        channels = filter(lambda x: x.getIconPath(), self.db.getChannels()
                          )  # filter out channels that don't have an icon
        self.assertTrue(
            len(channels) > 0, 'Channels with icon needed in db to run test')
        downloader = MythChannelIconResolver(self.conn)

        # Test - download icons for first 5 channels
        for channel in channels[:min(5, len(channels))]:
            if channel.getIconPath():
                dest = os.path.sep.join([
                    tempfile.gettempdir(),
                    'channel_' + str(channel.getChannelId()) +
                    channel.getCallSign() + str(time.time()) + '.png'
                ])
                downloader.store(channel, dest)

                # Verify
                log.debug('Downloaded %s to %s' %
                          (channel.getIconPath(), dest))
                self.assertTrue(os.path.exists(dest))
                self.assertTrue(os.path.isfile(dest))
                self.assertTrue(os.path.getsize(dest) > 0)

                # Cleanup
                os.remove(dest)

    def test_store_When_channel_has_no_icon_Then_do_nothing(self):
        # Setup
        channel = Channel({
            'name': 'Bogus Channel',
            'icon': None,
            'chanid': '9',
            'callsign': 'WXYZ'
        })
        conn = Mock()
        downloader = MythChannelIconResolver(conn)

        # Test
        downloader.store(channel, 'bogusDestDir')

        # Verify
        verifyZeroInteractions(conn)

    def test_store_When_channel_has_iconpath_but_filename_misspelled_Then_do_nothing(
            self):
        # Setup
        channel = Channel({
            'name': 'Bogus Channel',
            'icon': 'bogusIcon.png',
            'chanid': '9',
            'callsign': 'WXYZ'
        })
        downloader = MythChannelIconResolver(self.conn)

        # Test - download icons for first 5 channels
        dest = os.path.sep.join([
            tempfile.gettempdir(),
            str(channel.getChannelId()) + channel.getCallSign() +
            str(time.time()) + ".png"
        ])
        downloader.store(channel, dest)

        # Verify
        self.assertFalse(os.path.exists(dest))
Exemple #50
0
 def test_toString(self):
     when(self.platform).getScriptDataDir().thenReturn(self.sandbox)
     s = MythSettings(self.platform, self.translator)
     log.debug('MythSettings = \n%s' % s)
Exemple #51
0
class ConnectionTest(unittest.TestCase):

    def setUp(self):
        self.platform = getPlatform()
        self.translator = Mock()
        self.domainCache = Mock()
        self.settings = MythSettings(self.platform, self.translator)
        self.settings.put('streaming_enabled', 'False')
        
        privateConfig = OnDemandConfig()
        self.settings.put('mysql_host', privateConfig.get('mysql_host'))
        self.settings.put('mysql_port', privateConfig.get('mysql_port'))
        self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
        self.settings.setMySqlUser(privateConfig.get('mysql_user'))  
        self.settings.put('mysql_password', privateConfig.get('mysql_password'))
        self.settings.put('paths_recordedprefix', privateConfig.get('paths_recordedprefix'))
        
        self.db = MythDatabase(self.settings, self.translator, self.domainCache)
        self.bus = EventBus()
        self.conn = Connection(self.settings, self.translator, self.platform, self.bus, self.db)

    def tearDown(self):
        self.conn.close()

    def test_getServerVersion(self):
        sock = self.conn.connect(announce=None)
        try:
            version = self.conn.getServerVersion()
            log.debug('Server Protcol = %s'%version)
            self.assertTrue(version > 0)
        finally:
            sock.close()

    def test_negotiateProtocol_RaisesProtocolException_When_ClientVersion_NotSupported_By_Server(self):
        sock = self.conn.connect(announce=None)
        try:
            try:
                self.conn.negotiateProtocol(sock, clientVersion=8, versionToken='')
                self.fail('Should have thrown ProtocolException')
            except ProtocolException, pe:
                log.debug('PASS: %s', pe)
        finally:
            sock.close()

    def test_getSetting(self):
        reply = self.conn.getSetting('mythfillstatus', 'none')
        log.debug('reply = %s' % reply)
        if reply[0] == "-1":
            pass # fail
        else:
            pass # success
        # TODO : Left off here!
        
    def test_getTunerStatus_Success(self):
        tuners = self.db.getTuners()
        if len(tuners) == 0:
            log.warn('SKIPPING: need tuners to run test')
            return 
        status = self.conn.getTunerStatus(tuners.pop())
        log.debug('Tuner status = %s' % status)
        self.assertFalse(status is None)

    def test_getDiskUsage(self):
        du = self.conn.getDiskUsage()
        log.debug('Disk usage = %s' % du)
        self.assertTrue(du['hostname'] is not None)
        self.assertTrue(du['dir'] is not None)
        self.assertTrue(du['total'] is not None)
        self.assertTrue(du['used'] is not None)
        self.assertTrue(du['free'] is not None)
        
    def test_getLoad(self):
        load = self.conn.getLoad()
        log.debug('CPU Load = %s' % load)
        self.assertEquals(3, len(load))
        self.assertTrue(load['1'])
        self.assertTrue(load['5'])
        self.assertTrue(load['15'])

    def test_getUptime(self):
        uptime = self.conn.getUptime()
        log.debug('Uptime = %s' % uptime)
        self.assertFalse(uptime is None)
        
    def test_getGuideDataStatus(self):
        guideStatus = self.conn.getGuideDataStatus()
        log.debug('Guide data status = %s' % guideStatus)
        self.assertFalse(guideStatus is None)

    def test_getAllRecordings(self):
        recordings = self.conn.getAllRecordings()
        log.debug('Num Recordings = %s' % len(recordings))
        self.assertTrue(len(recordings) > 0)

    def test_getRecordings_AllRecordingGroupsAndTitles(self):
        recordings = self.conn.getRecordings()
        log.debug('Num Recordings = %s' % len(recordings))
        for i, r in enumerate(recordings):
            log.debug('%d - %s' %(i+1, r))
        self.assertTrue(len(recordings) > 0)

    def test_getRecording_Found(self):
        expected = self.getRecordings().pop()
        actual = self.conn.getRecording(expected.getChannelId(), expected.recstarttime())
        self.assertEquals(expected, actual)
        
    def test_getRecording_NotFound(self):
        recording = self.getRecordings().pop()
        actual = self.conn.getRecording(32, recording.recstarttime())
        self.assertTrue(actual is None)
  
    def test_getUpcomingRecordings_When_no_args_Then_returns_only_programs_that_will_be_recorded(self):
        upcoming = self.conn.getUpcomingRecordings()
        log.debug('Num upcoming recordings = %d' % (len(upcoming)))
        for i,program in enumerate(upcoming):
            log.debug('%d: tuner=%s %s' % (i, program.getTunerId(), program))
            #program.dumpData()
            
        for program in upcoming:
            self.assertTrue(program.getRecordingStatus() in Upcoming.SCHEDULED)
            self.assertTrue(program.getTunerId() >= 0)
            
    def test_getUpcomingRecordings_When_filter_is_scheduled_Then_returns_only_program_that_will_be_recorded(self):
        upcoming = self.conn.getUpcomingRecordings(Upcoming.SCHEDULED)
        log.debug('Num upcoming recordings (filter = Upcoming.SCHEDULED) = %d' % (len(upcoming)))
        for program in upcoming:
            self.assertTrue(program.getRecordingStatus() in Upcoming.SCHEDULED)

    def test_getUpcomingRecordings_When_filter_is_conflict_Then_returns_only_program_that_will_not_be_recorded_because_of_a_conflict(self):
        upcoming = self.conn.getUpcomingRecordings(Upcoming.CONFLICTS)
        log.debug('Num upcoming recordings (filter = Upcoming.CONFLICTS) = %d' % (len(upcoming)))
        for program in upcoming:
            self.assertTrue(program.getRecordingStatus() in Upcoming.CONFLICTS)

    def test_getScheduledRecordings(self):
        scheduled = self.conn.getScheduledRecordings()
        log.debug('Num scheduled recordings = %d' % (len(scheduled)))
        for i,program in enumerate(scheduled):
            log.debug('%d: %s' % (i, program))
        self.assertFalse(scheduled is None)            

    def test_getTunerShowing_NoCardsAreWatchingOrRecordingThePassedInShow(self):
        tunerId = self.conn.getTunerShowing('bogusshow')
        self.assertEquals(-1, tunerId, 'Expected no encoder to be watching or recording a bogus tv show')

    def test_getTunerShowing_ReturnCardThatShowIsBeingWatchedOn(self):
        log.warn("TODO: Write unit test - mockito")

    def test_getTunerShowing_ReturnCardThatShowIsBeingWatchedAndRecordedOn(self):
        log.warn("TODO: Write unit test - mockito")

    def test_getFreeTuner(self):
        tunerId, hostname, port = self.conn.getFreeTuner()
        if tunerId == -1:
            log.debug('No free tuners available')
            self.assertEquals('', hostname)
            self.assertEquals(-1, port)
        else:
            log.debug('Free tuner = id: %d hostname: %s  port: %d'%(tunerId, hostname, port))
            self.assertTrue(tunerId >= 0)
            self.assertTrue(len(hostname) > 0)
            self.assertTrue(port > 0)
        
    def test_getNextFreeTuner(self):
        tunerId, hostname, port = self.conn.getNextFreeTuner(-1)
        if tunerId is None:
            pass
        else:
            log.debug('Next free tuner = id:%d hostname:%s port:%d'%(tunerId, hostname, port))
        # TODO: valid assertions when tuner free and not available
        
    def test_isOk_OKMessageReturnsTrue(self):
        self.assertTrue(self.conn._isOk(['OK']))

    def test_isOk_OKMessageWithAdditionPayloadReturnsTrue(self):
        self.assertTrue(self.conn._isOk(['OK','foo', 'bar', 'baz']))

    def test_isOk_NoneMessageReturnsFalse(self):
        self.assertFalse(self.conn._isOk(None))
        
    def test_isOk_EmptyMessageReturnsFalse(self):
        self.assertFalse(self.conn._isOk([]))

    def test_isOk_BadMessageReturnsFalse(self):
        self.assertFalse(self.conn._isOk(['Bad']))

    def test_isTunerRecording(self):
        for t in self.conn.getTuners():
            log.debug('isTunerRecording(%d) = %s' % (t.tunerId, self.conn.isTunerRecording(t)))
        
    def test_getBookmark_Success(self):
        # TODO: only check bookmarked recordings
        recording = self.getRecordings()[0]
        log.debug('Getting bookmark for %s' % recording)
        bookmark = self.conn.getBookmark(recording)
        log.debug('bookmark = %s seconds' % bookmark)
        self.assertTrue(bookmark >= 0)
    
    def test_setBookmark_Success(self):
        p = self.getRecordings().pop()
        log.debug('Setting bookmark for %s' % p)
        self.conn.setBookmark(p, 1000)
        self.assertEquals(1000, self.conn.getBookmark(p))

    def test_setBookmark_ChannelIdInvalid(self):
        p = self.getRecordings().pop()
        p.setChannelId(999)
        self.assertEquals(999, p.getChannelId())
        self.assertRaises(ServerException, self.conn.setBookmark, p, 500)
        
    def test_getCommercialBreaks(self):
        recordings = reversed(self.conn.getAllRecordings())
        foundRecordingWithCommBreaks = False
        for r in recordings:
            if r.hasCommercials():
                foundRecordingWithCommBreaks = True
                log.debug('Recording %s has comm breaks' % r)
                breaks = self.conn.getCommercialBreaks(r)
                for j, b in enumerate(breaks):
                    log.debug('    %d - comm break = %s' % (j+1, b))
                return
        if not foundRecordingWithCommBreaks:
            log.warn('Could not find any comm flagged recordings to run unit test against')
    
    def test_getNumFreeTuners(self):
        cnt = self.conn.getNumFreeTuners()
        log.debug('Num free tuners = %d' % cnt)
        self.assertTrue(cnt >= 0)
        
    def test_getTuners(self):
        tuners = self.conn.getTuners()
        for i,t in enumerate(tuners):
            log.debug('Tuner %d = %s' % (i, t.tunerType))
            self.assertTrue(t.conn != None)
       
    def test_generateThumbnail_ReturnsTrue(self):
        recording = self.getRecordings()[-1]
        log.debug('Generating thumbnail for program: %s' % recording)
        result = self.conn.generateThumbnail(recording, self.db.getMasterBackend().ipAddress)
        self.assertTrue(result)

    def test_generateThumbnail_WithSpecificSize(self):
        recording = self.getRecordings()[-1]
        log.debug('Generating thumbnail for program: %s' % recording.title())
        result = self.conn.generateThumbnail(recording, self.db.getMasterBackend().ipAddress, 1280/4, 720/4)
        log.debug(result)
        self.assertTrue(result)
         
    def test_getThumbnailCreationTime_ThumbnailExists(self):
        recording = self.getRecordings()[0]
        log.debug('Getting thumbnail creation time for: %s' % recording.title())
        dt = self.conn.getThumbnailCreationTime(recording, self.db.getMasterBackend().ipAddress)
        log.debug('datetime = %s' % dt)
        
    def test_getThumbNailCreationTime_ThumbnailDoesNotExist(self):
        # TODO
        pass
    
    def test_rescheduleNotify_Successful(self):
        schedules = self.db.getRecordingSchedules()
        self.conn.rescheduleNotify(schedules.pop())
        log.debug('reschedule notify OK')

    def test_rescheduleNotify_Does_Something_Else_When_ScheduleId_missing(self):
        """
        @todo: fixme
        """
        pass
    
    def test_transferFile_FileExistsOnBackend_Success(self):
        # Setup
        recording = self.getRecordings()[-1]
        
        if not self.conn.getThumbnailCreationTime(recording, recording.hostname()): # generate thumbnail if necessary
            log.debug('Generating thumbnail...')
            self.conn.generateThumbnail(recording, recording.hostname())
            recording = self.conn.getRecording(recording.getChannelId(), recording.recstarttime())
            
        backendPath = recording.getBareFilename()
        if self.conn.protocol.genPixMapPreviewFilename(recording) != '<EMPTY>':
            backendPath += '.640x360'
        backendPath += '.png'
        destPath = os.path.join(tempfile.gettempdir(), recording.getBareFilename() + ".png")
        
        # Test
        try:
            log.debug('Transferring file %s to %s' % (backendPath, destPath))
            result = self.conn.transferFile(backendPath, destPath, recording.hostname())
            
            # Verify
            self.assertTrue(result)
            self.assertTrue(os.path.exists(destPath))
            self.assertTrue(os.path.isfile(destPath))
            
        finally:
            try: os.remove(destPath); 
            except: pass
    
    def test_transferFile_When_file_does_not_exist_on_backend_Then_transfer_aborted(self):
        dest = tempfile.mktemp('bogusfile.mpg')
        backendPath = "myth://" + self.db.getMasterBackend().ipAddress + ":" + str(self.db.getMasterBackend().port) + "/bogusfile.mpg"
        result = self.conn.transferFile(backendPath, dest, self.db.getMasterBackend().ipAddress)
        self.assertFalse(os.path.exists(dest))
        self.assertFalse(result)

    def test_transferFile_When_partial_transfer_requested_Then_only_send_part_of_file(self):
        # Setup
        recording = self.getRecordings()[-1]
        dest = tempfile.mktemp('.mpg', 'test_partial_transfer_')
        print dest
        
        try:
            # Test
            result = self.conn.transferFile(recording.getFilename(), dest, recording.hostname(), 1024 * 1000)
            
            # Verify
            self.assertTrue(result)
            self.assertTrue(os.path.exists(dest))
            self.assertEquals(1024*1000, os.path.getsize(dest))
        finally:
            try: os.remove(dest)
            except: pass

    def getRecordings(self):
        recordings = self.conn.getRecordings()
        self.assertTrue(recordings, 'Recordings required to run this test')
        return recordings
Exemple #52
0
class ConnectionTest(unittest.TestCase):
    def setUp(self):
        self.platform = getPlatform()
        self.translator = Mock()
        self.domainCache = Mock()
        self.settings = MythSettings(self.platform, self.translator)
        self.settings.put('streaming_enabled', 'False')

        privateConfig = OnDemandConfig()
        self.settings.put('mysql_host', privateConfig.get('mysql_host'))
        self.settings.put('mysql_port', privateConfig.get('mysql_port'))
        self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
        self.settings.setMySqlUser(privateConfig.get('mysql_user'))
        self.settings.put('mysql_password',
                          privateConfig.get('mysql_password'))
        self.settings.put('paths_recordedprefix',
                          privateConfig.get('paths_recordedprefix'))

        self.db = MythDatabase(self.settings, self.translator,
                               self.domainCache)
        self.bus = EventBus()
        self.conn = Connection(self.settings, self.translator, self.platform,
                               self.bus, self.db)

    def tearDown(self):
        self.conn.close()

    def test_getServerVersion(self):
        sock = self.conn.connect(announce=None)
        try:
            version = self.conn.getServerVersion()
            log.debug('Server Protcol = %s' % version)
            self.assertTrue(version > 0)
        finally:
            sock.close()

    def test_negotiateProtocol_RaisesProtocolException_When_ClientVersion_NotSupported_By_Server(
            self):
        sock = self.conn.connect(announce=None)
        try:
            try:
                self.conn.negotiateProtocol(sock,
                                            clientVersion=8,
                                            versionToken='')
                self.fail('Should have thrown ProtocolException')
            except ProtocolException, pe:
                log.debug('PASS: %s', pe)
        finally:
            sock.close()

    def test_getSetting(self):
        reply = self.conn.getSetting('mythfillstatus', 'none')
        log.debug('reply = %s' % reply)
        if reply[0] == "-1":
            pass  # fail
        else:
            pass  # success
        # TODO : Left off here!

    def test_getTunerStatus_Success(self):
        tuners = self.db.getTuners()
        if len(tuners) == 0:
            log.warn('SKIPPING: need tuners to run test')
            return
        status = self.conn.getTunerStatus(tuners.pop())
        log.debug('Tuner status = %s' % status)
        self.assertFalse(status is None)

    def test_getDiskUsage(self):
        du = self.conn.getDiskUsage()
        log.debug('Disk usage = %s' % du)
        self.assertTrue(du['hostname'] is not None)
        self.assertTrue(du['dir'] is not None)
        self.assertTrue(du['total'] is not None)
        self.assertTrue(du['used'] is not None)
        self.assertTrue(du['free'] is not None)

    def test_getLoad(self):
        load = self.conn.getLoad()
        log.debug('CPU Load = %s' % load)
        self.assertEquals(3, len(load))
        self.assertTrue(load['1'])
        self.assertTrue(load['5'])
        self.assertTrue(load['15'])

    def test_getUptime(self):
        uptime = self.conn.getUptime()
        log.debug('Uptime = %s' % uptime)
        self.assertFalse(uptime is None)

    def test_getGuideDataStatus(self):
        guideStatus = self.conn.getGuideDataStatus()
        log.debug('Guide data status = %s' % guideStatus)
        self.assertFalse(guideStatus is None)

    def test_getAllRecordings(self):
        recordings = self.conn.getAllRecordings()
        log.debug('Num Recordings = %s' % len(recordings))
        self.assertTrue(len(recordings) > 0)

    def test_getRecordings_AllRecordingGroupsAndTitles(self):
        recordings = self.conn.getRecordings()
        log.debug('Num Recordings = %s' % len(recordings))
        for i, r in enumerate(recordings):
            log.debug('%d - %s' % (i + 1, r))
        self.assertTrue(len(recordings) > 0)

    def test_getRecording_Found(self):
        expected = self.getRecordings().pop()
        actual = self.conn.getRecording(expected.getChannelId(),
                                        expected.recstarttime())
        self.assertEquals(expected, actual)

    def test_getRecording_NotFound(self):
        recording = self.getRecordings().pop()
        actual = self.conn.getRecording(32, recording.recstarttime())
        self.assertTrue(actual is None)

    def test_getUpcomingRecordings_When_no_args_Then_returns_only_programs_that_will_be_recorded(
            self):
        upcoming = self.conn.getUpcomingRecordings()
        log.debug('Num upcoming recordings = %d' % (len(upcoming)))
        for i, program in enumerate(upcoming):
            log.debug('%d: tuner=%s %s' % (i, program.getTunerId(), program))
            #program.dumpData()

        for program in upcoming:
            self.assertTrue(program.getRecordingStatus() in Upcoming.SCHEDULED)
            self.assertTrue(program.getTunerId() >= 0)

    def test_getUpcomingRecordings_When_filter_is_scheduled_Then_returns_only_program_that_will_be_recorded(
            self):
        upcoming = self.conn.getUpcomingRecordings(Upcoming.SCHEDULED)
        log.debug(
            'Num upcoming recordings (filter = Upcoming.SCHEDULED) = %d' %
            (len(upcoming)))
        for program in upcoming:
            self.assertTrue(program.getRecordingStatus() in Upcoming.SCHEDULED)

    def test_getUpcomingRecordings_When_filter_is_conflict_Then_returns_only_program_that_will_not_be_recorded_because_of_a_conflict(
            self):
        upcoming = self.conn.getUpcomingRecordings(Upcoming.CONFLICTS)
        log.debug(
            'Num upcoming recordings (filter = Upcoming.CONFLICTS) = %d' %
            (len(upcoming)))
        for program in upcoming:
            self.assertTrue(program.getRecordingStatus() in Upcoming.CONFLICTS)

    def test_getScheduledRecordings(self):
        scheduled = self.conn.getScheduledRecordings()
        log.debug('Num scheduled recordings = %d' % (len(scheduled)))
        for i, program in enumerate(scheduled):
            log.debug('%d: %s' % (i, program))
        self.assertFalse(scheduled is None)

    def test_getTunerShowing_NoCardsAreWatchingOrRecordingThePassedInShow(
            self):
        tunerId = self.conn.getTunerShowing('bogusshow')
        self.assertEquals(
            -1, tunerId,
            'Expected no encoder to be watching or recording a bogus tv show')

    def test_getTunerShowing_ReturnCardThatShowIsBeingWatchedOn(self):
        log.warn("TODO: Write unit test - mockito")

    def test_getTunerShowing_ReturnCardThatShowIsBeingWatchedAndRecordedOn(
            self):
        log.warn("TODO: Write unit test - mockito")

    def test_getFreeTuner(self):
        tunerId, hostname, port = self.conn.getFreeTuner()
        if tunerId == -1:
            log.debug('No free tuners available')
            self.assertEquals('', hostname)
            self.assertEquals(-1, port)
        else:
            log.debug('Free tuner = id: %d hostname: %s  port: %d' %
                      (tunerId, hostname, port))
            self.assertTrue(tunerId >= 0)
            self.assertTrue(len(hostname) > 0)
            self.assertTrue(port > 0)

    def test_getNextFreeTuner(self):
        tunerId, hostname, port = self.conn.getNextFreeTuner(-1)
        if tunerId is None:
            pass
        else:
            log.debug('Next free tuner = id:%d hostname:%s port:%d' %
                      (tunerId, hostname, port))
        # TODO: valid assertions when tuner free and not available

    def test_isOk_OKMessageReturnsTrue(self):
        self.assertTrue(self.conn._isOk(['OK']))

    def test_isOk_OKMessageWithAdditionPayloadReturnsTrue(self):
        self.assertTrue(self.conn._isOk(['OK', 'foo', 'bar', 'baz']))

    def test_isOk_NoneMessageReturnsFalse(self):
        self.assertFalse(self.conn._isOk(None))

    def test_isOk_EmptyMessageReturnsFalse(self):
        self.assertFalse(self.conn._isOk([]))

    def test_isOk_BadMessageReturnsFalse(self):
        self.assertFalse(self.conn._isOk(['Bad']))

    def test_isTunerRecording(self):
        for t in self.conn.getTuners():
            log.debug('isTunerRecording(%d) = %s' %
                      (t.tunerId, self.conn.isTunerRecording(t)))

    def test_getBookmark_Success(self):
        # TODO: only check bookmarked recordings
        recording = self.getRecordings()[0]
        log.debug('Getting bookmark for %s' % recording)
        bookmark = self.conn.getBookmark(recording)
        log.debug('bookmark = %s seconds' % bookmark)
        self.assertTrue(bookmark >= 0)

    def test_setBookmark_Success(self):
        p = self.getRecordings().pop()
        log.debug('Setting bookmark for %s' % p)
        self.conn.setBookmark(p, 1000)
        self.assertEquals(1000, self.conn.getBookmark(p))

    def test_setBookmark_ChannelIdInvalid(self):
        p = self.getRecordings().pop()
        p.setChannelId(999)
        self.assertEquals(999, p.getChannelId())
        self.assertRaises(ServerException, self.conn.setBookmark, p, 500)

    def test_getCommercialBreaks(self):
        recordings = reversed(self.conn.getAllRecordings())
        foundRecordingWithCommBreaks = False
        for r in recordings:
            if r.hasCommercials():
                foundRecordingWithCommBreaks = True
                log.debug('Recording %s has comm breaks' % r)
                breaks = self.conn.getCommercialBreaks(r)
                for j, b in enumerate(breaks):
                    log.debug('    %d - comm break = %s' % (j + 1, b))
                return
        if not foundRecordingWithCommBreaks:
            log.warn(
                'Could not find any comm flagged recordings to run unit test against'
            )

    def test_getNumFreeTuners(self):
        cnt = self.conn.getNumFreeTuners()
        log.debug('Num free tuners = %d' % cnt)
        self.assertTrue(cnt >= 0)

    def test_getTuners(self):
        tuners = self.conn.getTuners()
        for i, t in enumerate(tuners):
            log.debug('Tuner %d = %s' % (i, t.tunerType))
            self.assertTrue(t.conn != None)

    def test_generateThumbnail_ReturnsTrue(self):
        recording = self.getRecordings()[-1]
        log.debug('Generating thumbnail for program: %s' % recording)
        result = self.conn.generateThumbnail(
            recording,
            self.db.getMasterBackend().ipAddress)
        self.assertTrue(result)

    def test_generateThumbnail_WithSpecificSize(self):
        recording = self.getRecordings()[-1]
        log.debug('Generating thumbnail for program: %s' % recording.title())
        result = self.conn.generateThumbnail(
            recording,
            self.db.getMasterBackend().ipAddress, 1280 / 4, 720 / 4)
        log.debug(result)
        self.assertTrue(result)

    def test_getThumbnailCreationTime_ThumbnailExists(self):
        recording = self.getRecordings()[0]
        log.debug('Getting thumbnail creation time for: %s' %
                  recording.title())
        dt = self.conn.getThumbnailCreationTime(
            recording,
            self.db.getMasterBackend().ipAddress)
        log.debug('datetime = %s' % dt)

    def test_getThumbNailCreationTime_ThumbnailDoesNotExist(self):
        # TODO
        pass

    def test_rescheduleNotify_Successful(self):
        schedules = self.db.getRecordingSchedules()
        self.conn.rescheduleNotify(schedules.pop())
        log.debug('reschedule notify OK')

    def test_rescheduleNotify_Does_Something_Else_When_ScheduleId_missing(
            self):
        """
        @todo: fixme
        """
        pass

    def test_transferFile_FileExistsOnBackend_Success(self):
        # Setup
        recording = self.getRecordings()[-1]

        if not self.conn.getThumbnailCreationTime(
                recording,
                recording.hostname()):  # generate thumbnail if necessary
            log.debug('Generating thumbnail...')
            self.conn.generateThumbnail(recording, recording.hostname())
            recording = self.conn.getRecording(recording.getChannelId(),
                                               recording.recstarttime())

        backendPath = recording.getBareFilename()
        if self.conn.protocol.genPixMapPreviewFilename(recording) != '<EMPTY>':
            backendPath += '.640x360'
        backendPath += '.png'
        destPath = os.path.join(tempfile.gettempdir(),
                                recording.getBareFilename() + ".png")

        # Test
        try:
            log.debug('Transferring file %s to %s' % (backendPath, destPath))
            result = self.conn.transferFile(backendPath, destPath,
                                            recording.hostname())

            # Verify
            self.assertTrue(result)
            self.assertTrue(os.path.exists(destPath))
            self.assertTrue(os.path.isfile(destPath))

        finally:
            try:
                os.remove(destPath)
            except:
                pass

    def test_transferFile_When_file_does_not_exist_on_backend_Then_transfer_aborted(
            self):
        dest = tempfile.mktemp('bogusfile.mpg')
        backendPath = "myth://" + self.db.getMasterBackend(
        ).ipAddress + ":" + str(
            self.db.getMasterBackend().port) + "/bogusfile.mpg"
        result = self.conn.transferFile(backendPath, dest,
                                        self.db.getMasterBackend().ipAddress)
        self.assertFalse(os.path.exists(dest))
        self.assertFalse(result)

    def test_transferFile_When_partial_transfer_requested_Then_only_send_part_of_file(
            self):
        # Setup
        recording = self.getRecordings()[-1]
        dest = tempfile.mktemp('.mpg', 'test_partial_transfer_')
        print dest

        try:
            # Test
            result = self.conn.transferFile(recording.getFilename(), dest,
                                            recording.hostname(), 1024 * 1000)

            # Verify
            self.assertTrue(result)
            self.assertTrue(os.path.exists(dest))
            self.assertEquals(1024 * 1000, os.path.getsize(dest))
        finally:
            try:
                os.remove(dest)
            except:
                pass

    def getRecordings(self):
        recordings = self.conn.getRecordings()
        self.assertTrue(recordings, 'Recordings required to run this test')
        return recordings
Exemple #53
0
class BootStrapper(object):
    def __init__(self, splash):
        self.log = None
        self.platform = None
        self.stage = 'Initializing'
        self.shell = None
        self.splash = splash
        self.failSilent = False

    def run(self):
        try:
            try:
                self.bootstrapLogger()
                self.bootstrapPlatform()
                self.bootstrapEventBus()
                self.bootstrapCaches()
                self.bootstrapSettings()
                self.bootstrapUpdater()
                self.bootstrapFeeds()
                # TODO: Re-enable when twisted not loaded from dist-packages
                #self.bootstrapDebugShell()
                self.bootstrapHomeScreen()
            except Exception, ex:
                if not self.failSilent:
                    self.handleFailure(ex)
        finally:
            if self.splash:
                self.splash.close()

    def handleFailure(self, cause):
        msg = 'MythBox:%s - Error: %s' % (self.stage, cause)
        xbmc.log(msg)
        print traceback.print_exc()
        if self.log:
            self.log.exception(str(cause))
        xbmcgui.Dialog().ok('MythBox Error', 'Stage: %s' % self.stage,
                            'Exception: %s' % str(cause))

    def updateProgress(self, msg):
        self.log.info(msg)

    def bootstrapLogger(self):
        import logging
        import logging.config
        self.stage = 'Initializing Logger'

        import xbmcaddon
        scriptDir = xbmcaddon.Addon('script.mythbox').getAddonInfo('path')
        loggerIniFile = os.path.join(scriptDir, 'mythbox_log.ini')

        # needs to be in local scope for fileConfig to find it
        from mythbox.log import XbmcLogHandler

        xbmc.log('MythBox: loggerIniFile = %s' % loggerIniFile)
        logging.config.fileConfig(loggerIniFile)
        self.log = logging.getLogger('mythbox.core')
        self.log.info('Mythbox Logger Initialized')

    def bootstrapPlatform(self):
        self.stage = 'Initializing Platform'
        import mythbox.platform
        self.platform = mythbox.platform.getPlatform()
        self.platform.addLibsToSysPath()
        sys.setcheckinterval(0)
        cacheDir = self.platform.getCacheDir()
        from mythbox.util import requireDir
        requireDir(cacheDir)

        self.log.info('MythBox %s Initialized' % self.platform.addonVersion())

    def bootstrapEventBus(self):
        self.bus = EventBus()

    def bootstrapCaches(self):
        self.stage = 'Initializing Caches'

        from mythbox.util import NativeTranslator
        from mythbox.filecache import FileCache, HttpResolver, MythThumbnailFileCache
        from mythbox.mythtv.resolver import MythChannelIconResolver, MythThumbnailResolver
        from os.path import join

        from mythbox.mythtv.cache import DomainCache
        self.domainCache = DomainCache(bus=self.bus)

        cacheDir = self.platform.getCacheDir()
        self.translator = NativeTranslator(self.platform.getScriptDir())
        self.mythThumbnailCache = MythThumbnailFileCache(
            join(cacheDir, 'thumbnail'), MythThumbnailResolver(), self.bus,
            self.domainCache)
        self.mythChannelIconCache = FileCache(join(cacheDir, 'channel'),
                                              MythChannelIconResolver())
        self.httpCache = FileCache(join(cacheDir, 'http'), HttpResolver())

        self.cachesByName = {
            'mythThumbnailCache': self.mythThumbnailCache,
            'mythChannelIconCache': self.mythChannelIconCache,
            'httpCache': self.httpCache,
            'domainCache': self.domainCache
        }

    def bootstrapSettings(self):
        self.stage = 'Initializing Settings'
        from mythbox.settings import MythSettings
        self.settings = MythSettings(self.platform, self.translator,
                                     'settings.xml', self.bus)

        #from fanart import FanArt
        #self.log.debug('Settings = \n %s' % self.settings)

        class DelayedInstantiationProxy(object):
            '''Could use a little introspection to sort this out but eh...'''
            def __init__(self, *args, **kwargs):
                self.args = args
                self.kwargs = kwargs
                self.fanArt = None

            def requireDelegate(self):
                if self.fanArt is None:
                    from fanart import FanArt
                    self.fanArt = FanArt(*self.args, **self.kwargs)

            def getSeasonAndEpisode(self, program):
                self.requireDelegate()
                return self.fanArt.getSeasonAndEpisode(program)

            def getRandomPoster(self, program):
                self.requireDelegate()
                return self.fanArt.getRandomPoster(program)

            def getPosters(self, program):
                self.requireDelegate()
                return self.fanArt.getPosters(program)

            def hasPosters(self, program):
                self.requireDelegate()
                return self.fanArt.hasPosters(program)

            def clear(self):
                self.requireDelegate()
                self.fanArt.clear()

            def shutdown(self):
                self.requireDelegate()
                self.fanArt.shutdown()

            def configure(self, settings):
                self.requireDelegate()
                self.fanArt.configure(settings)

            def onEvent(self, event):
                self.requireDelegate()
                self.fanArt.onEvent(event)

        from fanart import FanArt
        self.fanArt = FanArt(self.platform, self.httpCache, self.settings,
                             self.bus)
        #self.fanArt = DelayedInstantiationProxy(self.platform, self.httpCache, self.settings, self.bus)

        try:
            import socket
            socket.setdefaulttimeout(float(os.getenv('MYTHBOX_TIMEOUT', '30')))
        except:
            self.log.exception('Error setting socket timeout')

        self.bus.register(self)

        # Generate fake event to reflect value in settings.xml instead of mythbox_log.ini
        from bus import Event
        self.onEvent({
            'id': Event.SETTING_CHANGED,
            'tag': 'logging_enabled',
            'old': 'DontCare',
            'new': self.settings.get('logging_enabled')
        })

    def bootstrapUpdater(self):
        self.stage = 'Initializing Updater'
        from mythbox.updater import UpdateChecker
        UpdateChecker(self.platform).run()

    def bootstrapFeeds(self):
        from mythbox.feeds import FeedHose
        self.feedHose = FeedHose(self.settings, self.bus)

    def bootstrapDebugShell(self):
        # debug shell only packaged with bin/package-debug-zip
        try:
            from mythbox.shell import DebugShell
            globals()['bootstrapper'] = self
            self.shell = DebugShell(self.bus, namespace=globals())
            self.shell.start()
        except ImportError:
            self.log.debug('Punting on debug shell -- not packaged')

    def bootstrapXbmcShutdownListener(self):
        from threading import Thread

        class XbmcShutdownListener(Thread):
            def __init__(self, home, bus, log):
                Thread.__init__(self)
                self.home = home
                self.log = log
                self.shutdownReceived = False
                bus.register(self)

            def onEvent(self, event):
                from bus import Event
                if event['id'] == Event.SHUTDOWN:
                    self.shutdownReceived = True
                    self.join()
                    xbmc.log('Joined shutdown listener')

            def run(self):
                import time
                xbmc.log('XbmcShutdownListener thread running..')
                cnt = 1
                while not xbmc.abortRequested and not self.shutdownReceived:
                    #xbmc.sleep(1000)
                    time.sleep(1)
                    xbmc.log(
                        'XbmcShutdownListner abort = %s user = %s tick %d ...'
                        % (xbmc.abortRequested, self.shutdownReceived, cnt))
                    cnt += 1

                if xbmc.abortRequested:
                    xbmc.log('XBMC requested shutdown..')
                    self.home.shutdown()
                    xbmc.log('XBMC requested shutdown complete')

                xbmc.log('XbmcShutdownListener thread terminating')

        self.shutdownListener = XbmcShutdownListener(self.home, self.bus,
                                                     self.log)
        self.shutdownListener.start()

    def bootstrapHomeScreen(self):

        from mythbox.ui.home import HomeWindow
        self.home = HomeWindow('mythbox_home.xml',
                               self.platform.getScriptDir(),
                               settings=self.settings,
                               translator=self.translator,
                               platform=self.platform,
                               fanArt=self.fanArt,
                               cachesByName=self.cachesByName,
                               bus=self.bus,
                               feedHose=self.feedHose)
        if self.splash:
            self.splash.close()
        #self.bootstrapXbmcShutdownListener()
        self.home.doModal()

    def onEvent(self, event):
        from bus import Event

        #
        # Apply changes to logger when user turns debug logging on/off
        #
        if event['id'] == Event.SETTING_CHANGED and event[
                'tag'] == 'logging_enabled':
            import logging
            logging.root.debug('Setting changed: %s %s %s' %
                               (event['tag'], event['old'], event['new']))

            if event['new'] == 'True':
                level = logging.DEBUG
            else:
                level = logging.WARN

            loggerNames = 'unittest mysql core method skin ui perf fanart settings cache event'.split(
            )  # wire inject'.split()

            for name in loggerNames:
                logger = logging.getLogger('mythbox.%s' % name)
                logger.setLevel(level)
Exemple #54
0
 def test_verifyMySQLUser_EmptyStringThrowsSettingsException(self):
     try:
         MythSettings.verifyMySQLUser("")
     except SettingsException, se:
         log.debug("PASS: %s" % se)
Exemple #55
0
class DeleteOrphansTest(unittest.TestCase):

    def setUp(self):
        self.platform = getPlatform()
        self.translator = Mock()
        self.domainCache = Mock()
        self.settings = MythSettings(self.platform, self.translator)
        self.settings.put('streaming_enabled', 'False')
        
        privateConfig = OnDemandConfig()
        self.settings.put('mysql_host', privateConfig.get('mysql_host'))
        self.settings.put('mysql_port', privateConfig.get('mysql_port'))
        self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
        self.settings.setMySqlUser(privateConfig.get('mysql_user'))  
        self.settings.put('mysql_password', privateConfig.get('mysql_password'))
        self.settings.put('paths_recordedprefix', privateConfig.get('paths_recordedprefix'))
        
        self.db = MythDatabase(self.settings, self.translator, self.domainCache)
        self.bus = EventBus()
        self.conn = Connection(self.settings, self.translator, self.platform, self.bus, self.db)

    def tearDown(self):
        self.conn.close()

    def test_getAllRecordings(self):
        recordings = self.conn.getAllRecordings()
        log.debug('Num Recordings = %s' % len(recordings))
        for i,r in enumerate(recordings):
            print i,r.getBareFilename()
 
        dirs = ['/usr2/mythtv','/usr2/mythtv2', '/usr2/mythtv3']
        
        mpgs = []
        
        for d in dirs:
            files = os.listdir(d)
            for f in files:
                if f.endswith('.mpg'):
                    mpgs.append(f)
                    print f
                    
        print 'Recs  total = ', len(recordings)
        print 'Files total = ', len(mpgs)
        print 'Extras      = ', len(mpgs) - len(recordings)    
        
        todelete = mpgs[:]
        for r in recordings:
            if r.getBareFilename() in mpgs:
                todelete.remove(r.getBareFilename())
                
        print 'Todelete    = ', len(todelete)

        bucket = []
        
        import datetime
        
        for f in todelete:
            for d in dirs:
                path = os.path.join(d,f)
                if os.path.exists(path):
                    bucket.append(path)
                    print path, os.path.getsize(path)
                        
        print 'Bucket     = ', len(bucket)
        sorted(bucket)
        
        total = 0
        for f in bucket:
            s = os.path.getsize(f)
            total += s
            
        print total/1000000000
        
        import shutil
        
        for src in bucket[:25]:
            dest = '/usr2/mythtv/backup/' + os.path.basename(src)
            print src,' -> ', dest
Exemple #56
0
class BootStrapper(object):
    
    def __init__(self, splash):
        self.log = None
        self.platform = None
        self.stage = 'Initializing'
        self.shell = None
        self.splash = splash
        self.failSilent = False
        
    def run(self):
        try:
            try:
                self.bootstrapLogger()
                self.bootstrapPlatform()
                self.bootstrapEventBus()            
                self.bootstrapCaches()
                self.bootstrapSettings()
                self.bootstrapUpdater()
                self.bootstrapFeeds()
                # TODO: Re-enable when twisted not loaded from dist-packages
                #self.bootstrapDebugShell()
                self.bootstrapHomeScreen()
            except Exception, ex:
                if not self.failSilent:
                    self.handleFailure(ex)
        finally:
            if self.splash:
                self.splash.close()
            
    def handleFailure(self, cause):
        msg = 'MythBox:%s - Error: %s' % (self.stage, cause)
        xbmc.log(msg)
        print traceback.print_exc()
        if self.log:
            self.log.exception(str(cause))
        xbmcgui.Dialog().ok('MythBox Error', 'Stage: %s' % self.stage, 'Exception: %s' % str(cause))
        
    def updateProgress(self, msg):
        self.log.info(msg)

    def bootstrapLogger(self):
        import logging
        import logging.config
        self.stage = 'Initializing Logger'
        
        import xbmcaddon
        scriptDir = xbmcaddon.Addon('script.mythbox').getAddonInfo('path')
        loggerIniFile = os.path.join(scriptDir, 'mythbox_log.ini')

        # needs to be in local scope for fileConfig to find it
        from mythbox.log import XbmcLogHandler
        
        xbmc.log('MythBox: loggerIniFile = %s' % loggerIniFile)
        logging.config.fileConfig(loggerIniFile)
        self.log = logging.getLogger('mythbox.core')
        self.log.info('Mythbox Logger Initialized')

    def bootstrapPlatform(self):
        self.stage = 'Initializing Platform'
        import mythbox.platform
        self.platform = mythbox.platform.getPlatform()
        self.platform.addLibsToSysPath()
        sys.setcheckinterval(0)
        cacheDir = self.platform.getCacheDir()
        from mythbox.util import requireDir
        requireDir(cacheDir)
        
        self.log.info('MythBox %s Initialized' % self.platform.addonVersion())

    def bootstrapEventBus(self):
        self.bus = EventBus()

    def bootstrapCaches(self):
        self.stage = 'Initializing Caches'
        
        from mythbox.util import NativeTranslator
        from mythbox.filecache import FileCache, HttpResolver, MythThumbnailFileCache
        from mythbox.mythtv.resolver import MythChannelIconResolver, MythThumbnailResolver 
        from os.path import join

        from mythbox.mythtv.cache import DomainCache
        self.domainCache = DomainCache(bus=self.bus)
        
        cacheDir = self.platform.getCacheDir()
        self.translator = NativeTranslator(self.platform.getScriptDir())
        self.mythThumbnailCache = MythThumbnailFileCache(join(cacheDir, 'thumbnail'), MythThumbnailResolver(), self.bus, self.domainCache)
        self.mythChannelIconCache = FileCache(join(cacheDir, 'channel'), MythChannelIconResolver())
        self.httpCache = FileCache(join(cacheDir, 'http'), HttpResolver())
        
        self.cachesByName = {
            'mythThumbnailCache'  : self.mythThumbnailCache, 
            'mythChannelIconCache': self.mythChannelIconCache, 
            'httpCache'           : self.httpCache,
            'domainCache'         : self.domainCache
        }

    def bootstrapSettings(self):
        self.stage = 'Initializing Settings'
        from mythbox.settings import MythSettings
        self.settings = MythSettings(self.platform, self.translator, 'settings.xml', self.bus)

        #from fanart import FanArt
        #self.log.debug('Settings = \n %s' % self.settings)

        class DelayedInstantiationProxy(object):
            '''Could use a little introspection to sort this out but eh...'''
            
            def __init__(self, *args, **kwargs):
                self.args = args
                self.kwargs = kwargs
                self.fanArt = None
                
            def requireDelegate(self):
                if self.fanArt is None:
                    from fanart import FanArt
                    self.fanArt = FanArt(*self.args, **self.kwargs)
            
            def getSeasonAndEpisode(self, program):
                self.requireDelegate()
                return self.fanArt.getSeasonAndEpisode(program)
            
            def getRandomPoster(self, program):
                self.requireDelegate()
                return self.fanArt.getRandomPoster(program)
            
            def getPosters(self, program):
                self.requireDelegate()
                return self.fanArt.getPosters(program)
        
            def hasPosters(self, program):
                self.requireDelegate()
                return self.fanArt.hasPosters(program)
            
            def clear(self):
                self.requireDelegate()
                self.fanArt.clear() 
        
            def shutdown(self):
                self.requireDelegate()
                self.fanArt.shutdown()
                
            def configure(self, settings):
                self.requireDelegate()
                self.fanArt.configure(settings)
            
            def onEvent(self, event):
                self.requireDelegate()
                self.fanArt.onEvent(event)
                    
        from fanart import FanArt
        self.fanArt = FanArt(self.platform, self.httpCache, self.settings, self.bus)
        #self.fanArt = DelayedInstantiationProxy(self.platform, self.httpCache, self.settings, self.bus)
        
        try:
            import socket
            socket.setdefaulttimeout(float(os.getenv('MYTHBOX_TIMEOUT', '30')))
        except:
            self.log.exception('Error setting socket timeout')
            
        self.bus.register(self)

        # Generate fake event to reflect value in settings.xml instead of mythbox_log.ini
        from bus import Event
        self.onEvent({'id': Event.SETTING_CHANGED, 'tag':'logging_enabled', 'old':'DontCare', 'new':self.settings.get('logging_enabled')})
        
    def bootstrapUpdater(self):
        self.stage = 'Initializing Updater'
        from mythbox.updater import UpdateChecker
        UpdateChecker(self.platform).run()

    def bootstrapFeeds(self):
        from mythbox.feeds import FeedHose
        self.feedHose = FeedHose(self.settings, self.bus)

    def bootstrapDebugShell(self):
        # debug shell only packaged with bin/package-debug-zip
        try: 
            from mythbox.shell import DebugShell
            globals()['bootstrapper'] = self
            self.shell = DebugShell(self.bus, namespace=globals())
            self.shell.start()
        except ImportError:
            self.log.debug('Punting on debug shell -- not packaged')

    def bootstrapXbmcShutdownListener(self):
        from threading import Thread
        
        class XbmcShutdownListener(Thread):        

            def __init__(self, home, bus, log):
                Thread.__init__(self)
                self.home = home
                self.log = log
                self.shutdownReceived = False
                bus.register(self)
             
            def onEvent(self, event):
                from bus import Event
                if event['id'] == Event.SHUTDOWN:
                    self.shutdownReceived = True
                    self.join()
                    xbmc.log('Joined shutdown listener') 
                
            def run(self):
                import time
                xbmc.log('XbmcShutdownListener thread running..')
                cnt = 1
                while not xbmc.abortRequested and not self.shutdownReceived:
                    #xbmc.sleep(1000)
                    time.sleep(1)
                    xbmc.log('XbmcShutdownListner abort = %s user = %s tick %d ...' % (xbmc.abortRequested, self.shutdownReceived, cnt))
                    cnt += 1
                    
                if xbmc.abortRequested:
                    xbmc.log('XBMC requested shutdown..')
                    self.home.shutdown()
                    xbmc.log('XBMC requested shutdown complete')
                    
                xbmc.log('XbmcShutdownListener thread terminating')
                
        self.shutdownListener = XbmcShutdownListener(self.home, self.bus, self.log)
        self.shutdownListener.start()

    def bootstrapHomeScreen(self):
        
        from mythbox.ui.home import HomeWindow
        self.home = HomeWindow(
                'mythbox_home.xml', 
                self.platform.getScriptDir(), 
                settings=self.settings, 
                translator=self.translator, 
                platform=self.platform, 
                fanArt=self.fanArt, 
                cachesByName=self.cachesByName,
                bus=self.bus,
                feedHose=self.feedHose)
        if self.splash:
            self.splash.close()
        #self.bootstrapXbmcShutdownListener()
        self.home.doModal()

    def onEvent(self, event):
        from bus import Event
        
        #
        # Apply changes to logger when user turns debug logging on/off
        #
        if event['id'] == Event.SETTING_CHANGED and event['tag'] == 'logging_enabled':
            import logging
            logging.root.debug('Setting changed: %s %s %s' % (event['tag'], event['old'], event['new']))

            if event['new'] == 'True': 
                level = logging.DEBUG
            else: 
                level = logging.WARN
                
            loggerNames = 'unittest mysql core method skin ui perf fanart settings cache event'.split() # wire inject'.split()
                
            for name in loggerNames:
                logger = logging.getLogger('mythbox.%s' %  name)
                logger.setLevel(level)
Exemple #57
0
class MythDatabaseTest(unittest.TestCase):
    def setUp(self):
        self.platform = Platform()
        self.langInfo = util_mock.XBMCLangInfo(self.platform)
        self.translator = util_mock.Translator(self.platform, self.langInfo)
        self.settings = MythSettings(self.platform, self.translator)
        self.protocol = protocol.Protocol56()
        privateConfig = OnDemandConfig()
        self.settings.put('mysql_host', privateConfig.get('mysql_host'))
        self.settings.put('mysql_port', privateConfig.get('mysql_port'))
        self.settings.put('mysql_database',
                          privateConfig.get('mysql_database'))
        self.settings.put('mysql_user', privateConfig.get('mysql_user'))
        self.settings.put('mysql_password',
                          privateConfig.get('mysql_password'))
        self.domainCache = Mock()
        self.db = MythDatabase(self.settings, self.translator,
                               self.domainCache)

    def tearDown(self):
        try:
            self.db.close()
        except:
            pass

    def test_constructor(self):
        self.assertTrue(self.db)

    def test_toBackend(self):
        master = self.db.getMasterBackend()
        self.assertEqual(master, self.db.toBackend(master.hostname))
        self.assertEqual(master, self.db.toBackend(master.ipAddress))
        self.assertTrue(master, self.db.toBackend('bogus'))
        self.assertEqual(master, self.db.toBackend(master.hostname.upper()))
        self.assertEqual(master, self.db.toBackend(master.hostname.lower()))

    def test_getBackends(self):
        bes = self.db.getBackends()
        self.assertTrue(len(bes) >= 1)

    def test_getMasterBackend(self):
        mbe = self.db.getMasterBackend()
        log.debug(mbe)
        self.assertTrue(mbe.hostname)
        self.assertTrue(mbe.ipAddress)
        self.assertTrue(mbe.port)
        self.assertTrue(mbe.master)
        self.assertFalse(mbe.slave)

    def test_getSlaveBackends(self):
        slaves = self.db.getSlaveBackends()
        for slave in slaves:
            log.debug(slave)
            self.assertFalse(slave.master)
            self.assertTrue(slave.slave)

    def test_getChannels(self):
        channels = self.db.getChannels()
        for i, channel in enumerate(channels):
            log.debug("%d - %s" % (i + 1, channel))
            self.assertTrue(
                'Expected int but was %s' % type(channel.getChannelId()),
                isinstance(channel.getChannelId(), int))
            self.assertTrue(
                'Expected str but was %s' % type(channel.getChannelNumber()),
                isinstance(channel.getChannelNumber(), str))
            self.assertTrue(
                'Expected str but was %s' % type(channel.getCallSign()),
                isinstance(channel.getCallSign(), str))
            self.assertTrue(
                'Expected str but was %s' % type(channel.getChannelName()),
                isinstance(channel.getChannelName(), str))
            self.assertTrue(
                'Expected str but was %s' % type(channel.getIconPath()),
                isinstance(channel.getIconPath(), str))
            self.assertTrue(
                'Expected int but was %s' % type(channel.getTunerId()),
                isinstance(channel.getTunerId(), int))

    def test_getRecordingProfileNames(self):
        self.assertTrue(self.db.getRecordingProfileNames())

    def test_getRecordingGroups(self):
        groups = self.db.getRecordingGroups()
        self.assertTrue('Default' in groups)

    def test_getRecordingTitles_InAllGroups(self):
        titles = self.db.getRecordingTitles('All Groups')
        self.assertTrue(len(titles) > 0)
        total = titles[0][1]
        for i, title in enumerate(titles):
            titleName = title[0]
            titleCount = title[1]
            log.debug('%d - %s x %s' % (i + 1, titleCount, titleName))

    def test_getRecordingTitles_ForNonExistantRecordingGroupReturnsAllShowsWithCountOfZero(
            self):
        titles = self.db.getRecordingTitles('bogus group')
        self.assertEquals(1, len(titles))
        self.assertEquals('All Shows', titles[0][0])
        self.assertEquals(0, titles[0][1])

    def test_getRecordingTitles_ForDeletedRecordingsGroup(self):
        deleted = self.db.getRecordingTitles('Deleted')
        for i, title in enumerate(deleted):
            titleName = title[0]
            titleCount = title[1]
            log.debug('%d - Deleted recording %s recorded %s times' %
                      (i + 1, titleName, titleCount))
        self.assertTrue(len(deleted) > 0)

    def test_getTuners(self):
        tuners = self.db.getTuners()
        self.assertTrue(len(tuners) > 0, 'No tuners found')
        for i, tuner in enumerate(tuners):
            log.debug('%d - %s' % (i + 1, tuner))
            self.assertIsNotNone(tuner.tunerId)
            self.assertIsNotNone(tuner.hostname)
            self.assertIsNotNone(tuner.signalTimeout)
            self.assertIsNotNone(tuner.channelTimeout)
            self.assertIsNotNone(tuner.domainCache)

    def test_getMythSetting_KeyOnly_Found(self):
        s = self.db.getMythSetting('mythfilldatabaseLastRunStatus')
        log.debug('mythfillstatus = %s' % s)
        self.assertFalse(s is None)

    def test_getMythSetting_KeyOnly_NotFound(self):
        s = self.db.getMythSetting('blahblah')
        self.assertTrue(s is None)

    def test_getMythSetting_KeyWithHostname_Found(self):
        # TODO
        pass

    def test_getMythSetting_KeyWithHostname_NotFound(self):
        s = self.db.getMythSetting('blahblah', 'foobar')
        self.assertTrue(s is None)

    def test_getRecordingSchedules_All(self):
        schedules = self.db.getRecordingSchedules()
        for i, s in enumerate(schedules):
            log.debug('%d - %s' % (i + 1, s))
        self.assertTrue(schedules)

    def test_getRecordingSchedules_By_Channel(self):
        # TODO
        pass

    def test_getRecordingSchedules_By_ScheduleId(self):
        # Setup
        schedules = self.db.getRecordingSchedules()
        if len(schedules) == 0:
            self.fail('Need schedules to run test')
        expectedSchedule = schedules.pop()

        # Test
        actualSchedules = self.db.getRecordingSchedules(
            scheduleId=expectedSchedule.getScheduleId())

        # Verify
        self.assertEquals(1, len(actualSchedules))
        self.assertEquals(expectedSchedule.getScheduleId(),
                          actualSchedules.pop().getScheduleId())

    def test_getJobs_All(self):
        when(self.domainCache).getUserJobs().thenReturn(self.db.getUserJobs())
        jobs = self.db.getJobs()
        self.assertTrue(jobs is not None)
        for index, job in enumerate(jobs):
            log.debug('job %d = %s' % (index, job))

    def test_getJobs_ForProgram(self):
        # Setup
        when(self.domainCache).getUserJobs().thenReturn(self.db.getUserJobs())
        jobs = self.db.getJobs()
        if len(jobs) == 0:
            log.warn('No jobs in database to test with. Test skipped...')
            return
        job = jobs[-1]  # last job
        data = [''] * self.protocol.recordSize()
        data[4] = job.channelId
        data[11] = time.mktime(job.startTime.timetuple())
        program = RecordedProgram(data=data,
                                  settings=Mock(),
                                  translator=Mock(),
                                  platform=Mock(),
                                  protocol=self.protocol,
                                  conn=Mock())

        # Test
        jobs = self.db.getJobs(program=program)

        # Verify
        self.assertTrue(len(jobs) > 0)
        for index, actual in enumerate(jobs):
            log.debug('job %d = %s' % (index, actual))
            self.assertEquals(job.channelId, actual.channelId)
            self.assertEquals(job.startTime, actual.startTime)

    def test_getJobs_ByJobType(self):
        # Setup
        when(self.domainCache).getUserJobs().thenReturn(self.db.getUserJobs())
        jobs = self.db.getJobs()
        if len(jobs) == 0:
            log.warn('No jobs in database to test with. Test skipped...')
            return
        job = jobs[0]

        # Test
        jobs = self.db.getJobs(jobType=job.jobType)

        # Verify
        self.assertTrue(len(jobs) > 0)
        for index, j2 in enumerate(jobs):
            log.debug('job %d = %s' % (index, j2))
            self.assertEquals(job.jobType, j2.jobType)

    def test_getJobs_ForProgram_ByJobType(self):
        # Setup
        when(self.domainCache).getUserJobs().thenReturn(self.db.getUserJobs())
        jobs = self.db.getJobs()
        if len(jobs) == 0:
            log.warn('No jobs in database to test with. Test skipped...')
            return
        job = jobs[-1]  # last job
        data = [''] * self.protocol.recordSize()
        data[4] = job.channelId
        data[11] = time.mktime(job.startTime.timetuple())
        program = RecordedProgram(data=data,
                                  settings=Mock(),
                                  translator=Mock(),
                                  platform=Mock(),
                                  protocol=self.protocol,
                                  conn=Mock())

        # Test
        jobs = self.db.getJobs(program=program, jobType=job.jobType)

        # Verify
        self.assertTrue(len(jobs) > 0)
        for index, actual in enumerate(jobs):
            log.debug('job %d = %s' % (index, actual))
            self.assertEquals(job.channelId, actual.channelId)
            self.assertEquals(job.startTime, actual.startTime)
            self.assertEquals(job.jobType, actual.jobType)

    def test_getUserJobs(self):
        userJobs = self.db.getUserJobs()
        for j in userJobs:
            log.debug(j)
        self.assertEqual(4, len(userJobs))

    def test_getTVGuideDataFlattened(self):
        # TODO: Convert to mocks w/ assertions
        channels = self.db.getChannels()[:2]
        programs = self.db.getTVGuideDataFlattened(
            datetime.datetime.now(),
            datetime.datetime.now() + datetime.timedelta(hours=4), channels)

        for p in programs:
            log.debug(p)

    def test_getFramerate(self):
        from mythbox.mythtv.conn import Connection
        from mythbox.util import safe_str
        from mythbox.mythtv.enums import RecordingStatus

        conn = Connection(settings=self.settings,
                          translator=Mock(),
                          platform=Mock(),
                          bus=Mock(),
                          db=self.db)
        try:
            recordings = conn.getAllRecordings()[-10:]
            for r in recordings:
                if r.isCommFlagged() and r.getRecordingStatus(
                ) == RecordingStatus.RECORDED:
                    fps = self.db.getFramerate(r)
                    log.debug('%s - %s - %s %d' %
                              (safe_str(r.title()), safe_str(
                                  r.subtitle()), fps, r.getRecordingStatus()))
                    self.assertGreaterEqual(fps, 0.0, fps)
        finally:
            conn.close()
Exemple #58
0
 def test_verifyBoolean_AllValuesThatShouldNotRaiseException(self):
     MythSettings.verifyBoolean("True", "blah")
     MythSettings.verifyBoolean("False", "blah")
     MythSettings.verifyBoolean("1", "blah")
     MythSettings.verifyBoolean("0", "blah")
Exemple #59
0
class DeleteOrphansTest(unittest.TestCase):

    def setUp(self):
        self.platform = getPlatform()
        self.translator = Mock()
        self.domainCache = Mock()
        self.settings = MythSettings(self.platform, self.translator)
        self.settings.put('streaming_enabled', 'False')
        
        privateConfig = OnDemandConfig()
        self.settings.put('mysql_host', privateConfig.get('mysql_host'))
        self.settings.put('mysql_port', privateConfig.get('mysql_port'))
        self.settings.setMySqlDatabase(privateConfig.get('mysql_database'))
        self.settings.setMySqlUser(privateConfig.get('mysql_user'))  
        self.settings.put('mysql_password', privateConfig.get('mysql_password'))
        self.settings.put('paths_recordedprefix', privateConfig.get('paths_recordedprefix'))
        
        self.db = MythDatabase(self.settings, self.translator, self.domainCache)
        self.bus = EventBus()
        self.conn = Connection(self.settings, self.translator, self.platform, self.bus, self.db)

    def tearDown(self):
        self.conn.close()

    def test_delete_orphaned_recordings(self):
        recordings = self.conn.getAllRecordings()
        log.debug('Num Recordings = %s' % len(recordings))
        for i,r in enumerate(recordings):
            print i,r.getBareFilename()
 
        dirs = ['/usr2/mythtv']
        
        mpgs = []
        
        for d in dirs:
            files = os.listdir(d)
            for f in files:
                if f.endswith('.mpg'):
                    mpgs.append(f)
                    print f
                    
        print 'Recs  total = ', len(recordings)
        print 'Files total = ', len(mpgs)
        print 'Extras      = ', len(mpgs) - len(recordings)    
        
        todelete = mpgs[:]
        for r in recordings:
            if r.getBareFilename() in mpgs:
                todelete.remove(r.getBareFilename())
                
        print 'Todelete    = ', len(todelete)

        bucket = []
        
        import datetime
        
        for f in todelete:
            for d in dirs:
                path = os.path.join(d,f)
                if os.path.exists(path):
                    bucket.append(path)
                    print path, os.path.getsize(path)
                        
        print 'Bucket     = ', len(bucket)
        sorted(bucket)
        
        total = 0
        for f in bucket:
            s = os.path.getsize(f)
            total += s
            
        print total/1000000000
        
        import shutil
        
        for src in bucket:
            dest = '/usr2/mythtv/backup/' + os.path.basename(src)
            print src,' -> ', dest
            #shutil.move(src, dest) 

    def test_recreate_lost_recordings(self):
        recordings = self.conn.getAllRecordings()
        log.debug('Num Recordings = %s' % len(recordings))
        for i,r in enumerate(recordings):
            print i,r.getBareFilename()
 
        dirs = ['/usr2/mythtv']
        
        mpgs = []
        
        for d in dirs:
            files = os.listdir(d)
            for f in files:
                if f.endswith('.mpg'):
                    mpgs.append(f)
                    print f
                    
        print 'Recs  total   = ', len(recordings)
        print 'Files total   = ', len(mpgs)
        print 'Missing total = ', len(recordings) - len(mpgs)    
        
        rec_names = [r.getBareFilename() for r in recordings]
        tocreate = rec_names[:]
        for m in mpgs:
            if m in rec_names:
                tocreate.remove(m)
                
        print 'Tocreate    = ', len(tocreate)

        bucket = []
        
        import datetime
        
        for f in tocreate:
            for d in dirs:
                path = os.path.join(d,f)
                if not os.path.exists(path):
                    bucket.append(path)
                    print path
                        
        print 'Bucket     = ', len(bucket)
        sorted(bucket)
                
        import shutil
        
        src = '/usr/copy/me.mpg'
        for dest in bucket:
            print src,' -> ', dest