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