LCOV - differential code coverage report
Current view: top level - libs/postgres_ffi/wal_craft/src/bin - wal_craft.rs (source / functions) Coverage Total Hit UBC CBC
Current: f6946e90941b557c917ac98cd5a7e9506d180f3e.info Lines: 82.6 % 121 100 21 100
Current Date: 2023-10-19 02:04:12 Functions: 100.0 % 6 6 6
Baseline: c8637f37369098875162f194f92736355783b050.info
Baseline Date: 2023-10-18 20:25:20

           TLA  Line data    Source code
       1                 : use anyhow::*;
       2                 : use clap::{value_parser, Arg, ArgMatches, Command};
       3                 : use std::{path::PathBuf, str::FromStr};
       4                 : use wal_craft::*;
       5                 : 
       6 CBC          10 : fn main() -> Result<()> {
       7              10 :     env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("wal_craft=info"))
       8              10 :         .init();
       9              10 :     let arg_matches = cli().get_matches();
      10              10 : 
      11              10 :     let wal_craft = |arg_matches: &ArgMatches, client| {
      12               5 :         let (intermediate_lsns, end_of_wal_lsn) = match arg_matches
      13               5 :             .get_one::<String>("type")
      14               5 :             .map(|s| s.as_str())
      15               5 :             .context("'type' is required")?
      16                 :         {
      17               5 :             Simple::NAME => Simple::craft(client)?,
      18               4 :             LastWalRecordXlogSwitch::NAME => LastWalRecordXlogSwitch::craft(client)?,
      19               3 :             LastWalRecordXlogSwitchEndsOnPageBoundary::NAME => {
      20               1 :                 LastWalRecordXlogSwitchEndsOnPageBoundary::craft(client)?
      21                 :             }
      22               2 :             WalRecordCrossingSegmentFollowedBySmallOne::NAME => {
      23               1 :                 WalRecordCrossingSegmentFollowedBySmallOne::craft(client)?
      24                 :             }
      25               1 :             LastWalRecordCrossingSegment::NAME => LastWalRecordCrossingSegment::craft(client)?,
      26 UBC           0 :             a => panic!("Unknown --type argument: {a}"),
      27                 :         };
      28 CBC          13 :         for lsn in intermediate_lsns {
      29               8 :             println!("intermediate_lsn = {lsn}");
      30               8 :         }
      31               5 :         println!("end_of_wal = {end_of_wal_lsn}");
      32               5 :         Ok(())
      33               5 :     };
      34                 : 
      35              10 :     match arg_matches.subcommand() {
      36 UBC           0 :         None => panic!("No subcommand provided"),
      37 CBC          10 :         Some(("print-postgres-config", _)) => {
      38              20 :             for cfg in REQUIRED_POSTGRES_CONFIG.iter() {
      39              20 :                 println!("{cfg}");
      40              20 :             }
      41               5 :             Ok(())
      42                 :         }
      43                 : 
      44               5 :         Some(("with-initdb", arg_matches)) => {
      45 UBC           0 :             let cfg = Conf {
      46               0 :                 pg_version: *arg_matches
      47               0 :                     .get_one::<u32>("pg-version")
      48               0 :                     .context("'pg-version' is required")?,
      49               0 :                 pg_distrib_dir: arg_matches
      50               0 :                     .get_one::<PathBuf>("pg-distrib-dir")
      51               0 :                     .context("'pg-distrib-dir' is required")?
      52               0 :                     .to_owned(),
      53               0 :                 datadir: arg_matches
      54               0 :                     .get_one::<PathBuf>("datadir")
      55               0 :                     .context("'datadir' is required")?
      56               0 :                     .to_owned(),
      57               0 :             };
      58               0 :             cfg.initdb()?;
      59               0 :             let srv = cfg.start_server()?;
      60               0 :             wal_craft(arg_matches, &mut srv.connect_with_timeout()?)?;
      61               0 :             srv.kill();
      62               0 :             Ok(())
      63                 :         }
      64 CBC           5 :         Some(("in-existing", arg_matches)) => wal_craft(
      65               5 :             arg_matches,
      66               5 :             &mut postgres::Config::from_str(
      67               5 :                 arg_matches
      68               5 :                     .get_one::<String>("connection")
      69               5 :                     .context("'connection' is required")?,
      70                 :             )
      71               5 :             .context(
      72               5 :                 "'connection' argument value could not be parsed as a postgres connection string",
      73               5 :             )?
      74               5 :             .connect(postgres::NoTls)?,
      75                 :         ),
      76 UBC           0 :         Some(_) => panic!("Unknown subcommand"),
      77                 :     }
      78 CBC          10 : }
      79                 : 
      80              11 : fn cli() -> Command {
      81              11 :     let type_arg = &Arg::new("type")
      82              11 :         .help("Type of WAL to craft")
      83              11 :         .value_parser([
      84              11 :             Simple::NAME,
      85              11 :             LastWalRecordXlogSwitch::NAME,
      86              11 :             LastWalRecordXlogSwitchEndsOnPageBoundary::NAME,
      87              11 :             WalRecordCrossingSegmentFollowedBySmallOne::NAME,
      88              11 :             LastWalRecordCrossingSegment::NAME,
      89              11 :         ])
      90              11 :         .required(true);
      91              11 : 
      92              11 :     Command::new("Postgres WAL crafter")
      93              11 :         .about("Crafts Postgres databases with specific WAL properties")
      94              11 :         .subcommand(
      95              11 :             Command::new("print-postgres-config")
      96              11 :                 .about("Print the configuration required for PostgreSQL server before running this script")
      97              11 :         )
      98              11 :         .subcommand(
      99              11 :             Command::new("with-initdb")
     100              11 :                 .about("Craft WAL in a new data directory first initialized with initdb")
     101              11 :                 .arg(type_arg)
     102              11 :                 .arg(
     103              11 :                     Arg::new("datadir")
     104              11 :                         .help("Data directory for the Postgres server")
     105              11 :                         .value_parser(value_parser!(PathBuf))
     106              11 :                         .required(true)
     107              11 :                 )
     108              11 :                 .arg(
     109              11 :                     Arg::new("pg-distrib-dir")
     110              11 :                         .long("pg-distrib-dir")
     111              11 :                         .value_parser(value_parser!(PathBuf))
     112              11 :                         .help("Directory with Postgres distributions (bin and lib directories, e.g. pg_install containing subpath `v14/bin/postgresql`)")
     113              11 :                         .default_value("/usr/local")
     114              11 :                 )
     115              11 :                 .arg(
     116              11 :                     Arg::new("pg-version")
     117              11 :                     .long("pg-version")
     118              11 :                     .help("Postgres version to use for the initial tenant")
     119              11 :                     .value_parser(value_parser!(u32))
     120              11 :                     .required(true)
     121              11 : 
     122              11 :                 )
     123              11 :         )
     124              11 :         .subcommand(
     125              11 :             Command::new("in-existing")
     126              11 :                 .about("Craft WAL at an existing recently created Postgres database. Note that server may append new WAL entries on shutdown.")
     127              11 :                 .arg(type_arg)
     128              11 :                 .arg(
     129              11 :                     Arg::new("connection")
     130              11 :                         .help("Connection string to the Postgres database to populate")
     131              11 :                         .required(true)
     132              11 :                 )
     133              11 :         )
     134              11 : }
     135                 : 
     136               1 : #[test]
     137               1 : fn verify_cli() {
     138               1 :     cli().debug_assert();
     139               1 : }
        

Generated by: LCOV version 2.1-beta