LCOV - code coverage report
Current view: top level - compute_tools/tests - pg_helpers_tests.rs (source / functions) Coverage Total Hit
Test: 472031e0b71f3195f7f21b1f2b20de09fd07bb56.info Lines: 100.0 % 104 104
Test Date: 2025-05-26 10:37:33 Functions: 100.0 % 6 6

            Line data    Source code
       1              : #[cfg(test)]
       2              : mod pg_helpers_tests {
       3              :     use std::fs::File;
       4              : 
       5              :     use compute_api::spec::{ComputeSpec, GenericOption, GenericOptions, PgIdent};
       6              :     use compute_tools::pg_helpers::*;
       7              : 
       8              :     #[test]
       9            1 :     fn params_serialize() {
      10            1 :         let file = File::open("../libs/compute_api/tests/cluster_spec.json").unwrap();
      11            1 :         let spec: ComputeSpec = serde_json::from_reader(file).unwrap();
      12            1 : 
      13            1 :         assert_eq!(
      14            1 :             spec.cluster.databases.first().unwrap().to_pg_options(),
      15            1 :             "LC_COLLATE 'C' LC_CTYPE 'C' TEMPLATE template0 OWNER \"alexk\""
      16            1 :         );
      17            1 :         assert_eq!(
      18            1 :             spec.cluster.roles.first().unwrap().to_pg_options(),
      19            1 :             " LOGIN PASSWORD 'md56b1d16b78004bbd51fa06af9eda75972'"
      20            1 :         );
      21            1 :     }
      22              : 
      23              :     #[test]
      24            1 :     fn settings_serialize() {
      25            1 :         let file = File::open("../libs/compute_api/tests/cluster_spec.json").unwrap();
      26            1 :         let spec: ComputeSpec = serde_json::from_reader(file).unwrap();
      27            1 : 
      28            1 :         assert_eq!(
      29            1 :             spec.cluster.settings.as_pg_settings(),
      30            1 :             r#"fsync = off
      31            1 : wal_level = logical
      32            1 : hot_standby = on
      33            1 : prewarm_lfc_on_startup = off
      34            1 : neon.safekeepers = '127.0.0.1:6502,127.0.0.1:6503,127.0.0.1:6501'
      35            1 : wal_log_hints = on
      36            1 : log_connections = on
      37            1 : shared_buffers = 32768
      38            1 : port = 55432
      39            1 : max_connections = 100
      40            1 : max_wal_senders = 10
      41            1 : listen_addresses = '0.0.0.0'
      42            1 : wal_sender_timeout = 0
      43            1 : password_encryption = md5
      44            1 : maintenance_work_mem = 65536
      45            1 : max_parallel_workers = 8
      46            1 : max_worker_processes = 8
      47            1 : neon.tenant_id = 'b0554b632bd4d547a63b86c3630317e8'
      48            1 : max_replication_slots = 10
      49            1 : neon.timeline_id = '2414a61ffc94e428f14b5758fe308e13'
      50            1 : shared_preload_libraries = 'neon'
      51            1 : synchronous_standby_names = 'walproposer'
      52            1 : neon.pageserver_connstring = 'host=127.0.0.1 port=6400'
      53            1 : test.escaping = 'here''s a backslash \\ and a quote '' and a double-quote " hooray'
      54            1 : "#
      55            1 :         );
      56            1 :     }
      57              : 
      58              :     #[test]
      59            1 :     fn ident_pg_quote() {
      60            1 :         let ident: PgIdent = PgIdent::from("\"name\";\\n select 1;");
      61            1 : 
      62            1 :         assert_eq!(ident.pg_quote(), "\"\"\"name\"\";\\n select 1;\"");
      63            1 :     }
      64              : 
      65              :     #[test]
      66            1 :     fn ident_pg_quote_dollar() {
      67            1 :         let test_cases = vec![
      68            1 :             ("name", ("$x$name$x$", "xx")),
      69            1 :             ("name$", ("$x$name$$x$", "xx")),
      70            1 :             ("name$$", ("$x$name$$$x$", "xx")),
      71            1 :             ("name$$$", ("$x$name$$$$x$", "xx")),
      72            1 :             ("name$$$$", ("$x$name$$$$$x$", "xx")),
      73            1 :             ("name$x$", ("$xx$name$x$$xx$", "xxx")),
      74            1 :             ("x", ("$xx$x$xx$", "xxx")),
      75            1 :             ("xx", ("$xxx$xx$xxx$", "xxxx")),
      76            1 :             ("$x", ("$xx$$x$xx$", "xxx")),
      77            1 :             ("x$", ("$xx$x$$xx$", "xxx")),
      78            1 :             ("$x$", ("$xx$$x$$xx$", "xxx")),
      79            1 :             ("xx$", ("$xxx$xx$$xxx$", "xxxx")),
      80            1 :             ("$xx", ("$xxx$$xx$xxx$", "xxxx")),
      81            1 :             ("$xx$", ("$xxx$$xx$$xxx$", "xxxx")),
      82            1 :         ];
      83              : 
      84           15 :         for (input, expected) in test_cases {
      85           14 :             let (escaped, tag) = PgIdent::from(input).pg_quote_dollar();
      86           14 :             assert_eq!(escaped, expected.0);
      87           14 :             assert_eq!(tag, expected.1);
      88              :         }
      89            1 :     }
      90              : 
      91              :     #[test]
      92            1 :     fn generic_options_search() {
      93            1 :         let generic_options: GenericOptions = Some(vec![
      94            1 :             GenericOption {
      95            1 :                 name: "present_value".into(),
      96            1 :                 value: Some("value".into()),
      97            1 :                 vartype: "string".into(),
      98            1 :             },
      99            1 :             GenericOption {
     100            1 :                 name: "missed_value".into(),
     101            1 :                 value: None,
     102            1 :                 vartype: "int".into(),
     103            1 :             },
     104            1 :         ]);
     105            1 :         assert_eq!(generic_options.find("present_value"), Some("value".into()));
     106            1 :         assert_eq!(generic_options.find("missed_value"), None);
     107            1 :         assert_eq!(generic_options.find("invalid_value"), None);
     108              : 
     109            1 :         let empty_generic_options: GenericOptions = Some(vec![]);
     110            1 :         assert_eq!(empty_generic_options.find("present_value"), None);
     111            1 :         assert_eq!(empty_generic_options.find("missed_value"), None);
     112            1 :         assert_eq!(empty_generic_options.find("invalid_value"), None);
     113              : 
     114            1 :         let none_generic_options: GenericOptions = None;
     115            1 :         assert_eq!(none_generic_options.find("present_value"), None);
     116            1 :         assert_eq!(none_generic_options.find("missed_value"), None);
     117            1 :         assert_eq!(none_generic_options.find("invalid_value"), None);
     118            1 :     }
     119              : 
     120              :     #[test]
     121            1 :     fn test_escape_literal() {
     122            1 :         assert_eq!(escape_literal("test"), "'test'");
     123            1 :         assert_eq!(escape_literal("test'"), "'test'''");
     124            1 :         assert_eq!(escape_literal("test\\'"), "E'test\\\\'''");
     125            1 :         assert_eq!(escape_literal("test\\'\\'"), "E'test\\\\''\\\\'''");
     126            1 :     }
     127              : }
        

Generated by: LCOV version 2.1-beta