OmniSciDB  6686921089
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SystemTableConcurrencyTest.java
Go to the documentation of this file.
1 /*
2  * Copyright 2021 OmniSci, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.mapd.tests;
17 
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
20 
21 import java.util.Arrays;
22 import java.util.List;
23 import java.util.concurrent.CyclicBarrier;
24 
26  final static Logger logger = LoggerFactory.getLogger(SystemTableConcurrencyTest.class);
27 
28  public static void main(String[] args) throws Exception {
30  test.testConcurrency();
31  }
32 
33  public void testConcurrency() throws Exception {
34  logger.info("SystemTableConcurrencyTest()");
35  runTest();
36  logger.info("SystemTableConcurrencyTest() done");
37  }
38 
39  private void runTest() throws Exception {
40  final List<ThreadDbQueries> queriesPerThread = Arrays.asList(
41  new ThreadDbQueries("omnisci",
42  Arrays.asList("CREATE USER user_1 (password = 'HyperInteractive');",
43  "ALTER USER user_1 (password = 'HyperInteractive2');",
44  "DROP USER user_1;",
45  "CREATE USER user_2 (password = 'HyperInteractive');",
46  "ALTER USER user_2 (password = 'HyperInteractive2');",
47  "DROP USER user_2;")),
48  new ThreadDbQueries("omnisci",
49  Arrays.asList("CREATE USER user_3 (password = 'HyperInteractive');",
50  "GRANT SELECT ON DATABASE omnisci TO user_3;",
51  "REVOKE SELECT ON DATABASE omnisci FROM user_3;",
52  "GRANT CREATE ON DATABASE omnisci TO user_3;",
53  "REVOKE CREATE ON DATABASE omnisci FROM user_3;",
54  "DROP USER user_3;")),
55  new ThreadDbQueries("omnisci",
56  Arrays.asList("CREATE DATABASE db_1;",
57  "CREATE DATABASE db_2;",
58  "DROP DATABASE db_1;",
59  "DROP DATABASE db_2;")),
60  new ThreadDbQueries("omnisci",
61  Arrays.asList("CREATE ROLE role_1;",
62  "CREATE ROLE role_2;",
63  "DROP ROLE role_1;",
64  "DROP ROLE role_2;")),
65  new ThreadDbQueries("omnisci",
66  Arrays.asList("CREATE TABLE table_1 (i INTEGER, t TEXT);",
67  "INSERT INTO table_1 VALUES (1, 'abc');",
68  "CREATE VIEW view_1 AS SELECT * FROM table_1;",
69  "DROP VIEW view_1;",
70  "DROP TABLE table_1;")),
71  new ThreadDbQueries("omnisci",
72  Arrays.asList("CREATE USER user_4 (password = 'HyperInteractive');",
73  "CREATE USER user_5 (password = 'HyperInteractive');",
74  "CREATE ROLE role_3;",
75  "CREATE ROLE role_4;",
76  "GRANT role_3, role_4 TO user_4, user_5;",
77  "REVOKE role_3 FROM user_5;",
78  "REVOKE role_4 FROM user_4, user_5;",
79  "REVOKE role_3 FROM user_4;",
80  "DROP USER user_4;",
81  "DROP USER user_5;",
82  "DROP ROLE role_3;",
83  "DROP ROLE role_4;")),
84  new ThreadDbQueries(
85  "information_schema", Arrays.asList("SELECT * FROM users;")),
86  new ThreadDbQueries(
87  "information_schema", Arrays.asList("SELECT * FROM permissions;")),
88  new ThreadDbQueries(
89  "information_schema", Arrays.asList("SELECT * FROM databases;")),
90  new ThreadDbQueries(
91  "information_schema", Arrays.asList("SELECT * FROM roles;")),
92  new ThreadDbQueries(
93  "information_schema", Arrays.asList("SELECT * FROM tables;")),
94  new ThreadDbQueries("information_schema",
95  Arrays.asList("SELECT * FROM role_assignments;")),
96  new ThreadDbQueries(
97  "information_schema", Arrays.asList("SELECT * FROM dashboards;")));
98 
99  final int num_threads = queriesPerThread.size()
100  + 1; // +1 for dashboard creation/update thread, which is created separately.
101  Exception[] exceptions = new Exception[num_threads];
102  Thread[] threads = new Thread[num_threads];
103 
104  // Use a barrier here to synchronize the start of each competing thread and make
105  // sure there is a race condition. The barrier ensures no thread will run until they
106  // are all created and waiting for the barrier to complete.
107  final CyclicBarrier barrier = new CyclicBarrier(
108  num_threads, () -> { logger.info("Barrier acquired. Starting queries..."); });
109 
110  threads[0] = new Thread(() -> {
111  try {
112  logger.info("Starting thread[0]");
113  MapdTestClient user = MapdTestClient.getClient(
114  "localhost", 6274, "omnisci", "admin", "HyperInteractive");
115  barrier.await();
116  logger.info("0 create dashboard \"dashboard_1\"");
117  int dashboardId = user.create_dashboard("dashboard_1");
118  logger.info("0 get dashboard " + dashboardId);
119  user.get_dashboard(dashboardId);
120  logger.info("0 replace dashboard " + dashboardId);
121  user.replace_dashboard(dashboardId, "dashboard_2", "admin");
122  logger.info("0 delete dashboard " + dashboardId);
123  user.delete_dashboard(dashboardId);
124  logger.info("Finished thread[0]");
125  } catch (Exception e) {
126  logger.error("Thread[0] Caught Exception: " + e.getMessage(), e);
127  exceptions[0] = e;
128  }
129  });
130  threads[0].start();
131 
132  for (int i = 0; i < queriesPerThread.size(); i++) {
133  final ThreadDbQueries threadQueries = queriesPerThread.get(i);
134  final int threadId = i + 1;
135  threads[threadId] = new Thread(() -> {
136  try {
137  logger.info("Starting thread[" + threadId + "]");
138  MapdTestClient user = MapdTestClient.getClient(
139  "localhost", 6274, threadQueries.database, "admin", "HyperInteractive");
140  barrier.await();
141  for (final String query : threadQueries.queries) {
142  runSqlAsUser(query, user, threadId);
143  }
144  logger.info("Finished thread[" + threadId + "]");
145  } catch (Exception e) {
146  logger.error("Thread[" + threadId + "] Caught Exception: " + e.getMessage(), e);
147  exceptions[threadId] = e;
148  }
149  });
150  threads[threadId].start();
151  }
152 
153  for (Thread t : threads) {
154  t.join();
155  }
156 
157  for (Exception e : exceptions) {
158  if (e != null) {
159  logger.error("Exception: " + e.getMessage(), e);
160  throw e;
161  }
162  }
163  }
164 
165  private void runSqlAsUser(String sql, MapdTestClient user, int threadId)
166  throws Exception {
167  logger.info(threadId + " " + sql);
168  user.runSql(sql);
169  }
170 
171  private class ThreadDbQueries {
172  public ThreadDbQueries(final String database, final List<String> queries) {
173  this.database = database;
174  this.queries = queries;
175  }
176 
177  public final String database;
178  public final List<String> queries;
179  }
180 }
ThreadDbQueries(final String database, final List< String > queries)
void runSqlAsUser(String sql, MapdTestClient user, int threadId)
char * t