Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@ environment:
- PYTHON: "C:\\Python36-x64"

install:
# We need our usual libraries
- "%PYTHON%\\python.exe -m pip install -r requirements.txt"
# We need to install the python-can library itself
- "%PYTHON%\\python.exe -m pip install ."
- "%PYTHON%\\python.exe -m pip install .[test]"

build: off

test_script:
# Note that you must use the environment variable %PYTHON% to refer to
# the interpreter you're using - Appveyor does not do anything special
# to put the Python version you want to use on PATH.
- "%PYTHON%\\python.exe setup.py test"
- "%PYTHON%\\python.exe setup.py test -v"
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ matrix:
- python: "nightly"

install:
- travis_retry pip install .
- travis_retry pip install -r requirements.txt
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo bash test/open_vcan.sh ; fi
- travis_retry pip install .[test]

script:
- py.test -v
4 changes: 2 additions & 2 deletions can/interfaces/virtual.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def recv(self, timeout=None):
except queue.Empty:
return None

logger.log(9, 'Received message:\n%s', msg)
#logger.log(9, 'Received message:\n%s', msg)
return msg

def send(self, msg, timeout=None):
Expand All @@ -55,7 +55,7 @@ def send(self, msg, timeout=None):
for bus_queue in self.channel:
if bus_queue is not self.queue or self.receive_own_messages:
bus_queue.put(msg)
logger.log(9, 'Transmitted message:\n%s', msg)
#logger.log(9, 'Transmitted message:\n%s', msg)

def shutdown(self):
self.channel.remove(self.queue)
10 changes: 8 additions & 2 deletions can/io/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@
See the :class:`Logger` class.
"""

import logging

from .asc import ASCWriter
from .blf import BLFWriter
from .csv import CSVWriter
from .log import CanutilsLogWriter
from .sqlite import SqliteWriter
from .stdout import Printer

log = logging.getLogger("can.io.logger")


class Logger(object):
"""
Expand All @@ -22,6 +26,7 @@ class Logger(object):
* .blf :class:`can.BLFWriter`
* .csv: :class:`can.CSVWriter`
* .db: :class:`can.SqliteWriter`
* .log :class:`can.CanutilsLogWriter`
* other: :class:`can.Printer`

Note this class itself is just a dispatcher,
Expand All @@ -35,13 +40,14 @@ def __new__(cls, other, filename):
return Printer()
elif filename.endswith(".asc"):
return ASCWriter(filename)
elif filename.endswith(".log"):
return CanutilsLogWriter(filename)
elif filename.endswith(".blf"):
return BLFWriter(filename)
elif filename.endswith(".csv"):
return CSVWriter(filename)
elif filename.endswith(".db"):
return SqliteWriter(filename)
elif filename.endswith(".log"):
return CanutilsLogWriter(filename)
else:
log.info('unknown file type "%s", falling pack to can.Printer', filename)
return Printer(filename)
4 changes: 3 additions & 1 deletion can/io/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ class LogReader(object):

@classmethod
def __new__(cls, other, filename):
if filename.endswith(".asc"):
if not filename:
raise TypeError("a filename must be given")
elif filename.endswith(".asc"):
return ASCReader(filename)
elif filename.endswith(".blf"):
return BLFReader(filename)
Expand Down
2 changes: 0 additions & 2 deletions requirements.txt

This file was deleted.

26 changes: 17 additions & 9 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,29 @@
python-can requires the setuptools package to be installed.
"""

from sys import version_info
import re
import logging
from setuptools import setup, find_packages

logging.basicConfig(level=logging.WARNING)

with open('can/__init__.py', 'r') as fd:
version = re.search(r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]',
fd.read(), re.MULTILINE).group(1)

with open('README.rst', 'r') as f:
long_description = f.read()

logging.basicConfig(level=logging.WARNING)
tests_require = [
'mock',
'nose',
'pyserial >= 3.0',
]
if version_info.major < 3:
tests_require += ['subprocess32 >= 3.2']

setup(

# Description
name="python-can",
url="https://github.com/hardbyte/python-can",
Expand All @@ -29,7 +37,9 @@
# Code
version=version,
packages=find_packages(),

# see https://www.python.org/dev/peps/pep-0345/#version-specifiers
python_requires='>=2.7,!=3.0,!=3.1,!=3.2',

# Author
author="Brian Thorne",
author_email="brian@thorne.link",
Expand All @@ -45,18 +55,16 @@

# Installation
install_requires=[
'setuptools',
#'Deprecated >= 1.1.0',
],
extras_require={
'serial': ['pyserial >= 3.0'],
'neovi': ['python-ics'],
'neovi': ['python-ics >= 2.8'],
'test': tests_require
},

# Testing
test_suite="nose.collector",
tests_require=[
'mock',
'nose',
'pyserial >= 3.0'
],
tests_require=tests_require,
)
45 changes: 40 additions & 5 deletions test/back2back_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@
This module tests two virtual busses attached to each other.
"""

