feat(es/transforms/testing): Reduce CI time by caching execution result (#2565)

swc_ecma_transforms_testing:
 - Cache execution test result on CI.
This commit is contained in:
Donny/강동윤 2021-10-28 13:00:25 +09:00 committed by GitHub
parent 7e29685a17
commit 0364f9a2ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 78 additions and 45 deletions

View File

@ -16,6 +16,7 @@ env:
CI: 1
CARGO_INCREMENTAL: 0
RUST_LOG: "debug"
SWC_CACHE_TEST: 1
jobs:
check-license:

4
Cargo.lock generated
View File

@ -2965,12 +2965,14 @@ dependencies = [
[[package]]
name = "swc_ecma_transforms_testing"
version = "0.42.0"
version = "0.42.1"
dependencies = [
"ansi_term 0.12.1",
"anyhow",
"hex",
"serde",
"serde_json",
"sha-1",
"swc_common",
"swc_ecma_ast",
"swc_ecma_codegen",

View File

@ -7,6 +7,7 @@
"ahash",
"anonymized",
"ANONYMIZED",
"ansi",
"Ansi",
"armv",
"arrayvec",

View File

@ -6,15 +6,17 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "swc_ecma_transforms_testing"
repository = "https://github.com/swc-project/swc.git"
version = "0.42.0"
version = "0.42.1"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
ansi_term = "0.12.1"
anyhow = "1"
hex = "0.4.3"
serde = "1"
serde_json = "1"
sha-1 = "0.9.8"
swc_common = {version = "0.14.0", path = "../../../common"}
swc_ecma_ast = {version = "0.56.0", path = "../../ast"}
swc_ecma_codegen = {version = "0.78.0", path = "../../codegen"}

View File

@ -1,9 +1,10 @@
use ansi_term::Color;
use anyhow::{bail, Context, Error};
use serde::de::DeserializeOwned;
use sha1::{Digest, Sha1};
use std::{
env,
fs::{create_dir_all, read_to_string, OpenOptions},
fs::{self, create_dir_all, read_to_string, OpenOptions},
io::{self, Write},
mem::{replace, take},
path::Path,
@ -380,7 +381,7 @@ where
let src_without_helpers = tester.print(&module, &tester.comments.clone());
module = module.fold_with(&mut inject_helpers());
let transfomred_src = tester.print(&module, &tester.comments.clone());
let transfromed_src = tester.print(&module, &tester.comments.clone());
println!(
"\t>>>>> Orig <<<<<\n{}\n\t>>>>> Code <<<<<\n{}",
@ -391,7 +392,7 @@ where
println!("\t>>>>> Expected stdout <<<<<\n{}", expected);
let actual = stdout_of(&transfomred_src).unwrap();
let actual = stdout_of(&transfromed_src).unwrap();
assert_eq!(expected, actual);
@ -438,57 +439,83 @@ where
module = module.fold_with(&mut inject_helpers());
let src = tester.print(&module, &tester.comments.clone());
let root = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("target")
.join("testing")
.join(test_name);
create_dir_all(&root).expect("failed to create parent directory for temp directory");
let tmp_dir = tempdir_in(&root).expect("failed to create a temp directory");
create_dir_all(&tmp_dir).unwrap();
let path = tmp_dir.path().join(format!("{}.test.js", test_name));
let mut tmp = OpenOptions::new()
.create(true)
.write(true)
.open(&path)
.expect("failed to create a temp file");
write!(tmp, "{}", src).expect("failed to write to temp file");
tmp.flush().unwrap();
println!(
"\t>>>>> Orig <<<<<\n{}\n\t>>>>> Code <<<<<\n{}",
input, src_without_helpers
);
let jest_path = find_executable("jest").expect("failed to find `jest` from path");
exec_with_jest(test_name, &src)
})
}
let mut base_cmd = if cfg!(target_os = "windows") {
let mut c = Command::new("cmd");
c.arg("/C").arg(&jest_path);
c
} else {
Command::new(&jest_path)
};
fn calc_hash(s: &str) -> String {
let mut hasher = Sha1::new();
hasher.update(s.as_bytes());
let sum = hasher.finalize();
// I hate windows.
if cfg!(target_os = "windows") && env::var("CI").is_ok() {
base_cmd.arg("--passWithNoTests");
}
hex::encode(sum)
}
let status = base_cmd
.args(&["--testMatch", &format!("{}", path.display())])
.current_dir(root)
.status()
.expect("failed to run jest");
if status.success() {
fn exec_with_jest(test_name: &str, src: &str) -> Result<(), ()> {
let root = Path::new(env!("CARGO_MANIFEST_DIR"))
.join("target")
.join("testing")
.join(test_name);
create_dir_all(&root).expect("failed to create parent directory for temp directory");
let hash = calc_hash(src);
let success_cache = root.join(format!("{}.success", hash));
if env::var("SWC_CACHE_TEST").unwrap_or_default() == "1" {
println!("Trying cache as `SWC_CACHE_TEST` is `1`");
if success_cache.exists() {
println!("Cache: success");
return Ok(());
}
::std::mem::forget(tmp_dir);
panic!("Execution failed")
})
}
let tmp_dir = tempdir_in(&root).expect("failed to create a temp directory");
create_dir_all(&tmp_dir).unwrap();
let path = tmp_dir.path().join(format!("{}.test.js", test_name));
let mut tmp = OpenOptions::new()
.create(true)
.write(true)
.open(&path)
.expect("failed to create a temp file");
write!(tmp, "{}", src).expect("failed to write to temp file");
tmp.flush().unwrap();
let jest_path = find_executable("jest").expect("failed to find `jest` from path");
let mut base_cmd = if cfg!(target_os = "windows") {
let mut c = Command::new("cmd");
c.arg("/C").arg(&jest_path);
c
} else {
Command::new(&jest_path)
};
// I hate windows.
if cfg!(target_os = "windows") && env::var("CI").is_ok() {
base_cmd.arg("--passWithNoTests");
}
let status = base_cmd
.args(&["--testMatch", &format!("{}", path.display())])
.current_dir(root)
.status()
.expect("failed to run jest");
if status.success() {
fs::write(&success_cache, "").unwrap();
return Ok(());
}
::std::mem::forget(tmp_dir);
panic!("Execution failed")
}
fn stdout_of(code: &str) -> Result<String, Error> {