From 675135f5220db9e21eded0e1e75259eac9225e67 Mon Sep 17 00:00:00 2001 From: Jean-Marie 'Histausse' Mineau Date: Fri, 8 Mar 2024 15:29:12 +0100 Subject: [PATCH] add report to tests --- .gitignore | 1 + androscalpel/src/tests/mod.rs | 30 ++++++++++++++++++++-- androscalpel_serializer/src/file_reader.rs | 2 ++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 7c0dd26..5943766 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ *.idsig *.jks /tests +test_repport.txt diff --git a/androscalpel/src/tests/mod.rs b/androscalpel/src/tests/mod.rs index 3ddaa3f..cc6aa5b 100644 --- a/androscalpel/src/tests/mod.rs +++ b/androscalpel/src/tests/mod.rs @@ -3,7 +3,24 @@ use androscalpel_serializer::Instruction as InsFormat; use androscalpel_serializer::*; use std::fs::File; use std::io; -use std::sync::OnceLock; +use std::io::Write; +use std::ops::Deref; +use std::sync::{Mutex, OnceLock}; +use std::time::Instant; + +fn write_to_report(data: &str) { + static REPORT_FILE: Mutex> = Mutex::new(None); + let mut report_file = REPORT_FILE.lock().unwrap(); + let mut report_file = if let Some(report_file) = report_file.deref() { + report_file + } else { + *report_file = Some( + File::create(&format!("{}/test_repport.txt", env!("CARGO_MANIFEST_DIR"),)).unwrap(), + ); + report_file.deref().as_ref().unwrap() + }; + writeln!(report_file, "{data}").unwrap(); +} fn get_dex(filename: &str) -> Vec { let hello_world_dex = format!("{}/src/tests/{}", env!("CARGO_MANIFEST_DIR"), filename); @@ -22,14 +39,23 @@ fn get_hello_world_apk() -> &'static Apk { static HELLO_WORLD_APK: OnceLock = OnceLock::new(); HELLO_WORLD_APK.get_or_init(|| { let mut apk = Apk::new(); + let start = Instant::now(); apk.add_dex_file(get_hello_world_dex()).unwrap(); + let duration = start.elapsed(); + write_to_report(&format!("Parsing classes_hello_world.dex: {duration:?}")); apk }) } fn get_hello_world_recompilled() -> &'static [u8] { static HELLO_WORLD_RECOMP: OnceLock> = OnceLock::new(); - HELLO_WORLD_RECOMP.get_or_init(|| get_hello_world_apk().gen_raw_dex().unwrap().pop().unwrap()) + HELLO_WORLD_RECOMP.get_or_init(|| { + let start = Instant::now(); + let dex = get_hello_world_apk().gen_raw_dex().unwrap().pop().unwrap(); + let duration = start.elapsed(); + write_to_report(&format!("Recompile classes_hello_world.dex: {duration:?}")); + dex + }) } fn get_class_dex<'a, 'b>(name: &'a str, dex: &'b DexFileReader) -> Option<&'b ClassDefItem> { diff --git a/androscalpel_serializer/src/file_reader.rs b/androscalpel_serializer/src/file_reader.rs index 89409d6..d8c4636 100644 --- a/androscalpel_serializer/src/file_reader.rs +++ b/androscalpel_serializer/src/file_reader.rs @@ -18,6 +18,8 @@ pub struct DexFileReader<'a> { /// This allows us to get the strings that are in a dex file but not used by its /// classes. (Yes, they are some, looking at you `~~D8{"backend":"dex","compilation-mode": /// "release","has-checksums":false,"min-api":24,"version":"8.2.42"}`) + /// + /// Use AtomicBool to hide this inside &self methods that are easy to run concurrently. string_was_resolved: Vec, type_ids: Vec, proto_ids: Vec,