@@ -9,102 +9,68 @@ use log::{debug, info, LevelFilter};
99use  rand:: distributions:: Alphanumeric ; 
1010use  rand:: Rng ; 
1111
12+ use  super :: docker:: RunningContainer ; 
1213use  crate :: e2e:: docker:: Docker ; 
13- use  crate :: e2e:: logs :: RunningServices ; 
14+ use  crate :: e2e:: logs_parser :: RunningServices ; 
1415use  crate :: e2e:: temp_dir:: Handler ; 
1516
1617pub  const  NUMBER_OF_ARGUMENTS :  usize  = 2 ; 
18+ const  CONTAINER_TAG :  & str  = "torrust-tracker:local" ; 
19+ const  TRACKER_CHECKER_CONFIG_FILE :  & str  = "tracker_checker.json" ; 
1720
21+ pub  struct  Arguments  { 
22+     pub  tracker_config_path :  String , 
23+ } 
24+ 
25+ /// Script to run E2E tests. 
26+ /// 
1827/// # Panics 
1928/// 
2029/// Will panic if it can't not perform any of the operations. 
2130pub  fn  run ( )  { 
22-     // todo: const 
23-     let  container_tag:  & str  = "torrust-tracker:local" ; 
24-     let  tracker_checker_config_file = "tracker_checker.json" ; 
25- 
26-     setup_logging ( LevelFilter :: Info ) ; 
31+     setup_runner_logging ( LevelFilter :: Info ) ; 
2732
2833    let  args = parse_arguments ( ) ; 
2934
30-     // Setup tracker configuration 
31-     info ! ( "Reading tracker configuration from file: {} ..." ,  args. tracker_config_path) ; 
32-     let  tracker_config = read_tracker_config ( & args. tracker_config_path ) ; 
35+     let  tracker_config = load_tracker_configuration ( & args. tracker_config_path ) ; 
3336
34-     // Build tracker container image 
35-     Docker :: build ( "./Containerfile" ,  container_tag) . expect ( "A tracker local docker image should be built" ) ; 
37+     build_tracker_container_image ( CONTAINER_TAG ) ; 
3638
37-     // Create temp dir 
38-     info ! ( 
39-         "Current dir: {:?}" , 
40-         env:: current_dir( ) . expect( "It should return the current dir" ) 
41-     ) ; 
42-     let  temp_dir_handler = Handler :: new ( ) . expect ( "A temp dir should be created" ) ; 
43-     info ! ( "Temp dir created: {:?}" ,  temp_dir_handler. temp_dir) ; 
39+     let  temp_dir = create_temp_dir ( ) ; 
4440
45-     // Run the tracker container 
4641    let  container_name = generate_random_container_name ( "tracker_" ) ; 
4742
4843    // code-review: if we want to use port 0 we don't know which ports we have to open. 
4944    // Besides, if we don't use port 0 we should get the port numbers from the tracker configuration. 
5045    // We could not use docker, but the intention was to create E2E tests including containerization. 
51-     info ! ( "Running docker tracker image: {container_name} ..." ) ; 
5246    let  env_vars = [ ( "TORRUST_TRACKER_CONFIG" . to_string ( ) ,  tracker_config. to_string ( ) ) ] ; 
5347    let  ports = [ 
5448        "6969:6969/udp" . to_string ( ) , 
5549        "7070:7070/tcp" . to_string ( ) , 
5650        "1212:1212/tcp" . to_string ( ) , 
5751        "1313:1313/tcp" . to_string ( ) , 
5852    ] ; 
59-     let  container =
60-         Docker :: run ( container_tag,  & container_name,  & env_vars,  & ports) . expect ( "A tracker local docker image should be running" ) ; 
61- 
62-     info ! ( "Waiting for the container {container_name} to be healthy ..." ) ; 
63-     let  is_healthy = Docker :: wait_until_is_healthy ( & container_name,  Duration :: from_secs ( 10 ) ) ; 
64- 
65-     assert ! ( is_healthy,  "Unhealthy tracker container: {container_name}" ) ; 
6653
67-     info ! ( "Container {container_name} is healthy ..." ) ; 
54+     let  container =  run_tracker_container ( & container_name ,   & env_vars ,   & ports ) ; 
6855
69-     // Extract running services from  container logs 
56+     let  running_services =  parse_running_services_from_logs ( & container) ; 
7057
71-     let  logs = Docker :: logs ( & container_name) . expect ( "Logs should be captured from running container" ) ; 
72- 
73-     debug ! ( "Logs after starting the container:\n {logs}" ) ; 
58+     let  tracker_checker_config =
59+         serde_json:: to_string_pretty ( & running_services) . expect ( "Running services should be serialized into JSON" ) ; 
7460
75-     let  mut  config  = RunningServices :: default ( ) ; 
76-     config . extract_from_logs ( & logs ) ; 
61+     let  mut  tracker_checker_config_path  = PathBuf :: from ( & temp_dir . temp_dir . path ( ) ) ; 
62+     tracker_checker_config_path . push ( TRACKER_CHECKER_CONFIG_FILE ) ; 
7763
78-     let  json = serde_json :: to_string_pretty ( & config ) . expect ( "Running services should be serialized into JSON" ) ; 
64+     write_tracker_checker_config ( & tracker_checker_config_path ,   & tracker_checker_config ) ; 
7965
80-     // Write tracker_checker configuration file 
81- 
82-     let  mut  absolute_tracker_checker_config_path = PathBuf :: from ( & temp_dir_handler. temp_dir . path ( ) ) ; 
83-     absolute_tracker_checker_config_path. push ( tracker_checker_config_file) ; 
84- 
85-     let  mut  file = File :: create ( absolute_tracker_checker_config_path. clone ( ) ) . expect ( "Tracker checker config file to be created" ) ; 
86-     file. write_all ( json. as_bytes ( ) ) 
87-         . expect ( "Tracker checker config file to be written" ) ; 
88-     info ! ( 
89-         "Tracker checker configuration file: {:?} \n {json}" , 
90-         absolute_tracker_checker_config_path
91-     ) ; 
92- 
93-     // Run the tracker_checker 
94- 
95-     info ! ( 
96-         "Running tacker checker: cargo --bin tracker_checker {}" , 
97-         absolute_tracker_checker_config_path. display( ) 
98-     ) ; 
99- 
100-     run_tracker_checker ( & absolute_tracker_checker_config_path) . expect ( "Tracker checker should check running services" ) ; 
101- 
102-     // End: container will be removed automatically when the `RunningContainer` is dropped. 
66+     run_tracker_checker ( & tracker_checker_config_path) . expect ( "Tracker checker should check running services" ) ; 
10367
10468    info ! ( "Running container `{}` will be automatically removed" ,  container. name) ; 
69+ 
70+     // Container will be removed automatically when the `RunningContainer` is dropped. 
10571} 
10672
107- fn  setup_logging ( level :  LevelFilter )  { 
73+ fn  setup_runner_logging ( level :  LevelFilter )  { 
10874    if  let  Err ( _err)  = fern:: Dispatch :: new ( ) 
10975        . format ( |out,  message,  record| { 
11076            out. finish ( format_args ! ( 
@@ -125,10 +91,6 @@ fn setup_logging(level: LevelFilter) {
12591    debug ! ( "logging initialized." ) ; 
12692} 
12793
128- pub  struct  Arguments  { 
129-     pub  tracker_config_path :  String , 
130- } 
131- 
13294fn  parse_arguments ( )  -> Arguments  { 
13395    let  args:  Vec < String >  = std:: env:: args ( ) . collect ( ) ; 
13496
@@ -145,9 +107,31 @@ fn parse_arguments() -> Arguments {
145107    } 
146108} 
147109
148- fn  read_tracker_config ( tracker_config_path :  & str )  -> String  { 
149-     std:: fs:: read_to_string ( tracker_config_path) 
150-         . unwrap_or_else ( |_| panic ! ( "Can't read tracker config file {tracker_config_path}" ) ) 
110+ fn  load_tracker_configuration ( tracker_config_path :  & str )  -> String  { 
111+     info ! ( "Reading tracker configuration from file: {} ..." ,  tracker_config_path) ; 
112+     read_file ( tracker_config_path) 
113+ } 
114+ 
115+ fn  read_file ( path :  & str )  -> String  { 
116+     std:: fs:: read_to_string ( path) . unwrap_or_else ( |_| panic ! ( "Can't read file {path}" ) ) 
117+ } 
118+ 
119+ fn  build_tracker_container_image ( tag :  & str )  { 
120+     info ! ( "Building tracker container image with tag: {} ..." ,  tag) ; 
121+     Docker :: build ( "./Containerfile" ,  tag) . expect ( "A tracker local docker image should be built" ) ; 
122+ } 
123+ 
124+ fn  create_temp_dir ( )  -> Handler  { 
125+     debug ! ( 
126+         "Current dir: {:?}" , 
127+         env:: current_dir( ) . expect( "It should return the current dir" ) 
128+     ) ; 
129+ 
130+     let  temp_dir_handler = Handler :: new ( ) . expect ( "A temp dir should be created" ) ; 
131+ 
132+     info ! ( "Temp dir created: {:?}" ,  temp_dir_handler. temp_dir) ; 
133+ 
134+     temp_dir_handler
151135} 
152136
153137fn  generate_random_container_name ( prefix :  & str )  -> String  { 
@@ -160,6 +144,40 @@ fn generate_random_container_name(prefix: &str) -> String {
160144    format ! ( "{prefix}{rand_string}" ) 
161145} 
162146
147+ fn  run_tracker_container ( container_name :  & str ,  env_vars :  & [ ( String ,  String ) ] ,  ports :  & [ String ] )  -> RunningContainer  { 
148+     info ! ( "Running docker tracker image: {container_name} ..." ) ; 
149+ 
150+     let  container =
151+         Docker :: run ( CONTAINER_TAG ,  container_name,  env_vars,  ports) . expect ( "A tracker local docker image should be running" ) ; 
152+ 
153+     info ! ( "Waiting for the container {container_name} to be healthy ..." ) ; 
154+ 
155+     let  is_healthy = Docker :: wait_until_is_healthy ( container_name,  Duration :: from_secs ( 10 ) ) ; 
156+ 
157+     assert ! ( is_healthy,  "Unhealthy tracker container: {container_name}" ) ; 
158+ 
159+     debug ! ( "Container {container_name} is healthy ..." ) ; 
160+ 
161+     container
162+ } 
163+ 
164+ fn  parse_running_services_from_logs ( container :  & RunningContainer )  -> RunningServices  { 
165+     let  logs = Docker :: logs ( & container. name ) . expect ( "Logs should be captured from running container" ) ; 
166+ 
167+     debug ! ( "Logs after starting the container:\n {logs}" ) ; 
168+ 
169+     RunningServices :: parse_from_logs ( & logs) 
170+ } 
171+ 
172+ fn  write_tracker_checker_config ( config_file_path :  & Path ,  config :  & str )  { 
173+     let  mut  file = File :: create ( config_file_path) . expect ( "Tracker checker config file to be created" ) ; 
174+ 
175+     file. write_all ( config. as_bytes ( ) ) 
176+         . expect ( "Tracker checker config file to be written" ) ; 
177+ 
178+     info ! ( "Tracker checker configuration file: {:?} \n {config}" ,  config_file_path) ; 
179+ } 
180+ 
163181/// Runs the tracker checker 
164182/// 
165183/// ```text 
@@ -174,6 +192,11 @@ fn generate_random_container_name(prefix: &str) -> String {
174192/// 
175193/// Will panic if the config path is not a valid string. 
176194pub  fn  run_tracker_checker ( config_path :  & Path )  -> io:: Result < ( ) >  { 
195+     info ! ( 
196+         "Running tacker checker: cargo --bin tracker_checker {}" , 
197+         config_path. display( ) 
198+     ) ; 
199+ 
177200    let  path = config_path. to_str ( ) . expect ( "The path should be a valid string" ) ; 
178201
179202    let  status = Command :: new ( "cargo" ) 
0 commit comments