Logo Search packages:      
Sourcecode: jockey version File versions  Download package

detection.py

# -*- coding: UTF-8 -*-

'''detection tests'''

# (c) 2007 Canonical Ltd.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import unittest, os.path, shutil

import jockey.detection
from jockey.detection import HardwareID
from jockey.oslib import OSLib

import sandbox

class DetectionTest(unittest.TestCase):
    def tearDown(self):
        '''Clean handler dir.'''

        shutil.rmtree(OSLib.inst.handler_dir)
        os.mkdir(OSLib.inst.handler_dir)

    def test_connected_modaliases(self):
        '''_connected_modaliases() returns correct mapping'''

        m = jockey.detection._connected_modaliases()

        self.assertEqual(set(m.keys()), set([None, 'vanilla', 'dullstd']))
        self.assertEqual(len(m['vanilla']), 2) # NB that we have two devices using that driver

        self.assertEqual(str(m['vanilla'][0]), 
            "HardwareID('modalias', 'pci:v00001001d00003D01sv00001234sd00000001bc03sc00i00')",
            'graphics card uses vanilla module')

        self.assertEqual('\n'.join(sorted([str(h) for h in m[None]])),
            '''HardwareID('modalias', 'dmi:foo[A-1]bar')
HardwareID('modalias', 'fire:1.2')
HardwareID('modalias', 'pci:v0000AAAAd000012AAsv00000000sdDEADBEEFbc02sc80i00')
HardwareID('modalias', 'pci:v0000FFF0d00000001sv00000000sd00000000bc06sc01i01')
HardwareID('modalias', 'ssb:v4243id0812rev05')''')

    def test_hwid_equality(self):
        '''HardwareID equality implementation
        
        This tests modalias pattern matching in particular, since this is
        nontrivial.'''

        # identity
        x = HardwareID('pci', '1234/5678')
        self.assertEqual(x, x)
        self.failIf(x != x)

        # trivial equality
        x = HardwareID('pci', '1234/5678')
        y = HardwareID('pci', '1234/5678')
        self.assertEqual(x, y)
        self.failIf(x != y)
        self.assertEqual(hash(x), hash(y))

        x = HardwareID('modalias', 'pci:v00001001d00003D01sv00001234sd00000001bc03sc00i00') 
        y = HardwareID('modalias', 'pci:v00001001d00003D01sv00001234sd00000001bc03sc00i00') 
        self.assertEqual(x, y)
        self.failIf(x != y)
        self.assertEqual(hash(x), hash(y))

        # trivial inequality
        x = HardwareID('pci', '1234/5678')
        y = HardwareID('pci', '1234/5679')
        self.assertNotEqual(x, y)
        self.assert_(x != y)

        x = HardwareID('modalias', 'pci:v00001001d00003D01sv00001234sd00000001bc03sc00i00') 
        y = HardwareID('modalias', 'pci:v00001001d00003D01sv00001235sd00000001bc03sc00i00') 
        self.assertNotEqual(x, y)
        self.assert_(x != y)

        # modalias pattern equality
        x = HardwareID('modalias', 'pci:v00001*d00003D*sv*sd*1bc03sc00i*') 
        y = HardwareID('modalias', 'pci:v00001001d00003D01sv00001234sd00000001bc03sc00i00') 

        self.assertEqual(x, y)
        self.failIf(x != y)
        self.assertEqual(y, x)
        self.failIf(y != x)
        self.assertEqual(hash(x), hash(y))

        # pattern comparison; this is necessary for usage as dictionary keys,
        # but should just be string comparison
        x = HardwareID('modalias', 'pci:v00001*d00003D*sv*sd*1bc03sc00i*') 
        y = HardwareID('modalias', 'pci:v00001*d00003D*sv*sd*1bc03sc00i*') 
        self.assertEqual(x, y)
        self.assertEqual(hash(x), hash(y))
        y = HardwareID('modalias', 'pci:v00001*d*sv*sd*1bc03sc00i*') 
        self.assertNotEqual(x, y)

        # non-modalias values should not match on patterns
        x = HardwareID('pci', '1234/5678')
        y = HardwareID('pci', '12*/56*')
        self.assertNotEqual(x, y)

    def test_hwid_dictionary(self):
        '''HardwareID can be used as dictionary keys''' 

        d = {
            HardwareID('pci', '1234/5678'): 'pci1',
            HardwareID('pci', '1234/5679'): 'pci2',
            HardwareID('modalias', 'pci:v0000AAAAd000012AAsv00000000sdDEADBEEFbc02sc80i00'): 'ma1',
            HardwareID('modalias', 'pci:v00001*d00003D*sv*sd*1bc03sc00i*'): 'ma_bc03',
            HardwareID('modalias', 'pci:v00001*d00003D*sv*sd*1bc04sc00i*'): 'ma_bc04',
        }

        self.assertEqual(d[HardwareID('pci', '1234/5678')], 'pci1')
        self.assertRaises(KeyError, d.__getitem__, HardwareID('pci', '1235/1111'))
        self.assertEqual(d[HardwareID('modalias',
            'pci:v00001001d00003D01sv00001234sd00000001bc03sc00i00')], 'ma_bc03')
        self.assertEqual(d[HardwareID('modalias',
            'pci:v0000AAAAd000012AAsv00000000sdDEADBEEFbc02sc80i00')], 'ma1')
        self.assertRaises(KeyError, d.__getitem__, HardwareID('modalias',
            'pci:v0000FFF0d00000001sv00000000sd00000000bc06sc01i01'))

    def test_get_handlers_no_driverdb(self):
        '''get_handlers() returns applicable handlers without a driver db'''

        open (os.path.join(OSLib.inst.handler_dir, 'kmod_nodetect.py'), 'w').write(
            sandbox.h_availability_py)

        h = jockey.detection.get_handlers(sandbox.TestUI())

        self.assertEqual(len(h), 1, 'get_handlers() found one applicable handler')
        for h in h: pass # get single item in set h
        self.assert_(isinstance(h, jockey.handlers.Handler))
        self.assert_(h.available())
        self.assertEqual(str(h.__class__).split('.')[-1], 'AvailMod')
        self.assertEqual(h.module, 'vanilla')
        self.assertEqual(h.name(), 'free module with available hardware, graphics card')

        self.assert_(h.enabled())

    def test_get_handlers_invalid(self):
        '''get_handlers() does not fall over when reading invalid handler
        files'''

        open (os.path.join(OSLib.inst.handler_dir, '01_no_python.py'), 'w').write(
            "Ce n'est ne pas un fichier Python!")
        open (os.path.join(OSLib.inst.handler_dir, '02_valid.py'), 'w').write(
            'import jockey.handlers\n' + sandbox.h_avail_mod)
        open (os.path.join(OSLib.inst.handler_dir, '03_inval_python.py'), 'w').write(
            'import i.do.not.exist\n' + sandbox.h_avail_mod.replace('AvailMod', 'AlsoAvailMod'))

        h = jockey.detection.get_handlers(sandbox.TestUI())

        self.assertEqual(len(h), 1, 'get_handlers() found one applicable handler')
        for h in h: pass # get single item in set h
        self.assert_(isinstance(h, jockey.handlers.Handler))
        self.assertEqual(h.module, 'vanilla')
        self.assert_('Invalid custom handler' in sandbox.log.getvalue())

    def test_get_handlers_driverdb(self):
        '''get_handlers() returns applicable handlers with querying the driver db'''

        open (os.path.join(OSLib.inst.handler_dir, 'testhandlers.py'), 'w').write('''
import jockey.handlers

%s

class VanillaGfxHandler(jockey.handlers.KernelModuleHandler):
    def __init__(self, ui):
        jockey.handlers.KernelModuleHandler.__init__(self, ui, 'vanilla3d')

class NonexistingModHandler(jockey.handlers.KernelModuleHandler):
    def __init__(self, ui):
        jockey.handlers.KernelModuleHandler.__init__(self, ui, 'nonexisting')
''' % sandbox.h_avail_mod)

        result = jockey.detection.get_handlers(sandbox.TestUI(), sandbox.TestDriverDB())

        out = '\n'.join(sorted([str(h) for h in result]))
        self.assertEqual(out, 
'''kmod:firmwifi([FirmwareHandler, nonfree, disabled] standard module which needs firmware)
kmod:mint([KernelModuleHandler, nonfree, enabled] nonfree module with available hardware, wifi)
kmod:spam([KernelModuleHandler, free, enabled] free mystical module without modaliases)
kmod:vanilla([AvailMod, free, enabled] free module with available hardware, graphics card)
kmod:vanilla3d([VanillaGfxHandler, nonfree, enabled] nonfree, replacement graphics driver for vanilla)''')

        for h in result:
            if h.module == 'firmwifi':
                self.failIf(h.enabled())
            else:
                self.assert_(h.enabled())

    def test_localkernelmod_driverdb(self):
        '''LocalKernelModulesDriverDB creates appropriate handlers
        
        It should prefer custom handlers over autogenerated standard ones and
        create standard ones for detected hardware.'''

        open (os.path.join(OSLib.inst.handler_dir, 'testhandlers.py'), 'w').write('''
import jockey.handlers

class MintWrapper(jockey.handlers.KernelModuleHandler):
    def __init__(self, ui):
        jockey.handlers.KernelModuleHandler.__init__(self, ui, 'mint',
            'I taste even mintier')
''')

        result = jockey.detection.get_handlers(sandbox.TestUI(),
            jockey.detection.LocalKernelModulesDriverDB())

        out = '\n'.join(sorted([str(h) for h in result]))

        self.assertEqual(out, 
'''kmod:firmwifi([KernelModuleHandler, free, enabled] standard module which needs firmware)
kmod:foodmi([KernelModuleHandler, free, enabled] foo DMI driver for [A-1] devices)
kmod:mint([MintWrapper, nonfree, enabled] I taste even mintier)
kmod:vanilla([KernelModuleHandler, free, enabled] free module with available hardware, graphics card)
kmod:vanilla3d([KernelModuleHandler, nonfree, enabled] nonfree, replacement graphics driver for vanilla)''')

        for h in result:
            self.assert_(h.enabled())

    def test_localkernelmod_driverdb_ignored_customhandler(self):
        '''LocalKernelModulesDriverDB creates custom handler for ignored module'''

        open (os.path.join(OSLib.inst.handler_dir, 'testhandlers.py'), 
            'w').write(sandbox.h_ignored_custom_mod)

        result = jockey.detection.get_handlers(sandbox.TestUI(),
            jockey.detection.LocalKernelModulesDriverDB())

        out = '\n'.join(sorted([str(h) for h in result]))

        self.assertEqual(out, 
'''kmod:dullstd([LessDullMod, free, enabled] standard module which should be ignored for detection)
kmod:firmwifi([KernelModuleHandler, free, enabled] standard module which needs firmware)
kmod:foodmi([KernelModuleHandler, free, enabled] foo DMI driver for [A-1] devices)
kmod:mint([KernelModuleHandler, nonfree, enabled] nonfree module with available hardware, wifi)
kmod:vanilla([KernelModuleHandler, free, enabled] free module with available hardware, graphics card)
kmod:vanilla3d([KernelModuleHandler, nonfree, enabled] nonfree, replacement graphics driver for vanilla)''')

        for h in result:
            self.assert_(h.enabled())

    def test_localkernelmod_driverdb_overrides(self):
        '''LocalKernelModulesDriverDB respects modalias overrides'''

        try:
            f = open(os.path.join(OSLib.inst.modaliases[1], 'ham.alias'), 'w')
            f.write('''# some bogus modaliases
alias usb:v057Cp3500d*dc*dsc*dp*ic*isc*ip* fcdslslusb
alias usb:v0582p0044d*dc*dsc*dp*ic*isc*ip* snd_usb_audio
''')
            f.close()

            # assign spam module to the unknown piece of hardware
            f = open(os.path.join(OSLib.inst.modaliases[1], 'spam'), 'w')
            f.write('''# let's put an use to spam
alias pci:v0000FFF0d*1sv*sd*bc06sc*i* spam
''')
            f.close()

            result = jockey.detection.get_handlers(sandbox.TestUI(),
                jockey.detection.LocalKernelModulesDriverDB())

            out = '\n'.join(sorted([str(h) for h in result]))

            self.assertEqual(out, 
'''kmod:firmwifi([KernelModuleHandler, free, enabled] standard module which needs firmware)
kmod:foodmi([KernelModuleHandler, free, enabled] foo DMI driver for [A-1] devices)
kmod:mint([KernelModuleHandler, nonfree, enabled] nonfree module with available hardware, wifi)
kmod:spam([KernelModuleHandler, free, enabled] free mystical module without modaliases)
kmod:vanilla([KernelModuleHandler, free, enabled] free module with available hardware, graphics card)
kmod:vanilla3d([KernelModuleHandler, nonfree, enabled] nonfree, replacement graphics driver for vanilla)''')
        finally:
            for f in os.listdir(OSLib.inst.modaliases[1]):
                os.unlink(os.path.join(OSLib.inst.modaliases[1], f))

    def test_localkernelmod_driverdb_modalias_reset(self):
        '''LocalKernelModulesDriverDB resetting of modaliases'''

        try:
            f = open(os.path.join(OSLib.inst.modaliases[1], '01_bad'), 'w')
            f.write('alias pci:v0000FFF0d*sv*sd*bc*sc*i* cherry\n')
            f.close()
            # resets both the original and above bogus cherry entry; resetting
            # vanilla uncovers vanilla3d (which is the second candidate)
            f = open(os.path.join(OSLib.inst.modaliases[1], '02_reset'), 'w')
            f.write('reset cherry\nreset vanilla\n')
            f.close()
            f = open(os.path.join(OSLib.inst.modaliases[1], '03_good'), 'w')
            f.write('alias pci:v0000FFF0d*1sv*sd*bc06sc*i* spam\n')
            f.close()

            result = jockey.detection.get_handlers(sandbox.TestUI(),
                jockey.detection.LocalKernelModulesDriverDB())

            out = '\n'.join(sorted([str(h) for h in result]))

            self.assertEqual(out, 
'''kmod:firmwifi([KernelModuleHandler, free, enabled] standard module which needs firmware)
kmod:foodmi([KernelModuleHandler, free, enabled] foo DMI driver for [A-1] devices)
kmod:mint([KernelModuleHandler, nonfree, enabled] nonfree module with available hardware, wifi)
kmod:spam([KernelModuleHandler, free, enabled] free mystical module without modaliases)
kmod:vanilla3d([KernelModuleHandler, nonfree, enabled] nonfree, replacement graphics driver for vanilla)''')
        finally:
            for f in os.listdir(OSLib.inst.modaliases[1]):
                os.unlink(os.path.join(OSLib.inst.modaliases[1], f))

    def test_get_handlers_license_filter(self):
        '''get_handlers() returns applicable handlers with license filtering'''

        open (os.path.join(OSLib.inst.handler_dir, 'testhandlers.py'), 'w').write('''
import jockey.handlers

%s

class VanillaGfxHandler(jockey.handlers.KernelModuleHandler):
    def __init__(self, ui):
        jockey.handlers.KernelModuleHandler.__init__(self, ui, 'vanilla3d')
''' % sandbox.h_avail_mod)

        result = jockey.detection.get_handlers(sandbox.TestUI(),
            sandbox.TestDriverDB(), mode=jockey.detection.MODE_FREE)

        out = '\n'.join(sorted([str(h) for h in result]))
        self.assertEqual(out, 
'''kmod:spam([KernelModuleHandler, free, enabled] free mystical module without modaliases)
kmod:vanilla([AvailMod, free, enabled] free module with available hardware, graphics card)''')

        result = jockey.detection.get_handlers(sandbox.TestUI(),
            sandbox.TestDriverDB(), mode=jockey.detection.MODE_NONFREE)

        out = '\n'.join(sorted([str(h) for h in result]))
        self.assertEqual(out, 
'''kmod:firmwifi([FirmwareHandler, nonfree, disabled] standard module which needs firmware)
kmod:mint([KernelModuleHandler, nonfree, enabled] nonfree module with available hardware, wifi)
kmod:vanilla3d([VanillaGfxHandler, nonfree, enabled] nonfree, replacement graphics driver for vanilla)''')

    def test_get_handlers_driverdb_nonexisting_module(self):
        '''get_handlers() ignores nonexisting kernel modules'''

        class MyDDB(jockey.detection.DriverDB):
            '''Always return the same nonexisting kernel module as handler.'''

            def query(self, hwid):
                return [jockey.detection.DriverID(handler='KernelModuleHandler',
                    module='superdriver')]

        result = jockey.detection.get_handlers(sandbox.TestUI(), MyDDB())
        self.assertEqual(result, set())

    def test_get_handlers_all(self):
        '''get_handlers() with available_only=False'''

        open (os.path.join(OSLib.inst.handler_dir, 'kmod_nodetect.py'), 'w').write(
            sandbox.h_availability_py)

        h = jockey.detection.get_handlers(sandbox.TestUI(),
            available_only=False)

        self.assertEqual(len(h), 3)


Generated by  Doxygen 1.6.0   Back to index