Created
January 29, 2018 06:09
-
-
Save jwmcglynn/095fdb904e77cf2952736167bc544347 to your computer and use it in GitHub Desktop.
The tests below expose a bug/limitation of the Xmodem template code provided for CS140E assignment1.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! | |
//! To fix this, the only byte that should handle a CAN is the packet receive response, which can be ACK, NAK, and CAN. | |
//! My fix for this required changing expect_byte, expect_byte_or_cancel, and read_byte. | |
/// Test sending a packet containing control characters, it should be received | |
/// intact. | |
#[test] | |
fn test_read_packet_control_characters() { | |
use std::io::{Read, Write}; | |
let (mut tx, rx) = pipe(); | |
let mut xmodem = Xmodem::new(rx); | |
let mut source_packet = [0u8; 128]; | |
source_packet[0..5].copy_from_slice(&[SOH, EOT, ACK, NAK, CAN]); | |
let checksum: u8 = source_packet.iter().fold(0, |acc, &x| { | |
acc.wrapping_add(x) | |
}); | |
tx.write(&[SOH, 1, 254]).expect("header"); | |
tx.write(&source_packet).expect("packet"); | |
tx.write(&[checksum]).expect("checksum"); | |
let mut dest_packet = [0u8; 128]; | |
xmodem.read_packet(&mut dest_packet).expect("read packet"); | |
assert_eq!(&dest_packet[..], &source_packet[..]); | |
// We should get the NAK to indicate start of transmission, and then an ACK | |
// to indicate success. | |
let mut response = [0u8; 2]; | |
tx.read(&mut response).expect("response"); | |
assert_eq!(&response[..], &[NAK, ACK]); | |
} | |
/// Test sending with CAN as a checksum. | |
#[test] | |
fn test_read_packet_checksum_can() { | |
use std::io::{Read, Write}; | |
let (mut tx, rx) = pipe(); | |
let mut xmodem = Xmodem::new(rx); | |
let mut source_packet = [0u8; 128]; | |
source_packet[0] = CAN; | |
tx.write(&[SOH, 1, 254]).expect("header"); | |
tx.write(&source_packet).expect("packet"); | |
tx.write(&[CAN]).expect("checksum"); | |
let mut dest_packet = [0u8; 128]; | |
xmodem.read_packet(&mut dest_packet).expect("read packet"); | |
assert_eq!(&dest_packet[..], &source_packet[..]); | |
// We should get the NAK to indicate start of transmission, and then an ACK | |
// to indicate success. | |
let mut response = [0u8; 2]; | |
tx.read(&mut response).expect("response"); | |
assert_eq!(&response[..], &[NAK, ACK]); | |
} | |
/// Test large packet numbers and wrapping. | |
#[test] | |
fn test_read_packet_numbers() { | |
use std::io::{Read, Write}; | |
let (mut tx, rx) = pipe(); | |
let mut xmodem = Xmodem::new(rx); | |
let mut started = false; | |
for x in 1..512 { | |
let mut source_packet = [0u8; 128]; | |
let packet_number: u8 = x as u8; | |
tx.write(&[SOH, packet_number, (255 - packet_number)]).expect("header"); | |
tx.write(&source_packet).expect("packet"); | |
tx.write(&[0]).expect("checksum"); | |
let mut dest_packet = [0u8; 128]; | |
xmodem.read_packet(&mut dest_packet).expect("read packet"); | |
assert_eq!(&dest_packet[..], &source_packet[..]); | |
if !started { | |
started = true; | |
let mut start = [0u8; 1]; | |
tx.read(&mut start).expect("start"); | |
assert_eq!(&start[..], &[NAK]); | |
} | |
// We should get an ACK to indicate success. | |
let mut ack = [0u8; 1]; | |
tx.read(&mut ack).expect("ack"); | |
assert_eq!(&ack[..], &[ACK]); | |
} | |
// Don't validate the rest it's handled by test_read_packet. | |
} | |
/// Test sending a packet containing control characters, it should be received | |
/// intact. | |
#[test] | |
fn test_write_packet_control_characters() { | |
use std::io::{Read, Write}; | |
let (tx, mut rx) = pipe(); | |
let mut xmodem = Xmodem::new(tx); | |
// All the bytes sent from the receiver->transmitter, including start | |
// of transmission, packet ack, and EOT sequence response. | |
rx.write(&[NAK, ACK, NAK, ACK]).expect("responses"); | |
let mut source_packet = [0u8; 128]; | |
source_packet[0..5].copy_from_slice(&[SOH, EOT, ACK, NAK, CAN]); | |
xmodem.write_packet(&source_packet).expect("write packet"); | |
xmodem.write_packet(&[]).expect("transmission end"); | |
let mut header = [0u8; 3]; | |
rx.read(&mut header).expect("read header"); | |
assert_eq!(&header[..], &[SOH, 1, 254]); | |
let mut dest_packet = [0u8; 128]; | |
rx.read(&mut dest_packet).expect("read packet"); | |
assert_eq!(&dest_packet[..], &source_packet[..]); | |
// Don't validate the rest of the data, that is tested in test_write_packet. | |
} | |
// Test writing large packet numbers and wrapping. | |
#[test] | |
fn test_write_packet_numbers() { | |
use std::io::{Read, Write}; | |
let (tx, mut rx) = pipe(); | |
let mut xmodem = Xmodem::new(tx); | |
// All the bytes sent from the receiver->transmitter, including start | |
// of transmission, packet ack, and EOT sequence response. | |
rx.write(&[NAK]).expect("start"); | |
for x in 1..512 { | |
rx.write(&[ACK]).expect("packet ack"); | |
let mut source_packet = [0u8; 128]; | |
xmodem.write_packet(&source_packet).expect("write packet"); | |
let mut header = [0u8; 3]; | |
rx.read(&mut header).expect("read header"); | |
let packet_number: u8 = x as u8; | |
assert_eq!(&header[..], &[SOH, packet_number as u8, (255 - packet_number) as u8]); | |
let mut dest_packet = [0u8; 128]; | |
rx.read(&mut dest_packet).expect("read packet"); | |
assert_eq!(&dest_packet[..], &source_packet[..]); | |
let mut checksum = [0u8; 1]; | |
rx.read(&mut checksum).expect("read checksum"); | |
} | |
// Don't validate the rest, that's handled by test_write_packet. | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment