<commit_before>import rospy
import threading
import os
import signal
import subprocess
import sys

DEFAULT_RESPAWN_DELAY = 1.0

class ProcRunner(threading.Thread):
    """
    A Thread that launches and manages a subprocess.

    """
    def __init__(self,
                 cmd,
                 respawn_delay=DEFAULT_RESPAWN_DELAY,
                 shell=False,
                 spawn_hooks=[],
                 respawn_limit=-1,
                 respawn=True):
        """
        respawn handles whether or not the application shall be automatically
                respawned at all, default is True.

        """
        super(self.__class__, self).__init__()
        self.cmd = cmd
        self.shell = shell
        self.respawn_delay = respawn_delay
        self.respawn = respawn
        self.spawn_count = 0
        if not shell:
            self.cmd_str = ' '.join(cmd)
        self.done = False
        self.proc = None
        self._spawn_hooks = []
        self.respawn_limit = respawn_limit
        # add all spawn hooks passed
        for spawn_hook in spawn_hooks:
            self.add_spawn_hook(spawn_hook)

    def _kill_proc(self):
        """
        Attempts to kill the process group with SIGTERM.
        """
        if self.proc is None:
            return

        pid = self.proc.pid

        rospy.loginfo('sending SIGTERM to process group {}'.format(pid))

        try:
            os.killpg(pid, signal.SIGTERM)
        except OSError:
            rospy.logwarn('process group {} did not exist'.format(pid))
        finally:
            self.proc.wait()
            self.proc = None

    def _reached_respawn_limit(self):
        """
        Introduces possibility to give up on respawning of a process
        """
        if (self.respawn_limit == -1):
            rospy.logdebug("Respawn limit set to infinity")
            return False
        elif (self.respawn_limit > 0) and (self.spawn_count >= self.respawn_limit):
            rospy.logwarn("Respawn limit of %s reached - not launching application %s" % (self.respawn_limit, self.cmd_str))
            return True

    def _start_proc(self):
        """
        Starts or restarts the process and checks whether respawn limit was reached
        """
        if self._reached_respawn_limit():
            return False
        if self.spawn_count > 0:
            rospy.logwarn('Respawn #{} for process: {}'.format(
                self.spawn_count, self.cmd_str))

        self.proc = subprocess.Popen(self.cmd,
                                     preexec_fn=os.setsid,
                                     shell=self.shell,
                                     close_fds=True)
        self._run_spawn_hooks()
        self.spawn_count += 1
        rospy.loginfo("Launched '{}' with pid {}".format(self.cmd, self.proc.pid))

    def _run_spawn_hooks(self):
        """
        Calls all _spawn_hooks if any exist
        """
        def run_spawn_hook(hook):
            try:
                hook()
            except:
                rospy.logerr("Caught an Exception while running a spawn hook!")
                # Log the traceback.
                rospy.logerr(sys.exc_info()[2])

        map(run_spawn_hook, self._spawn_hooks)

    def run(self):
        """
        Begin managing the process.
        """
        while True:
            if self.done:
                return
            self._start_proc()
            try:
                self.proc.wait()
            except AttributeError:
                # in this case, self.proc has been dereferenced by _kill_proc()
                pass
            if not self.respawn:
                return
            if not self.done:
                rospy.sleep(self.respawn_delay)

    def shutdown(self, *args, **kwargs):
        """
        Finish this Thread by killing the process and marking completion.
        """
        self.done = True
        self._kill_proc()

    def add_spawn_hook(self, spawn_hook):
        """
        Add a single spawn hook to any existing spawn hooks

        spawn_hook must be callable
        """
        if not callable(spawn_hook):
            raise TypeError("Passed a non-callable object as a spawn hook")
        self._spawn_hooks.append(spawn_hook)

    def get_pid(self):
        """
        Return process id, or 0 to signify error
        """
        if self.proc:
            return self.proc.pid
        return None

    def handle_soft_relaunch(self, *args, **kwargs):
        self._kill_proc()

# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
<commit_msg>Revert "Remove unnecessary locking from ProcRunner"<commit_after>import rospy
import threading
import os
import signal
import subprocess
import sys

DEFAULT_RESPAWN_DELAY = 1.0

class ProcRunner(threading.Thread):
    """
    A Thread that launches and manages a subprocess.

    """
    def __init__(self,
                 cmd,
                 respawn_delay=DEFAULT_RESPAWN_DELAY,
                 shell=False,
                 spawn_hooks=[],
                 respawn_limit=-1,
                 respawn=True):
        """
        respawn handles whether or not the application shall be automatically
                respawned at all, default is True.

        """
        super(self.__class__, self).__init__()
        self.cmd = cmd
        self.shell = shell
        self.respawn_delay = respawn_delay
        self.respawn = respawn
        self.lock = threading.Lock()
        self.spawn_count = 0
        if not shell:
            self.cmd_str = ' '.join(cmd)
        self.done = False
        self.proc = None
        self._spawn_hooks = []
        self.respawn_limit = respawn_limit
        # add all spawn hooks passed
        for spawn_hook in spawn_hooks:
            self.add_spawn_hook(spawn_hook)

    def _kill_proc(self):
        """
        Attempts to kill the process group with SIGTERM.
        """
        if self.proc is None:
            return

        pid = self.proc.pid

        rospy.loginfo('sending SIGTERM to process group {}'.format(pid))

        try:
            os.killpg(pid, signal.SIGTERM)
        except OSError:
            rospy.logwarn('process group {} did not exist'.format(pid))
        finally:
            self.proc.wait()
            self.proc = None

    def _reached_respawn_limit(self):
        """
        Introduces possibility to give up on respawning of a process
        """
        if (self.respawn_limit == -1):
            rospy.logdebug("Respawn limit set to infinity")
            return False
        elif (self.respawn_limit > 0) and (self.spawn_count >= self.respawn_limit):
            rospy.logwarn("Respawn limit of %s reached - not launching application %s" % (self.respawn_limit, self.cmd_str))
            return True

    def _start_proc(self):
        """
        Starts or restarts the process and checks whether respawn limit was reached
        """
        if self._reached_respawn_limit():
            return False
        if self.spawn_count > 0:
            rospy.logwarn('Respawn #{} for process: {}'.format(
                self.spawn_count, self.cmd_str))

        self.proc = subprocess.Popen(self.cmd,
                                     preexec_fn=os.setsid,
                                     shell=self.shell,
                                     close_fds=True)
        self._run_spawn_hooks()
        self.spawn_count += 1
        rospy.loginfo("Launched '{}' with pid {}".format(self.cmd, self.proc.pid))

    def _run_spawn_hooks(self):
        """
        Calls all _spawn_hooks if any exist
        """
        def run_spawn_hook(hook):
            try:
                hook()
            except:
                rospy.logerr("Caught an Exception while running a spawn hook!")
                # Log the traceback.
                rospy.logerr(sys.exc_info()[2])

        map(run_spawn_hook, self._spawn_hooks)

    def run(self):
        """
        Begin managing the process.
        """
        while True:
            with self.lock:
                if self.done:
                    return
                self._start_proc()
            try:
                self.proc.wait()
            except AttributeError:
                # in this case, self.proc has been dereferenced by _kill_proc()
                pass
            if not self.respawn:
                return
            if not self.done:
                rospy.sleep(self.respawn_delay)

    def shutdown(self, *args, **kwargs):
        """
        Finish this Thread by killing the process and marking completion.
        """
        with self.lock:
            self.done = True
            self._kill_proc()

    def add_spawn_hook(self, spawn_hook):
        """
        Add a single spawn hook to any existing spawn hooks

        spawn_hook must be callable
        """
        if not callable(spawn_hook):
            raise TypeError("Passed a non-callable object as a spawn hook")
        self._spawn_hooks.append(spawn_hook)

    def get_pid(self):
        """
        Return process id, or 0 to signify error
        """
        if self.proc:
            return self.proc.pid
        return None

    def handle_soft_relaunch(self, *args, **kwargs):
        self._kill_proc()

# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4
<|endoftext|>


<commit_before>"""

This file contains a set of functions for matching values which may be written in different formats
e.g.
0.1uF = 100n (different suffix specified, one has missing unit)
0R1 = 0.1Ohm (Unit replaces decimal, different units)

"""

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import re

PREFIX_MICRO = [u"μ", "u", "micro"]
PREFIX_MILLI = ["milli", "m"]
PREFIX_NANO = ["nano", "n"]
PREFIX_PICO = ["pico", "p"]
PREFIX_KILO = ["kilo", "k"]
PREFIX_MEGA = ["mega", "meg"]
PREFIX_GIGA = ["giga", "g"]

# All prefixes
PREFIX_ALL = PREFIX_PICO + PREFIX_NANO + PREFIX_MICRO + PREFIX_MILLI + PREFIX_KILO + PREFIX_MEGA + PREFIX_GIGA

# Common methods of expressing component units
UNIT_R = ["r", "ohms", "ohm", u"Ω"]
UNIT_C = ["farad", "f"]
UNIT_L = ["henry", "h"]

UNIT_ALL = UNIT_R + UNIT_C + UNIT_L

def getUnit(unit):
    """
    Return a simplified version of a units string, for comparison purposes
    """

    if not unit:
        return None

    unit = unit.lower()

    if unit in UNIT_R:
        return "R"
    if unit in UNIT_C:
        return "F"
    if unit in UNIT_L:
        return "H"

    return None

def getPrefix(prefix):
    """
    Return the (numerical) value of a given prefix
    """

    if not prefix:
        return 1

    prefix = prefix.lower()

    if prefix in PREFIX_PICO:
        return 1.0e-12
    if prefix in PREFIX_NANO:
        return 1.0e-9
    if prefix in PREFIX_MICRO:
        return 1.0e-6
    if prefix in PREFIX_MILLI:
        return 1.0e-3
    if prefix in PREFIX_KILO:
        return 1.0e3
    if prefix in PREFIX_MEGA:
        return 1.0e6
    if prefix in PREFIX_GIGA:
        return 1.0e9

    return 1

def groupString(group):  # Return a reg-ex string for a list of values
    return "|".join(group)

def matchString():
    return "^([0-9\.]+)(" + groupString(PREFIX_ALL) + ")*(" + groupString(UNIT_ALL) + ")*(\d*)$"

def compMatch(component):
    """
    Return a normalized value and units for a given component value string
    e.g. compMatch("10R2") returns (10, R)
    e.g. compMatch("3.3mOhm") returns (0.0033, R)
    """

    # Remove any commas
    component = component.strip().replace(",", "").lower()

    match = matchString()

    result = re.search(match, component)

    if not result:
        return None

    if not len(result.groups()) == 4:
        return None

    value, prefix, units, post = result.groups()

    # Special case where units is in the middle of the string
    # e.g. "0R05" for 0.05Ohm
    # In this case, we will NOT have a decimal
    # We will also have a trailing number

    if post and "." not in value:
        try:
            value = float(int(value))
            postValue = float(int(post)) / (10 ** len(post))
            value = value * 1.0 + postValue
        except:
            return None

    try:
        val = float(value)
    except:
        return None

    val = "{0:.15f}".format(val * 1.0 * getPrefix(prefix))

    return (val, getUnit(units))

def componentValue(valString):

    result = compMatch(valString)

    if not result:
        return valString  # Return the same string back

    if not len(result) == 2:  # Result length is incorrect
        return valString

    val = result[0]

    return val

def compareValues(c1, c2):
    """ Compare two values """

    r1 = compMatch(c1)
    r2 = compMatch(c2)

    if not r1 or not r2:
        return False

    (v1, u1) = r1
    (v2, u2) = r2

    if v1 == v2:
        # Values match
        if u1 == u2:
            return True  # Units match
        if not u1:
            return True  # No units for component 1
        if not u2:
            return True  # No units for component 2

    return False
