diff --git a/tezt/manual_tests/main.ml b/tezt/manual_tests/main.ml index b9c6fb74331931c68f35aeb040aa638022460c56..d4823982d7cf2865847c34929cdc5a94eff36757 100644 --- a/tezt/manual_tests/main.ml +++ b/tezt/manual_tests/main.ml @@ -35,5 +35,6 @@ let () = Dal.register () ; Baker_test.register ~protocols:Protocol.all ; Non_blocking_rpc.register () ; + Storage_upgrade.register () ; (* Test.run () should be the last statement, don't register afterwards! *) Test.run () diff --git a/tezt/manual_tests/non_blocking_rpc.ml b/tezt/manual_tests/non_blocking_rpc.ml index 4e69890386311744c29e307298b88c21baaa2781..4e59c558170e539cdc145deb6d4a22b8ec91f4a3 100644 --- a/tezt/manual_tests/non_blocking_rpc.ml +++ b/tezt/manual_tests/non_blocking_rpc.ml @@ -84,12 +84,12 @@ let write_identity ~path id = | Error e -> Test.fail "Cannot convert to JSON: %s" e | Ok json -> write_file (Filename.concat path "identity.json") json -let reference_dir = +let reference_dir () = match Sys.getenv_opt "REF_DIR" with | Some v -> v | None -> Test.fail "cannot find reference directory" -let bootstrapping_snapshot = +let bootstrapping_snapshot () = match Sys.getenv_opt "BOOT_SNAP" with | Some v -> v | None -> Test.fail "cannot find bootstrapping snapshot" @@ -204,7 +204,7 @@ let benchmark_bootstrap_node ~reference_node ~node_name ~rpc_external = let* bootstrap_node = spawn_bootstrapping_node ~node_name - ~snapshot_uri:bootstrapping_snapshot + ~snapshot_uri:(bootstrapping_snapshot ()) ~reference_node ~rpc_external in @@ -228,7 +228,9 @@ let get_progress_after_bootstrapping () = ~title:"Check progress made by node during bootstrapping" ~tags:["get"; "node"; "progress"] @@ fun () -> - let* reference_node = spawn_reference_node ~reference_dir in + let* reference_node = + spawn_reference_node ~reference_dir:(reference_dir ()) + in let* external_level = benchmark_bootstrap_node ~reference_node diff --git a/tezt/manual_tests/storage_upgrade.ml b/tezt/manual_tests/storage_upgrade.ml new file mode 100644 index 0000000000000000000000000000000000000000..dc93257fd52c467c84529391d22092c56bbb3c70 --- /dev/null +++ b/tezt/manual_tests/storage_upgrade.ml @@ -0,0 +1,164 @@ +(*****************************************************************************) +(* *) +(* SPDX-License-Identifier: MIT *) +(* Copyright (c) 2024 Nomadic Labs *) +(* *) +(*****************************************************************************) + +(* Testing + ------- + Component: Storage upgrade procedure (octez-node upgrade storage) + Invocation: dune exec tezt/manual_tests/main.exe -- --file storage_upgrade.ml + Subject: Ensure that the storage upgrade is sound + + Note: this v.3.2 upgrade test aims to a semi-automatic tools that + is not expected to be generic enough to be fully automatized. +*) + +let dir_to_upgrade () = + match Sys.getenv_opt "DIR_TO_UPGRADE" with + | Some v -> v + | None -> Test.fail "cannot find dir to upgrade directory" + +type network_params = { + network : Node.argument; + (* cycle length must be a bit bigger than the actual size of a + cycle. *) + cycle_length : int; + (* Stride is expected to be at least 2 times the number of cycles so + that we query at least 2 blocks per cycle. *) + stride : int; +} + +let network_constants () = + match Sys.getenv_opt "NETWORK" with + | Some "pariscnet" -> + let cycle_length = 128 in + { + network = Network "https://teztnets.com/pariscnet"; + cycle_length = cycle_length * 2; + stride = cycle_length / 3; + } + | Some "mainnet" -> + let cycle_length = 4_096 in + { + network = Network "mainnet"; + cycle_length = 24_576; + stride = cycle_length / 3; + } + | Some _ | None -> + Test.fail "Unknown network. You can use [pariscnet, mainnet]" + +let run_cmd cmd = + let* s = Lwt_unix.system cmd in + match s with + | Unix.WEXITED 0 -> unit + | Unix.WEXITED _ -> Test.fail "error in command [%s]" cmd + | _ -> unit + +let print_duration d = + match d with + | None -> assert false + | Some d -> Log.info "Upgrade duration: %a@." Ptime.Span.pp d + +let contiguous_blocks_query node ~start ~length = + let rec loop level = + let cpt = level - start in + Log.info "Status %d/%d (%d %%)" cpt length (100 * cpt / length) ; + if level >= start + length then unit + else + (* Client is too slow, using raw curl calls instead *) + (* let* _ = Client.shell_header ~block:(string_of_int level) client in *) + let cmd = + Format.sprintf + "curl http://127.0.0.1:%d/chains/main/blocks/%d/header" + (Node.rpc_port node) + level + in + let* () = run_cmd cmd in + loop (level + 1) + in + Log.info "Checking every block from %d to %d" start (start + length) ; + loop start + +let sparse_blocks_query node ~last ~stride = + let rec loop level cpt = + let j = last / stride in + Log.info "Status %d/%d (%d %%)" cpt (j + 1) (100 * cpt / j) ; + if level >= last then unit + else + (* Client is too slow, using raw curl calls instead *) + (* let* _ = Client.shell_header ~block:(string_of_int level) client in *) + let cmd = + Format.sprintf + "curl http://127.0.0.1:%d/chains/main/blocks/%d/header" + (Node.rpc_port node) + level + in + let* () = run_cmd cmd in + loop (level + stride) (cpt + 1) + in + Log.info "Checking 1 block out of %d, from %d to %d" stride 0 last ; + loop 0 0 + +(* This manual test aims to be small utility to: + - bench the upgrade storage procedure (v_3_2) + - check the consistency of the storage after the upgrade + + To do so, given: + - DIR_TO_UPGRADE: points to a data directory of version 3.1 + - NETWORK: specifies the network to target + we are: + - running the storage upgrade procedure + - ensuring that a complete cycle is consistent -- by requesting + several contiguous blocks so that we iter over at least 1 full + cycle + - ensuring that several blocks of every cycle are consistent -- by + requesting at least 2 blocks of each cycle +*) +let test_v_3_2_storage_upgrade () = + Test.register + ~__FILE__ + ~title:"Check v.3.2 storage upgrade" + ~tags:["storage"; "upgrade"; "storage_3_2"] + @@ fun () -> + let args = Node.[Connections 0] in + let node_to_upgrade = + Node.create ~name:"node_to_upgrade" ~data_dir:(dir_to_upgrade ()) args + in + let params = network_constants () in + let* () = Node.config_update node_to_upgrade [params.network] in + (* Bench the upgrade procedure *) + let start = Unix.gettimeofday () in + Log.info "Upgrading the storage" ; + let* () = Node.upgrade_storage node_to_upgrade in + let duration = Unix.gettimeofday () -. start in + let d = Ptime.Span.of_float_s duration in + let () = print_duration d in + Log.info "Start the node to request blocks, ensuring consistency" ; + let* () = Node.run node_to_upgrade args in + let* () = Node.wait_for_ready node_to_upgrade in + let* client = Client.init ~endpoint:(Node node_to_upgrade) () in + let* current_head = Client.level client in + let stride = params.stride in + if stride > current_head then + Test.fail + "Not enough blocks (%d) to run the test. Provide at least %d blocks in \ + the data directory." + current_head + stride ; + Log.info "Checking blocks consistency up to level %d@." current_head ; + (* [start] is set to an arbitrary value as it only aims to be the + query start point of enough blocks that we iter over several + cycles. *) + let* () = + contiguous_blocks_query + node_to_upgrade + ~start:1_000 + ~length:params.cycle_length + in + let* () = sparse_blocks_query node_to_upgrade ~last:current_head ~stride in + let () = print_duration d in + unit + +let register () = test_v_3_2_storage_upgrade ()