File: test_tty.rs

package info (click to toggle)
rust-serialport 4.8.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 844 kB
  • sloc: makefile: 2
file content (162 lines) | stat: -rw-r--r-- 5,596 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//! Tests for the `posix::TTYPort` struct.
#![cfg(unix)]

extern crate serialport;

use std::io::{Read, Write};
use std::os::unix::prelude::*;
use std::str;
use std::time::Duration;

use serialport::{SerialPort, TTYPort};

#[test]
fn test_ttyport_pair() {
    // FIXME: Create a mutex across all tests for using `TTYPort::pair()` as it's not threadsafe
    let (mut master, mut slave) = TTYPort::pair().expect("Unable to create ptty pair");
    master
        .set_timeout(Duration::from_millis(10))
        .expect("Unable to set timeout on the master");
    slave
        .set_timeout(Duration::from_millis(10))
        .expect("Unable to set timeout on the slave");

    // Test file descriptors.
    assert!(
        master.as_raw_fd() > 0,
        "Invalid file descriptor on master ptty"
    );
    assert!(
        slave.as_raw_fd() > 0,
        "Invalid file descriptor on slae ptty"
    );
    assert_ne!(
        master.as_raw_fd(),
        slave.as_raw_fd(),
        "master and slave ptty's share the same file descriptor."
    );

    let msg = "Test Message";
    let mut buf = [0u8; 128];

    // Write the string on the master
    let nbytes = master
        .write(msg.as_bytes())
        .expect("Unable to write bytes.");
    assert_eq!(
        nbytes,
        msg.len(),
        "Write message length differs from sent message."
    );

    // Read it on the slave
    let nbytes = slave.read(&mut buf).expect("Unable to read bytes.");
    assert_eq!(
        nbytes,
        msg.len(),
        "Read message length differs from sent message."
    );

    assert_eq!(
        str::from_utf8(&buf[..nbytes]).unwrap(),
        msg,
        "Received message does not match sent"
    );
}

#[test]
fn test_ttyport_timeout() {
    let result = std::sync::Arc::new(std::sync::Mutex::new(None));
    let result_thread = result.clone();

    std::thread::spawn(move || {
        // FIXME: Create a mutex across all tests for using `TTYPort::pair()` as it's not threadsafe
        let (mut master, _slave) = TTYPort::pair().expect("Unable to create ptty pair");
        master.set_timeout(Duration::new(1, 0)).unwrap();

        let mut buffer = [0u8];
        let read_res = master.read(&mut buffer);

        *result_thread.lock().unwrap() = Some(read_res);
    });

    std::thread::sleep(std::time::Duration::new(2, 0));

    let read_res = result.lock().unwrap();
    match *read_res {
        Some(Ok(_)) => panic!("Received data without sending"),
        Some(Err(ref e)) => assert_eq!(e.kind(), std::io::ErrorKind::TimedOut),
        None => panic!("Read did not time out"),
    }
}

#[test]
#[cfg(any(target_os = "ios", target_os = "macos"))]
fn test_osx_pty_pair() {
    #![allow(unused_variables)]
    let (mut master, slave) = TTYPort::pair().expect("Unable to create ptty pair");
    let (output_sink, output_stream) = std::sync::mpsc::sync_channel(1);
    let name = slave.name().unwrap();

    master.write_all("12".as_bytes()).expect("");

    let reader_thread = std::thread::spawn(move || {
        let mut port = TTYPort::open(&serialport::new(&name, 0)).expect("unable to open");
        let mut buffer = [0u8; 2];
        let amount = port.read_exact(&mut buffer);
        output_sink
            .send(String::from_utf8(buffer.to_vec()).expect("buffer not read as valid utf-8"))
            .expect("unable to send from thread");
    });

    reader_thread.join().expect("unable to join sink thread");
    assert_eq!(output_stream.recv().unwrap(), "12");
}

// On Mac this should work (in fact used to in b77768a) but now fails. It's not functionality that
// should be required, and the ptys work otherwise. So going to just disable this test instead.
#[test]
#[cfg_attr(any(target_os = "ios", target_os = "macos"), ignore)]
fn test_ttyport_set_standard_baud() {
    // `master` must be used here as Dropping it causes slave to be deleted by the OS.
    // TODO: Convert this to a statement-level attribute once
    //       https://github.com/rust-lang/rust/issues/15701 is on stable.
    // FIXME: Create a mutex across all tests for using `TTYPort::pair()` as it's not threadsafe
    #![allow(unused_variables)]
    let (master, mut slave) = TTYPort::pair().expect("Unable to create ptty pair");

    slave.set_baud_rate(9600).unwrap();
    assert_eq!(slave.baud_rate().unwrap(), 9600);
    slave.set_baud_rate(57600).unwrap();
    assert_eq!(slave.baud_rate().unwrap(), 57600);
    slave.set_baud_rate(115_200).unwrap();
    assert_eq!(slave.baud_rate().unwrap(), 115_200);
}

// On mac this fails because you can't set nonstandard baud rates for these virtual ports
#[test]
#[cfg_attr(
    any(
        target_os = "ios",
        all(target_os = "linux", target_env = "musl"),
        target_arch="powerpc",
        target_arch="powerpc64",
        target_os = "macos"
    ),
    ignore
)]
fn test_ttyport_set_nonstandard_baud() {
    // `master` must be used here as Dropping it causes slave to be deleted by the OS.
    // TODO: Convert this to a statement-level attribute once
    //       https://github.com/rust-lang/rust/issues/15701 is on stable.
    // FIXME: Create a mutex across all tests for using `TTYPort::pair()` as it's not threadsafe
    #![allow(unused_variables)]
    let (master, mut slave) = TTYPort::pair().expect("Unable to create ptty pair");

    slave.set_baud_rate(10000).unwrap();
    assert_eq!(slave.baud_rate().unwrap(), 10000);
    slave.set_baud_rate(60000).unwrap();
    assert_eq!(slave.baud_rate().unwrap(), 60000);
    slave.set_baud_rate(1_200_000).unwrap();
    assert_eq!(slave.baud_rate().unwrap(), 1_200_000);
}