<commit_msg>Coding goes at the top of the file<commit_after># -*- coding: utf-8 -*-

"""

This file contains a set of functions for matching values which may be written in different formats
e.g.
0.1uF = 100n (different suffix specified, one has missing unit)
0R1 = 0.1Ohm (Unit replaces decimal, different units)

"""

from __future__ import unicode_literals
import re

PREFIX_MICRO = [u"μ", "u", "micro"]
PREFIX_MILLI = ["milli", "m"]
PREFIX_NANO = ["nano", "n"]
PREFIX_PICO = ["pico", "p"]
PREFIX_KILO = ["kilo", "k"]
PREFIX_MEGA = ["mega", "meg"]
PREFIX_GIGA = ["giga", "g"]

# All prefixes
PREFIX_ALL = PREFIX_PICO + PREFIX_NANO + PREFIX_MICRO + PREFIX_MILLI + PREFIX_KILO + PREFIX_MEGA + PREFIX_GIGA

# Common methods of expressing component units
UNIT_R = ["r", "ohms", "ohm", u"Ω"]
UNIT_C = ["farad", "f"]
UNIT_L = ["henry", "h"]

UNIT_ALL = UNIT_R + UNIT_C + UNIT_L

def getUnit(unit):
    """
    Return a simplified version of a units string, for comparison purposes
    """

    if not unit:
        return None

    unit = unit.lower()

    if unit in UNIT_R:
        return "R"
    if unit in UNIT_C:
        return "F"
    if unit in UNIT_L:
        return "H"

    return None

def getPrefix(prefix):
    """
    Return the (numerical) value of a given prefix
    """

    if not prefix:
        return 1

    prefix = prefix.lower()

    if prefix in PREFIX_PICO:
        return 1.0e-12
    if prefix in PREFIX_NANO:
        return 1.0e-9
    if prefix in PREFIX_MICRO:
        return 1.0e-6
    if prefix in PREFIX_MILLI:
        return 1.0e-3
    if prefix in PREFIX_KILO:
        return 1.0e3
    if prefix in PREFIX_MEGA:
        return 1.0e6
    if prefix in PREFIX_GIGA:
        return 1.0e9

    return 1

def groupString(group):  # Return a reg-ex string for a list of values
    return "|".join(group)

def matchString():
    return "^([0-9\.]+)(" + groupString(PREFIX_ALL) + ")*(" + groupString(UNIT_ALL) + ")*(\d*)$"

def compMatch(component):
    """
    Return a normalized value and units for a given component value string
    e.g. compMatch("10R2") returns (10, R)
    e.g. compMatch("3.3mOhm") returns (0.0033, R)
    """

    # Remove any commas
    component = component.strip().replace(",", "").lower()

    match = matchString()

    result = re.search(match, component)

    if not result:
        return None

    if not len(result.groups()) == 4:
        return None

    value, prefix, units, post = result.groups()

    # Special case where units is in the middle of the string
    # e.g. "0R05" for 0.05Ohm
    # In this case, we will NOT have a decimal
    # We will also have a trailing number

    if post and "." not in value:
        try:
            value = float(int(value))
            postValue = float(int(post)) / (10 ** len(post))
            value = value * 1.0 + postValue
        except:
            return None

    try:
        val = float(value)
    except:
        return None

    val = "{0:.15f}".format(val * 1.0 * getPrefix(prefix))

    return (val, getUnit(units))

def componentValue(valString):

    result = compMatch(valString)

    if not result:
        return valString  # Return the same string back

    if not len(result) == 2:  # Result length is incorrect
        return valString

    val = result[0]

    return val

def compareValues(c1, c2):
    """ Compare two values """

    r1 = compMatch(c1)
    r2 = compMatch(c2)

    if not r1 or not r2:
        return False

    (v1, u1) = r1
    (v2, u2) = r2

    if v1 == v2:
        # Values match
        if u1 == u2:
            return True  # Units match
        if not u1:
            return True  # No units for component 1
        if not u2:
            return True  # No units for component 2

    return False
<|endoftext|>


<commit_before>from raspibot.Serial import AttinyProtocol, InvalidResponseException

import pytest

ALIVE = b'\x01'

ENCODERS_RIGHT = b'\x02'
ENCODERS_LEFT = b'\x03'
ENCODERS_BOTH = b'\x04'

ENCODERS_RESET_RIGHT = b'\x05'
ENCODERS_RESET_LEFT = b'\x06'
ENCODERS_RESET_BOTH = b'\x07'

ACK = b'\x10'
NAK = b'\x14'

SET_RIGHT_MOTOR = b'\x25'
SET_LEFT_MOTOR = b'\x29'
SET_BOTH_MOTORS = b'\x2D'

MOTOR_MIN = -127
MOTOR_MAX = 127
MOTOR_ZERO = 0

# as signed byte values:
BYTES_MOTOR_MIN = MOTOR_MIN.to_bytes(1, 'big', signed=True)
BYTES_MOTOR_MAX = MOTOR_MAX.to_bytes(1, 'big', signed=True)
BYTES_MOTOR_ZERO = MOTOR_ZERO.to_bytes(1, 'big', signed=True)

INVALID_RESPONSE = b'\x23'

class MockSerial:

    def __init__(self, bytes):
        self._bytes = bytes
        self._position = 0
        self.received = b''

    def write(self, bytes):
        self.received += bytes

    def read(self, count):
        try:
            return self._bytes[self._position:self._position+count]
            self._position += count
        except IndexError:
            return b''

def test_get_encoders():
    left, right = 0, 65535
    encoder_bytes = left.to_bytes(2, 'big') + right.to_bytes(2, 'big')
    serial = MockSerial(encoder_bytes)

    attiny = AttinyProtocol(serial)
    result = attiny.get_encoders()

    assert serial.received == ENCODERS_BOTH

    # use it as a tuple
    assert result == (left, right)

    # access tuple fields by index
    assert result[0] == left
    assert result[1] == right

    # access tuple fields by name
    assert result.left == left
    assert result.right == right

def test_get_left_encoder():
    value = 43690
    encoder_bytes = value.to_bytes(2, 'big')
    serial = MockSerial(encoder_bytes)

    attiny = AttinyProtocol(serial)
    result = attiny.get_left_encoder()

    assert serial.received == ENCODERS_LEFT
    assert result == value

def test_get_right_encoder():
    value = 21845
    encoder_bytes = value.to_bytes(2, 'big')
    serial = MockSerial(encoder_bytes)

    attiny = AttinyProtocol(serial)
    result = attiny.get_right_encoder()

    assert serial.received == ENCODERS_RIGHT
    assert result == value

def test_alive_ack():
    # send out an ACK byte
    serial = MockSerial(ACK)

    attiny = AttinyProtocol(serial)
    result = attiny.alive()

    assert serial.received == ALIVE
    assert result == True

def test_alive_nak():
    # send out an NAK byte
    serial = MockSerial(NAK)

    attiny = AttinyProtocol(serial)
    result = attiny.alive()

    assert serial.received == ALIVE
    assert result == False

def test_alive_undefined():
    # send out something that is neither an ACK or a NAK byte
    serial = MockSerial(INVALID_RESPONSE)

    attiny = AttinyProtocol(serial)
    with pytest.raises(InvalidResponseException):
        attiny.alive()

    assert serial.received == ALIVE

def test_set_right_motor_min():
    serial = MockSerial(ACK)

    right = MOTOR_MIN
    right_bytes = BYTES_MOTOR_MIN

    attiny = AttinyProtocol(serial)
    result = attiny.set_right_motor(right)

    assert len(serial.received) == 2
    assert serial.received == SET_RIGHT_MOTOR + right_bytes

    assert result == True

def test_set_right_motor_under_min():
    serial = MockSerial(ACK)

    right = MOTOR_MIN - 1
    right_bytes = BYTES_MOTOR_MIN

    attiny = AttinyProtocol(serial)
    result = attiny.set_right_motor(right)

    assert len(serial.received) == 2
    assert serial.received == SET_RIGHT_MOTOR + right_bytes

    assert result == True

def test_set_right_motor_max():
    serial = MockSerial(ACK)

    right = MOTOR_MAX
    right_bytes = BYTES_MOTOR_MAX

    attiny = AttinyProtocol(serial)
    result = attiny.set_right_motor(right)

    assert len(serial.received) == 2
    assert serial.received == SET_RIGHT_MOTOR + right_bytes

    assert result == True

def test_set_right_motor_over_max():
    serial = MockSerial(ACK)

    right = MOTOR_MAX + 1
    right_bytes = BYTES_MOTOR_MAX

    attiny = AttinyProtocol(serial)
    result = attiny.set_right_motor(right)

    assert len(serial.received) == 2
    assert serial.received == SET_RIGHT_MOTOR + right_bytes

    assert result == True

def test_set_right_motor_zero():
    serial = MockSerial(ACK)

    right = MOTOR_ZERO
    right_bytes = BYTES_MOTOR_ZERO

    attiny = AttinyProtocol(serial)
    result = attiny.set_right_motor(right)

    assert len(serial.received) == 2
    assert serial.received == SET_RIGHT_MOTOR + right_bytes

    assert result == True

def test_set_right_motor_nak():
    serial = MockSerial(NAK)

    attiny = AttinyProtocol(serial)
    result = attiny.set_right_motor(0)

    assert result == False

def test_set_right_motor_timeout():
    serial = MockSerial(b'')

    attiny = AttinyProtocol(serial)
    result = attiny.set_right_motor(0)

    assert result == False

def test_set_right_motor_invalid():
    serial = MockSerial(INVALID_RESPONSE)

    attiny = AttinyProtocol(serial)
    with pytest.raises(InvalidResponseException):
        attiny.set_right_motor(0)

def test_set_left_motor_min():
    serial = MockSerial(ACK)

    left = MOTOR_MIN
    left_bytes = BYTES_MOTOR_MIN

    attiny = AttinyProtocol(serial)
    result = attiny.set_left_motor(left);

    assert len(serial.received) == 2
    assert serial.received == SET_LEFT_MOTOR + left_bytes

    assert result == True

def test_set_left_motor_under_min():
    serial = MockSerial(ACK)

    left = MOTOR_MIN - 1
    left_bytes = BYTES_MOTOR_MIN

    attiny = AttinyProtocol(serial)
    result = attiny.set_left_motor(left);

    assert len(serial.received) == 2
    assert serial.received == SET_LEFT_MOTOR + left_bytes

    assert result == True

def test_set_left_motor_max():
    serial = MockSerial(ACK)

    left = MOTOR_MAX
    left_bytes = BYTES_MOTOR_MAX

    attiny = AttinyProtocol(serial)
    result = attiny.set_left_motor(left);

    assert len(serial.received) == 2
    assert serial.received == SET_LEFT_MOTOR + left_bytes

    assert result == True

def test_set_left_motor_over_max():
    serial = MockSerial(ACK)

    left = MOTOR_MAX + 1
    left_bytes = BYTES_MOTOR_MAX

    attiny = AttinyProtocol(serial)
    result = attiny.set_left_motor(left);

    assert len(serial.received) == 2
    assert serial.received == SET_LEFT_MOTOR + left_bytes

    assert result == True

def test_set_left_motor_zero():
    serial = MockSerial(ACK)

    left = MOTOR_ZERO
    left_bytes = BYTES_MOTOR_ZERO

    attiny = AttinyProtocol(serial)
    result = attiny.set_left_motor(left);

    assert len(serial.received) == 2
    assert serial.received == SET_LEFT_MOTOR + left_bytes

    assert result == True

def test_set_left_motor_nak():
    serial = MockSerial(NAK)

    attiny = AttinyProtocol(serial)
    result = attiny.set_left_motor(0)

    assert result == False

def test_set_left_motor_timeout():
    serial = MockSerial(b'')

    attiny = AttinyProtocol(serial)
    result = attiny.set_left_motor(0)

    assert result == False

