PageRenderTime 27ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/activeobjects-plugin/src/test/java/com/atlassian/activeobjects/backup/TestActiveObjectsBackup.java

https://bitbucket.org/amierzwicki/ao-plugin-quickfix
Java | 385 lines | 324 code | 61 blank | 0 comment | 14 complexity | 5693347830b91181b3a40b1f40ce6506 MD5 | raw file
Possible License(s): Apache-2.0
  1. package com.atlassian.activeobjects.backup;
  2. import com.atlassian.activeobjects.test.model.Model;
  3. import com.google.common.collect.ImmutableList;
  4. import com.google.common.collect.ImmutableMap;
  5. import net.java.ao.DatabaseProvider;
  6. import net.java.ao.db.HSQLDatabaseProvider;
  7. import net.java.ao.db.MySQLDatabaseProvider;
  8. import net.java.ao.db.OracleDatabaseProvider;
  9. import net.java.ao.db.PostgreSQLDatabaseProvider;
  10. import net.java.ao.db.SQLServerDatabaseProvider;
  11. import net.java.ao.test.jdbc.NonTransactional;
  12. import org.custommonkey.xmlunit.SimpleNamespaceContext;
  13. import org.custommonkey.xmlunit.XMLUnit;
  14. import org.custommonkey.xmlunit.XpathEngine;
  15. import org.custommonkey.xmlunit.exceptions.XpathException;
  16. import org.junit.After;
  17. import org.junit.Before;
  18. import org.junit.Test;
  19. import org.w3c.dom.Document;
  20. import org.w3c.dom.Node;
  21. import org.w3c.dom.NodeList;
  22. import java.sql.Types;
  23. import static org.custommonkey.xmlunit.XMLAssert.*;
  24. public final class TestActiveObjectsBackup extends AbstractTestActiveObjectsBackup
  25. {
  26. private static final String HSQL = "/com/atlassian/activeobjects/backup/hsql.xml";
  27. private static final String HSQL_EMPTY = "/com/atlassian/activeobjects/backup/hsql_empty.xml";
  28. private static final String MYSQL = "/com/atlassian/activeobjects/backup/mysql.xml";
  29. private static final String ORACLE = "/com/atlassian/activeobjects/backup/oracle.xml";
  30. private static final String LEGACY_ORACLE = "/com/atlassian/activeobjects/backup/legacy_oracle.xml";
  31. private static final String POSTGRES = "/com/atlassian/activeobjects/backup/postgres.xml";
  32. private static final String SQLSERVER = "/com/atlassian/activeobjects/backup/sqlserver.xml";
  33. private Model model;
  34. @Test
  35. @NonTransactional
  36. public void testHsqlBackup() throws Exception
  37. {
  38. testBackup(HSQL, HSQL_DATA);
  39. }
  40. @Test
  41. @NonTransactional
  42. public void testHsqlEmptyBackup() throws Exception
  43. {
  44. String xmlBackup = read(HSQL_EMPTY);
  45. checkXmlBackup(xmlBackup, HSQL_DATA);
  46. restore(xmlBackup);
  47. }
  48. @Test
  49. @NonTransactional
  50. public void testMySqlBackup() throws Exception
  51. {
  52. testBackup(MYSQL, MYSQL_DATA);
  53. }
  54. @Test
  55. @NonTransactional
  56. public void testPostgresBackup() throws Exception
  57. {
  58. testBackup(POSTGRES, POSTGRES_DATA);
  59. }
  60. @Test
  61. @NonTransactional
  62. public void testOracleBackup() throws Exception
  63. {
  64. testBackup(ORACLE, ORACLE_DATA);
  65. }
  66. @Test
  67. @NonTransactional
  68. public void testLegacyOracleBackup() throws Exception
  69. {
  70. testBackup(LEGACY_ORACLE, LEGACY_ORACLE_DATA);
  71. }
  72. @Test
  73. @NonTransactional
  74. public void testSqlServerBackup() throws Exception
  75. {
  76. testBackup(SQLSERVER, SQL_SERVER_DATA);
  77. }
  78. public final void testBackup(String xml, Iterable<BackupData> data) throws Exception
  79. {
  80. final String xmlBackup = read(xml);
  81. checkXmlBackup(xmlBackup, data);
  82. restore(xmlBackup);
  83. restore(xmlBackup); // if we don't clean up correctly doing an second restore in a row will fail
  84. assertDataPresent();
  85. final String secondXmlBackup = save();
  86. checkXmlBackup(secondXmlBackup, getCurrentDatabaseData());
  87. }
  88. private Iterable<BackupData> getCurrentDatabaseData()
  89. {
  90. final DatabaseProvider provider = entityManager.getProvider();
  91. if (provider instanceof HSQLDatabaseProvider)
  92. {
  93. return HSQL_DATA;
  94. }
  95. else if (provider instanceof MySQLDatabaseProvider)
  96. {
  97. return MYSQL_DATA;
  98. }
  99. else if (provider instanceof PostgreSQLDatabaseProvider)
  100. {
  101. return POSTGRES_DATA;
  102. }
  103. else if (provider instanceof OracleDatabaseProvider)
  104. {
  105. return ORACLE_DATA;
  106. }
  107. else if (provider instanceof SQLServerDatabaseProvider)
  108. {
  109. return SQL_SERVER_DATA;
  110. }
  111. else
  112. {
  113. throw new IllegalStateException("Can't figure out which DB we're testing against!");
  114. }
  115. }
  116. private void checkXmlBackup(String xmlBackup, Iterable<BackupData> data) throws Exception
  117. {
  118. final XpathEngine engine = newXpathEngine();
  119. final Document doc = XMLUnit.buildControlDocument(xmlBackup);
  120. for (BackupData bd : data)
  121. {
  122. assertHasBackupData(engine, doc, bd);
  123. }
  124. }
  125. private void assertHasBackupData(XpathEngine xpathEngine, Document xmlBackupDoc, BackupData bd) throws Exception
  126. {
  127. assertHasColumn(xpathEngine, xmlBackupDoc, bd.table, bd.column, bd.primaryKey, bd.autoIncrement, bd.sqlType);
  128. }
  129. private void assertHasColumn(XpathEngine xpathEngine, Document xmlBackupDoc, String tableName, String columnName, boolean pK, boolean autoIncrement, SqlType sqlType) throws XpathException
  130. {
  131. NodeList tableNodes = xpathEngine.getMatchingNodes("/ao:backup/ao:table[@name='" + tableName + "']/ao:column[@name='" + columnName + "']", xmlBackupDoc);
  132. assertEquals(1, tableNodes.getLength());
  133. Node table = tableNodes.item(0);
  134. assertAttributeEquals("Expected " + tableName + "." + columnName + " to " + (pK ? "" : "NOT ") + "be a primary key.", table, "primaryKey", pK);
  135. assertAttributeEquals("Expected " + tableName + "." + columnName + " to " + (autoIncrement ? "" : "NOT ") + "be auto increment.", table, "autoIncrement", autoIncrement);
  136. assertAttributeEquals("Expected " + tableName + "." + columnName + " to be of SQL Type: " + sqlType.type, table, "sqlType", sqlType.type);
  137. if (sqlType.precision != null)
  138. {
  139. assertAttributeEquals("Expected " + tableName + "." + columnName + " to have precision: " + sqlType.precision, table, "precision", sqlType.precision);
  140. }
  141. if (sqlType.scale != null)
  142. {
  143. assertAttributeEquals("Expected " + tableName + "." + columnName + " to have scale: " + sqlType.scale, table, "scale", sqlType.scale);
  144. }
  145. assertEquals(1, xpathEngine.getMatchingNodes("/ao:backup/ao:data[@tableName='" + tableName + "']/ao:column[@name='" + columnName + "']", xmlBackupDoc).getLength());
  146. }
  147. private void assertAttributeEquals(String message, Node table, String attribute, Object expected)
  148. {
  149. assertEquals(message, String.valueOf(expected), attributeValue(table, attribute));
  150. }
  151. private XpathEngine newXpathEngine()
  152. {
  153. XpathEngine engine = XMLUnit.newXpathEngine();
  154. engine.setNamespaceContext(new SimpleNamespaceContext(ImmutableMap.of("ao", "http://www.atlassian.com/ao")));
  155. return engine;
  156. }
  157. private String attributeValue(Node node, String name)
  158. {
  159. return node.getAttributes().getNamedItem(name).getNodeValue();
  160. }
  161. private void assertDataPresent()
  162. {
  163. model.checkAuthors();
  164. model.checkBooks();
  165. }
  166. @Before
  167. public void setUpModel()
  168. {
  169. model = new Model(entityManager);
  170. model.emptyDatabase();
  171. }
  172. @After
  173. public void tearDownModel()
  174. {
  175. model = null;
  176. }
  177. private static final class BackupData
  178. {
  179. public final String table, column;
  180. public final boolean primaryKey;
  181. public final boolean autoIncrement;
  182. public final SqlType sqlType;
  183. public BackupData(String table, String column, boolean primaryKey, boolean autoIncrement, SqlType sqlType)
  184. {
  185. this.table = table;
  186. this.column = column;
  187. this.sqlType = sqlType;
  188. this.primaryKey = primaryKey;
  189. this.autoIncrement = autoIncrement;
  190. }
  191. static BackupData of(String table, String column, SqlType sqlType)
  192. {
  193. return of(table, column, sqlType, false, false);
  194. }
  195. static BackupData of(String table, String column, SqlType sqlType, boolean primaryKey, boolean autoIncrement)
  196. {
  197. return new BackupData(table, column, primaryKey, autoIncrement, sqlType);
  198. }
  199. static BackupData of(BackupData data, SqlType sqlType)
  200. {
  201. return of(data.table, data.column, sqlType, data.primaryKey, data.autoIncrement);
  202. }
  203. }
  204. private static final class SqlType
  205. {
  206. public final int type;
  207. public final Integer precision;
  208. public final Integer scale;
  209. public SqlType(int type, Integer precision, Integer scale)
  210. {
  211. this.type = type;
  212. this.precision = precision;
  213. this.scale = scale;
  214. }
  215. static SqlType of(int type)
  216. {
  217. return of(type, null);
  218. }
  219. private static SqlType of(int type, Integer precision)
  220. {
  221. return of(type, precision, null);
  222. }
  223. private static SqlType of(int type, Integer precision, Integer scale)
  224. {
  225. return new SqlType(type, precision, scale);
  226. }
  227. }
  228. private static final BackupData AUTHORSHIP_AUTHOR_ID = BackupData.of("AO_000000_AUTHORSHIP", "AUTHOR_ID", SqlType.of(Types.INTEGER));
  229. private static final BackupData AUTHORSHIP_BOOK_ID = BackupData.of("AO_000000_AUTHORSHIP", "BOOK_ID", SqlType.of(Types.BIGINT));
  230. private static final BackupData AUTHORSHIP_ID = BackupData.of("AO_000000_AUTHORSHIP", "ID", SqlType.of(Types.INTEGER), true, true);
  231. private static final BackupData BOOK_ABSTRACT = BackupData.of("AO_000000_BOOK", "ABSTRACT", SqlType.of(Types.LONGVARCHAR));
  232. private static final BackupData BOOK_ISBN = BackupData.of("AO_000000_BOOK", "ISBN", SqlType.of(Types.BIGINT), true, false);
  233. private static final BackupData BOOK_READ = BackupData.of("AO_000000_BOOK", "IS_READ", SqlType.of(Types.BOOLEAN));
  234. private static final BackupData BOOK_PAGES = BackupData.of("AO_000000_BOOK", "NUMBER_OF_PAGES", SqlType.of(Types.INTEGER));
  235. private static final BackupData BOOK_PRICE = BackupData.of("AO_000000_BOOK", "PRICE", SqlType.of(Types.DOUBLE));
  236. private static final BackupData BOOK_PUBLISHED = BackupData.of("AO_000000_BOOK", "PUBLISHED", SqlType.of(Types.TIMESTAMP));
  237. private static final BackupData BOOK_TITLE = BackupData.of("AO_000000_BOOK", "TITLE", SqlType.of(Types.VARCHAR, 255));
  238. private static final BackupData AUTHOR_NAME = BackupData.of("AO_000000_LONG_NAME_TO_AUTHOR", "NAME", SqlType.of(Types.VARCHAR, 60));
  239. private static final BackupData AUTHOR_ID = BackupData.of("AO_000000_LONG_NAME_TO_AUTHOR", "ID", SqlType.of(Types.INTEGER), true, true);
  240. private static Iterable<BackupData> HSQL_DATA = ImmutableList.of(
  241. AUTHORSHIP_AUTHOR_ID,
  242. AUTHORSHIP_BOOK_ID,
  243. AUTHORSHIP_ID,
  244. BOOK_ABSTRACT,
  245. BOOK_ISBN,
  246. BOOK_READ,
  247. BOOK_PAGES,
  248. BOOK_PRICE,
  249. BOOK_PUBLISHED,
  250. BOOK_TITLE,
  251. AUTHOR_NAME,
  252. AUTHOR_ID
  253. );
  254. private static Iterable<BackupData> MYSQL_DATA = ImmutableList.of(
  255. AUTHORSHIP_AUTHOR_ID,
  256. AUTHORSHIP_BOOK_ID,
  257. AUTHORSHIP_ID,
  258. BOOK_ABSTRACT,
  259. BOOK_ISBN,
  260. BackupData.of(BOOK_READ, SqlType.of(Types.BIT)),
  261. BOOK_PAGES,
  262. BOOK_PRICE,
  263. BOOK_PUBLISHED,
  264. BOOK_TITLE,
  265. AUTHOR_NAME,
  266. AUTHOR_ID
  267. );
  268. private static Iterable<BackupData> POSTGRES_DATA = ImmutableList.of(
  269. AUTHORSHIP_AUTHOR_ID,
  270. AUTHORSHIP_BOOK_ID,
  271. AUTHORSHIP_ID,
  272. BackupData.of(BOOK_ABSTRACT, SqlType.of(Types.VARCHAR, -1)),
  273. BOOK_ISBN,
  274. BackupData.of(BOOK_READ, SqlType.of(Types.BIT)),
  275. BOOK_PAGES,
  276. BOOK_PRICE,
  277. BOOK_PUBLISHED,
  278. BOOK_TITLE,
  279. AUTHOR_NAME,
  280. AUTHOR_ID
  281. );
  282. private static Iterable<BackupData> ORACLE_DATA = ImmutableList.of(
  283. BackupData.of(AUTHORSHIP_AUTHOR_ID, SqlType.of(Types.NUMERIC, 11)),
  284. BackupData.of(AUTHORSHIP_BOOK_ID, SqlType.of(Types.NUMERIC, 20)),
  285. BackupData.of(AUTHORSHIP_ID, SqlType.of(Types.NUMERIC, 11)),
  286. BackupData.of(BOOK_ABSTRACT, SqlType.of(Types.CLOB)),
  287. BackupData.of(BOOK_ISBN, SqlType.of(Types.NUMERIC, 20)),
  288. BackupData.of(BOOK_READ, SqlType.of(Types.NUMERIC, 1)),
  289. BackupData.of(BOOK_PAGES, SqlType.of(Types.NUMERIC, 11)),
  290. BackupData.of(BOOK_PRICE, SqlType.of(Types.NUMERIC, 126)),
  291. BOOK_PUBLISHED,
  292. BOOK_TITLE,
  293. AUTHOR_NAME,
  294. BackupData.of(AUTHOR_ID, SqlType.of(Types.NUMERIC, 11))
  295. );
  296. private static Iterable<BackupData> LEGACY_ORACLE_DATA = ImmutableList.of(
  297. BackupData.of(AUTHORSHIP_AUTHOR_ID, SqlType.of(Types.NUMERIC, 11)),
  298. BackupData.of(AUTHORSHIP_BOOK_ID, SqlType.of(Types.NUMERIC, 20)),
  299. BackupData.of(AUTHORSHIP_ID, SqlType.of(Types.NUMERIC, 11)),
  300. BackupData.of(BOOK_ABSTRACT, SqlType.of(Types.CLOB)),
  301. BackupData.of(BOOK_ISBN, SqlType.of(Types.NUMERIC, 20)),
  302. BackupData.of(BOOK_READ, SqlType.of(Types.NUMERIC, 1)),
  303. BackupData.of(BOOK_PAGES, SqlType.of(Types.NUMERIC, 11)),
  304. BackupData.of(BOOK_PRICE, SqlType.of(Types.NUMERIC, 32, 16)),
  305. BOOK_PUBLISHED,
  306. BOOK_TITLE,
  307. AUTHOR_NAME,
  308. BackupData.of(AUTHOR_ID, SqlType.of(Types.NUMERIC, 11))
  309. );
  310. private static Iterable<BackupData> SQL_SERVER_DATA = ImmutableList.of(
  311. AUTHORSHIP_AUTHOR_ID,
  312. AUTHORSHIP_BOOK_ID,
  313. AUTHORSHIP_ID,
  314. BackupData.of(BOOK_ABSTRACT, SqlType.of(Types.CLOB)),
  315. BOOK_ISBN,
  316. BackupData.of(BOOK_READ, SqlType.of(Types.BIT)),
  317. BOOK_PAGES,
  318. BOOK_PRICE,
  319. BOOK_PUBLISHED,
  320. BOOK_TITLE,
  321. AUTHOR_NAME,
  322. AUTHOR_ID
  323. );
  324. }