mirror of
				https://github.com/KevinMidboe/python-gpiozero.git
				synced 2025-10-29 17:50:37 +00:00 
			
		
		
		
	Merge pull request #220 from waveform80/test-real-pins
Add "real" pins tests
This commit is contained in:
		@@ -245,6 +245,7 @@ class NativePin(Pin):
 | 
			
		||||
    def close(self):
 | 
			
		||||
        self.when_changed = None
 | 
			
		||||
        self.function = 'input'
 | 
			
		||||
        self.pull = 'up' if self.number in (2, 3) else 'floating'
 | 
			
		||||
 | 
			
		||||
    def _get_function(self):
 | 
			
		||||
        return self.GPIO_FUNCTION_NAMES[(self._MEM[self._func_offset] >> self._func_shift) & 7]
 | 
			
		||||
@@ -253,7 +254,7 @@ class NativePin(Pin):
 | 
			
		||||
        try:
 | 
			
		||||
            value = self.GPIO_FUNCTIONS[value]
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            raise PinInvalidFunction('invalid function "%s" for pin %r' % self)
 | 
			
		||||
            raise PinInvalidFunction('invalid function "%s" for pin %r' % (value, self))
 | 
			
		||||
        self._MEM[self._func_offset] = (
 | 
			
		||||
            self._MEM[self._func_offset]
 | 
			
		||||
            & ~(7 << self._func_shift)
 | 
			
		||||
@@ -282,7 +283,7 @@ class NativePin(Pin):
 | 
			
		||||
        try:
 | 
			
		||||
            value = self.GPIO_PULL_UPS[value]
 | 
			
		||||
        except KeyError:
 | 
			
		||||
            raise PinInvalidPull('invalid pull direction "%s" for pin %r' % self)
 | 
			
		||||
            raise PinInvalidPull('invalid pull direction "%s" for pin %r' % (value, self))
 | 
			
		||||
        self._MEM[self._MEM.GPPUD_OFFSET] = value
 | 
			
		||||
        sleep(0.000000214)
 | 
			
		||||
        self._MEM[self._pull_offset] = 1 << self._pull_shift
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ from ..exc import (
 | 
			
		||||
    PinInvalidFunction,
 | 
			
		||||
    PinSetInput,
 | 
			
		||||
    PinFixedPull,
 | 
			
		||||
    PinInvalidPull,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -144,7 +145,7 @@ class PiGPIOPin(Pin):
 | 
			
		||||
            self.frequency = None
 | 
			
		||||
            self.when_changed = None
 | 
			
		||||
            self.function = 'input'
 | 
			
		||||
            self.pull = 'floating'
 | 
			
		||||
            self.pull = 'up' if self.number in (2, 3) else 'floating'
 | 
			
		||||
 | 
			
		||||
    def _get_function(self):
 | 
			
		||||
        return self.GPIO_FUNCTION_NAMES[self._connection.get_mode(self._number)]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										143
									
								
								tests/test_real_pins.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								tests/test_real_pins.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,143 @@
 | 
			
		||||
from __future__ import (
 | 
			
		||||
    unicode_literals,
 | 
			
		||||
    absolute_import,
 | 
			
		||||
    print_function,
 | 
			
		||||
    division,
 | 
			
		||||
    )
 | 
			
		||||
str = type('')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import io
 | 
			
		||||
import subprocess
 | 
			
		||||
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
from gpiozero import PinFixedPull, PinInvalidPull, PinInvalidFunction
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# This module assumes you've wired the following GPIO pins together
 | 
			
		||||
TEST_PIN = 22
 | 
			
		||||
INPUT_PIN = 27
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Skip the entire module if we're not on a Pi
 | 
			
		||||
def is_a_pi():
 | 
			
		||||
    with io.open('/proc/cpuinfo', 'r') as cpuinfo:
 | 
			
		||||
        for line in cpuinfo:
 | 
			
		||||
            if line.startswith('Hardware'):
 | 
			
		||||
                hardware, colon, soc = line.strip().split(None, 2)
 | 
			
		||||
                return soc in ('BCM2708', 'BCM2709', 'BCM2835', 'BCM2836')
 | 
			
		||||
        else:
 | 
			
		||||
            return False
 | 
			
		||||
pytestmark = pytest.mark.skipif(not is_a_pi(), reason='tests cannot run on non-Pi platforms')
 | 
			
		||||
del is_a_pi
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# Try and import as many pin libraries as possible
 | 
			
		||||
PIN_CLASSES = []
 | 
			
		||||
try:
 | 
			
		||||
    from gpiozero.pins.rpigpio import RPiGPIOPin
 | 
			
		||||
    PIN_CLASSES.append(RPiGPIOPin)
 | 
			
		||||
except ImportError:
 | 
			
		||||
    RPiGPIOPin = None
 | 
			
		||||
try:
 | 
			
		||||
    from gpiozero.pins.rpio import RPIOPin
 | 
			
		||||
    PIN_CLASSES.append(RPIOPin)
 | 
			
		||||
except ImportError:
 | 
			
		||||
    RPIOPin = None
 | 
			
		||||
try:
 | 
			
		||||
    from gpiozero.pins.pigpiod import PiGPIOPin
 | 
			
		||||
    PIN_CLASSES.append(PiGPIOPin)
 | 
			
		||||
except ImportError:
 | 
			
		||||
    PiGPIOPin = None
 | 
			
		||||
try:
 | 
			
		||||
    from gpiozero.pins.native import NativePin
 | 
			
		||||
    PIN_CLASSES.append(NativePin)
 | 
			
		||||
except ImportError:
 | 
			
		||||
    NativePin = None
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='module', params=PIN_CLASSES)
 | 
			
		||||
def pin_class(request):
 | 
			
		||||
    # pigpiod needs to be running for PiGPIOPin
 | 
			
		||||
    if request.param.__name__ == 'PiGPIOPin':
 | 
			
		||||
        subprocess.check_call(['sudo', 'pigpiod'])
 | 
			
		||||
        # Unfortunately, pigpiod provides no option for running in the
 | 
			
		||||
        # foreground, so we have to use the sledgehammer of killall to get shot
 | 
			
		||||
        # of it
 | 
			
		||||
        def kill_pigpiod():
 | 
			
		||||
            subprocess.check_call(['sudo', 'killall', 'pigpiod'])
 | 
			
		||||
        request.addfinalizer(kill_pigpiod)
 | 
			
		||||
    return request.param
 | 
			
		||||
 | 
			
		||||
@pytest.fixture
 | 
			
		||||
def pins(request, pin_class):
 | 
			
		||||
    # Why return both pins in a single fixture? If we defined one fixture for
 | 
			
		||||
    # each pin then pytest will (correctly) test RPiGPIOPin(22) against
 | 
			
		||||
    # NativePin(27) and so on. This isn't supported, so we don't test it
 | 
			
		||||
    test_pin = pin_class(22)
 | 
			
		||||
    input_pin = pin_class(27)
 | 
			
		||||
    input_pin.function = 'input'
 | 
			
		||||
    input_pin.pull = 'down'
 | 
			
		||||
    def fin():
 | 
			
		||||
        test_pin.close()
 | 
			
		||||
        input_pin.close()
 | 
			
		||||
    request.addfinalizer(fin)
 | 
			
		||||
    return test_pin, input_pin
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_pin_numbers(pins):
 | 
			
		||||
    test_pin, input_pin = pins
 | 
			
		||||
    assert test_pin.number == 22
 | 
			
		||||
    assert input_pin.number == 27
 | 
			
		||||
 | 
			
		||||
def test_function_bad(pins):
 | 
			
		||||
    test_pin, input_pin = pins
 | 
			
		||||
    with pytest.raises(PinInvalidFunction):
 | 
			
		||||
        test_pin.function = 'foo'
 | 
			
		||||
 | 
			
		||||
def test_output(pins):
 | 
			
		||||
    test_pin, input_pin = pins
 | 
			
		||||
    test_pin.function = 'output'
 | 
			
		||||
    test_pin.state = 0
 | 
			
		||||
    assert input_pin.state == 0
 | 
			
		||||
    test_pin.state = 1
 | 
			
		||||
    assert input_pin.state == 1
 | 
			
		||||
 | 
			
		||||
def test_output_with_state(pins):
 | 
			
		||||
    test_pin, input_pin = pins
 | 
			
		||||
    test_pin.output_with_state(0)
 | 
			
		||||
    assert input_pin.state == 0
 | 
			
		||||
    test_pin.output_with_state(1)
 | 
			
		||||
    assert input_pin.state == 1
 | 
			
		||||
 | 
			
		||||
def test_pull(pins):
 | 
			
		||||
    test_pin, input_pin = pins
 | 
			
		||||
    test_pin.function = 'input'
 | 
			
		||||
    test_pin.pull = 'up'
 | 
			
		||||
    assert input_pin.state == 1
 | 
			
		||||
    test_pin.pull = 'down'
 | 
			
		||||
    test_pin, input_pin = pins
 | 
			
		||||
    assert input_pin.state == 0
 | 
			
		||||
 | 
			
		||||
def test_pull_bad(pins):
 | 
			
		||||
    test_pin, input_pin = pins
 | 
			
		||||
    test_pin.function = 'input'
 | 
			
		||||
    with pytest.raises(PinInvalidPull):
 | 
			
		||||
        test_pin.pull = 'foo'
 | 
			
		||||
 | 
			
		||||
def test_pull_down_warning(pin_class):
 | 
			
		||||
    pin = pin_class(2)
 | 
			
		||||
    try:
 | 
			
		||||
        with pytest.raises(PinFixedPull):
 | 
			
		||||
            pin.pull = 'down'
 | 
			
		||||
    finally:
 | 
			
		||||
        pin.close()
 | 
			
		||||
 | 
			
		||||
def test_input_with_pull(pins):
 | 
			
		||||
    test_pin, input_pin = pins
 | 
			
		||||
    test_pin.input_with_pull('up')
 | 
			
		||||
    assert input_pin.state == 1
 | 
			
		||||
    test_pin.input_with_pull('down')
 | 
			
		||||
    assert input_pin.state == 0
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user