def test_set_left_motor_invalid():
    serial = MockSerial(INVALID_RESPONSE)

    attiny = AttinyProtocol(serial)
    with pytest.raises(InvalidResponseException):
        attiny.set_left_motor(0)

def test_set_both_motors_minmax():
    serial = MockSerial(ACK)

    left = MOTOR_MIN
    left_bytes = BYTES_MOTOR_MIN

    right = MOTOR_MAX
    right_bytes = BYTES_MOTOR_MAX

    attiny = AttinyProtocol(serial)
    attiny.set_motors(left, right)

    assert len(serial.received) == 3
    assert serial.received == SET_BOTH_MOTORS + left_bytes + right_bytes

def test_set_both_motors_exceed_minmax():
    serial = MockSerial(ACK)

    left = MOTOR_MIN - 1
    left_bytes = BYTES_MOTOR_MIN

    right = MOTOR_MAX + 1
    right_bytes = BYTES_MOTOR_MAX

    attiny = AttinyProtocol(serial)
    attiny.set_motors(left, right)

    assert len(serial.received) == 3
    assert serial.received == SET_BOTH_MOTORS + left_bytes + right_bytes

def test_set_both_motors_maxmin():
    serial = MockSerial(ACK)

    left = MOTOR_MAX
    left_bytes = BYTES_MOTOR_MAX

    right = MOTOR_MIN
    right_bytes = BYTES_MOTOR_MIN

    attiny = AttinyProtocol(serial)
    attiny.set_motors(left, right)

    assert len(serial.received) == 3
    assert serial.received == SET_BOTH_MOTORS + left_bytes + right_bytes

def test_set_both_motors_exceed_maxmin():
    serial = MockSerial(ACK)

    left = MOTOR_MAX + 1
    left_bytes = BYTES_MOTOR_MAX

    right = MOTOR_MIN - 1
    right_bytes = BYTES_MOTOR_MIN

    attiny = AttinyProtocol(serial)
    attiny.set_motors(left, right)

    assert len(serial.received) == 3
    assert serial.received == SET_BOTH_MOTORS + left_bytes + right_bytes

def test_set_both_motors_zero():
    serial = MockSerial(ACK)

    left = MOTOR_ZERO
    left_bytes = BYTES_MOTOR_ZERO

    right = MOTOR_ZERO
    right_bytes = BYTES_MOTOR_ZERO

    attiny = AttinyProtocol(serial)
    result = attiny.set_motors(left, right)

    assert len(serial.received) == 3
    assert serial.received == SET_BOTH_MOTORS + left_bytes + right_bytes

    assert result == True

def test_set_both_motors_nak():
    serial = MockSerial(NAK)

    attiny = AttinyProtocol(serial)
    result = attiny.set_motors(0, 0)

    assert result == False

def test_set_both_motors_timeout():
    serial = MockSerial(b'')

    attiny = AttinyProtocol(serial)
    result = attiny.set_motors(0, 0)

    assert result == False

def test_set_both_motors_invalid():
    serial = MockSerial(INVALID_RESPONSE)

    attiny = AttinyProtocol(serial)
    with pytest.raises(InvalidResponseException):
        attiny.set_motors(0, 0)

# flake8: noqa
<commit_msg>add tests for serial: left encoder reset<commit_after>from raspibot.Serial import AttinyProtocol, InvalidResponseException

import pytest

ALIVE = b'\x01'

ENCODERS_RIGHT = b'\x02'
ENCODERS_LEFT = b'\x03'
ENCODERS_BOTH = b'\x04'

ENCODERS_RESET_RIGHT = b'\x05'
ENCODERS_RESET_LEFT = b'\x06'
ENCODERS_RESET_BOTH = b'\x07'

ACK = b'\x10'
NAK = b'\x14'

SET_RIGHT_MOTOR = b'\x25'
SET_LEFT_MOTOR = b'\x29'
SET_BOTH_MOTORS = b'\x2D'

MOTOR_MIN = -127
MOTOR_MAX = 127
MOTOR_ZERO = 0

# as signed byte values:
BYTES_MOTOR_MIN = MOTOR_MIN.to_bytes(1, 'big', signed=True)
BYTES_MOTOR_MAX = MOTOR_MAX.to_bytes(1, 'big', signed=True)
BYTES_MOTOR_ZERO = MOTOR_ZERO.to_bytes(1, 'big', signed=True)

INVALID_RESPONSE = b'\x23'

class MockSerial:

    def __init__(self, bytes):
        self._bytes = bytes
        self._position = 0
        self.received = b''

    def write(self, bytes):
        self.received += bytes

    def read(self, count):
        try:
            return self._bytes[self._position:self._position+count]
            self._position += count
        except IndexError:
            return b''

def test_get_encoders():
    left, right = 0, 65535
    encoder_bytes = left.to_bytes(2, 'big') + right.to_bytes(2, 'big')
    serial = MockSerial(encoder_bytes)

    attiny = AttinyProtocol(serial)
    result = attiny.get_encoders()

    assert serial.received == ENCODERS_BOTH

    # use it as a tuple
    assert result == (left, right)

    # access tuple fields by index
    assert result[0] == left
    assert result[1] == right

    # access tuple fields by name
    assert result.left == left
    assert result.right == right

def test_get_left_encoder():
    value = 43690
    encoder_bytes = value.to_bytes(2, 'big')
    serial = MockSerial(encoder_bytes)

    attiny = AttinyProtocol(serial)
    result = attiny.get_left_encoder()

    assert serial.received == ENCODERS_LEFT
    assert result == value

def test_get_right_encoder():
    value = 21845
    encoder_bytes = value.to_bytes(2, 'big')
    serial = MockSerial(encoder_bytes)

    attiny = AttinyProtocol(serial)
    result = attiny.get_right_encoder()

    assert serial.received == ENCODERS_RIGHT
    assert result == value

def test_reset_left_encoder():
    serial = MockSerial(ACK)
    attiny = AttinyProtocol(serial)

    result = attiny.reset_left_encoder()

    assert serial.received == ENCODERS_RESET_LEFT
    assert result == True

def test_reset_left_encoder_nak():
    serial = MockSerial(NAK)
    attiny = AttinyProtocol(serial)

    result = attiny.reset_left_encoder()

    assert serial.received == ENCODERS_RESET_LEFT
    assert result == False

def test_reset_left_encoder_timeout():
    serial = MockSerial(b'')
    attiny = AttinyProtocol(serial)

    result = attiny.reset_left_encoder()

    assert serial.received == ENCODERS_RESET_LEFT
    assert result == False

def test_reset_left_encoder_invalid():
    serial = MockSerial(INVALID_RESPONSE)
    attiny = AttinyProtocol(serial)

    with pytest.raises(InvalidResponseException):
        attiny.reset_left_encoder()

def test_alive_ack():
    # send out an ACK byte
    serial = MockSerial(ACK)

    attiny = AttinyProtocol(serial)
    result = attiny.alive()

    assert serial.received == ALIVE
    assert result == True

def test_alive_nak():
    # send out an NAK byte
    serial = MockSerial(NAK)

    attiny = AttinyProtocol(serial)
    result = attiny.alive()

    assert serial.received == ALIVE
    assert result == False

def test_alive_undefined():
    # send out something that is neither an ACK or a NAK byte
    serial = MockSerial(INVALID_RESPONSE)

    attiny = AttinyProtocol(serial)
    with pytest.raises(InvalidResponseException):
        attiny.alive()

    assert serial.received == ALIVE

def test_set_right_motor_min():
    serial = MockSerial(ACK)

    right = MOTOR_MIN
    right_bytes = BYTES_MOTOR_MIN

    attiny = AttinyProtocol(serial)
    result = attiny.set_right_motor(right)

    assert len(serial.received) == 2
    assert serial.received == SET_RIGHT_MOTOR + right_bytes

    assert result == True

def test_set_right_motor_under_min():
    serial = MockSerial(ACK)

    right = MOTOR_MIN - 1
    right_bytes = BYTES_MOTOR_MIN

    attiny = AttinyProtocol(serial)
    result = attiny.set_right_motor(right)

    assert len(serial.received) == 2
    assert serial.received == SET_RIGHT_MOTOR + right_bytes

    assert result == True

def test_set_right_motor_max():
    serial = MockSerial(ACK)

    right = MOTOR_MAX
    right_bytes = BYTES_MOTOR_MAX

    attiny = AttinyProtocol(serial)
    result = attiny.set_right_motor(right)

    assert len(serial.received) == 2
    assert serial.received == SET_RIGHT_MOTOR + right_bytes

    assert result == True

def test_set_right_motor_over_max():
    serial = MockSerial(ACK)

    right = MOTOR_MAX + 1
    right_bytes = BYTES_MOTOR_MAX

    attiny = AttinyProtocol(serial)
    result = attiny.set_right_motor(right)

    assert len(serial.received) == 2
    assert serial.received == SET_RIGHT_MOTOR + right_bytes

    assert result == True

def test_set_right_motor_zero():
    serial = MockSerial(ACK)

    right = MOTOR_ZERO
    right_bytes = BYTES_MOTOR_ZERO

    attiny = AttinyProtocol(serial)
    result = attiny.set_right_motor(right)

    assert len(serial.received) == 2
    assert serial.received == SET_RIGHT_MOTOR + right_bytes

    assert result == True

def test_set_right_motor_nak():
    serial = MockSerial(NAK)

    attiny = AttinyProtocol(serial)
    result = attiny.set_right_motor(0)

    assert result == False

def test_set_right_motor_timeout():
    serial = MockSerial(b'')

    attiny = AttinyProtocol(serial)
    result = attiny.set_right_motor(0)

    assert result == False

def test_set_right_motor_invalid():
    serial = MockSerial(INVALID_RESPONSE)

    attiny = AttinyProtocol(serial)
    with pytest.raises(InvalidResponseException):
        attiny.set_right_motor(0)

def test_set_left_motor_min():
    serial = MockSerial(ACK)

    left = MOTOR_MIN
    left_bytes = BYTES_MOTOR_MIN

    attiny = AttinyProtocol(serial)
    result = attiny.set_left_motor(left);

    assert len(serial.received) == 2
    assert serial.received == SET_LEFT_MOTOR + left_bytes

    assert result == True

def test_set_left_motor_under_min():
    serial = MockSerial(ACK)

    left = MOTOR_MIN - 1
    left_bytes = BYTES_MOTOR_MIN

    attiny = AttinyProtocol(serial)
    result = attiny.set_left_motor(left);

    assert len(serial.received) == 2
    assert serial.received == SET_LEFT_MOTOR + left_bytes

    assert result == True

def test_set_left_motor_max():
    serial = MockSerial(ACK)

    left = MOTOR_MAX
    left_bytes = BYTES_MOTOR_MAX

    attiny = AttinyProtocol(serial)
    result = attiny.set_left_motor(left);

    assert len(serial.received) == 2
    assert serial.received == SET_LEFT_MOTOR + left_bytes

    assert result == True

def test_set_left_motor_over_max():
    serial = MockSerial(ACK)

    left = MOTOR_MAX + 1
    left_bytes = BYTES_MOTOR_MAX

    attiny = AttinyProtocol(serial)
    result = attiny.set_left_motor(left);

    assert len(serial.received) == 2
    assert serial.received == SET_LEFT_MOTOR + left_bytes

    assert result == True

def test_set_left_motor_zero():
    serial = MockSerial(ACK)

    left = MOTOR_ZERO
    left_bytes = BYTES_MOTOR_ZERO

    attiny = AttinyProtocol(serial)
    result = attiny.set_left_motor(left);

    assert len(serial.received) == 2
    assert serial.received == SET_LEFT_MOTOR + left_bytes

    assert result == True