from __future__ import absolute_import
from __future__ import absolute_import, print_function

import sys
import unittest
import time
from time import sleep

import can

from .config import *
from .data.example_data import generate_message

BITRATE = 500000
TIMEOUT = 0.1
Expand Down Expand Up @@ -80,12 +82,12 @@ def test_no_message(self):
def test_timestamp(self):
self.bus2.send(can.Message())
recv_msg1 = self.bus1.recv(TIMEOUT)
time.sleep(5)
sleep(2.0)
self.bus2.send(can.Message())
recv_msg2 = self.bus1.recv(TIMEOUT)
delta_time = recv_msg2.timestamp - recv_msg1.timestamp
self.assertTrue(4.8 < delta_time < 5.2,
'Time difference should have been 5s +/- 200ms.'
self.assertTrue(1.75 <= delta_time <= 2.25,
'Time difference should have been 2s +/- 250ms.'
'But measured {}'.format(delta_time))

def test_standard_message(self):
Expand Down Expand Up @@ -130,6 +132,39 @@ def test_fd_message_with_brs(self):
data=[0xff] * 48)
self._send_and_receive(msg)

# FIXME
@unittest.skip("skip until CAN FD support is fixed, see issue #274")
#@unittest.skipUnless(TEST_INTERFACE_SOCKETCAN, "skip testing of socketcan")
class BasicTestSocketCan(unittest.TestCase):

def setUp(self):
socketcan_version = can.util.choose_socketcan_implementation()
print("testing python-can's socketcan version:",
socketcan_version)

self.bus1 = can.interface.Bus(channel="vcan0",
bustype=socketcan_version,
bitrate=250000,
fd=TEST_CAN_FD)
self.bus2 = can.interface.Bus(channel="vcan0",
bustype=socketcan_version,
bitrate=250000,
fd=TEST_CAN_FD)

def tearDown(self):
self.bus1.shutdown()
self.bus2.shutdown()

def test_basics(self):
reader = can.BufferedReader()
notifier = can.Notifier(self.bus2, [reader])

message = can.Message(arbitration_id=0x4321, data=[1, 2, 3], extended_id=True)
self.bus1.send(message)

self.assertEqual(message, reader.get_message(timeout=2.0))
notifier.stop()


if __name__ == '__main__':
unittest.main()
29 changes: 28 additions & 1 deletion test/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,18 @@
# coding: utf-8

"""
This module contains some configuration for the tests.
This module contains various configuration for the tests.

Some tests are skipped when run on a CI server because they are not
reproducible, see #243 (https://github.com/hardbyte/python-can/issues/243).
"""

import platform
from os import environ as environment


# ############################## Continuos integration

# see here for the environment variables that are set on the CI servers:
# - https://docs.travis-ci.com/user/environment-variables/
# - https://www.appveyor.com/docs/environment-variables/
Expand All @@ -21,4 +25,27 @@
environment.get('CI', '').lower() == 'true' or \
environment.get('CONTINUOUS_INTEGRATION', '').lower() == 'true'

if IS_APPVEYOR and IS_TRAVIS:
raise EnvironmentError("IS_APPVEYOR and IS_TRAVIS cannot be both True at the same time")

# ############################## Platforms

_sys = platform.system().lower()
IS_WINDOWS = "windows" in _sys or ("win" in _sys and "darwin" not in _sys)
IS_LINUX = "linux" in _sys
IS_OSX = "darwin" in _sys

if (IS_WINDOWS and IS_LINUX) or (IS_LINUX and IS_OSX) or (IS_WINDOWS and IS_OSX):
raise EnvironmentError(
"only one of IS_WINDOWS ({}), IS_LINUX ({}) and IS_OSX ({}) ".format(IS_WINDOWS, IS_LINUX, IS_OSX) +
"can be True at the same time " +
'(platform.system() == "{}")'.format(platform.system())
)
elif not IS_WINDOWS and not IS_LINUX and not IS_OSX:
raise EnvironmentError("one of IS_WINDOWS, IS_LINUX, IS_OSX has to be True")

