Skip to content

Commit cd17e6b

Browse files
committed
Add tests to make sure no schema except specified one is touched
1 parent a3a21a2 commit cd17e6b

File tree

4 files changed

+127
-54
lines changed

4 files changed

+127
-54
lines changed

src/pgsql-params.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ class connection_params_t
3434

3535
auto end() const noexcept { return m_params.end(); }
3636

37+
void merge_with(connection_params_t const &other)
38+
{
39+
for (auto const &p : other.m_params) {
40+
m_params[p.first] = p.second;
41+
}
42+
}
43+
3744
private:
3845
std::map<std::string, std::string> m_params;
3946

tests/common-import.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class import_t
131131
std::initializer_list<std::string> input_data,
132132
std::string const &format = "opl")
133133
{
134-
options.connection_params = m_db.connection_params();
134+
options.connection_params.merge_with(m_db.connection_params());
135135

136136
properties_t const properties{options.connection_params,
137137
options.middle_dbschema};
@@ -165,7 +165,7 @@ class import_t
165165

166166
void run_file(options_t options, char const *file = nullptr)
167167
{
168-
options.connection_params = m_db.connection_params();
168+
options.connection_params.merge_with(m_db.connection_params());
169169

170170
properties_t const properties{options.connection_params,
171171
options.middle_dbschema};

tests/common-options.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,21 @@ class opt_t
8989
return *this;
9090
}
9191

92+
opt_t &schema(char const *schema_name)
93+
{
94+
m_opt.dbschema = schema_name;
95+
m_opt.middle_dbschema = schema_name;
96+
m_opt.output_dbschema = schema_name;
97+
return *this;
98+
}
99+
100+
opt_t &user(char const *user, char const *password)
101+
{
102+
m_opt.connection_params.set("user", user);
103+
m_opt.connection_params.set("password", password);
104+
return *this;
105+
}
106+
92107
private:
93108
options_t m_opt;
94109
};

tests/test-output-flex-update.cpp

Lines changed: 103 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "common-import.hpp"
1313
#include "common-options.hpp"
14+
#include "common-pg.hpp"
1415

1516
namespace {
1617

@@ -38,8 +39,50 @@ struct options_slim_expire
3839
}
3940
};
4041

