1#!/usr/bin/env python
2#
3# This file is part of pySerial - Cross platform serial port support for Python
4# (C) 2001-2015 Chris Liechti <[email protected]>
5#
6# SPDX-License-Identifier:    BSD-3-Clause
7"""\
8Some tests for the serial module.
9Part of pyserial (http://pyserial.sf.net)  (C)2002 [email protected]
10
11Intended to be run on different platforms, to ensure portability of
12the code.
13
14These tests open a serial port and change all the settings on the fly.
15If the port is really correctly configured cannot be determined - that
16would require external hardware or a null modem cable and an other
17serial port library... Thus it mainly tests that all features are
18correctly implemented and that the interface does what it should.
19
20"""
21
22import unittest
23import serial
24
25# on which port should the tests be performed:
26PORT = 'loop://'
27
28
29class Test_ChangeAttributes(unittest.TestCase):
30    """Test with timeouts"""
31
32    def setUp(self):
33        # create a closed serial port
34        self.s = serial.serial_for_url(PORT, do_not_open=True)
35
36    def tearDown(self):
37        self.s.close()
38
39    def test_PortSetting(self):
40        self.s.port = PORT
41        self.assertEqual(self.s.portstr.lower(), PORT.lower())
42        # test internals
43        self.assertEqual(self.s._port, PORT)
44        # test on the fly change
45        self.s.open()
46        self.assertTrue(self.s.isOpen())
47
48    def test_DoubleOpen(self):
49        self.s.open()
50        # calling open for a second time is an error
51        self.assertRaises(serial.SerialException, self.s.open)
52
53    def test_BaudrateSetting(self):
54        self.s.open()
55        for baudrate in (300, 9600, 19200, 115200):
56            self.s.baudrate = baudrate
57            # test get method
58            self.assertEqual(self.s.baudrate, baudrate)
59            # test internals
60            self.assertEqual(self.s._baudrate, baudrate)
61        # test illegal values
62        for illegal_value in (-300, -1, 'a', None):
63            self.assertRaises(ValueError, setattr, self.s, 'baudrate', illegal_value)
64
65    # skip this test as pyserial now tries to set even non standard baud rates.
66    # therefore the test can not choose a value that fails on any system.
67    def disabled_test_BaudrateSetting2(self):
68        # test illegal values, depending on machine/port some of these may be valid...
69        self.s.open()
70        for illegal_value in (500000, 576000, 921600, 92160):
71            self.assertRaises(ValueError, setattr, self.s, 'baudrate', illegal_value)
72
73    def test_BytesizeSetting(self):
74        for bytesize in (5, 6, 7, 8):
75            self.s.bytesize = bytesize
76            # test get method
77            self.assertEqual(self.s.bytesize, bytesize)
78            # test internals
79            self.assertEqual(self.s._bytesize, bytesize)
80        # test illegal values
81        for illegal_value in (0, 1, 3, 4, 9, 10, 'a', None):
82            self.assertRaises(ValueError, setattr, self.s, 'bytesize', illegal_value)
83
84    def test_ParitySetting(self):
85        for parity in (serial.PARITY_NONE, serial.PARITY_EVEN, serial.PARITY_ODD):
86            self.s.parity = parity
87            # test get method
88            self.assertEqual(self.s.parity, parity)
89            # test internals
90            self.assertEqual(self.s._parity, parity)
91        # test illegal values
92        for illegal_value in (0, 57, 'a', None):
93            self.assertRaises(ValueError, setattr, self.s, 'parity', illegal_value)
94
95    def test_StopbitsSetting(self):
96        for stopbits in (1, 2):
97            self.s.stopbits = stopbits
98            # test get method
99            self.assertEqual(self.s.stopbits, stopbits)
100            # test internals
101            self.assertEqual(self.s._stopbits, stopbits)
102        # test illegal values
103        for illegal_value in (0, 3, 2.5, 57, 'a', None):
104            self.assertRaises(ValueError, setattr, self.s, 'stopbits', illegal_value)
105
106    def test_TimeoutSetting(self):
107        for timeout in (None, 0, 1, 3.14159, 10, 1000, 3600):
108            self.s.timeout = timeout
109            # test get method
110            self.assertEqual(self.s.timeout, timeout)
111            # test internals
112            self.assertEqual(self.s._timeout, timeout)
113        # test illegal values
114        for illegal_value in (-1, 'a'):
115            self.assertRaises(ValueError, setattr, self.s, 'timeout', illegal_value)
116
117    def test_XonXoffSetting(self):
118        for xonxoff in (True, False):
119            self.s.xonxoff = xonxoff
120            # test get method
121            self.assertEqual(self.s.xonxoff, xonxoff)
122            # test internals
123            self.assertEqual(self.s._xonxoff, xonxoff)
124        # no illegal values here, normal rules for the boolean value of an
125        # object are used thus all objects have a truth value.
126
127    def test_RtsCtsSetting(self):
128        for rtscts in (True, False):
129            self.s.rtscts = rtscts
130            # test get method
131            self.assertEqual(self.s.rtscts, rtscts)
132            # test internals
133            self.assertEqual(self.s._rtscts, rtscts)
134        # no illegal values here, normal rules for the boolean value of an
135        # object are used thus all objects have a truth value.
136
137    # this test does not work anymore since serial_for_url that is used
138    # now, already sets a port
139    def disabled_test_UnconfiguredPort(self):
140        # an unconfigured port cannot be opened
141        self.assertRaises(serial.SerialException, self.s.open)
142
143    def test_PortOpenClose(self):
144        for i in range(3):
145            # open the port and check flag
146            self.assertTrue(not self.s.isOpen())
147            self.s.open()
148            self.assertTrue(self.s.isOpen())
149            self.s.close()
150            self.assertTrue(not self.s.isOpen())
151
152
153if __name__ == '__main__':
154    import sys
155    sys.stdout.write(__doc__)
156    if len(sys.argv) > 1:
157        PORT = sys.argv[1]
158    sys.stdout.write("Testing port: {!r}\n".format(PORT))
159    sys.argv[1:] = ['-v']
160    # When this module is executed from the command-line, it runs all its tests
161    unittest.main()
162