# ############################## What tests to run

TEST_CAN_FD = True

TEST_INTERFACE_SOCKETCAN = IS_CI and IS_LINUX
2 changes: 1 addition & 1 deletion test/data/example_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,5 +124,5 @@ def generate_message(arbitration_id):
Generates a new message with the given ID, some random data
and a non-extended ID.
"""
data = bytes([random.randrange(0, 2 ** 8 - 1) for _ in range(8)])
data = bytearray([random.randrange(0, 2 ** 8 - 1) for _ in range(8)])
return Message(arbitration_id=arbitration_id, data=data, extended_id=False)
34 changes: 29 additions & 5 deletions test/listener_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ def testClassesImportable(self):
self.assertTrue(hasattr(can, 'BLFReader'))
self.assertTrue(hasattr(can, 'BLFWriter'))

self.assertTrue(hasattr(can, 'CSVReader'))
self.assertTrue(hasattr(can, 'CSVWriter'))

self.assertTrue(hasattr(can, 'CanutilsLogWriter'))
Expand Down Expand Up @@ -73,23 +74,46 @@ def testBasicListenerCanBeAddedToNotifier(self):
notifier.stop()
self.assertIn(a_listener, notifier.listeners)

def testLogger(self):
def testPlayerTypeResolution(self):
def test_filetype_to_instance(extension, klass):
can_player = can.LogReader("test.{}".format(extension))
self.assertIsInstance(can_player, klass)
if hasattr(can_player, "stop"):
can_player.stop()

test_filetype_to_instance("asc", can.ASCReader)
test_filetype_to_instance("blf", can.BLFReader)
test_filetype_to_instance("csv", can.CSVReader)
test_filetype_to_instance("db" , can.SqliteReader)
test_filetype_to_instance("log", can.CanutilsLogReader)

# test file extensions that are not supported
with self.assertRaisesRegexp(NotImplementedError, "xyz_42"):
test_filetype_to_instance("xyz_42", can.Printer)
with self.assertRaises(BaseException):
test_filetype_to_instance(None, can.Printer)

def testLoggerTypeResolution(self):
def test_filetype_to_instance(extension, klass):
can_logger = can.Logger("test.{}".format(extension))
self.assertIsInstance(can_logger, klass)
can_logger.stop()

test_filetype_to_instance('asc', can.ASCWriter)
test_filetype_to_instance('log', can.CanutilsLogWriter)
test_filetype_to_instance("asc", can.ASCWriter)
test_filetype_to_instance("blf", can.BLFWriter)
test_filetype_to_instance("csv", can.CSVWriter)
test_filetype_to_instance("db", can.SqliteWriter)
test_filetype_to_instance("db" , can.SqliteWriter)
test_filetype_to_instance("log", can.CanutilsLogWriter)
test_filetype_to_instance("txt", can.Printer)

# test file extensions that should usa a fallback
test_filetype_to_instance(None, can.Printer)
test_filetype_to_instance("some_unknown_extention_42", can.Printer)

def testBufferedListenerReceives(self):
a_listener = can.BufferedReader()
a_listener(generate_message(0xDADADA))
m = a_listener.get_message(0.2)
m = a_listener.get_message(0.1)
self.assertIsNotNone(m)


Expand Down
7 changes: 3 additions & 4 deletions test/network_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def producer(self, ready_event, msg_read):
extended_id=self.extended_flags[i],
data=self.data[i]
)
logging.debug("writing message: {}".format(m))
#logging.debug("writing message: {}".format(m))
if msg_read is not None:
# Don't send until the other thread is ready
msg_read.wait()
Expand Down Expand Up @@ -92,15 +92,14 @@ def testProducerConsumer(self):
print("No messages... lets go")
break
else:
print("received messages before the test has started...")
self.assertTrue(False)
self.fail("received messages before the test has started ...")
ready.set()
i = 0
while i < self.num_messages:
msg_read.set()
msg = self.server_bus.recv(timeout=0.5)
self.assertIsNotNone(msg, "Didn't receive a message")
logging.debug("Received message {} with data: {}".format(i, msg.data))
#logging.debug("Received message {} with data: {}".format(i, msg.data))

self.assertEqual(msg.id_type, self.extended_flags[i])
if not msg.is_remote_frame:
Expand Down
7 changes: 7 additions & 0 deletions test/open_vcan.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

# Used by .travis.yml (which is executed with sudo privileges)

modprobe vcan
ip link add dev vcan0 type vcan
ip link set up vcan0
Loading