42+
struct options_slim_schema
43+
{
44+
static options_t options()
45+
{
46+
auto conn = db.db().connect();
47+
// Create limited user (if it doesn't exist yet),
48+
// which we need to test that the public schema won't be touched.
49+
// If the public schema is tried to be modified at any point, this user won't have the
50+
// necessary permissions, and hence the test will fail.
51+
conn.exec(R"(
52+
DO
53+
$$
54+
BEGIN
55+
IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'limited') THEN
56+
CREATE ROLE limited LOGIN PASSWORD 'password_limited';
57+
END IF;
58+
END
59+
$$;
60+
)");
61+
conn.exec("REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM "
62+
"PUBLIC, limited;");
63+
conn.exec("REVOKE CREATE ON SCHEMA public FROM PUBLIC, limited;");
64+
conn.exec(
65+
"CREATE SCHEMA IF NOT EXISTS myschema AUTHORIZATION limited;");
66+
conn.close();
67+
return testing::opt_t()
68+
.slim()
69+
.flex(conf_file)
70+
.schema("myschema")
71+
.user("limited", "password_limited");
72+
}
73+
};
74+
75+
// Return a string with the schema name prepended to the table name.
76+
std::string with_schema(char const *table_name, options_t const &options)
77+
{
78+
if (options.dbschema.empty()) {
79+
return {table_name};
80+
}
81+
return options.dbschema + "." + table_name;
82+
}
83+
4184
TEMPLATE_TEST_CASE("updating a node", "", options_slim_default,
42-
options_slim_expire)
85+
options_slim_expire, options_slim_schema)
4386
{
4487
options_t options = TestType::options();
4588

@@ -48,16 +91,16 @@ TEMPLATE_TEST_CASE("updating a node", "", options_slim_default,
4891

4992
auto conn = db.db().connect();
5093

51-
REQUIRE(0 == conn.get_count("osm2pgsql_test_point"));
94+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
5295

5396
// give the node a tag...
5497
options.append = true;
5598
REQUIRE_NOTHROW(
5699
db.run_import(options, "n10 v2 dV x10 y10 Tamenity=restaurant\n"));
57100

58-
REQUIRE(1 == conn.get_count("osm2pgsql_test_point"));
101+
REQUIRE(1 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
59102
REQUIRE(1 ==
60-
conn.get_count("osm2pgsql_test_point",
103+
conn.get_count(with_schema("osm2pgsql_test_point", options),
61104
"node_id = 10 AND tags->'amenity' = 'restaurant'"));
62105

63106
SECTION("remove the tag from node")
@@ -70,11 +113,11 @@ TEMPLATE_TEST_CASE("updating a node", "", options_slim_default,
70113
REQUIRE_NOTHROW(db.run_import(options, "n10 v3 dD\n"));
71114
}
72115

73-
REQUIRE(0 == conn.get_count("osm2pgsql_test_point"));
116+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
74117
}
75118

76119
TEMPLATE_TEST_CASE("updating a way", "", options_slim_default,
77-
options_slim_expire)
120+
options_slim_expire, options_slim_schema)
78121
{
79122
options_t options = TestType::options();
80123

@@ -86,9 +129,9 @@ TEMPLATE_TEST_CASE("updating a way", "", options_slim_default,
86129

87130
auto conn = db.db().connect();
88131

89-
REQUIRE(0 == conn.get_count("osm2pgsql_test_point"));
90-
REQUIRE(1 == conn.get_count("osm2pgsql_test_line"));
91-
REQUIRE(1 == conn.get_count("osm2pgsql_test_line",
132+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
133+
REQUIRE(1 == conn.get_count(with_schema("osm2pgsql_test_line", options)));
134+
REQUIRE(1 == conn.get_count(with_schema("osm2pgsql_test_line", options),
92135
"osm_id = 20 AND tags->'highway' = 'primary' "
93136
"AND ST_NumPoints(geom) = 2"));
94137

@@ -97,18 +140,18 @@ TEMPLATE_TEST_CASE("updating a way", "", options_slim_default,
97140
REQUIRE_NOTHROW(
98141
db.run_import(options, "w20 v2 dV Thighway=secondary Nn10,n11\n"));
99142

100-
REQUIRE(0 == conn.get_count("osm2pgsql_test_point"));
101-
REQUIRE(1 == conn.get_count("osm2pgsql_test_line"));
102-
REQUIRE(1 == conn.get_count("osm2pgsql_test_line",
143+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
144+
REQUIRE(1 == conn.get_count(with_schema("osm2pgsql_test_line", options)));
145+
REQUIRE(1 == conn.get_count(with_schema("osm2pgsql_test_line", options),
103146
"osm_id = 20 AND tags->'highway' = "
104147
"'secondary' AND ST_NumPoints(geom) = 2"));
105148

106149
// now change a node in the way...
107150
REQUIRE_NOTHROW(db.run_import(options, "n10 v2 dV x10.0 y10.3\n"));
108151

109-
REQUIRE(0 == conn.get_count("osm2pgsql_test_point"));
110-
REQUIRE(1 == conn.get_count("osm2pgsql_test_line"));
111-
REQUIRE(1 == conn.get_count("osm2pgsql_test_line",
152+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
153+
REQUIRE(1 == conn.get_count(with_schema("osm2pgsql_test_line", options)));
154+
REQUIRE(1 == conn.get_count(with_schema("osm2pgsql_test_line", options),
112155
"osm_id = 20 AND tags->'highway' = "
113156
"'secondary' AND ST_NumPoints(geom) = 2"));
114157

@@ -117,21 +160,21 @@ TEMPLATE_TEST_CASE("updating a way", "", options_slim_default,
117160
options, "n12 v1 dV x10.2 y10.1\n"
118161
"w20 v3 dV Thighway=residential Nn10,n11,n12\n"));
119162

120-
REQUIRE(0 == conn.get_count("osm2pgsql_test_point"));
121-
REQUIRE(1 == conn.get_count("osm2pgsql_test_line"));
122-
REQUIRE(1 == conn.get_count("osm2pgsql_test_line",
163+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
164+
REQUIRE(1 == conn.get_count(with_schema("osm2pgsql_test_line", options)));
165+
REQUIRE(1 == conn.get_count(with_schema("osm2pgsql_test_line", options),
123166
"osm_id = 20 AND tags->'highway' = "
124167
"'residential' AND ST_NumPoints(geom) = 3"));
125168

126169
// now delete the way...
127170
REQUIRE_NOTHROW(db.run_import(options, "w20 v4 dD\n"));
128171

129-
REQUIRE(0 == conn.get_count("osm2pgsql_test_point"));
130-
REQUIRE(0 == conn.get_count("osm2pgsql_test_line"));
172+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
173+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_line", options)));
131174
}
132175

133176
TEMPLATE_TEST_CASE("ways as linestrings and polygons", "", options_slim_default,
134-
options_slim_expire)
177+
options_slim_expire, options_slim_schema)
135178
{
136179
options_t options = TestType::options();
137180

@@ -145,10 +188,11 @@ TEMPLATE_TEST_CASE("ways as linestrings and polygons", "", options_slim_default,
145188

146189
auto conn = db.db().connect();
147190

148-
REQUIRE(0 == conn.get_count("osm2pgsql_test_point"));
149-
REQUIRE(0 == conn.get_count("osm2pgsql_test_line"));
150-
REQUIRE(1 == conn.get_count("osm2pgsql_test_polygon"));
151-
REQUIRE(1 == conn.get_count("osm2pgsql_test_polygon",
191+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
192+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_line", options)));
193+
REQUIRE(1 ==
194+
conn.get_count(with_schema("osm2pgsql_test_polygon", options)));
195+
REQUIRE(1 == conn.get_count(with_schema("osm2pgsql_test_polygon", options),
152196
"osm_id = 20 AND tags->'building' = 'yes' AND "
153197
"ST_GeometryType(geom) = 'ST_Polygon'"));
154198

@@ -157,48 +201,52 @@ TEMPLATE_TEST_CASE("ways as linestrings and polygons", "", options_slim_default,
157201
REQUIRE_NOTHROW(db.run_import(
158202
options, "w20 v2 dV Thighway=secondary Nn10,n11,n12,n13,n10\n"));
159203

160-
REQUIRE(0 == conn.get_count("osm2pgsql_test_point"));
161-
REQUIRE(1 == conn.get_count("osm2pgsql_test_line"));
204+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
205+
REQUIRE(1 == conn.get_count(with_schema("osm2pgsql_test_line", options)));
162206
REQUIRE(1 ==
163-
conn.get_count("osm2pgsql_test_line",
207+
conn.get_count(with_schema("osm2pgsql_test_line", options),
164208
"osm_id = 20 AND tags->'highway' = 'secondary' AND "
165209
"ST_GeometryType(geom) = 'ST_LineString'"));
166-
REQUIRE(0 == conn.get_count("osm2pgsql_test_polygon"));
210+
REQUIRE(0 ==
211+
conn.get_count(with_schema("osm2pgsql_test_polygon", options)));
167212

168213
// now remove a node from the way...
169214
REQUIRE_NOTHROW(db.run_import(
170215
options, "w20 v3 dV Thighway=secondary Nn10,n11,n12,n13\n"));
171216

172-
REQUIRE(0 == conn.get_count("osm2pgsql_test_point"));
173-
REQUIRE(1 == conn.get_count("osm2pgsql_test_line"));
217+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
218+
REQUIRE(1 == conn.get_count(with_schema("osm2pgsql_test_line", options)));
174219
REQUIRE(1 ==
175-
conn.get_count("osm2pgsql_test_line",
220+
conn.get_count(with_schema("osm2pgsql_test_line", options),
176221
"osm_id = 20 AND tags->'highway' = 'secondary' AND "
177222
"ST_GeometryType(geom) = 'ST_LineString'"));
178-
REQUIRE(0 == conn.get_count("osm2pgsql_test_polygon"));
223+
REQUIRE(0 ==
224+
conn.get_count(with_schema("osm2pgsql_test_polygon", options)));
179225

180226
// now change the tag back to an area tag (but the way is not closed)...
181227
REQUIRE_NOTHROW(
182228
db.run_import(options, "w20 v4 dV Tbuilding=yes Nn10,n11,n12,n13\n"));
183229

184-
REQUIRE(0 == conn.get_count("osm2pgsql_test_point"));
185-
REQUIRE(0 == conn.get_count("osm2pgsql_test_line"));
186-
REQUIRE(0 == conn.get_count("osm2pgsql_test_polygon"));
230+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
231+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_line", options)));
232+
REQUIRE(0 ==
233+
conn.get_count(with_schema("osm2pgsql_test_polygon", options)));
187234

188235
// now close the way again
189236
REQUIRE_NOTHROW(db.run_import(
190237
options, "w20 v5 dV Tbuilding=yes Nn10,n11,n12,n13,n10\n"));
191238

192-
REQUIRE(0 == conn.get_count("osm2pgsql_test_point"));
193-
REQUIRE(0 == conn.get_count("osm2pgsql_test_line"));
194-
REQUIRE(1 == conn.get_count("osm2pgsql_test_polygon"));
195-
REQUIRE(1 == conn.get_count("osm2pgsql_test_polygon",
239+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
240+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_line", options)));
241+
REQUIRE(1 ==
242+
conn.get_count(with_schema("osm2pgsql_test_polygon", options)));
243+
REQUIRE(1 == conn.get_count(with_schema("osm2pgsql_test_polygon", options),
196244
"osm_id = 20 AND tags->'building' = 'yes' AND "
197245
"ST_GeometryType(geom) = 'ST_Polygon'"));
198246
}
199247

200248
TEMPLATE_TEST_CASE("multipolygons", "", options_slim_default,
201-
options_slim_expire)
249+
options_slim_expire, options_slim_schema)
202250
{
203251
options_t options = TestType::options();
204252

@@ -213,10 +261,11 @@ TEMPLATE_TEST_CASE("multipolygons", "", options_slim_default,
213261

214262
auto conn = db.db().connect();
215263

216-
REQUIRE(0 == conn.get_count("osm2pgsql_test_point"));
217-
REQUIRE(0 == conn.get_count("osm2pgsql_test_line"));
218-
REQUIRE(1 == conn.get_count("osm2pgsql_test_polygon"));
219-
REQUIRE(1 == conn.get_count("osm2pgsql_test_polygon",
264+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
265+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_line", options)));
266+
REQUIRE(1 ==
267+
conn.get_count(with_schema("osm2pgsql_test_polygon", options)));
268+
REQUIRE(1 == conn.get_count(with_schema("osm2pgsql_test_polygon", options),
220269
"osm_id = -30 AND tags->'building' = 'yes' AND "
221270
"ST_GeometryType(geom) = 'ST_Polygon'"));
222271

@@ -226,10 +275,11 @@ TEMPLATE_TEST_CASE("multipolygons", "", options_slim_default,
226275
options,
227276
"r30 v2 dV Ttype=multipolygon,building=yes,name=Shed Mw20@\n"));
228277

229-
REQUIRE(0 == conn.get_count("osm2pgsql_test_point"));
230-
REQUIRE(0 == conn.get_count("osm2pgsql_test_line"));
231-
REQUIRE(1 == conn.get_count("osm2pgsql_test_polygon"));
232-
REQUIRE(1 == conn.get_count("osm2pgsql_test_polygon",
278+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
279+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_line", options)));
280+
REQUIRE(1 ==
281+
conn.get_count(with_schema("osm2pgsql_test_polygon", options)));
282+
REQUIRE(1 == conn.get_count(with_schema("osm2pgsql_test_polygon", options),
233283
"osm_id = -30 AND tags->'building' = 'yes' AND "
234284
"ST_GeometryType(geom) = 'ST_Polygon'"));
235285

@@ -244,7 +294,8 @@ TEMPLATE_TEST_CASE("multipolygons", "", options_slim_default,
244294
options, "r30 v3 dV Tbuilding=yes,name=Shed Mw20@\n"));
245295
}
246296

247-
REQUIRE(0 == conn.get_count("osm2pgsql_test_point"));
248-
REQUIRE(0 == conn.get_count("osm2pgsql_test_line"));
249-
REQUIRE(0 == conn.get_count("osm2pgsql_test_polygon"));
297+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_point", options)));
298+
REQUIRE(0 == conn.get_count(with_schema("osm2pgsql_test_line", options)));
299+
REQUIRE(0 ==
300+
conn.get_count(with_schema("osm2pgsql_test_polygon", options)));
250301
}

0 commit comments

Comments
 (0)