def test_set_left_motor_nak():
    serial = MockSerial(NAK)

    attiny = AttinyProtocol(serial)
    result = attiny.set_left_motor(0)

    assert result == False

def test_set_left_motor_timeout():
    serial = MockSerial(b'')

    attiny = AttinyProtocol(serial)
    result = attiny.set_left_motor(0)

    assert result == False

def test_set_left_motor_invalid():
    serial = MockSerial(INVALID_RESPONSE)

    attiny = AttinyProtocol(serial)
    with pytest.raises(InvalidResponseException):
        attiny.set_left_motor(0)

def test_set_both_motors_minmax():
    serial = MockSerial(ACK)

    left = MOTOR_MIN
    left_bytes = BYTES_MOTOR_MIN

    right = MOTOR_MAX
    right_bytes = BYTES_MOTOR_MAX

    attiny = AttinyProtocol(serial)
    attiny.set_motors(left, right)

    assert len(serial.received) == 3
    assert serial.received == SET_BOTH_MOTORS + left_bytes + right_bytes

def test_set_both_motors_exceed_minmax():
    serial = MockSerial(ACK)

    left = MOTOR_MIN - 1
    left_bytes = BYTES_MOTOR_MIN

    right = MOTOR_MAX + 1
    right_bytes = BYTES_MOTOR_MAX

    attiny = AttinyProtocol(serial)
    attiny.set_motors(left, right)

    assert len(serial.received) == 3
    assert serial.received == SET_BOTH_MOTORS + left_bytes + right_bytes

def test_set_both_motors_maxmin():
    serial = MockSerial(ACK)

    left = MOTOR_MAX
    left_bytes = BYTES_MOTOR_MAX

    right = MOTOR_MIN
    right_bytes = BYTES_MOTOR_MIN

    attiny = AttinyProtocol(serial)
    attiny.set_motors(left, right)

    assert len(serial.received) == 3
    assert serial.received == SET_BOTH_MOTORS + left_bytes + right_bytes

def test_set_both_motors_exceed_maxmin():
    serial = MockSerial(ACK)

    left = MOTOR_MAX + 1
    left_bytes = BYTES_MOTOR_MAX

    right = MOTOR_MIN - 1
    right_bytes = BYTES_MOTOR_MIN

    attiny = AttinyProtocol(serial)
    attiny.set_motors(left, right)

    assert len(serial.received) == 3
    assert serial.received == SET_BOTH_MOTORS + left_bytes + right_bytes

def test_set_both_motors_zero():
    serial = MockSerial(ACK)

    left = MOTOR_ZERO
    left_bytes = BYTES_MOTOR_ZERO

    right = MOTOR_ZERO
    right_bytes = BYTES_MOTOR_ZERO

    attiny = AttinyProtocol(serial)
    result = attiny.set_motors(left, right)

    assert len(serial.received) == 3
    assert serial.received == SET_BOTH_MOTORS + left_bytes + right_bytes

    assert result == True

def test_set_both_motors_nak():
    serial = MockSerial(NAK)

    attiny = AttinyProtocol(serial)
    result = attiny.set_motors(0, 0)

    assert result == False

def test_set_both_motors_timeout():
    serial = MockSerial(b'')

    attiny = AttinyProtocol(serial)
    result = attiny.set_motors(0, 0)

    assert result == False

def test_set_both_motors_invalid():
    serial = MockSerial(INVALID_RESPONSE)

    attiny = AttinyProtocol(serial)
    with pytest.raises(InvalidResponseException):
        attiny.set_motors(0, 0)

# flake8: noqa
<|endoftext|>


<commit_before>#
# Copyright (C) 2012 Satoru SATOH <ssato @ redhat.com>
# License: MIT
#
# pylint: disable=missing-docstring
from __future__ import absolute_import

import os.path
import unittest

import anyconfig.backend.xml as TT
import anyconfig.tests.common
from anyconfig.tests.common import dicts_equal

CNF_0_S = """<?xml version="1.0" encoding="UTF-8"?>
<config name='foo'>
  0
  bbb
  <sect0>
    <c>x, y, z</c>
  </sect0>
</config>
"""

CNF_0 = {'config': {'@attrs': {'name': 'foo'},
                    '@children': [{'a': {'@text': '0'}},
                                  {'b': {'@attrs': {'id': 'b0'},
                                         '@text': 'bbb'}},
                                  {'sect0': {
                                      '@children': [{'c': {
                                          '@text': 'x, y, z'
                                      }}]}}]}}

class Test(unittest.TestCase):

    cnf = CNF_0
    cnf_s = CNF_0_S

    def setUp(self):
        self.workdir = anyconfig.tests.common.setup_workdir()
        self.cpath = os.path.join(self.workdir, "test0.xml")
        open(self.cpath, 'w').write(self.cnf_s)

    def tearDown(self):
        anyconfig.tests.common.cleanup_workdir(self.workdir)

    def test_00_supports(self):
        self.assertFalse(TT.Parser.supports("/a/b/c/d.ini"))
        self.assertTrue(TT.Parser.supports("/a/b/c/d.xml"))

    def test_10_loads(self):
        cnf = TT.Parser.loads(self.cnf_s)
        self.assertTrue(dicts_equal(cnf, self.cnf), str(cnf))

    def test_20_load(self):
        cnf = TT.Parser.load(self.cpath)
        self.assertTrue(dicts_equal(cnf, self.cnf), str(cnf))

    def test_30_dumps(self):
        cnf = TT.Parser.loads(TT.Parser.dumps(self.cnf))
        self.assertTrue(dicts_equal(cnf, self.cnf), str(cnf))

    def test_40_dump(self):
        TT.Parser.dump(self.cnf, self.cpath)
        cnf = TT.Parser.load(self.cpath)
        self.assertTrue(dicts_equal(cnf, self.cnf), str(cnf))

# vim:sw=4:ts=4:et:
<commit_msg>add some test cases of anyconfig.backend.xml.{etree_to_container,container_to_etree}<commit_after>#
# Copyright (C) 2012 Satoru SATOH <ssato @ redhat.com>
# License: MIT
#
# pylint: disable=missing-docstring
from __future__ import absolute_import

import copy
import os.path
import unittest

import anyconfig.backend.xml as TT
import anyconfig.tests.common
from anyconfig.tests.common import dicts_equal, to_bytes

CNF_0_S = """<?xml version="1.0" encoding="UTF-8"?>
<config name='foo'>
  0
  bbb
  <sect0>
    <c>x, y, z</c>
  </sect0>
</config>
"""

CNF_0 = {'config': {'@attrs': {'name': 'foo'},
                    '@children': [{'a': {'@text': '0'}},
                                  {'b': {'@attrs': {'id': 'b0'},
                                         '@text': 'bbb'}},
                                  {'sect0': {
                                      '@children': [{'c': {
                                          '@text': 'x, y, z'
                                      }}]}}]}}

class Test00(unittest.TestCase):

    def setUp(self):
        self.root = TT.ET.Element("config", attrib=dict(name="foo"))
        celm0 = TT.ET.SubElement(self.root, "a")
        celm0.text = '0'
        celm1 = TT.ET.SubElement(self.root, "b", attrib=dict(id="b0", ))
        celm1.text = "bbb"
        self.tree = TT.ET.ElementTree(self.root)

        self.cnf = copy.deepcopy(CNF_0)
        del self.cnf["config"]["@children"][-1]

        self.cnf_s = to_bytes('<config name="foo">0'
                              'bbb</config>')

    def test_10_etree_to_container__empty(self):
        self.assertEquals(TT.etree_to_container(None, dict), {})

    def test_12_etree_to_container(self):
        cnf = TT.etree_to_container(self.root, TT.Parser.container())
        self.assertTrue(dicts_equal(cnf, self.cnf), str(cnf))

    def test_20_container_to_etree(self):
        tree = TT.container_to_etree(self.cnf, TT.Parser.container())
        buf = TT.BytesIO()
        tree.write(buf)
        cnf_s = buf.getvalue()
        self.assertEquals(cnf_s, self.cnf_s, cnf_s)

class Test10(unittest.TestCase):

    cnf = CNF_0
    cnf_s = CNF_0_S

    def test_10_supports(self):
        self.assertFalse(TT.Parser.supports("/a/b/c/d.ini"))
        self.assertTrue(TT.Parser.supports("/a/b/c/d.xml"))

    def test_20_loads(self):
        cnf = TT.Parser.loads(self.cnf_s)
        self.assertTrue(dicts_equal(cnf, self.cnf), str(cnf))

    def test_30_dumps(self):
        cnf = TT.Parser.loads(TT.Parser.dumps(self.cnf))
        self.assertTrue(dicts_equal(cnf, self.cnf), str(cnf))

class Test20(unittest.TestCase):

    cnf = CNF_0
    cnf_s = CNF_0_S

    def setUp(self):
        self.workdir = anyconfig.tests.common.setup_workdir()
        self.cpath = os.path.join(self.workdir, "test0.xml")
        open(self.cpath, 'w').write(self.cnf_s)

    def tearDown(self):
        anyconfig.tests.common.cleanup_workdir(self.workdir)

    def test_10_load(self):
        cnf = TT.Parser.load(self.cpath)
        self.assertTrue(dicts_equal(cnf, self.cnf), str(cnf))

    def test_20_dump(self):
        TT.Parser.dump(self.cnf, self.cpath)
        cnf = TT.Parser.load(self.cpath)
        self.assertTrue(dicts_equal(cnf, self.cnf), str(cnf))

# vim:sw=4:ts=4:et:
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import absolute_import

import operator

import pytest

import numpy as np

import dask.array as da
import dask.array.utils as dau

import dask_ndmeasure._utils

def test__norm_input_labels_index_err():
    shape = (15, 16)
    chunks = (4, 5)
    ind = None

    a = np.random.random(shape)
    d = da.from_array(a, chunks=chunks)

    lbls = (a < 0.5).astype(np.int64)
    d_lbls = da.from_array(lbls, chunks=d.chunks)

    lbls = lbls[:-1]
    d_lbls = d_lbls[:-1]

    with pytest.raises(ValueError):
        dask_ndmeasure._utils._norm_input_labels_index(d, d_lbls, ind)

def test__norm_input_labels_index():
    shape = (15, 16)
    chunks = (4, 5)
    ind = None

    a = np.random.random(shape)
    d = da.from_array(a, chunks=chunks)

    lbls = (a < 0.5).astype(int)
    d_lbls = da.from_array(lbls, chunks=d.chunks)

    d_n, d_lbls_n, ind_n = dask_ndmeasure._utils._norm_input_labels_index(
        d, d_lbls, ind
    )

    assert isinstance(d_n, da.Array)
    assert isinstance(d_lbls_n, da.Array)
    assert isinstance(ind_n, da.Array)

    dau.assert_eq(d_n, d)
    dau.assert_eq(d_lbls_n, d_lbls)
    dau.assert_eq(ind_n, np.array([1], dtype=int))

