Skip to content

mtreinish/subunit-rust

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Subunit Rust

subunit-rust CI subunit on crates.io

This repo contains a implementation of the subunit v2 protocol in Rust. It provides an interface for both writing and reading subunit streams natively in rust. The subunit v2 protocol is documented in the testing-cabal/subunit repository.

Reading subunit packets

Reading subunit packets first requires an object implementing the Read trait containing the subunit stream. The iter_stream() function is used to parse the contents and return an iterator of ScannedItem enums. For example, parsing a subunit stream from a file:

    use std::fs::File;
    use subunit::io::sync::iter_stream;
    use subunit::types::stream::ScannedItem;

    let f = File::open("results.subunit")?;
    for item in iter_stream(f) {
        match item? {
            ScannedItem::Event(event) => {
                // Process the event
                println!("Got event: {:?}", event);
            },
            ScannedItem::UTF8chars(text) => {
                // Process text
                println!("Got text: {:?}", text);
            },
            ScannedItem::Unknown(bytes, err) => {
                // Handle unknown data
                eprintln!("Unknown data: {:?}", err);
            },
        }
    }
    # Ok::<(), Box<dyn std::error::Error>>(())

In this example, the results.subunit file will be opened and parsed with a ScannedItem for each packet in the file.

Writing subunit packets

Writing a subunit packet first requires creating an event structure to describe the contents of the packet. The Event API uses a builder pattern for construction. For example:

    use subunit::types::{event::Event, teststatus::TestStatus};
    use chrono::{TimeZone, Utc};

    let event_start = Event::new(TestStatus::InProgress)
        .test_id("A_test_id")
        .datetime(Utc.with_ymd_and_hms(2014, 7, 8, 9, 10, 11).unwrap())?
        .tag("tag_a")
        .tag("tag_b")
        .build();
    # Ok::<(), Box<dyn std::error::Error>>(())

A typical test event normally involves 2 packets though, one to mark the start and the other to mark the finish of a test:

    use subunit::types::{event::Event, teststatus::TestStatus};
    use chrono::{TimeZone, Utc};

    let event_end = Event::new(TestStatus::Success)
        .test_id("A_test_id")
        .datetime(Utc.with_ymd_and_hms(2014, 7, 8, 9, 12, 0).unwrap())?
        .tag("tag_a")
        .tag("tag_b")
        .mime_type("text/plain;charset=utf8")
        .file_content("stdout:''", b"stdout content")
        .build();
    # Ok::<(), Box<dyn std::error::Error>>(())

Then you'll want to write the packet out to something. Anything that implements the std::io::Write trait can be used for the packets, including things like a File and a TCPStream. In this case we'll use Vec to keep it in memory:

    use subunit::serialize::Serializable;
    use subunit::types::{event::Event, teststatus::TestStatus};
    use chrono::{TimeZone, Utc};

    let mut subunit_stream: Vec<u8> = Vec::new();

    let event_start = Event::new(TestStatus::InProgress)
        .test_id("A_test_id")
        .datetime(Utc.with_ymd_and_hms(2014, 7, 8, 9, 10, 11).unwrap())?
        .tag("tag_a")
        .tag("tag_b")
        .build();

    let event_end = Event::new(TestStatus::Success)
        .test_id("A_test_id")
        .datetime(Utc.with_ymd_and_hms(2014, 7, 8, 9, 12, 0).unwrap())?
        .tag("tag_a")
        .tag("tag_b")
        .mime_type("text/plain;charset=utf8")
        .file_content("stdout:''", b"stdout content")
        .build();

    event_start.serialize(&mut subunit_stream)?;
    event_end.serialize(&mut subunit_stream)?;
    # Ok::<(), Box<dyn std::error::Error>>(())

With this the subunit_stream buffer will contain the contents of the subunit stream for that test event.

About

A subunit v2 protocol implementation in Rust

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages