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.

TestDbImpl.java 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2020 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.util.HashMap;
  22. import java.util.Map;
  23. import java.util.function.BiConsumer;
  24. import java.util.function.Consumer;
  25. import java.util.function.Function;
  26. import javax.annotation.Nullable;
  27. import org.apache.commons.codec.digest.DigestUtils;
  28. import org.apache.commons.lang.StringUtils;
  29. import org.junit.AssumptionViolatedException;
  30. import org.sonar.api.config.internal.Settings;
  31. import org.sonar.db.dialect.H2;
  32. import org.sonar.process.logging.LogbackHelper;
  33. class TestDbImpl extends CoreTestDb {
  34. private static TestDbImpl defaultSchemaBaseTestDb;
  35. // instantiating MyBatis objects is costly => we cache them for default schema
  36. private static final Map<MyBatisConfExtension[], TestDbImpl> defaultSchemaTestDbsWithExtensions = new HashMap<>();
  37. private boolean isDefault;
  38. private MyBatis myBatis;
  39. private TestDbImpl(@Nullable String schemaPath, MyBatisConfExtension... confExtensions) {
  40. super();
  41. isDefault = (schemaPath == null);
  42. init(schemaPath, confExtensions);
  43. }
  44. private TestDbImpl(TestDbImpl base, MyBatis myBatis) {
  45. super(base.getDatabase());
  46. this.isDefault = base.isDefault;
  47. this.myBatis = myBatis;
  48. }
  49. private void init(@Nullable String schemaPath, MyBatisConfExtension[] confExtensions) {
  50. Consumer<Settings> loadOrchestratorSettings = settings -> {
  51. OrchestratorSettingsUtils.loadOrchestratorSettings(settings);
  52. };
  53. Function<Settings, Database> databaseCreator = settings -> {
  54. String dialect = settings.getString("sonar.jdbc.dialect");
  55. if (dialect != null && !"h2".equals(dialect)) {
  56. return new DefaultDatabase(new LogbackHelper(), settings);
  57. }
  58. return SQDatabase.newH2Database("h2Tests" + DigestUtils.md5Hex(StringUtils.defaultString(schemaPath)), schemaPath == null);
  59. };
  60. Consumer<Database> schemaPathExecutor = database -> {
  61. if (schemaPath == null) {
  62. return;
  63. }
  64. // scripts are assumed to be using H2 specific syntax, ignore the test if not on H2
  65. if (!database.getDialect().getId().equals("h2")) {
  66. database.stop();
  67. throw new AssumptionViolatedException("This test is intended to be run on H2 only");
  68. }
  69. ((SQDatabase) database).executeScript(schemaPath);
  70. };
  71. BiConsumer<Database, Boolean> createMyBatis = (db, created) -> myBatis = newMyBatis(db, confExtensions);
  72. init(loadOrchestratorSettings, databaseCreator, schemaPathExecutor, createMyBatis);
  73. }
  74. private static MyBatis newMyBatis(Database db, MyBatisConfExtension[] extensions) {
  75. MyBatis newMyBatis = new MyBatis(db, extensions);
  76. newMyBatis.start();
  77. return newMyBatis;
  78. }
  79. static TestDbImpl create(@Nullable String schemaPath, MyBatisConfExtension... confExtensions) {
  80. MyBatisConfExtension[] extensionArray = confExtensions.length == 0 ? null : confExtensions;
  81. if (schemaPath == null) {
  82. if (defaultSchemaBaseTestDb == null) {
  83. defaultSchemaBaseTestDb = new TestDbImpl(null);
  84. }
  85. if (extensionArray != null) {
  86. return defaultSchemaTestDbsWithExtensions.computeIfAbsent(
  87. extensionArray,
  88. extensions -> new TestDbImpl(defaultSchemaBaseTestDb, newMyBatis(defaultSchemaBaseTestDb.getDatabase(), extensions)));
  89. }
  90. return defaultSchemaBaseTestDb;
  91. }
  92. return new TestDbImpl(schemaPath, confExtensions);
  93. }
  94. @Override
  95. public void start() {
  96. if (!isDefault && !H2.ID.equals(getDatabase().getDialect().getId())) {
  97. throw new AssumptionViolatedException("Test disabled because it supports only H2");
  98. }
  99. }
  100. @Override
  101. public void stop() {
  102. if (!isDefault) {
  103. super.stop();
  104. }
  105. }
  106. MyBatis getMyBatis() {
  107. return myBatis;
  108. }
  109. }