@pytest.mark.parametrize(
    "shape, chunks, ind", [
        ((15, 16), (4, 5), 0),
        ((15, 16), (4, 5), 1),
        ((15, 16), (4, 5), [1]),
        ((15, 16), (4, 5), [1, 2]),
        ((15, 16), (4, 5), [1, 100]),
        ((15, 16), (4, 5), [[1, 2, 3, 4]]),
        ((15, 16), (4, 5), [[1, 2], [3, 4]]),
        ((15, 16), (4, 5), [[[1], [2], [3], [4]]]),
    ]
)
def test__get_label_matches(shape, chunks, ind):
    a = np.random.random(shape)
    d = da.from_array(a, chunks=chunks)

    lbls = np.zeros(a.shape, dtype=np.int64)
    lbls += (
        (a < 0.5).astype(lbls.dtype) +
        (a < 0.25).astype(lbls.dtype) +
        (a < 0.125).astype(lbls.dtype) +
        (a < 0.0625).astype(lbls.dtype)
    )
    d_lbls = da.from_array(lbls, chunks=d.chunks)

    ind = np.array(ind)
    d_ind = da.from_array(ind, chunks=1)

    lbl_mtch = operator.eq(
        ind[(Ellipsis,) + lbls.ndim * (None,)],
        lbls[ind.ndim * (None,)]
    )
    input_i_mtch = (
        lbl_mtch.astype(np.int64)[ind.ndim * (slice(None),) + (None,)] *
        np.indices(a.shape, dtype=np.int64)[ind.ndim * (None,)]
    )
    input_mtch = lbl_mtch.astype(a.dtype) * a[ind.ndim * (None,)]

    d_lbl_mtch = dask_ndmeasure._utils._get_label_matches(d_lbls, ind)

    assert issubclass(d_lbl_mtch.dtype.type, np.bool8)

    dau.assert_eq(d_lbl_mtch, lbl_mtch)

@pytest.mark.parametrize(
    "shape, chunks", [
        ((15,), (4,)),
        ((15, 16), (4, 5)),
        ((15, 1, 16), (4, 1, 5)),
        ((15, 12, 16), (4, 5, 6)),
    ]
)
def test___ravel_shape_indices(shape, chunks):
    a = np.arange(int(np.prod(shape)), dtype=np.int64).reshape(shape)
    d = dask_ndmeasure._utils._ravel_shape_indices(
        shape, dtype=np.int64, chunks=chunks
    )

    dau.assert_eq(d, a)
<commit_msg>Test warning for index of rank higher than 1<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import absolute_import

import operator

import pytest

import numpy as np

import dask.array as da
import dask.array.utils as dau

import dask_ndmeasure._utils

def test__norm_input_labels_index_err():
    shape = (15, 16)
    chunks = (4, 5)
    ind = None

    a = np.random.random(shape)
    d = da.from_array(a, chunks=chunks)

    lbls = (a < 0.5).astype(np.int64)
    d_lbls = da.from_array(lbls, chunks=d.chunks)

    lbls = lbls[:-1]
    d_lbls = d_lbls[:-1]

    with pytest.raises(ValueError):
        dask_ndmeasure._utils._norm_input_labels_index(d, d_lbls, ind)

def test__norm_input_labels_index():
    shape = (15, 16)
    chunks = (4, 5)
    ind = None

    a = np.random.random(shape)
    d = da.from_array(a, chunks=chunks)

    lbls = (a < 0.5).astype(int)
    d_lbls = da.from_array(lbls, chunks=d.chunks)

    d_n, d_lbls_n, ind_n = dask_ndmeasure._utils._norm_input_labels_index(
        d, d_lbls, ind
    )

    assert isinstance(d_n, da.Array)
    assert isinstance(d_lbls_n, da.Array)
    assert isinstance(ind_n, da.Array)

    dau.assert_eq(d_n, d)
    dau.assert_eq(d_lbls_n, d_lbls)
    dau.assert_eq(ind_n, np.array([1], dtype=int))

@pytest.mark.parametrize(
    "shape, chunks, ind", [
        ((15, 16), (4, 5), 1),
        ((15, 16), (4, 5), [1]),
        ((15, 16), (4, 5), [[1, 2, 3, 4]]),
        ((15, 16), (4, 5), [[1, 2], [3, 4]]),
        ((15, 16), (4, 5), [[[1], [2], [3], [4]]]),
    ]
)
def test__norm_input_labels_index_warn(shape, chunks, ind):
    a = np.random.random(shape)
    d = da.from_array(a, chunks=chunks)

    lbls = np.zeros(a.shape, dtype=np.int64)
    lbls += (
        (a < 0.5).astype(lbls.dtype) +
        (a < 0.25).astype(lbls.dtype) +
        (a < 0.125).astype(lbls.dtype) +
        (a < 0.0625).astype(lbls.dtype)
    )
    d_lbls = da.from_array(lbls, chunks=d.chunks)

    ind = np.array(ind)
    d_ind = da.from_array(ind, chunks=1)

    with pytest.warns(None) as w:
        dask_ndmeasure._utils._norm_input_labels_index(
            d, d_lbls, ind
        )

    if ind.ndim > 1:
        assert len(w) == 1
        w.pop(FutureWarning)
    else:
        assert len(w) == 0

@pytest.mark.parametrize(
    "shape, chunks, ind", [
        ((15, 16), (4, 5), 0),
        ((15, 16), (4, 5), 1),
        ((15, 16), (4, 5), [1]),
        ((15, 16), (4, 5), [1, 2]),
        ((15, 16), (4, 5), [1, 100]),
        ((15, 16), (4, 5), [[1, 2, 3, 4]]),
        ((15, 16), (4, 5), [[1, 2], [3, 4]]),
        ((15, 16), (4, 5), [[[1], [2], [3], [4]]]),
    ]
)
def test__get_label_matches(shape, chunks, ind):
    a = np.random.random(shape)
    d = da.from_array(a, chunks=chunks)

    lbls = np.zeros(a.shape, dtype=np.int64)
    lbls += (
        (a < 0.5).astype(lbls.dtype) +
        (a < 0.25).astype(lbls.dtype) +
        (a < 0.125).astype(lbls.dtype) +
        (a < 0.0625).astype(lbls.dtype)
    )
    d_lbls = da.from_array(lbls, chunks=d.chunks)

    ind = np.array(ind)
    d_ind = da.from_array(ind, chunks=1)

    lbl_mtch = operator.eq(
        ind[(Ellipsis,) + lbls.ndim * (None,)],
        lbls[ind.ndim * (None,)]
    )
    input_i_mtch = (
        lbl_mtch.astype(np.int64)[ind.ndim * (slice(None),) + (None,)] *
        np.indices(a.shape, dtype=np.int64)[ind.ndim * (None,)]
    )
    input_mtch = lbl_mtch.astype(a.dtype) * a[ind.ndim * (None,)]

    d_lbl_mtch = dask_ndmeasure._utils._get_label_matches(d_lbls, ind)

    assert issubclass(d_lbl_mtch.dtype.type, np.bool8)

    dau.assert_eq(d_lbl_mtch, lbl_mtch)

@pytest.mark.parametrize(
    "shape, chunks", [
        ((15,), (4,)),
        ((15, 16), (4, 5)),
        ((15, 1, 16), (4, 1, 5)),
        ((15, 12, 16), (4, 5, 6)),
    ]
)
def test___ravel_shape_indices(shape, chunks):
    a = np.arange(int(np.prod(shape)), dtype=np.int64).reshape(shape)
    d = dask_ndmeasure._utils._ravel_shape_indices(
        shape, dtype=np.int64, chunks=chunks
    )

    dau.assert_eq(d, a)
<|endoftext|>


<commit_before>

import unittest
from cpuinfo import *
import helpers

class TestActual(unittest.TestCase):
	def setUp(self):
		helpers.backup_data_source(cpuinfo)

	def tearDown(self):
		helpers.restore_data_source(cpuinfo)

	def test_all(self):
		os_type = helpers.get_os_type()

		if os_type == 'BeOS':
			self.assertEqual({}, cpuinfo._get_cpu_info_from_registry())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cpufreq_info())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_lscpu())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_proc_cpuinfo())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysctl())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_kstat())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_dmesg())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot())
			self.assertTrue(len(cpuinfo._get_cpu_info_from_sysinfo()) > 0)
			#self.assertTrue(len(cpuinfo._get_cpu_info_from_cpuid()) > 0)
			self.assertTrue(len(cpuinfo.get_cpu_info()) > 0)
		elif os_type == 'BSD':
			self.assertEqual({}, cpuinfo._get_cpu_info_from_registry())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cpufreq_info())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_lscpu())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_proc_cpuinfo())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysctl())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_kstat())
			self.assertTrue(len(cpuinfo._get_cpu_info_from_dmesg()) > 0)
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysinfo())
			# FIXME: This fails by segfaulting for some reason
			#self.assertEqual({}, cpuinfo._get_cpu_info_from_cpuid())
			self.assertTrue(len(cpuinfo.get_cpu_info()) > 0)
		elif os_type == 'Cygwin':
			self.assertEqual({}, cpuinfo._get_cpu_info_from_registry())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cpufreq_info())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_lscpu())
			self.assertTrue(len(cpuinfo._get_cpu_info_from_proc_cpuinfo()) > 0)
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysctl())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_kstat())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_dmesg())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysinfo())
			# FIXME: This fails by segfaulting for some reason
			#self.assertEqual({}, cpuinfo._get_cpu_info_from_cpuid())
			self.assertTrue(len(cpuinfo.get_cpu_info()) > 0)
		elif os_type == 'MacOS':
			self.assertEqual({}, cpuinfo._get_cpu_info_from_registry())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cpufreq_info())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_lscpu())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_proc_cpuinfo())
			self.assertTrue(len(cpuinfo._get_cpu_info_from_sysctl()) > 0)
			self.assertEqual({}, cpuinfo._get_cpu_info_from_kstat())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_dmesg())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysinfo())
			# FIXME: This fails by segfaulting for some reason
			#self.assertEqual({}, cpuinfo._get_cpu_info_from_cpuid())
			self.assertTrue(len(cpuinfo.get_cpu_info()) > 0)
		elif os_type == 'Linux':
			self.assertEqual({}, cpuinfo._get_cpu_info_from_registry())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cpufreq_info())
			self.assertTrue(len(cpuinfo._get_cpu_info_from_lscpu()) > 0)
			self.assertTrue(len(cpuinfo._get_cpu_info_from_proc_cpuinfo()) > 0)
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysctl())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_kstat())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_dmesg())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysinfo())
			#self.assertTrue(len(cpuinfo._get_cpu_info_from_cpuid()) > 0)
			self.assertTrue(len(cpuinfo.get_cpu_info()) > 0)
		elif os_type == 'Solaris':
			self.assertEqual({}, cpuinfo._get_cpu_info_from_registry())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cpufreq_info())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_lscpu())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_proc_cpuinfo())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysctl())
			self.assertTrue(len(cpuinfo._get_cpu_info_from_kstat()) > 0)
			self.assertEqual({}, cpuinfo._get_cpu_info_from_dmesg())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysinfo())
			# FIXME: This fails by segfaulting for some reason
			#self.assertEqual({}, cpuinfo._get_cpu_info_from_cpuid())
			self.assertTrue(len(cpuinfo.get_cpu_info()) > 0)
		elif os_type == 'Windows':
			self.assertTrue(len(cpuinfo._get_cpu_info_from_registry()) > 0)
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cpufreq_info())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_lscpu())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_proc_cpuinfo())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysctl())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_kstat())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_dmesg())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysinfo())
			#self.assertTrue(len(cpuinfo._get_cpu_info_from_cpuid()) > 0)
			self.assertTrue(len(cpuinfo.get_cpu_info()) > 0)
		else:
			raise AssertionError('Unexpected OS type "{0}".'.format(os_type))
<commit_msg>Turned off actual test that fails on PPC Linux.<commit_after>

import unittest
from cpuinfo import *
import helpers

