You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DbTester.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2021 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. package org.sonar.db;
  21. import java.sql.Connection;
  22. import java.sql.SQLException;
  23. import java.util.Arrays;
  24. import java.util.Comparator;
  25. import java.util.List;
  26. import java.util.Map;
  27. import java.util.stream.Stream;
  28. import javax.annotation.Nullable;
  29. import org.apache.commons.dbcp2.BasicDataSource;
  30. import org.picocontainer.containers.TransientPicoContainer;
  31. import org.sonar.api.utils.System2;
  32. import org.sonar.core.util.SequenceUuidFactory;
  33. import org.sonar.core.util.UuidFactory;
  34. import org.sonar.db.alm.integration.pat.AlmPatsDbTester;
  35. import org.sonar.db.almsettings.AlmSettingsDbTester;
  36. import org.sonar.db.component.ComponentDbTester;
  37. import org.sonar.db.component.ProjectLinkDbTester;
  38. import org.sonar.db.event.EventDbTester;
  39. import org.sonar.db.favorite.FavoriteDbTester;
  40. import org.sonar.db.issue.IssueDbTester;
  41. import org.sonar.db.measure.MeasureDbTester;
  42. import org.sonar.db.newcodeperiod.NewCodePeriodDbTester;
  43. import org.sonar.db.notification.NotificationDbTester;
  44. import org.sonar.db.permission.template.PermissionTemplateDbTester;
  45. import org.sonar.db.plugin.PluginDbTester;
  46. import org.sonar.db.property.InternalComponentPropertyDbTester;
  47. import org.sonar.db.property.PropertyDbTester;
  48. import org.sonar.db.qualitygate.QualityGateDbTester;
  49. import org.sonar.db.qualityprofile.QualityProfileDbTester;
  50. import org.sonar.db.rule.RuleDbTester;
  51. import org.sonar.db.source.FileSourceTester;
  52. import org.sonar.db.user.RootFlagAssertions;
  53. import org.sonar.db.user.UserDbTester;
  54. import org.sonar.db.webhook.WebhookDbTester;
  55. import org.sonar.db.webhook.WebhookDeliveryDbTester;
  56. /**
  57. * This class should be called using @Rule.
  58. * Data is truncated between each tests. The schema is created between each test.
  59. */
  60. public class DbTester extends AbstractDbTester<TestDbImpl> {
  61. private final UuidFactory uuidFactory = new SequenceUuidFactory();
  62. private final System2 system2;
  63. private DbClient client;
  64. private DbSession session = null;
  65. private final UserDbTester userTester;
  66. private final ComponentDbTester componentTester;
  67. private final ProjectLinkDbTester componentLinkTester;
  68. private final FavoriteDbTester favoriteTester;
  69. private final EventDbTester eventTester;
  70. private final PermissionTemplateDbTester permissionTemplateTester;
  71. private final PropertyDbTester propertyTester;
  72. private final QualityGateDbTester qualityGateDbTester;
  73. private final IssueDbTester issueDbTester;
  74. private final RuleDbTester ruleDbTester;
  75. private final NewCodePeriodDbTester newCodePeriodTester;
  76. private final NotificationDbTester notificationDbTester;
  77. private final RootFlagAssertions rootFlagAssertions;
  78. private final QualityProfileDbTester qualityProfileDbTester;
  79. private final MeasureDbTester measureDbTester;
  80. private final FileSourceTester fileSourceTester;
  81. private final PluginDbTester pluginDbTester;
  82. private final WebhookDbTester webhookDbTester;
  83. private final WebhookDeliveryDbTester webhookDeliveryDbTester;
  84. private final InternalComponentPropertyDbTester internalComponentPropertyTester;
  85. private final AlmSettingsDbTester almSettingsDbTester;
  86. private final AlmPatsDbTester almPatsDbtester;
  87. private DbTester(System2 system2, @Nullable String schemaPath, MyBatisConfExtension... confExtensions) {
  88. super(TestDbImpl.create(schemaPath, confExtensions));
  89. this.system2 = system2;
  90. initDbClient();
  91. this.userTester = new UserDbTester(this);
  92. this.componentTester = new ComponentDbTester(this);
  93. this.componentLinkTester = new ProjectLinkDbTester(this);
  94. this.favoriteTester = new FavoriteDbTester(this);
  95. this.eventTester = new EventDbTester(this);
  96. this.permissionTemplateTester = new PermissionTemplateDbTester(this);
  97. this.propertyTester = new PropertyDbTester(this);
  98. this.qualityGateDbTester = new QualityGateDbTester(this);
  99. this.issueDbTester = new IssueDbTester(this);
  100. this.ruleDbTester = new RuleDbTester(this);
  101. this.notificationDbTester = new NotificationDbTester(this);
  102. this.rootFlagAssertions = new RootFlagAssertions(this);
  103. this.qualityProfileDbTester = new QualityProfileDbTester(this);
  104. this.measureDbTester = new MeasureDbTester(this);
  105. this.fileSourceTester = new FileSourceTester(this);
  106. this.pluginDbTester = new PluginDbTester(this);
  107. this.webhookDbTester = new WebhookDbTester(this);
  108. this.webhookDeliveryDbTester = new WebhookDeliveryDbTester(this);
  109. this.internalComponentPropertyTester = new InternalComponentPropertyDbTester(this);
  110. this.newCodePeriodTester = new NewCodePeriodDbTester(this);
  111. this.almSettingsDbTester = new AlmSettingsDbTester(this);
  112. this.almPatsDbtester = new AlmPatsDbTester(this);
  113. }
  114. public static DbTester create() {
  115. return new DbTester(System2.INSTANCE, null);
  116. }
  117. public static DbTester create(System2 system2) {
  118. return new DbTester(system2, null);
  119. }
  120. public static DbTester createWithExtensionMappers(System2 system2, Class<?> firstMapperClass, Class<?>... otherMapperClasses) {
  121. return new DbTester(system2, null, new DbTesterMyBatisConfExtension(firstMapperClass, otherMapperClasses));
  122. }
  123. private void initDbClient() {
  124. TransientPicoContainer ioc = new TransientPicoContainer();
  125. ioc.addComponent(db.getMyBatis());
  126. ioc.addComponent(system2);
  127. ioc.addComponent(uuidFactory);
  128. for (Class daoClass : DaoModule.classes()) {
  129. ioc.addComponent(daoClass);
  130. }
  131. List<Dao> daos = ioc.getComponents(Dao.class);
  132. client = new DbClient(db.getDatabase(), db.getMyBatis(), new TestDBSessions(db.getMyBatis()), daos.toArray(new Dao[daos.size()]));
  133. }
  134. @Override
  135. protected void before() {
  136. db.start();
  137. db.truncateTables();
  138. initDbClient();
  139. }
  140. public UserDbTester users() {
  141. return userTester;
  142. }
  143. public ComponentDbTester components() {
  144. return componentTester;
  145. }
  146. public ProjectLinkDbTester componentLinks() {
  147. return componentLinkTester;
  148. }
  149. public FavoriteDbTester favorites() {
  150. return favoriteTester;
  151. }
  152. public EventDbTester events() {
  153. return eventTester;
  154. }
  155. public PermissionTemplateDbTester permissionTemplates() {
  156. return permissionTemplateTester;
  157. }
  158. public PropertyDbTester properties() {
  159. return propertyTester;
  160. }
  161. public QualityGateDbTester qualityGates() {
  162. return qualityGateDbTester;
  163. }
  164. public RootFlagAssertions rootFlag() {
  165. return rootFlagAssertions;
  166. }
  167. public IssueDbTester issues() {
  168. return issueDbTester;
  169. }
  170. public RuleDbTester rules() {
  171. return ruleDbTester;
  172. }
  173. public NewCodePeriodDbTester newCodePeriods() {
  174. return newCodePeriodTester;
  175. }
  176. public NotificationDbTester notifications() {
  177. return notificationDbTester;
  178. }
  179. public QualityProfileDbTester qualityProfiles() {
  180. return qualityProfileDbTester;
  181. }
  182. public MeasureDbTester measures() {
  183. return measureDbTester;
  184. }
  185. public FileSourceTester fileSources() {
  186. return fileSourceTester;
  187. }
  188. public PluginDbTester pluginDbTester() {
  189. return pluginDbTester;
  190. }
  191. public WebhookDbTester webhooks() {
  192. return webhookDbTester;
  193. }
  194. public WebhookDeliveryDbTester webhookDelivery() {
  195. return webhookDeliveryDbTester;
  196. }
  197. public InternalComponentPropertyDbTester internalComponentProperties() {
  198. return internalComponentPropertyTester;
  199. }
  200. public AlmSettingsDbTester almSettings() {
  201. return almSettingsDbTester;
  202. }
  203. public AlmPatsDbTester almPats() {
  204. return almPatsDbtester;
  205. }
  206. @Override
  207. protected void after() {
  208. if (session != null) {
  209. session.rollback();
  210. session.close();
  211. }
  212. db.stop();
  213. }
  214. public DbSession getSession() {
  215. if (session == null) {
  216. session = db.getMyBatis().openSession(false);
  217. }
  218. return session;
  219. }
  220. public void commit() {
  221. getSession().commit();
  222. }
  223. public DbClient getDbClient() {
  224. return client;
  225. }
  226. public int countRowsOfTable(DbSession dbSession, String tableName) {
  227. return super.countRowsOfTable(tableName, new DbSessionConnectionSupplier(dbSession));
  228. }
  229. public int countSql(DbSession dbSession, String sql) {
  230. return super.countSql(sql, new DbSessionConnectionSupplier(dbSession));
  231. }
  232. public List<Map<String, Object>> select(DbSession dbSession, String selectSql) {
  233. return super.select(selectSql, new DbSessionConnectionSupplier(dbSession));
  234. }
  235. public Map<String, Object> selectFirst(DbSession dbSession, String selectSql) {
  236. return super.selectFirst(selectSql, new DbSessionConnectionSupplier(dbSession));
  237. }
  238. @Deprecated
  239. public MyBatis myBatis() {
  240. return db.getMyBatis();
  241. }
  242. @Deprecated
  243. public Connection openConnection() throws SQLException {
  244. return getConnection();
  245. }
  246. private Connection getConnection() throws SQLException {
  247. return db.getDatabase().getDataSource().getConnection();
  248. }
  249. @Deprecated
  250. public Database database() {
  251. return db.getDatabase();
  252. }
  253. public String getUrl() {
  254. return ((BasicDataSource) db.getDatabase().getDataSource()).getUrl();
  255. }
  256. private static class DbSessionConnectionSupplier implements ConnectionSupplier {
  257. private final DbSession dbSession;
  258. public DbSessionConnectionSupplier(DbSession dbSession) {
  259. this.dbSession = dbSession;
  260. }
  261. @Override
  262. public Connection get() {
  263. return dbSession.getConnection();
  264. }
  265. @Override
  266. public void close() {
  267. // closing dbSession is not our responsability
  268. }
  269. }
  270. private static class DbTesterMyBatisConfExtension implements MyBatisConfExtension {
  271. // do not replace with a lambda to allow cache of MyBatis instances in TestDbImpl to work
  272. private final Class<?>[] mapperClasses;
  273. public DbTesterMyBatisConfExtension(Class<?> firstMapperClass, Class<?>... otherMapperClasses) {
  274. this.mapperClasses = Stream.concat(
  275. Stream.of(firstMapperClass),
  276. Arrays.stream(otherMapperClasses))
  277. .sorted(Comparator.comparing(Class::getName))
  278. .toArray(Class<?>[]::new);
  279. }
  280. @Override
  281. public Stream<Class<?>> getMapperClasses() {
  282. return Arrays.stream(mapperClasses);
  283. }
  284. @Override
  285. public boolean equals(Object o) {
  286. if (this == o) {
  287. return true;
  288. }
  289. if (o == null || getClass() != o.getClass()) {
  290. return false;
  291. }
  292. DbTesterMyBatisConfExtension that = (DbTesterMyBatisConfExtension) o;
  293. return Arrays.equals(mapperClasses, that.mapperClasses);
  294. }
  295. @Override
  296. public int hashCode() {
  297. return Arrays.hashCode(mapperClasses);
  298. }
  299. }
  300. }