Output network-test logs into files in CI (#6355)

* Add ci_logger

* Update artifact name

* Add env var

* Add fork_name

* Fix clippy error

* Add comments
This commit is contained in:
Akihito Nakano
2024-10-03 22:53:36 +09:00
committed by GitHub
parent f870b66f49
commit a4a673b780
4 changed files with 74 additions and 12 deletions

View File

@@ -173,8 +173,19 @@ jobs:
channel: stable channel: stable
cache-target: release cache-target: release
bins: cargo-nextest bins: cargo-nextest
- name: Create CI logger dir
run: mkdir ${{ runner.temp }}/network_test_logs
- name: Run network tests for all known forks - name: Run network tests for all known forks
run: make test-network run: make test-network
env:
TEST_FEATURES: portable,ci_logger
CI_LOGGER_DIR: ${{ runner.temp }}/network_test_logs
- name: Upload logs
uses: actions/upload-artifact@v4
with:
name: network_test_logs
path: ${{ runner.temp }}/network_test_logs
slasher-tests: slasher-tests:
name: slasher-tests name: slasher-tests
needs: [check-labels] needs: [check-labels]

View File

@@ -43,13 +43,15 @@ use rayon::prelude::*;
use sensitive_url::SensitiveUrl; use sensitive_url::SensitiveUrl;
use slog::{o, Drain, Logger}; use slog::{o, Drain, Logger};
use slog_async::Async; use slog_async::Async;
use slog_term::{FullFormat, TermDecorator}; use slog_term::{FullFormat, PlainSyncDecorator, TermDecorator};
use slot_clock::{SlotClock, TestingSlotClock}; use slot_clock::{SlotClock, TestingSlotClock};
use state_processing::per_block_processing::compute_timestamp_at_slot; use state_processing::per_block_processing::compute_timestamp_at_slot;
use state_processing::state_advance::complete_state_advance; use state_processing::state_advance::complete_state_advance;
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::fmt; use std::fmt;
use std::fs::{File, OpenOptions};
use std::io::BufWriter;
use std::str::FromStr; use std::str::FromStr;
use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::{Arc, LazyLock}; use std::sync::{Arc, LazyLock};
@@ -68,6 +70,8 @@ use types::{typenum::U4294967296, *};
pub const HARNESS_GENESIS_TIME: u64 = 1_567_552_690; pub const HARNESS_GENESIS_TIME: u64 = 1_567_552_690;
// Environment variable to read if `fork_from_env` feature is enabled. // Environment variable to read if `fork_from_env` feature is enabled.
pub const FORK_NAME_ENV_VAR: &str = "FORK_NAME"; pub const FORK_NAME_ENV_VAR: &str = "FORK_NAME";
// Environment variable to read if `ci_logger` feature is enabled.
pub const CI_LOGGER_DIR_ENV_VAR: &str = "CI_LOGGER_DIR";
// Default target aggregators to set during testing, this ensures an aggregator at each slot. // Default target aggregators to set during testing, this ensures an aggregator at each slot.
// //
@@ -2750,17 +2754,57 @@ pub struct MakeAttestationOptions {
pub fork: Fork, pub fork: Fork,
} }
pub fn build_log(level: slog::Level, enabled: bool) -> Logger { pub enum LoggerType {
let decorator = TermDecorator::new().build(); Test,
let drain = FullFormat::new(decorator).build().fuse(); // The logs are output to files for each test.
let drain = Async::new(drain).build().fuse(); CI,
// No logs will be printed.
Null,
}
if enabled { fn ci_decorator() -> PlainSyncDecorator<BufWriter<File>> {
let log_dir = std::env::var(CI_LOGGER_DIR_ENV_VAR).unwrap_or_else(|e| {
panic!("{CI_LOGGER_DIR_ENV_VAR} env var must be defined when using ci_logger: {e:?}");
});
let fork_name = std::env::var(FORK_NAME_ENV_VAR)
.map(|s| format!("{s}_"))
.unwrap_or_default();
// The current test name can be got via the thread name.
let test_name = std::thread::current()
.name()
.unwrap()
.to_string()
// Colons are not allowed in files that are uploaded to GitHub Artifacts.
.replace("::", "_");
let log_path = format!("/{log_dir}/{fork_name}{test_name}.log");
let file = OpenOptions::new()
.create(true)
.append(true)
.open(log_path)
.unwrap();
let file = BufWriter::new(file);
PlainSyncDecorator::new(file)
}
pub fn build_log(level: slog::Level, logger_type: LoggerType) -> Logger {
match logger_type {
LoggerType::Test => {
let drain = FullFormat::new(TermDecorator::new().build()).build().fuse();
let drain = Async::new(drain).build().fuse();
Logger::root(drain.filter_level(level).fuse(), o!()) Logger::root(drain.filter_level(level).fuse(), o!())
} else { }
LoggerType::CI => {
let drain = FullFormat::new(ci_decorator()).build().fuse();
let drain = Async::new(drain).build().fuse();
Logger::root(drain.filter_level(level).fuse(), o!())
}
LoggerType::Null => {
let drain = FullFormat::new(TermDecorator::new().build()).build().fuse();
let drain = Async::new(drain).build().fuse();
Logger::root(drain.filter(|_| false).fuse(), o!()) Logger::root(drain.filter(|_| false).fuse(), o!())
} }
} }
}
pub enum NumBlobs { pub enum NumBlobs {
Random, Random,

View File

@@ -57,3 +57,4 @@ disable-backfill = []
fork_from_env = ["beacon_chain/fork_from_env"] fork_from_env = ["beacon_chain/fork_from_env"]
portable = ["beacon_chain/portable"] portable = ["beacon_chain/portable"]
test_logger = [] test_logger = []
ci_logger = []

View File

@@ -15,7 +15,7 @@ use beacon_chain::data_availability_checker::Availability;
use beacon_chain::eth1_chain::CachingEth1Backend; use beacon_chain::eth1_chain::CachingEth1Backend;
use beacon_chain::test_utils::{ use beacon_chain::test_utils::{
build_log, generate_rand_block_and_blobs, generate_rand_block_and_data_columns, test_spec, build_log, generate_rand_block_and_blobs, generate_rand_block_and_data_columns, test_spec,
BeaconChainHarness, EphemeralHarnessType, NumBlobs, BeaconChainHarness, EphemeralHarnessType, LoggerType, NumBlobs,
}; };
use beacon_chain::validator_monitor::timestamp_now; use beacon_chain::validator_monitor::timestamp_now;
use beacon_chain::{ use beacon_chain::{
@@ -103,8 +103,14 @@ struct TestRigConfig {
impl TestRig { impl TestRig {
fn test_setup_with_config(config: Option<TestRigConfig>) -> Self { fn test_setup_with_config(config: Option<TestRigConfig>) -> Self {
let enable_log = cfg!(feature = "test_logger"); let logger_type = if cfg!(feature = "test_logger") {
let log = build_log(slog::Level::Trace, enable_log); LoggerType::Test
} else if cfg!(feature = "ci_logger") {
LoggerType::CI
} else {
LoggerType::Null
};
let log = build_log(slog::Level::Trace, logger_type);
// Use `fork_from_env` logic to set correct fork epochs // Use `fork_from_env` logic to set correct fork epochs
let mut spec = test_spec::<E>(); let mut spec = test_spec::<E>();