class TestActual(unittest.TestCase):
	def setUp(self):
		helpers.backup_data_source(cpuinfo)

	def tearDown(self):
		helpers.restore_data_source(cpuinfo)

	def test_all(self):
		os_type = helpers.get_os_type()

		if os_type == 'BeOS':
			self.assertEqual({}, cpuinfo._get_cpu_info_from_registry())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cpufreq_info())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_lscpu())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_proc_cpuinfo())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysctl())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_kstat())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_dmesg())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot())
			self.assertTrue(len(cpuinfo._get_cpu_info_from_sysinfo()) > 0)
			#self.assertTrue(len(cpuinfo._get_cpu_info_from_cpuid()) > 0)
			self.assertTrue(len(cpuinfo.get_cpu_info()) > 0)
		elif os_type == 'BSD':
			self.assertEqual({}, cpuinfo._get_cpu_info_from_registry())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cpufreq_info())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_lscpu())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_proc_cpuinfo())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysctl())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_kstat())
			self.assertTrue(len(cpuinfo._get_cpu_info_from_dmesg()) > 0)
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysinfo())
			# FIXME: This fails by segfaulting for some reason
			#self.assertEqual({}, cpuinfo._get_cpu_info_from_cpuid())
			self.assertTrue(len(cpuinfo.get_cpu_info()) > 0)
		elif os_type == 'Cygwin':
			self.assertEqual({}, cpuinfo._get_cpu_info_from_registry())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cpufreq_info())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_lscpu())
			self.assertTrue(len(cpuinfo._get_cpu_info_from_proc_cpuinfo()) > 0)
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysctl())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_kstat())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_dmesg())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysinfo())
			# FIXME: This fails by segfaulting for some reason
			#self.assertEqual({}, cpuinfo._get_cpu_info_from_cpuid())
			self.assertTrue(len(cpuinfo.get_cpu_info()) > 0)
		elif os_type == 'MacOS':
			self.assertEqual({}, cpuinfo._get_cpu_info_from_registry())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cpufreq_info())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_lscpu())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_proc_cpuinfo())
			self.assertTrue(len(cpuinfo._get_cpu_info_from_sysctl()) > 0)
			self.assertEqual({}, cpuinfo._get_cpu_info_from_kstat())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_dmesg())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysinfo())
			# FIXME: This fails by segfaulting for some reason
			#self.assertEqual({}, cpuinfo._get_cpu_info_from_cpuid())
			self.assertTrue(len(cpuinfo.get_cpu_info()) > 0)
		elif os_type == 'Linux':
			self.assertEqual({}, cpuinfo._get_cpu_info_from_registry())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cpufreq_info())
			#self.assertTrue(len(cpuinfo._get_cpu_info_from_lscpu()) > 0)
			self.assertTrue(len(cpuinfo._get_cpu_info_from_proc_cpuinfo()) > 0)
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysctl())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_kstat())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_dmesg())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysinfo())
			#self.assertTrue(len(cpuinfo._get_cpu_info_from_cpuid()) > 0)
			self.assertTrue(len(cpuinfo.get_cpu_info()) > 0)
		elif os_type == 'Solaris':
			self.assertEqual({}, cpuinfo._get_cpu_info_from_registry())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cpufreq_info())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_lscpu())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_proc_cpuinfo())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysctl())
			self.assertTrue(len(cpuinfo._get_cpu_info_from_kstat()) > 0)
			self.assertEqual({}, cpuinfo._get_cpu_info_from_dmesg())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysinfo())
			# FIXME: This fails by segfaulting for some reason
			#self.assertEqual({}, cpuinfo._get_cpu_info_from_cpuid())
			self.assertTrue(len(cpuinfo.get_cpu_info()) > 0)
		elif os_type == 'Windows':
			self.assertTrue(len(cpuinfo._get_cpu_info_from_registry()) > 0)
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cpufreq_info())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_lscpu())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_proc_cpuinfo())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysctl())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_kstat())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_dmesg())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_cat_var_run_dmesg_boot())
			self.assertEqual({}, cpuinfo._get_cpu_info_from_sysinfo())
			#self.assertTrue(len(cpuinfo._get_cpu_info_from_cpuid()) > 0)
			self.assertTrue(len(cpuinfo.get_cpu_info()) > 0)
		else:
			raise AssertionError('Unexpected OS type "{0}".'.format(os_type))
<|endoftext|>


<commit_before>import errno
import sys
import socket
from struct import pack

import pytest
import _pytest.outcomes

from arpreq import arpreq

localhost = {
    "int": 0x7F000001,
    "bytes": b"127.0.0.1",
    "unicode": u"127.0.0.1",
}

try:
    localhost["long"] = long(0x7F000001)
except NameError as e:
    localhost["long"] = pytest.param(None, marks=[pytest.mark.skip(str(e))])

try:
    import ipaddress
except ImportError as e:
    localhost["ipaddress"] = pytest.param(
        None,
        marks=[pytest.mark.skip(str(e))],
    )
else:
    localhost["ipaddress"] = ipaddress.IPv4Address(u"127.0.0.1")

try:
    import ipaddr
except ImportError as e:
    localhost["ipaddr"] = pytest.param(None, marks=[pytest.mark.skip(str(e))])
else:
    localhost["ipaddr"] = ipaddr.IPv4Address("127.0.0.1")

try:
    import netaddr
except ImportError as e:
    localhost["netaddr"] = pytest.param(None, marks=[pytest.mark.skip(str(e))])
else:
    localhost["netaddr"] = netaddr.IPAddress("127.0.0.1")

@pytest.mark.parametrize(
    "value",
    localhost.values(),
    ids=tuple(localhost.keys()),
)
def test_localhost(value):
    assert arpreq(value) == '00:00:00:00:00:00'

def decode_address(value):
    return socket.inet_ntoa(pack(">I", socket.htonl(int(value, base=16))))

def decode_flags(value):
    return int(value, base=16)

def icmp_socket():
    try:
        return socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                             socket.IPPROTO_ICMP)
    except IOError as e:
        if e.errno != errno.EACCES:
            raise
        pytest.skip("Can't use unprivileged ICMP. Allow with sysctl "
                    "net.ipv4.ping_group_range='0 2147483647'")

def ping(address):
    with icmp_socket() as sock:
        sock.connect((address, 0))
        sock.settimeout(1)
        request = pack(
            '>BBHHH32s',
            8, # ICMP Type 8 (ECHO Request)
            0, # Sub-Code 0
            0, # Checksum,
            0, # Identifier
            0, # Sequence No
            b'\x00' * 32 # Payload
        )
        sock.send(request)
        try:
            reply = sock.recv(65536)
        except socket.timeout:
            pass

def get_gateways():
    """Get all gateways of routes"""
    with open("/proc/net/route") as f:
        # Skip header
        next(f)
        for line in f:
            fields = line.strip().split()
            destination = decode_address(fields[1])
            mask = decode_address(fields[7])
            gateway = decode_address(fields[2])
            flags = decode_flags(fields[3])
            # Check if RTF_UP and RTF_GATEWAY flags are set
            if flags & 0x3 == 0x3:
                yield gateway

@pytest.fixture(scope="session")
def gateways():
    """Sends an ICMP Echo-Request to all gateways to fill ARP cache"""
    ips = set(get_gateways())
    for ip in ips:
        ping(ip)
    return ips

def get_arp_cache():
    """Get all complete ARP entries"""
    with open("/proc/net/arp") as f:
        # Skip header
        next(f)
        for line in f:
            ip_address, hw_type, flags, hw_address, mask, device = line.split()
            # Check if ATF_COM flag is set
            if decode_flags(flags) & 0x2:
                yield ip_address, hw_address

@pytest.fixture(scope="session")
def arp_cache(request):
    # Request gateways during runtime to handle if skipped
    try:
        request.getfixturevalue("gateways")
    except _pytest.outcomes.Skipped:
        pass
    return tuple(get_arp_cache())

def test_cached_entries(arp_cache):
    for ip, mac in arp_cache:
        assert arpreq(ip) == mac

def test_gateways(gateways):
    for gateway in gateways:
        assert arpreq(gateway) is not None

@pytest.mark.parametrize("value", [
    "Foobar",
    -1,
    1 << 32,
    1 << 64,
    u"\u201c\ufffd\u201d"
])
def test_illegal_argument(value):
    with pytest.raises(ValueError):
        arpreq(value)

@pytest.mark.parametrize("value", [None, object(), [], ()])
def test_illegal_type(value):
    with pytest.raises(TypeError):
        arpreq(value)
<commit_msg>Move ICMP timeout handling to caller<commit_after>import errno
import sys
import socket
from struct import pack

import pytest
import _pytest.outcomes

from arpreq import arpreq

localhost = {
    "int": 0x7F000001,
    "bytes": b"127.0.0.1",
    "unicode": u"127.0.0.1",
}

try:
    localhost["long"] = long(0x7F000001)
except NameError as e:
    localhost["long"] = pytest.param(None, marks=[pytest.mark.skip(str(e))])

try:
    import ipaddress
except ImportError as e:
    localhost["ipaddress"] = pytest.param(
        None,
        marks=[pytest.mark.skip(str(e))],
    )
else:
    localhost["ipaddress"] = ipaddress.IPv4Address(u"127.0.0.1")

try:
    import ipaddr
except ImportError as e:
    localhost["ipaddr"] = pytest.param(None, marks=[pytest.mark.skip(str(e))])
else:
    localhost["ipaddr"] = ipaddr.IPv4Address("127.0.0.1")

try:
    import netaddr
except ImportError as e:
    localhost["netaddr"] = pytest.param(None, marks=[pytest.mark.skip(str(e))])
else:
    localhost["netaddr"] = netaddr.IPAddress("127.0.0.1")

@pytest.mark.parametrize(
    "value",
    localhost.values(),
    ids=tuple(localhost.keys()),
)
def test_localhost(value):
    assert arpreq(value) == '00:00:00:00:00:00'

def decode_address(value):
    return socket.inet_ntoa(pack(">I", socket.htonl(int(value, base=16))))

def decode_flags(value):
    return int(value, base=16)

def icmp_socket():
    try:
        return socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
                             socket.IPPROTO_ICMP)
    except IOError as e:
        if e.errno != errno.EACCES:
            raise
        pytest.skip("Can't use unprivileged ICMP. Allow with sysctl "
                    "net.ipv4.ping_group_range='0 2147483647'")

def ping(address):
    with icmp_socket() as sock:
        sock.connect((address, 0))
        sock.settimeout(1)
        request = pack(
            '>BBHHH32s',
            8, # ICMP Type 8 (ECHO Request)
            0, # Sub-Code 0
            0, # Checksum,
            0, # Identifier
            0, # Sequence No
            b'\x00' * 32 # Payload
        )
        sock.send(request)
        reply = sock.recv(65536)

def get_gateways():
    """Get all gateways of routes"""
    with open("/proc/net/route") as f:
        # Skip header
        next(f)
        for line in f:
            fields = line.strip().split()
            destination = decode_address(fields[1])
            mask = decode_address(fields[7])
            gateway = decode_address(fields[2])
            flags = decode_flags(fields[3])
            # Check if RTF_UP and RTF_GATEWAY flags are set
            if flags & 0x3 == 0x3:
                yield gateway

@pytest.fixture(scope="session")
def gateways():
    """Sends an ICMP Echo-Request to all gateways to fill ARP cache"""
    ips = set(get_gateways())
    for ip in ips:
        try:
            ping(ip)
        except socket.timeout:
            pass
    return ips

def get_arp_cache():
    """Get all complete ARP entries"""
    with open("/proc/net/arp") as f:
        # Skip header
        next(f)
        for line in f:
            ip_address, hw_type, flags, hw_address, mask, device = line.split()
            # Check if ATF_COM flag is set
            if decode_flags(flags) & 0x2:
                yield ip_address, hw_address

@pytest.fixture(scope="session")
def arp_cache(request):
    # Request gateways during runtime to handle if skipped
    try:
        request.getfixturevalue("gateways")
    except _pytest.outcomes.Skipped:
        pass
    return tuple(get_arp_cache())

def test_cached_entries(arp_cache):
    for ip, mac in arp_cache:
        assert arpreq(ip) == mac

def test_gateways(gateways):
    for gateway in gateways:
        assert arpreq(gateway) is not None

