1212
1313# Add the pyclient directory to $PYTHONPATH
1414import hashlib
15+ import pathlib
1516from logging import setLogRecordFactory
1617import sys
1718import signal
3334from typing import Coroutine , Sequence , Callable , Optional , Tuple , Dict , TextIO
3435import re
3536import trio
37+ import json
3638
3739from util .test_base import repeat_test , ApolloTest
3840from util .consts import CHECKPOINT_SEQUENCES
4648import inspect
4749from enum import Enum
4850from util import bft_metrics , eliot_logging as log
49- from util .eliot_logging import log_call , logdir_timestamp , log_message
51+ from util .eliot_logging import log_call , logdir_timestamp , log_message , add_destinations , remove_destination , \
52+ format_eliot_message
5053from util import skvbc as kvbc
5154from util .bft_test_exceptions import AlreadyRunningError , AlreadyStoppedError , KeyExchangeError , CreError
5255from bft_config import BFTConfig
@@ -217,8 +220,9 @@ async def wrapper(*args, **kwargs):
217220 async with trio .open_nursery () as background_nursery :
218221 @repeat_test (num_repeats , break_on_first_failure , break_on_first_success , test_name )
219222 async def test_with_bft_network ():
220- with BftTestNetwork .new (config , background_nursery , with_cre = with_cre , use_unified_certs = use_unified_certs ) as bft_network :
221- bft_network .current_test = test_name
223+ with BftTestNetwork .new (
224+ config , background_nursery , with_cre = with_cre ,
225+ use_unified_certs = use_unified_certs , case_name = test_name ) as bft_network :
222226 seed = test_instance .test_seed
223227 with log .start_task (action_type = f"{ async_fn .__name__ } " ,
224228 bft_config = f'{ bft_config } _clients={ config .num_clients } ' ,
@@ -256,8 +260,14 @@ async def test_with_bft_network():
256260class BftTestNetwork :
257261 """Encapsulates a BFT network instance for testing purposes"""
258262
263+ def write_message (self , message ):
264+ self ._eliot_log_file .write (f"{ json .dumps (message )} \n " )
265+
259266 def __enter__ (self ):
260267 """context manager method for 'with' statements"""
268+ if not self ._eliot_log_file :
269+ self ._eliot_log_file = (self .current_test_case_path / 'eliot.log' ).open ('a+' )
270+ add_destinations (self .write_message )
261271 return self
262272
263273 def __exit__ (self , etype , value , tb ):
@@ -293,9 +303,14 @@ def __exit__(self, etype, value, tb):
293303 self .perf_proc .wait ()
294304
295305 self .check_error_logs ()
306+ remove_destination (self .write_message )
307+ if self ._eliot_log_file :
308+ self ._eliot_log_file .close ()
309+ self ._eliot_log_file = None
296310
297311 def __init__ (self , is_existing , origdir , config , testdir , certdir , builddir , toolsdir ,
298- procs , replicas , clients , metrics , client_factory , background_nursery , ro_replicas = []):
312+ procs , replicas , clients , metrics , client_factory , background_nursery , ro_replicas = [],
313+ case_name = "" ):
299314 self .is_existing = is_existing
300315 # An existing deployment might pass some of the folders paths as empty so we skip the next assertion.
301316 if not is_existing :
@@ -322,9 +337,8 @@ def __init__(self, is_existing, origdir, config, testdir, certdir, builddir, too
322337 else :
323338 self .client_factory = partial (self ._create_new_client , BFT_CLIENT_TYPE )
324339 self .open_fds = {}
325- self .current_test = ""
340+ self .current_test = case_name
326341 self .background_nursery = background_nursery
327- self .current_test_case_path = None
328342 self .test_start_time = None
329343 self .perf_proc = None
330344 self .ro_replicas = ro_replicas
@@ -335,13 +349,25 @@ def __init__(self, is_existing, origdir, config, testdir, certdir, builddir, too
335349 self .cre_fds = None
336350 self .cre_id = self .config .n + self .config .num_ro_replicas + self .config .num_clients + RESERVED_CLIENTS_QUOTA
337351 self ._logs_dir = Path (self .builddir ) / "tests" / "apollo" / "logs" / logdir_timestamp ()
352+ self ._eliot_log_file = None
353+ self ._suite_name = os .environ .get ('TEST_NAME' , None )
354+ if not self ._suite_name :
355+ now = datetime .now ().strftime ("%y-%m-%d_%H:%M:%S" )
356+ self ._suite_name = f"{ now } _{ self .current_test } "
357+
358+ if os .environ .get ('BLOCKCHAIN_VERSION' , default = "1" ).lower () == "4" :
359+ self ._suite_name = self ._suite_name + "_v4"
360+
361+ self .current_test_case_path = self ._logs_dir / self ._suite_name / self .current_test
362+ self .current_test_case_path .mkdir (parents = True , exist_ok = True )
338363
339364 # Setup transaction signing parameters
340365 self .setup_txn_signing ()
341366 self ._generate_operator_keys ()
342367
343368 @classmethod
344- def new (cls , config , background_nursery , client_factory = None , with_cre = False , use_unified_certs = False ):
369+ def new (cls , config , background_nursery , client_factory = None , with_cre = False , use_unified_certs = False ,
370+ case_name = None ):
345371 builddir = os .path .abspath ("../../build" )
346372 toolsdir = os .path .join (builddir , "tools" )
347373 testdir = tempfile .mkdtemp (prefix = 'testdir_' )
@@ -367,7 +393,8 @@ def new(cls, config, background_nursery, client_factory=None, with_cre=False, us
367393 ro_replicas = [bft_config .Replica (i , "127.0.0.1" ,
368394 bft_config .bft_msg_port_from_node_id (i ),
369395 bft_config .metrics_port_from_node_id (i ))
370- for i in range (config .n , config .n + config .num_ro_replicas )]
396+ for i in range (config .n , config .n + config .num_ro_replicas )],
397+ case_name = case_name
371398 )
372399 bft_network .with_cre = with_cre
373400 bft_network .use_unified_certs = use_unified_certs
@@ -427,13 +454,6 @@ def start_cre(self):
427454 stderr_file = None
428455
429456 if os .environ .get ('KEEP_APOLLO_LOGS' , "" ).lower () in ["true" , "on" ]:
430- test_name = os .environ .get ('TEST_NAME' )
431-
432- if not test_name :
433- now = datetime .now ().strftime ("%y-%m-%d_%H:%M:%S" )
434- test_name = f"{ now } _{ self .current_test } "
435-
436- self .current_test_case_path = self ._logs_dir / test_name / self .current_test
437457 test_log = f"{ self .current_test_case_path / 'stdout_cre.log' } "
438458
439459 Path (self .current_test_case_path ).mkdir (parents = True , exist_ok = True )
@@ -590,7 +610,7 @@ def generate_tls_certs(self, num_to_generate, start_index=0, use_unified_certs=F
590610
591611 def copy_certs_from_server_to_clients (self , src ):
592612 src_cert = self .certdir + "/" + str (src )
593- for c in range (self .num_total_replicas () , self .num_total_replicas () + self .config .num_clients + RESERVED_CLIENTS_QUOTA ):
613+ for c in range (self .num_total_replicas (), self .num_total_replicas () + self .config .num_clients + RESERVED_CLIENTS_QUOTA ):
594614 comp_cert_dir = self .certdir + "/" + str (c )
595615 shutil .rmtree (comp_cert_dir , ignore_errors = True )
596616 shutil .copytree (src_cert , comp_cert_dir )
@@ -615,7 +635,7 @@ def _create_reserved_clients(self):
615635
616636 def new_reserved_client (self ):
617637 if len (self .reserved_client_ids_in_use ) == RESERVED_CLIENTS_QUOTA :
618- raise NotImplemented ("You must increase RESERVED_CLIENTS_QUOTA, see comment above" )
638+ raise NotImplemented ("You must increase RESERVED_CLIENTS_QUOTA, see comment above" )
619639 start_id = self .num_total_replicas () + self .config .num_clients
620640 reserved_client_ids = [ id for id in range (start_id , start_id + RESERVED_CLIENTS_QUOTA ) ]
621641 free_reserved_client_ids = set (reserved_client_ids ) - set (self .reserved_client_ids_in_use )
@@ -849,13 +869,7 @@ def start_replica(self, replica_id):
849869 keep_logs = os .environ .get ('KEEP_APOLLO_LOGS' , "" ).lower () in ["true" , "on" ]
850870
851871 if keep_logs :
852- test_name = os .environ .get ('TEST_NAME' )
853- if os .environ .get ('BLOCKCHAIN_VERSION' , default = "1" ) == "4" :
854- test_name = test_name + "_v4"
855-
856- test_name = test_name if test_name else f"{ self .current_test } "
857-
858- self .current_test_case_path = self ._logs_dir / test_name / self .current_test
872+ suite_name = self ._suite_name
859873 replica_test_log_path = self .current_test_case_path / f"stdout_{ replica_id } .log"
860874
861875 Path (self .current_test_case_path ).mkdir (parents = True , exist_ok = True )
@@ -876,7 +890,7 @@ def start_replica(self, replica_id):
876890 """
877891 if os .environ .get ('CODECOVERAGE' , "" ).lower () in ["true" , "on" ] and \
878892 os .environ .get ('GRACEFUL_SHUTDOWN' ,"" ).lower () in ["true" , "on" ]:
879- self .coverage_dir = f"{ self .builddir } /tests/apollo/codecoverage/{ test_name } /{ self .current_test } /"
893+ self .coverage_dir = f"{ self .builddir } /tests/apollo/codecoverage/{ suite_name } /{ self .current_test } /"
880894 Path (self .coverage_dir ).mkdir (parents = True , exist_ok = True )
881895 profraw_file_name = f"coverage_{ replica_id } _%9m.profraw"
882896 profraw_file_path = os .path .join (
0 commit comments