Skip to content

Commit

Permalink
Merge pull request #32 from codecov/pr32
Browse files Browse the repository at this point in the history
create test_utils crate to house all fixtures and reusable helpers
  • Loading branch information
matt-codecov authored Sep 9, 2024
2 parents 79dfe5a + 5feb70f commit 5fefe51
Show file tree
Hide file tree
Showing 16 changed files with 128 additions and 56 deletions.
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[workspace]

resolver = "2"
members = ["bindings", "core"]
members = ["bindings", "core", "test_utils"]
default-members = ["core"]

[profile.release]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,5 @@ $ pytest

Run benchmarks with:
```
$ cargo bench
$ cargo bench --features testing
```
3 changes: 3 additions & 0 deletions codecov.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
comment:
layout: "condensed_header, diff, condensed_files, components, condensed_footer"

ignore:
- "test_utils/"

coverage:
status:
project:
Expand Down
1 change: 1 addition & 0 deletions core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ winnow = "0.5.34"
[dev-dependencies]
divan = "0.1.14"
tempfile = "3.9.0"
test_utils = { path = "../test_utils" }

[[bench]]
name = "pyreport"
Expand Down
39 changes: 19 additions & 20 deletions core/benches/pyreport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use codecov_rs::{
report::test::{TestReport, TestReportBuilder},
};
use divan::Bencher;
use test_utils::fixtures::{read_fixture, FixtureFormat::Pyreport, FixtureSize::Large};
use winnow::Parser as _;