@pytest.mark.parametrize("value", [
    "Foobar",
    -1,
    1 << 32,
    1 << 64,
    u"\u201c\ufffd\u201d"
])
def test_illegal_argument(value):
    with pytest.raises(ValueError):
        arpreq(value)

@pytest.mark.parametrize("value", [None, object(), [], ()])
def test_illegal_type(value):
    with pytest.raises(TypeError):
        arpreq(value)
<|endoftext|>


<commit_before>import os
import weakref
import pytest
from pytestqt.qt_compat import qt_api

def test_basics(qtbot):
    """
    Basic test that works more like a sanity check to ensure we are setting up a QApplication
    properly and are able to display a simple event_recorder.
    """
    assert qt_api.QApplication.instance() is not None
    widget = qt_api.QWidget()
    qtbot.addWidget(widget)
    widget.setWindowTitle('W1')
    widget.show()

    assert widget.isVisible()
    assert widget.windowTitle() == 'W1'

def test_key_events(qtbot, event_recorder):
    """
    Basic key events test.
    """
    def extract(key_event):
        return (
            key_event.type(),
            key_event.key(),
            key_event.text(),
        )

    event_recorder.registerEvent(qt_api.QtGui.QKeyEvent, extract)

    qtbot.keyPress(event_recorder, 'a')
    assert event_recorder.event_data == (qt_api.QEvent.KeyPress, int(qt_api.Qt.Key_A), 'a')

    qtbot.keyRelease(event_recorder, 'a')
    assert event_recorder.event_data == (qt_api.QEvent.KeyRelease, int(qt_api.Qt.Key_A), 'a')

def test_mouse_events(qtbot, event_recorder):
    """
    Basic mouse events test.
    """
    def extract(mouse_event):
        return (
            mouse_event.type(),
            mouse_event.button(),
            mouse_event.modifiers(),
        )

    event_recorder.registerEvent(qt_api.QtGui.QMouseEvent, extract)

    qtbot.mousePress(event_recorder, qt_api.Qt.LeftButton)
    assert event_recorder.event_data == (qt_api.QEvent.MouseButtonPress, qt_api.Qt.LeftButton, qt_api.Qt.NoModifier)

    qtbot.mousePress(event_recorder, qt_api.Qt.RightButton, qt_api.Qt.AltModifier)
    assert event_recorder.event_data == (qt_api.QEvent.MouseButtonPress, qt_api.Qt.RightButton, qt_api.Qt.AltModifier)

def test_stop_for_interaction(qtbot, timer):
    """
    Test qtbot.stopForInteraction()
    """
    widget = qt_api.QWidget()
    qtbot.addWidget(widget)
    qtbot.waitForWindowShown(widget)
    timer.single_shot_callback(widget.close, 0)
    qtbot.stopForInteraction()

@pytest.mark.parametrize('show', [True, False])
@pytest.mark.parametrize('method_name', ['waitExposed', 'waitActive'])
def test_wait_window(show, method_name, qtbot):
    """
    Using one of the wait-widget methods should not raise anything if the widget
    is properly displayed, otherwise should raise a TimeoutError.
    """
    method = getattr(qtbot, method_name)
    if qt_api.pytest_qt_api != 'pyqt5':
        with pytest.raises(RuntimeError) as exc_info:
            with method(None, None):
                pass
        assert str(exc_info.value) == 'Available in PyQt5 only'
    else:
        widget = qt_api.QWidget()
        qtbot.add_widget(widget)
        if show:
            with method(widget, timeout=1000):
                widget.show()
        else:
            with pytest.raises(qtbot.TimeoutError):
                with method(widget, timeout=100):
                    pass

@pytest.mark.parametrize('method_name', ['waitExposed', 'waitActive'])
def test_wait_window_propagates_other_exception(method_name, qtbot):
    """
    Exceptions raised inside the with-statement of wait-widget methods should
    propagate properly.
    """
    if qt_api.pytest_qt_api != 'pyqt5':
        pytest.skip('Available in PyQt5 only')

    method = getattr(qtbot, method_name)
    widget = qt_api.QWidget()
    qtbot.add_widget(widget)
    with pytest.raises(ValueError) as exc_info:
        with method(widget, timeout=100):
            widget.show()
            raise ValueError('some other error')
    assert str(exc_info.value) == 'some other error'

def test_widget_kept_as_weakref(qtbot):
    """
    Test if the widget is kept as a weak reference in QtBot
    """
    widget = qt_api.QWidget()
    qtbot.add_widget(widget)
    widget = weakref.ref(widget)
    assert widget() is None

def test_event_processing_before_and_after_teardown(testdir):
    """
    Make sure events are processed before and after fixtures are torn down.

    The test works by creating a session object which pops() one of its events
    whenever a processEvents() occurs. Fixture and tests append values
    to the event list but expect the list to have been processed (by the pop())
    at each point of interest.

    https://github.com/pytest-dev/pytest-qt/issues/67
    """
    testdir.makepyfile(
        '''
        from pytestqt.qt_compat import qt_api
        import pytest

        @pytest.fixture(scope='session')
        def events_queue(qapp):
            class EventsQueue(qt_api.QtCore.QObject):

                def __init__(self):
                    qt_api.QtCore.QObject.__init__(self)
                    self.events = []

                def pop_later(self):
                    qapp.postEvent(self, qt_api.QEvent(qt_api.QEvent.User))

                def event(self, ev):
                    if ev.type() == qt_api.QEvent.User:
                        self.events.pop(-1)
                    return qt_api.QtCore.QObject.event(self, ev)

            return EventsQueue()

        @pytest.yield_fixture
        def fix(events_queue, qapp):
            assert events_queue.events == []
            yield
            assert events_queue.events == []
            events_queue.events.append('fixture teardown')
            events_queue.pop_later()

        @pytest.mark.parametrize('i', range(3))
        def test_events(events_queue, fix, i):
            assert events_queue.events == []
            events_queue.events.append('test event')
            events_queue.pop_later()
        '''
    )
    res = testdir.runpytest()
    res.stdout.fnmatch_lines([
        '*3 passed in*',
    ])

def test_header(testdir):
    testdir.makeconftest(
        '''
        from pytestqt import qt_compat
        from pytestqt.qt_compat import qt_api

        def mock_get_versions():
            return qt_compat.VersionTuple('PyQtAPI', '1.0', '2.5', '3.5')

        assert hasattr(qt_api, 'get_versions')
        qt_api.get_versions = mock_get_versions
        '''
    )
    res = testdir.runpytest()
    res.stdout.fnmatch_lines([
        '*test session starts*',
        'PyQtAPI 1.0 -- Qt runtime 2.5 -- Qt compiled 3.5',
    ])

def test_public_api_backward_compatibility():
    """
    Test backward compatibility for version 1.6.0: since then symbols that were available from
    pytestqt.plugin have been moved to other modules to enhance navigation and maintainability,
    this test ensures the same symbols are still available from the same imports. (#90)
    """
    import pytestqt.plugin
    assert pytestqt.plugin.QtBot
    assert pytestqt.plugin.SignalBlocker
    assert pytestqt.plugin.MultiSignalBlocker
    assert pytestqt.plugin.SignalTimeoutError
    assert pytestqt.plugin.format_captured_exceptions
    assert pytestqt.plugin.capture_exceptions
    assert pytestqt.plugin.QtLoggingPlugin
    assert pytestqt.plugin.Record

def test_qvariant(tmpdir):
    """Test that make_variant and extract_from_variant work in the same way
    across all supported Qt bindings.
    """
    settings = qt_api.QtCore.QSettings(str(tmpdir / 'foo.ini'),
                                       qt_api.QtCore.QSettings.IniFormat)
    settings.setValue('int', qt_api.make_variant(42))
    settings.setValue('str', qt_api.make_variant('Hello'))
    settings.setValue('empty', qt_api.make_variant())

    assert qt_api.extract_from_variant(settings.value('int')) == 42
    assert qt_api.extract_from_variant(settings.value('str')) == 'Hello'
    assert qt_api.extract_from_variant(settings.value('empty')) is None

def test_widgets_closed_before_fixtures(testdir):
    """
    Ensure widgets added by "qtbot.add_widget" are closed before all other
    fixtures are teardown. (#106).
    """
    testdir.makepyfile('''
        import pytest
        from pytestqt.qt_compat import qt_api

        class Widget(qt_api.QWidget):

            closed = False

            def closeEvent(self, e):
                e.accept()
                self.closed = True

        @pytest.yield_fixture
        def widget(qtbot):
            w = Widget()
            qtbot.add_widget(w)
            yield w
            assert w.closed

        def test_foo(widget):
            pass
    ''')
    result = testdir.runpytest()
    result.stdout.fnmatch_lines([
        '*= 1 passed in *'
    ])

def test_qtbot_wait(qtbot, stop_watch):
    stop_watch.start()
    qtbot.wait(250)
    stop_watch.stop()
    assert stop_watch.elapsed >= 220

@pytest.fixture
def event_recorder(qtbot):

    class EventRecorder(qt_api.QWidget):

        """
        Widget that records some kind of events sent to it.

        When this event_recorder receives a registered event (by calling `registerEvent`), it will call
        the associated *extract* function and hold the return value from the function in the
        `event_data` member.
        """

        def __init__(self):
            qt_api.QWidget.__init__(self)
            self._event_types = {}
            self.event_data = None

        def registerEvent(self, event_type, extract_func):
            self._event_types[event_type] = extract_func

        def event(self, ev):
            for event_type, extract_func in self._event_types.items():
                if isinstance(ev, event_type):
                    self.event_data = extract_func(ev)
                    return True

            return False

    widget = EventRecorder()
    qtbot.addWidget(widget)
    return widget

@pytest.mark.parametrize('value, expected', [
    (True, True),
    (False, False),
    ('True', True),
    ('False', False),
    ('true', True),
    ('false', False),
])
def test_parse_ini_boolean_valid(value, expected):
    import pytestqt.qtbot
    assert pytestqt.qtbot._parse_ini_boolean(value) == expected

def test_parse_ini_boolean_invalid():
    import pytestqt.qtbot
    with pytest.raises(ValueError):
        pytestqt.qtbot._parse_ini_boolean('foo')

@pytest.mark.parametrize('option_api', ['pyqt4', 'pyqt5', 'pyside', 'pyside2'])
def test_qt_api_ini_config(testdir, option_api):
    """
    Test qt_api ini option handling.
    """
    from pytestqt.qt_compat import qt_api

    testdir.makeini("""
        [pytest]
        qt_api={option_api}
    """.format(option_api=option_api))

    testdir.makepyfile('''
        import pytest

        def test_foo(qtbot):
            pass
    ''')

    result = testdir.runpytest_subprocess()
    if qt_api.pytest_qt_api.replace('v2', '') == option_api:  # handle pyqt4v2
        result.stdout.fnmatch_lines([
            '* 1 passed in *'
        ])
    else:
        try:
            ModuleNotFoundError
        except NameError:
            # Python < 3.6
            result.stderr.fnmatch_lines([
                '*ImportError:*'
            ])
        else:
            # Python >= 3.6
            result.stderr.fnmatch_lines([
                '*ModuleNotFoundError:*'
            ])

def test_invalid_qt_api_envvar(testdir, monkeypatch):
    """
    Make sure the error message with an invalid PYQTEST_QT_API is correct.
    """
    testdir.makepyfile('''
        import pytest

        def test_foo(qtbot):
            pass
    ''')
    monkeypatch.setenv('PYTEST_QT_API', 'piecute')
    result = testdir.runpytest_subprocess()
    result.stderr.fnmatch_lines(['* Invalid value for $PYTEST_QT_API: piecute'])
<commit_msg>Add test for qapp_args<commit_after>import os
import sys
import weakref
import pytest
from pytestqt.qt_compat import qt_api

