Skip to content

Commit

Permalink
feat: add junit support (#54)
Browse files Browse the repository at this point in the history
* feat: add junit support

Signed-off-by: Alex Chi <iskyzh@gmail.com>

* bump to 0.5.3

Signed-off-by: Alex Chi <iskyzh@gmail.com>
  • Loading branch information
skyzh authored Jun 26, 2022
1 parent b197296 commit d42eae2
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
with:
command: test
args: --no-fail-fast --all-features
- name: Run all examples
- name: Run examples
run: |
for example in examples/*.rs
do
Expand Down
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.5.3] - 2022-06-26

### Added

- Add junit support. Use `--junit <filename>` to generate junit xml.


## [0.5.2] - 2022-06-16

### Fixed
Expand Down
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "sqllogictest"
version = "0.5.2"
version = "0.5.3"
edition = "2021"
description = "Sqllogictest parser and runner."
license = "MIT OR Apache-2.0"
Expand All @@ -11,7 +11,7 @@ keywords = ["sql", "database", "parser", "cli"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[features]
bin = ["anyhow", "console", "tokio-postgres", "env_logger", "clap", "tokio", "futures"]
bin = ["anyhow", "console", "tokio-postgres", "env_logger", "clap", "tokio", "futures", "quick-junit"]

[dependencies]
anyhow = { version = "1", optional = true }
Expand All @@ -26,6 +26,7 @@ glob = "0.3"
humantime = "2"
itertools = "0.10"
log = "0.4"
quick-junit = { version = "0.2", optional = true }
tempfile = "3"
thiserror = "1"
tokio = { version = "1", features = [
Expand Down
81 changes: 63 additions & 18 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ use std::collections::BTreeMap;
use std::io::{stdout, Write};
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::time::Instant;
use std::time::{Duration, Instant};

use anyhow::{anyhow, Context, Result};
use async_trait::async_trait;
use clap::{ArgEnum, Parser};
use console::style;
use futures::StreamExt;
use itertools::Itertools;
use quick_junit::{NonSuccessKind, Report, TestCase, TestCaseStatus, TestSuite};
use sqllogictest::{Control, Record, TestErrorKind};

#[derive(Copy, Clone, Debug, PartialEq, ArgEnum)]
Expand Down Expand Up @@ -58,6 +59,7 @@ struct Opt {
#[clap(short = 'w', long, default_value = "postgres")]
pass: String,

/// Whether to enable colorful output.
#[clap(
long,
arg_enum,
Expand All @@ -71,6 +73,10 @@ struct Opt {
/// database will be created for each test file.
#[clap(long, short)]
jobs: Option<usize>,

/// Report to junit XML.
#[clap(long)]
junit: Option<String>,
}

#[tokio::main]
Expand Down Expand Up @@ -120,7 +126,14 @@ async fn main() -> Result<()> {
return Err(anyhow!("no test case found"));
}

if let Some(job) = &opt.jobs {
let mut report = Report::new(
opt.junit
.clone()
.unwrap_or_else(|| "sqllogictest".to_string()),
);
let mut test_suite = TestSuite::new("sqllogictest");

let result = if let Some(job) = &opt.jobs {
let mut create_databases = BTreeMap::new();
for file in files {
let db_name = file
Expand Down Expand Up @@ -170,11 +183,20 @@ async fn main() -> Result<()> {
let start = Instant::now();

while let Some((file, res, mut buf)) = stream.next().await {
if let Err(e) = res {
writeln!(buf, "{}\n\n{:?}", style("[FAILED]").red().bold(), e)?;
writeln!(buf)?;
failed_case.push(file);
}
let case = match res {
Ok(duration) => {
let mut case = TestCase::new(file, TestCaseStatus::success());
case.set_time(duration);
case
}
Err(e) => {
writeln!(buf, "{}\n\n{:?}", style("[FAILED]").red().bold(), e)?;
writeln!(buf)?;
failed_case.push(file.clone());
TestCase::new(file, TestCaseStatus::non_success(NonSuccessKind::Failure))
}
};
test_suite.add_test_case(case);
tokio::task::block_in_place(|| stdout().write_all(&buf))?;
}

Expand All @@ -184,7 +206,7 @@ async fn main() -> Result<()> {
);

if !failed_case.is_empty() {
Err(anyhow!("some test case failed:\n{:#?}", failed_case))
return Err(anyhow!("some test case failed:\n{:#?}", failed_case));
} else {
Ok(())
}
Expand All @@ -194,19 +216,40 @@ async fn main() -> Result<()> {
let mut failed_case = vec![];

for file in files {
if let Err(e) = run_test_file(&mut std::io::stdout(), pg.clone(), &file).await {
println!("{}\n\n{:?}", style("[FAILED]").red().bold(), e);
println!();
failed_case.push(file.to_string_lossy().to_string());
}
let filename = file.to_string_lossy().to_string();
let case = match run_test_file(&mut std::io::stdout(), pg.clone(), &file).await {
Ok(duration) => {
let mut case = TestCase::new(filename, TestCaseStatus::success());
case.set_time(duration);
case
}
Err(e) => {
println!("{}\n\n{:?}", style("[FAILED]").red().bold(), e);
println!();
failed_case.push(filename.clone());
TestCase::new(
filename,
TestCaseStatus::non_success(NonSuccessKind::Failure),
)
}
};
test_suite.add_test_case(case);
}

if !failed_case.is_empty() {
Err(anyhow!("some test case failed:\n{:#?}", failed_case))
} else {
Ok(())
}
};

report.add_test_suite(test_suite);

if let Some(junit_file) = opt.junit {
tokio::fs::write(format!("{}-junit.xml", junit_file), report.to_string()?).await?;
}

result
}

async fn flush(out: &mut impl std::io::Write) -> std::io::Result<()> {
Expand All @@ -218,7 +261,7 @@ async fn run_test_file_on_db(
filename: PathBuf,
db_name: String,
opt: Opt,
) -> Result<()> {
) -> Result<Duration> {
let (client, connection) = tokio_postgres::Config::new()
.host(&opt.host)
.port(opt.port)
Expand All @@ -240,18 +283,18 @@ async fn run_test_file_on_db(
engine_name: opt.engine.clone(),
};

run_test_file(out, pg, filename).await?;
let result = run_test_file(out, pg, filename).await?;

handle.abort();

Ok(())
Ok(result)
}

async fn run_test_file<T: std::io::Write>(
out: &mut T,
engine: Postgres,
filename: impl AsRef<Path>,
) -> Result<()> {
) -> Result<Duration> {
let filename = filename.as_ref();
let mut runner = sqllogictest::Runner::new(engine);
let records = tokio::task::block_in_place(|| {
Expand Down Expand Up @@ -341,6 +384,8 @@ async fn run_test_file<T: std::io::Write>(
))?;
}

let duration = begin_times[0].elapsed();

finish(
out,
&mut begin_times,
Expand All @@ -350,7 +395,7 @@ async fn run_test_file<T: std::io::Write>(

writeln!(out)?;

Ok(())
Ok(duration)
}

#[derive(Clone)]
Expand Down
3 changes: 2 additions & 1 deletion src/parser.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
//! Sqllogictest parser.
use crate::ParseErrorKind::InvalidIncludeFile;
use std::fmt;
use std::path::Path;
use std::sync::Arc;
use std::time::Duration;

use crate::ParseErrorKind::InvalidIncludeFile;

/// The location in source file.
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct Location {
Expand Down

0 comments on commit d42eae2

Please sign in to comment.