Skip to content

Commit 3461c65

Browse files
committed
#882 Improve schema test coverage (getTablePrivileges)
1 parent e27651f commit 3461c65

File tree

1 file changed

+153
-25
lines changed

1 file changed

+153
-25
lines changed

src/test/org/firebirdsql/jdbc/FBDatabaseMetaDataTablePrivilegesTest.java

Lines changed: 153 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,19 @@
44

55
import org.firebirdsql.common.FBTestProperties;
66
import org.firebirdsql.common.extension.UsesDatabaseExtension;
7+
import org.firebirdsql.util.FirebirdSupportInfo;
78
import org.junit.jupiter.api.AfterAll;
89
import org.junit.jupiter.api.BeforeAll;
910
import org.junit.jupiter.api.Test;
1011
import org.junit.jupiter.api.extension.RegisterExtension;
12+
import org.junit.jupiter.params.ParameterizedTest;
13+
import org.junit.jupiter.params.provider.CsvSource;
1114

1215
import java.sql.Connection;
1316
import java.sql.DatabaseMetaData;
1417
import java.sql.ResultSet;
1518
import java.sql.SQLException;
16-
import java.util.Arrays;
19+
import java.util.ArrayList;
1720
import java.util.Collections;
1821
import java.util.EnumMap;
1922
import java.util.List;
@@ -22,6 +25,8 @@
2225
import static org.firebirdsql.common.FBTestProperties.getConnectionViaDriverManager;
2326
import static org.firebirdsql.common.FBTestProperties.getDefaultSupportInfo;
2427
import static org.firebirdsql.common.FBTestProperties.ifSchemaElse;
28+
import static org.firebirdsql.common.FBTestProperties.resolveSchema;
29+
import static org.firebirdsql.common.FbAssumptions.assumeFeature;
2530
import static org.firebirdsql.common.matchers.MatcherAssume.assumeThat;
2631
import static org.hamcrest.Matchers.equalToIgnoringCase;
2732
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -33,22 +38,14 @@
3338
*/
3439
class FBDatabaseMetaDataTablePrivilegesTest {
3540

36-
// TODO Add schema support: tests involving other schema
37-
3841
private static final String SYSDBA = "SYSDBA";
3942
private static final String USER1 = "USER1";
4043
private static final String user2 = getDefaultSupportInfo().supportsCaseSensitiveUserNames() ? "user2" : "USER2";
4144
private static final String PUBLIC = "PUBLIC";
4245

4346
@RegisterExtension
44-
static final UsesDatabaseExtension.UsesDatabaseForAll usesDatabase = UsesDatabaseExtension.usesDatabaseForAll(
45-
"create table TBL1 (COL1 integer, COL2 varchar(50), \"val3\" varchar(50))",
46-
"create table \"tbl2\" (COL1 integer, COL2 varchar(50), \"val3\" varchar(50))",
47-
"grant all on TBL1 to USER1",
48-
"grant select on TBL1 to PUBLIC",
49-
"grant update (COL1, \"val3\") on TBL1 to \"user2\"",
50-
"grant select on \"tbl2\" to \"user2\" with grant option",
51-
"grant references (COL1) on \"tbl2\" to USER1");
47+
static final UsesDatabaseExtension.UsesDatabaseForAll usesDatabase =
48+
UsesDatabaseExtension.usesDatabaseForAll(createDbInitStatements());
5249

5350
private static final MetadataResultSetDefinition getTablePrivilegesDefinition =
5451
new MetadataResultSetDefinition(TablePrivilegesMetadata.class);
@@ -64,6 +61,26 @@ static void setupAll() throws SQLException {
6461
dbmd = con.getMetaData();
6562
}
6663

64+
private static List<String> createDbInitStatements() {
65+
var statements = new ArrayList<>(List.of(
66+
"create table TBL1 (COL1 integer, COL2 varchar(50), \"val3\" varchar(50))",
67+
"create table \"tbl2\" (COL1 integer, COL2 varchar(50), \"val3\" varchar(50))",
68+
"grant all on TBL1 to USER1",
69+
"grant select on TBL1 to PUBLIC",
70+
"grant update (COL1, \"val3\") on TBL1 to \"user2\"",
71+
"grant select on \"tbl2\" to \"user2\" with grant option",
72+
"grant references (COL1) on \"tbl2\" to USER1"));
73+
if (getDefaultSupportInfo().supportsSchemas()) {
74+
statements.addAll(List.of(
75+
"create schema OTHER_SCHEMA",
76+
"create table OTHER_SCHEMA.TBL3 (COL1 integer, COL2 varchar(50))",
77+
"grant all on OTHER_SCHEMA.TBL3 to USER1",
78+
"grant select on OTHER_SCHEMA.TBL3 to \"user2\""));
79+
}
80+
81+
return statements;
82+
}
83+
6784
@AfterAll
6885
static void tearDownAll() throws SQLException {
6986
try {
@@ -84,9 +101,23 @@ void testTablePrivilegesMetaDataColumns() throws Exception {
84101
}
85102
}
86103

87-
@Test
88-
void testTablePrivileges_TBL1_all() throws Exception {
89-
List<Map<TablePrivilegesMetadata, Object>> rules = Arrays.asList(
104+
@ParameterizedTest
105+
@CsvSource(useHeadersInDisplayName = true, nullValues = "<NIL>", textBlock = """
106+
schemaPattern, tableNamePattern
107+
<NIL>, TBL1
108+
%, TBL1
109+
PUBLIC, TBL1
110+
#NOTE: Only works because there is no other TBL_ in default schema
111+
PUBLIC, TBL_
112+
""")
113+
void testTablePrivileges_TBL1_all(String schemaPattern, String tableNamePattern) throws Exception {
114+
List<Map<TablePrivilegesMetadata, Object>> rules = getTBL1_all();
115+
116+
validateExpectedColumnPrivileges(schemaPattern, tableNamePattern, rules);
117+
}
118+
119+
private List<Map<TablePrivilegesMetadata, Object>> getTBL1_all() {
120+
return List.of(
90121
createRule("TBL1", SYSDBA, true, "DELETE"),
91122
createRule("TBL1", USER1, false, "DELETE"),
92123
createRule("TBL1", SYSDBA, true, "INSERT"),
@@ -99,22 +130,112 @@ void testTablePrivileges_TBL1_all() throws Exception {
99130
createRule("TBL1", SYSDBA, true, "UPDATE"),
100131
createRule("TBL1", USER1, false, "UPDATE"),
101132
createRule("TBL1", user2, false, "UPDATE"));
133+
}
102134

103-
validateExpectedColumnPrivileges("TBL1", rules);
135+
@ParameterizedTest
136+
@CsvSource(useHeadersInDisplayName = true, nullValues = "<NIL>", textBlock = """
137+
schemaPattern, tableNamePattern
138+
<NIL>, tbl2
139+
%, tbl2
140+
PUBLIC, tbl2
141+
#NOTE: Only works because there is no other tbl_ in default schema
142+
PUBLIC, tbl_
143+
""")
144+
void testColumnPrivileges_tbl2_all(String schemaPattern, String tableNamePattern) throws Exception {
145+
List<Map<TablePrivilegesMetadata, Object>> rules = getTbl2_all();
146+
147+
validateExpectedColumnPrivileges(schemaPattern, tableNamePattern, rules);
104148
}
105149

106-
@Test
107-
void testColumnPrivileges_tbl2_all() throws Exception {
108-
List<Map<TablePrivilegesMetadata, Object>> rules = Arrays.asList(
150+
private List<Map<TablePrivilegesMetadata, Object>> getTbl2_all() {
151+
return List.of(
109152
createRule("tbl2", SYSDBA, true, "DELETE"),
110153
createRule("tbl2", SYSDBA, true, "INSERT"),
111154
createRule("tbl2", SYSDBA, true, "REFERENCES"),
112155
createRule("tbl2", USER1, false, "REFERENCES"),
113156
createRule("tbl2", SYSDBA, true, "SELECT"),
114157
createRule("tbl2", user2, true, "SELECT"),
115158
createRule("tbl2", SYSDBA, true, "UPDATE"));
159+
}
160+
161+
@ParameterizedTest
162+
@CsvSource(useHeadersInDisplayName = true, nullValues = "<NIL>", textBlock = """
163+
schemaPattern, tableNamePattern
164+
<NIL>, TBL3
165+
%, TBL3
166+
OTHER_SCHEMA, TBL3
167+
OTHER\\_SCHEMA, TBL3
168+
OTHER%, TBL3
169+
#NOTE: Only works because there is no other TBL_ in OTHER_SCHEMA
170+
OTHER_SCHEMA, TBL_
171+
""")
172+
void testColumnPrivileges_otherSchemaTBL3_all(String schemaPattern, String tableNamePattern) throws Exception {
173+
assumeFeature(FirebirdSupportInfo::supportsSchemas, "Test requires schema support");
174+
List<Map<TablePrivilegesMetadata, Object>> rules = getTBL3_all();
175+
176+
validateExpectedColumnPrivileges(schemaPattern, tableNamePattern, rules);
177+
}
116178

117-
validateExpectedColumnPrivileges("tbl2", rules);
179+
private List<Map<TablePrivilegesMetadata, Object>> getTBL3_all() {
180+
return List.of(
181+
createRule("OTHER_SCHEMA", "TBL3", SYSDBA, true, "DELETE"),
182+
createRule("OTHER_SCHEMA", "TBL3", USER1, false, "DELETE"),
183+
createRule("OTHER_SCHEMA", "TBL3", SYSDBA, true, "INSERT"),
184+
createRule("OTHER_SCHEMA", "TBL3", USER1, false, "INSERT"),
185+
createRule("OTHER_SCHEMA", "TBL3", SYSDBA, true, "REFERENCES"),
186+
createRule("OTHER_SCHEMA", "TBL3", USER1, false, "REFERENCES"),
187+
createRule("OTHER_SCHEMA", "TBL3", SYSDBA, true, "SELECT"),
188+
createRule("OTHER_SCHEMA", "TBL3", USER1, false, "SELECT"),
189+
createRule("OTHER_SCHEMA", "TBL3", user2, false, "SELECT"),
190+
createRule("OTHER_SCHEMA", "TBL3", SYSDBA, true, "UPDATE"),
191+
createRule("OTHER_SCHEMA", "TBL3", USER1, false, "UPDATE"));
192+
}
193+
194+
@ParameterizedTest
195+
@CsvSource(useHeadersInDisplayName = true, nullValues = "<NIL>", textBlock = """
196+
schemaPattern, tableNamePattern
197+
<NIL>, <NIL>
198+
%, <NIL>
199+
<NIL>, %
200+
%, %
201+
""")
202+
void testColumnPrivileges_all(String schemaPattern, String tableNamePattern) throws Exception {
203+
var rules = new ArrayList<Map<TablePrivilegesMetadata, Object>>();
204+
if (getDefaultSupportInfo().supportsSchemas()) {
205+
rules.addAll(getTBL3_all());
206+
}
207+
rules.addAll(getTBL1_all());
208+
rules.addAll(getTbl2_all());
209+
210+
validateExpectedColumnPrivileges(schemaPattern, tableNamePattern, rules);
211+
}
212+
213+
@ParameterizedTest
214+
@CsvSource(useHeadersInDisplayName = true, nullValues = "<NIL>", textBlock = """
215+
schemaPattern, tableNamePattern
216+
PUBLIC, <NIL>
217+
PUBLIC, %
218+
""")
219+
void testColumnPrivileges_defaultSchema_all(String schemaPattern, String tableNamePattern) throws Exception {
220+
var rules = new ArrayList<Map<TablePrivilegesMetadata, Object>>();
221+
rules.addAll(getTBL1_all());
222+
rules.addAll(getTbl2_all());
223+
224+
validateExpectedColumnPrivileges(schemaPattern, tableNamePattern, rules);
225+
}
226+
227+
@ParameterizedTest
228+
@CsvSource(useHeadersInDisplayName = true, nullValues = "<NIL>", textBlock = """
229+
schemaPattern, tableNamePattern
230+
OTHER_SCHEMA, <NIL>
231+
OTHER\\_SCHEMA, %
232+
OTHER%, <NIL>
233+
""")
234+
void testColumnPrivileges_otherSchema_all(String schemaPattern, String tableNamePattern) throws Exception {
235+
assumeFeature(FirebirdSupportInfo::supportsSchemas, "Test requires schema support");
236+
List<Map<TablePrivilegesMetadata, Object>> rules = getTBL3_all();
237+
238+
validateExpectedColumnPrivileges(schemaPattern, tableNamePattern, rules);
118239
}
119240

120241
private Map<TablePrivilegesMetadata, Object> createRule(String tableName, String grantee, boolean grantable,
@@ -133,16 +254,16 @@ private Map<TablePrivilegesMetadata, Object> createRule(String schema, String ta
133254
return rules;
134255
}
135256

136-
private void validateExpectedColumnPrivileges(String tableNamePattern,
137-
List<Map<TablePrivilegesMetadata, Object>> expectedTablePrivileges) throws SQLException {
138-
validateExpectedColumnPrivileges(null, tableNamePattern, expectedTablePrivileges);
139-
}
140-
141257
private void validateExpectedColumnPrivileges(String schemaPattern, String tableNamePattern,
142258
List<Map<TablePrivilegesMetadata, Object>> expectedTablePrivileges) throws SQLException {
143-
try (ResultSet tablePrivileges = dbmd.getTablePrivileges(null, schemaPattern, tableNamePattern)) {
259+
try (ResultSet tablePrivileges = dbmd.getTablePrivileges(null, resolveSchema(schemaPattern), tableNamePattern)) {
144260
int privilegeCount = 0;
145261
while (tablePrivileges.next()) {
262+
if (isProbablySystemTable(tablePrivileges.getString("TABLE_SCHEM"),
263+
tablePrivileges.getString("TABLE_NAME"))) {
264+
// skip system tables
265+
continue;
266+
}
146267
if (privilegeCount < expectedTablePrivileges.size()) {
147268
Map<TablePrivilegesMetadata, Object> rules = expectedTablePrivileges.get(privilegeCount);
148269
getTablePrivilegesDefinition.checkValidationRulesComplete(rules);
@@ -154,6 +275,13 @@ private void validateExpectedColumnPrivileges(String schemaPattern, String table
154275
}
155276
}
156277

278+
private static boolean isProbablySystemTable(String schema, String tableName) {
279+
return "SYSTEM".equals(schema)
280+
|| tableName.startsWith("RDB$")
281+
|| tableName.startsWith("MON$")
282+
|| tableName.startsWith("SEC$");
283+
}
284+
157285
private static final Map<TablePrivilegesMetadata, Object> DEFAULT_TABLE_PRIVILEGES_VALUES;
158286
static {
159287
Map<TablePrivilegesMetadata, Object> defaults = new EnumMap<>(TablePrivilegesMetadata.class);

0 commit comments

Comments
 (0)