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 : }
|