// #[global_allocator]
Expand Down Expand Up @@ -32,9 +33,12 @@ fn simple_report_json() {
#[divan::bench]
fn complex_report_json(bencher: Bencher) {
// this is a ~11M `report_json`
let report = load_fixture(
"pyreport/large/worker-c71ddfd4cb1753c7a540e5248c2beaa079fc3341-report_json.json",
);
let report = read_fixture(
Pyreport,
Large,
"worker-c71ddfd4cb1753c7a540e5248c2beaa079fc3341-report_json.json",
)
.unwrap();

bencher.bench(|| parse_report_json(&report));
}
Expand Down Expand Up @@ -69,14 +73,21 @@ fn simple_chunks() {
#[divan::bench(sample_count = 1)]
fn complex_chunks(bencher: Bencher) {
// this is a ~96M `chunks` file
let chunks =
load_fixture("pyreport/large/worker-c71ddfd4cb1753c7a540e5248c2beaa079fc3341-chunks.txt");
let chunks = read_fixture(
Pyreport,
Large,
"worker-c71ddfd4cb1753c7a540e5248c2beaa079fc3341-chunks.txt",
)
.unwrap();
let chunks = std::str::from_utf8(&chunks).unwrap();

// parsing the chunks depends on having loaded the `report_json`
let report = load_fixture(
"pyreport/large/worker-c71ddfd4cb1753c7a540e5248c2beaa079fc3341-report_json.json",
);
let report = read_fixture(
Pyreport,
Large,
"worker-c71ddfd4cb1753c7a540e5248c2beaa079fc3341-report_json.json",
)
.unwrap();
let report_json::ParsedReportJson { files, sessions } = parse_report_json(&report);

bencher.bench(|| parse_chunks_file(chunks, files.clone(), sessions.clone()));
Expand All @@ -95,15 +106,3 @@ fn parse_chunks_file(input: &str, files: HashMap<usize, i64>, sessions: HashMap<
.parse_next(&mut chunks_stream)
.unwrap();
}

#[track_caller]
fn load_fixture(path: &str) -> Vec<u8> {
let path = format!("./fixtures/{path}");
let contents = std::fs::read(path).unwrap();

if contents.starts_with(b"version https://git-lfs.github.com/spec/v1") {
panic!("Fixture has not been pulled from Git LFS");
}

contents
}
12 changes: 0 additions & 12 deletions core/tests/common/mod.rs

This file was deleted.

35 changes: 13 additions & 22 deletions core/tests/test_pyreport_shim.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
use std::{
collections::HashMap,
fs::File,
io::Seek,
path::{Path, PathBuf},
};
use std::{collections::HashMap, fs::File, io::Seek, path::PathBuf};

use codecov_rs::{
parsers::pyreport::{
Expand All @@ -17,10 +12,11 @@ use codecov_rs::{
use rand::{rngs::StdRng, Rng, SeedableRng};
use serde_json::json;
use tempfile::TempDir;
use test_utils::fixtures::{
open_fixture, read_fixture, FixtureFormat::Pyreport, FixtureSize::Small,
};
use winnow::Parser;

mod common;

type ChunksStream<'a> = chunks::ReportOutputStream<&'a str, SqliteReport, SqliteReportBuilder>;

struct Ctx {
Expand All @@ -37,7 +33,7 @@ fn setup() -> Ctx {

#[test]
fn test_parse_report_json() {
let input = common::read_sample_file(Path::new("codecov-rs-reports-json-d2a9ba1.txt"));
let input = read_fixture(Pyreport, Small, "codecov-rs-reports-json-d2a9ba1.txt").unwrap();

let rng_seed = 5;
let mut rng = StdRng::seed_from_u64(rng_seed);
Expand Down Expand Up @@ -79,8 +75,7 @@ fn test_parse_report_json() {
let ParsedReportJson {
files: actual_files,
sessions: actual_sessions,
} = report_json::parse_report_json(input.as_bytes(), &mut report_builder)
.expect("Failed to parse");
} = report_json::parse_report_json(&input, &mut report_builder).expect("Failed to parse");
assert_eq!(actual_files, expected_json_files);
assert_eq!(actual_sessions, expected_json_sessions);

Expand All @@ -98,7 +93,8 @@ fn test_parse_report_json() {

#[test]
fn test_parse_chunks_file() {
let input = common::read_sample_file(Path::new("codecov-rs-chunks-d2a9ba1.txt"));
let input = read_fixture(Pyreport, Small, "codecov-rs-chunks-d2a9ba1.txt").unwrap();
let input = std::str::from_utf8(&input).unwrap();
let test_ctx = setup();

let mut report_builder = SqliteReportBuilder::new(test_ctx.db_file).unwrap();
Expand Down Expand Up @@ -132,7 +128,7 @@ fn test_parse_chunks_file() {
);

let mut buf = ChunksStream {
input: &input,
input,
state: chunks_parse_ctx,
};

Expand Down Expand Up @@ -210,10 +206,8 @@ fn test_parse_chunks_file() {
#[test]
fn test_parse_pyreport() {
let report_json_file =
File::open(common::sample_data_path().join("codecov-rs-reports-json-d2a9ba1.txt"))
.expect("Failed to open report json file");
let chunks_file = File::open(common::sample_data_path().join("codecov-rs-chunks-d2a9ba1.txt"))
.expect("Failed to open chunks file");
open_fixture(Pyreport, Small, "codecov-rs-reports-json-d2a9ba1.txt").unwrap();
let chunks_file = open_fixture(Pyreport, Small, "codecov-rs-chunks-d2a9ba1.txt").unwrap();
let test_ctx = setup();

let rng_seed = 5;
Expand Down Expand Up @@ -318,11 +312,8 @@ fn test_parse_pyreport() {
#[test]
fn test_sql_to_pyreport_to_sql_totals_match() {
let report_json_input_file =
File::open(common::sample_data_path().join("codecov-rs-reports-json-d2a9ba1.txt"))
.expect("Failed to open report json file");
let chunks_input_file =
File::open(common::sample_data_path().join("codecov-rs-chunks-d2a9ba1.txt"))
.expect("Failed to open chunks file");
open_fixture(Pyreport, Small, "codecov-rs-reports-json-d2a9ba1.txt").unwrap();
let chunks_input_file = open_fixture(Pyreport, Small, "codecov-rs-chunks-d2a9ba1.txt").unwrap();
let test_ctx = setup();

let report = pyreport::parse_pyreport(
Expand Down
10 changes: 10 additions & 0 deletions test_utils/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[package]
name = "test_utils"
version = "0.1.0"
publish = false
edition = "2021"

[lib]
name = "test_utils"

[dependencies]
File renamed without changes.
74 changes: 74 additions & 0 deletions test_utils/src/fixtures.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use std::{
fmt,
fs::File,
io::{Read, Seek},
path::PathBuf,
};

#[derive(Copy, Clone)]
pub enum FixtureFormat {
Pyreport,
}

impl fmt::Display for FixtureFormat {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FixtureFormat::Pyreport => write!(f, "pyreport"),
}
}
}

#[derive(Copy, Clone)]
pub enum FixtureSize {
Large,
Small,
}

impl fmt::Display for FixtureSize {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FixtureSize::Large => write!(f, "large"),
FixtureSize::Small => write!(f, ""),
}
}
}

fn fixture_dir(format: FixtureFormat, size: FixtureSize) -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("fixtures")
.join(format.to_string())
.join(size.to_string())
}

#[track_caller]
pub fn open_fixture(
format: FixtureFormat,
size: FixtureSize,
name: &str,
) -> Result<File, &'static str> {
let path = fixture_dir(format, size).join(name);
let mut file = File::open(path).map_err(|_| "failed to open file")?;

let mut buf = [0; 50];
file.read(&mut buf)
.map_err(|_| "failed to read beginning of file")?;
if buf.starts_with(b"version https://git-lfs.github.com/spec/v1") {
Err("fixture has not been pulled from Git LFS")
} else {
file.rewind().unwrap();
Ok(file)
}
}

pub fn read_fixture(
format: FixtureFormat,
size: FixtureSize,
name: &str,
) -> Result<Vec<u8>, &'static str> {
// Just make sure the file exists and that it has been pulled from Git LFS
let _file = open_fixture(format, size, name)?;

// Actually read and return the contents
let path = fixture_dir(format, size).join(name);
std::fs::read(path).map_err(|_| "failed to read file")
}
1 change: 1 addition & 0 deletions test_utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod fixtures;

0 comments on commit 5fefe51

Please sign in to comment.