def test_basics(qtbot):
    """
    Basic test that works more like a sanity check to ensure we are setting up a QApplication
    properly and are able to display a simple event_recorder.
    """
    assert qt_api.QApplication.instance() is not None
    widget = qt_api.QWidget()
    qtbot.addWidget(widget)
    widget.setWindowTitle('W1')
    widget.show()

    assert widget.isVisible()
    assert widget.windowTitle() == 'W1'

def test_key_events(qtbot, event_recorder):
    """
    Basic key events test.
    """
    def extract(key_event):
        return (
            key_event.type(),
            key_event.key(),
            key_event.text(),
        )

    event_recorder.registerEvent(qt_api.QtGui.QKeyEvent, extract)

    qtbot.keyPress(event_recorder, 'a')
    assert event_recorder.event_data == (qt_api.QEvent.KeyPress, int(qt_api.Qt.Key_A), 'a')

    qtbot.keyRelease(event_recorder, 'a')
    assert event_recorder.event_data == (qt_api.QEvent.KeyRelease, int(qt_api.Qt.Key_A), 'a')

def test_mouse_events(qtbot, event_recorder):
    """
    Basic mouse events test.
    """
    def extract(mouse_event):
        return (
            mouse_event.type(),
            mouse_event.button(),
            mouse_event.modifiers(),
        )

    event_recorder.registerEvent(qt_api.QtGui.QMouseEvent, extract)

    qtbot.mousePress(event_recorder, qt_api.Qt.LeftButton)
    assert event_recorder.event_data == (qt_api.QEvent.MouseButtonPress, qt_api.Qt.LeftButton, qt_api.Qt.NoModifier)

    qtbot.mousePress(event_recorder, qt_api.Qt.RightButton, qt_api.Qt.AltModifier)
    assert event_recorder.event_data == (qt_api.QEvent.MouseButtonPress, qt_api.Qt.RightButton, qt_api.Qt.AltModifier)

def test_stop_for_interaction(qtbot, timer):
    """
    Test qtbot.stopForInteraction()
    """
    widget = qt_api.QWidget()
    qtbot.addWidget(widget)
    qtbot.waitForWindowShown(widget)
    timer.single_shot_callback(widget.close, 0)
    qtbot.stopForInteraction()

@pytest.mark.parametrize('show', [True, False])
@pytest.mark.parametrize('method_name', ['waitExposed', 'waitActive'])
def test_wait_window(show, method_name, qtbot):
    """
    Using one of the wait-widget methods should not raise anything if the widget
    is properly displayed, otherwise should raise a TimeoutError.
    """
    method = getattr(qtbot, method_name)
    if qt_api.pytest_qt_api != 'pyqt5':
        with pytest.raises(RuntimeError) as exc_info:
            with method(None, None):
                pass
        assert str(exc_info.value) == 'Available in PyQt5 only'
    else:
        widget = qt_api.QWidget()
        qtbot.add_widget(widget)
        if show:
            with method(widget, timeout=1000):
                widget.show()
        else:
            with pytest.raises(qtbot.TimeoutError):
                with method(widget, timeout=100):
                    pass

@pytest.mark.parametrize('method_name', ['waitExposed', 'waitActive'])
def test_wait_window_propagates_other_exception(method_name, qtbot):
    """
    Exceptions raised inside the with-statement of wait-widget methods should
    propagate properly.
    """
    if qt_api.pytest_qt_api != 'pyqt5':
        pytest.skip('Available in PyQt5 only')

    method = getattr(qtbot, method_name)
    widget = qt_api.QWidget()
    qtbot.add_widget(widget)
    with pytest.raises(ValueError) as exc_info:
        with method(widget, timeout=100):
            widget.show()
            raise ValueError('some other error')
    assert str(exc_info.value) == 'some other error'

def test_widget_kept_as_weakref(qtbot):
    """
    Test if the widget is kept as a weak reference in QtBot
    """
    widget = qt_api.QWidget()
    qtbot.add_widget(widget)
    widget = weakref.ref(widget)
    assert widget() is None

def test_event_processing_before_and_after_teardown(testdir):
    """
    Make sure events are processed before and after fixtures are torn down.

    The test works by creating a session object which pops() one of its events
    whenever a processEvents() occurs. Fixture and tests append values
    to the event list but expect the list to have been processed (by the pop())
    at each point of interest.

    https://github.com/pytest-dev/pytest-qt/issues/67
    """
    testdir.makepyfile(
        '''
        from pytestqt.qt_compat import qt_api
        import pytest

        @pytest.fixture(scope='session')
        def events_queue(qapp):
            class EventsQueue(qt_api.QtCore.QObject):

                def __init__(self):
                    qt_api.QtCore.QObject.__init__(self)
                    self.events = []

                def pop_later(self):
                    qapp.postEvent(self, qt_api.QEvent(qt_api.QEvent.User))

                def event(self, ev):
                    if ev.type() == qt_api.QEvent.User:
                        self.events.pop(-1)
                    return qt_api.QtCore.QObject.event(self, ev)

            return EventsQueue()

        @pytest.yield_fixture
        def fix(events_queue, qapp):
            assert events_queue.events == []
            yield
            assert events_queue.events == []
            events_queue.events.append('fixture teardown')
            events_queue.pop_later()

        @pytest.mark.parametrize('i', range(3))
        def test_events(events_queue, fix, i):
            assert events_queue.events == []
            events_queue.events.append('test event')
            events_queue.pop_later()
        '''
    )
    res = testdir.runpytest()
    res.stdout.fnmatch_lines([
        '*3 passed in*',
    ])

def test_header(testdir):
    testdir.makeconftest(
        '''
        from pytestqt import qt_compat
        from pytestqt.qt_compat import qt_api

        def mock_get_versions():
            return qt_compat.VersionTuple('PyQtAPI', '1.0', '2.5', '3.5')

        assert hasattr(qt_api, 'get_versions')
        qt_api.get_versions = mock_get_versions
        '''
    )
    res = testdir.runpytest()
    res.stdout.fnmatch_lines([
        '*test session starts*',
        'PyQtAPI 1.0 -- Qt runtime 2.5 -- Qt compiled 3.5',
    ])

def test_public_api_backward_compatibility():
    """
    Test backward compatibility for version 1.6.0: since then symbols that were available from
    pytestqt.plugin have been moved to other modules to enhance navigation and maintainability,
    this test ensures the same symbols are still available from the same imports. (#90)
    """
    import pytestqt.plugin
    assert pytestqt.plugin.QtBot
    assert pytestqt.plugin.SignalBlocker
    assert pytestqt.plugin.MultiSignalBlocker
    assert pytestqt.plugin.SignalTimeoutError
    assert pytestqt.plugin.format_captured_exceptions
    assert pytestqt.plugin.capture_exceptions
    assert pytestqt.plugin.QtLoggingPlugin
    assert pytestqt.plugin.Record

def test_qvariant(tmpdir):
    """Test that make_variant and extract_from_variant work in the same way
    across all supported Qt bindings.
    """
    settings = qt_api.QtCore.QSettings(str(tmpdir / 'foo.ini'),
                                       qt_api.QtCore.QSettings.IniFormat)
    settings.setValue('int', qt_api.make_variant(42))
    settings.setValue('str', qt_api.make_variant('Hello'))
    settings.setValue('empty', qt_api.make_variant())

    assert qt_api.extract_from_variant(settings.value('int')) == 42
    assert qt_api.extract_from_variant(settings.value('str')) == 'Hello'
    assert qt_api.extract_from_variant(settings.value('empty')) is None

def test_widgets_closed_before_fixtures(testdir):
    """
    Ensure widgets added by "qtbot.add_widget" are closed before all other
    fixtures are teardown. (#106).
    """
    testdir.makepyfile('''
        import pytest
        from pytestqt.qt_compat import qt_api

        class Widget(qt_api.QWidget):

            closed = False

            def closeEvent(self, e):
                e.accept()
                self.closed = True

        @pytest.yield_fixture
        def widget(qtbot):
            w = Widget()
            qtbot.add_widget(w)
            yield w
            assert w.closed

        def test_foo(widget):
            pass
    ''')
    result = testdir.runpytest()
    result.stdout.fnmatch_lines([
        '*= 1 passed in *'
    ])

def test_qtbot_wait(qtbot, stop_watch):
    stop_watch.start()
    qtbot.wait(250)
    stop_watch.stop()
    assert stop_watch.elapsed >= 220

@pytest.fixture
def event_recorder(qtbot):

    class EventRecorder(qt_api.QWidget):

        """
        Widget that records some kind of events sent to it.

        When this event_recorder receives a registered event (by calling `registerEvent`), it will call
        the associated *extract* function and hold the return value from the function in the
        `event_data` member.
        """

        def __init__(self):
            qt_api.QWidget.__init__(self)
            self._event_types = {}
            self.event_data = None

        def registerEvent(self, event_type, extract_func):
            self._event_types[event_type] = extract_func

        def event(self, ev):
            for event_type, extract_func in self._event_types.items():
                if isinstance(ev, event_type):
                    self.event_data = extract_func(ev)
                    return True

            return False

    widget = EventRecorder()
    qtbot.addWidget(widget)
    return widget

@pytest.mark.parametrize('value, expected', [
    (True, True),
    (False, False),
    ('True', True),
    ('False', False),
    ('true', True),
    ('false', False),
])
def test_parse_ini_boolean_valid(value, expected):
    import pytestqt.qtbot
    assert pytestqt.qtbot._parse_ini_boolean(value) == expected

def test_parse_ini_boolean_invalid():
    import pytestqt.qtbot
    with pytest.raises(ValueError):
        pytestqt.qtbot._parse_ini_boolean('foo')

@pytest.mark.parametrize('option_api', ['pyqt4', 'pyqt5', 'pyside', 'pyside2'])
def test_qt_api_ini_config(testdir, option_api):
    """
    Test qt_api ini option handling.
    """
    from pytestqt.qt_compat import qt_api

    testdir.makeini("""
        [pytest]
        qt_api={option_api}
    """.format(option_api=option_api))

    testdir.makepyfile('''
        import pytest

        def test_foo(qtbot):
            pass
    ''')

    result = testdir.runpytest_subprocess()
    if qt_api.pytest_qt_api.replace('v2', '') == option_api:  # handle pyqt4v2
        result.stdout.fnmatch_lines([
            '* 1 passed in *'
        ])
    else:
        try:
            ModuleNotFoundError
        except NameError:
            # Python < 3.6
            result.stderr.fnmatch_lines([
                '*ImportError:*'
            ])
        else:
            # Python >= 3.6
            result.stderr.fnmatch_lines([
                '*ModuleNotFoundError:*'
            ])

def test_invalid_qt_api_envvar(testdir, monkeypatch):
    """
    Make sure the error message with an invalid PYQTEST_QT_API is correct.
    """
    testdir.makepyfile('''
        import pytest

        def test_foo(qtbot):
            pass
    ''')
    monkeypatch.setenv('PYTEST_QT_API', 'piecute')
    result = testdir.runpytest_subprocess()
    result.stderr.fnmatch_lines(['* Invalid value for $PYTEST_QT_API: piecute'])

@pytest.mark.skipif(qt_api.pytest_qt_api in ['pyqt4', 'pyqt4v2', 'pyside'],
                    reason="QApplication.arguments() doesn't return custom arguments with Qt4 and Windows")
def test_qapp_args(testdir):
    """
    Test customizing of QApplication arguments.
    """
    testdir.makeconftest(
        '''
        import pytest

        @pytest.fixture(scope='session')
        def qapp_args():
            return ['--test-arg']
        '''
    )
    testdir.makepyfile('''
        def test_args(qapp):
            assert '--test-arg' in list(qapp.arguments())
    ''')
    result = testdir.runpytest_subprocess()
    result.stdout.fnmatch_lines([
        '*= 1 passed in *'
    ])
<|endoftext|>