1 /*****************************************************************************
5 * Creation date 12 Oct 2012
8 *****************************************************************************/
10 package test.splat.common;
13 import java.io.FileWriter;
14 import java.io.IOException;
15 import java.util.Date;
16 import java.util.List;
19 import javax.sql.DataSource;
21 import org.hibernate.SessionFactory;
22 import org.splat.dal.bo.som.Document;
23 import org.splat.dal.bo.som.DocumentType;
24 import org.splat.dal.bo.som.ProjectElement;
25 import org.splat.dal.bo.som.Publication;
26 import org.splat.exception.BusinessException;
27 import org.splat.log.AppLogger;
28 import org.splat.service.PublicationService;
29 import org.splat.service.StepService;
30 import org.splat.service.technical.RepositoryService;
31 import org.springframework.beans.factory.annotation.Autowired;
32 import org.springframework.beans.factory.annotation.Qualifier;
33 import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
34 import org.springframework.orm.hibernate3.HibernateTemplate;
35 import org.springframework.test.context.ContextConfiguration;
36 import org.springframework.test.context.transaction.TransactionConfiguration;
37 import org.springframework.transaction.TransactionDefinition;
38 import org.springframework.transaction.TransactionStatus;
39 import org.springframework.transaction.support.AbstractPlatformTransactionManager;
40 import org.springframework.transaction.support.DefaultTransactionDefinition;
41 import org.testng.Assert;
42 import org.testng.annotations.BeforeClass;
43 import org.testng.annotations.BeforeMethod;
44 import org.testng.annotations.Test;
47 * Base Siman Test class. Each test method is transactional by default.
48 * Use <code>NotTransactional</code> annotation to declare test method as not transactional.
49 * By default all operations on database are rolledback after each test method.
50 * To avoid this use <code>Rollback(false)</code> annotation.
52 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
56 @ContextConfiguration(locations = {
57 "/test/spring/ut-applicationContext.xml",
58 "/test/spring/ut-datasourceContext.xml",
59 "/spring/businessServiceContext.xml",
60 "/spring/daoContext.xml",
61 "/spring/globalContext.xml",
62 "/spring/technicalServiceContext.xml"
64 @TransactionConfiguration(defaultRollback = true, transactionManager = "txManager")
65 @Test(singleThreaded=true, groups = {"service", "functional", "business"})
66 public class BaseTest extends TestListingAndOrder {
68 // ========================================= static methods
70 * Logger for the class.
72 private static final AppLogger LOG = AppLogger.getLogger(BaseTest.class);
75 * The helper class to work with hibernate session.
77 private HibernateTemplate _hibernateTemplate;
80 * Get the hibernateTemplate.
81 * @return the hibernateTemplate
83 @Test(enabled = false)
84 public HibernateTemplate getHibernateTemplate() {
85 return _hibernateTemplate;
88 // ======================================= static variables
92 * @see org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests#setDataSource(javax.sql.DataSource)
96 @Test(enabled = false)
97 // public void setDataSource(@Qualifier("p6spyiBatisDatasource")
98 @SuppressWarnings("deprecation")
99 public void setDataSource(@Qualifier("simanDatasource")
100 final DataSource dataSource) {
101 this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
105 * Set a hibernate session factory.
106 * @param aSessionFactory the hibernate session factory
109 @Test(enabled = false)
110 public void setSessionFactory(@Qualifier("simanSessionFactory")
111 final SessionFactory aSessionFactory) {
112 _hibernateTemplate = new HibernateTemplate(aSessionFactory);
116 * Method for the test data creation. It is called before the first test
120 public void initClass() {
122 // Initialize UserContext
123 // initUserContext();
125 } catch (Exception e) {
126 Assert.fail("Exception occured during the testing data creation. ", e);
132 * Insert base data before each method : matricule, department, language, reference.
135 public void insertBaseDataBeforeMethod() {
136 LOG.debug(" >>>>>>>>>>>>>>> COMMON - insertBaseDataBeforeMethod");
140 // [PRIVATE METHOD] ------------------------------
142 // [DATA PROVIDER METHOD : Insert / Select] ------------------------------
144 * Insert data for test : document.
147 // protected void insertData(final DocumentWithBLOBs document) {
148 // // Insert document
149 // _documentDAO.insert(document);
153 * Uses the current transaction to execute SQL statement in order to be able to
154 * see the current state of the database.
155 * @param statement the sql statement
157 @SuppressWarnings("deprecation")
158 protected void executeAndDisplaySqlStatement(final String statement) {
159 List<Map<String, Object>> resultSet = simpleJdbcTemplate.queryForList(statement);
160 displayResultset(resultSet);
164 * Uses the current transaction to execute SQL statement in order to be able to
165 * see the current state of the database.
166 * @param statement the sql statement
167 * @param args the sql statement parameters
169 @SuppressWarnings("deprecation")
170 protected void executeAndDisplaySqlStatement(final String statement, final Object...args) {
171 List<Map<String, Object>> resultSet = simpleJdbcTemplate.queryForList(statement, args);
172 displayResultset(resultSet);
176 * Displays resultset in log.
177 * @param resultSet the resultset to display.
179 private void displayResultset(final List<Map<String, Object>> resultSet) {
180 if(!resultSet.isEmpty()) {
181 Map<String, Object> firstElement = resultSet.get(0);
182 LOG.debug(firstElement.keySet().toString());
184 for (Map<String, Object> line : resultSet) {
185 StringBuilder logLine = new StringBuilder("[");
186 logLine.append(line.values());
188 LOG.debug(logLine.toString());
194 // ==========================================================================
195 // NESTED TRANSACTIONS MANAGEMENT
196 // ==========================================================================
199 * Used for nested transactions management.
201 private transient TransactionStatus _nestedTxStatus;
204 * The StepService. Later injected by Spring.
207 @Qualifier("stepService")
208 private transient StepService _stepService;
211 * The PublicationService. Later injected by Spring.
214 @Qualifier("publicationService")
215 private transient PublicationService _publicationService;
218 * The RepositoryService. Later injected by Spring.
221 @Qualifier("repositoryService")
222 private transient RepositoryService _repositoryService;
225 * Use this method to start a new transaction within an existing one.
226 * Consider the following test scenario:
228 * 1: check service.XX on valid data:
229 * - createInitialData();
230 * - service.XX(); (performs some changes on initial data)
231 * 2: check service.XX on invalid data:
232 * - deleteInitialData(); (as data were changed by previous call)
233 * - createInitialData();
234 * - adjustInitialData();
236 * To make such a test we need to provide deleteInitialData() method and call
237 * createInitialData() twice. The latter might lead to significant increasing of
238 * the test execution time.
240 * Consider an alternative approach:
242 * 1: check service.XX on valid data:
243 * - createInitialData();
244 * - startNestedTransaction();
246 * - rollbackNestedTransaction();
247 * 2: check service.XX on invalid data:
248 * - startNestedTransaction();
249 * - adjustInitialData();
251 * - rollbackNestedTransaction();
252 * Thus you're able to create and manage the nested transactions programmatically.
253 * @see test.areva.hewis.mlst2.service.gpao.rpta.TaBaseService#rollbackNestedTransaction()
255 protected void startNestedTransaction() {
256 AbstractPlatformTransactionManager txManager =
257 (AbstractPlatformTransactionManager) applicationContext.getBean("txManager");
259 DefaultTransactionDefinition txDefinition = new DefaultTransactionDefinition();
260 txDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
262 _nestedTxStatus = txManager.getTransaction(txDefinition);
266 * Rollbacks the nested transaction.
267 * @see test.areva.hewis.mlst2.service.gpao.rpta.TaBaseService#startNestedTransaction()
269 protected void rollbackNestedTransaction() {
270 AbstractPlatformTransactionManager txManager =
271 (AbstractPlatformTransactionManager) applicationContext.getBean("txManager");
272 txManager.rollback(_nestedTxStatus);
277 * Rollbacks the nested transaction and start a new one.
278 * @see test.areva.hewis.mlst2.service.gpao.rpta.TaBaseService#startNestedTransaction()
279 * @see test.areva.hewis.mlst2.service.gpao.rpta.TaBaseService#rollbackNestedTransaction()
281 protected void rollbackAndRestartNestedTransaction() {
282 rollbackNestedTransaction();
283 startNestedTransaction();
291 * @throws IOException
292 * if file creation failed
294 protected void createFile(final String fname) throws IOException {
295 // Create a file in the download directory
296 LOG.debug("Create file: " + fname);
297 String filePath = fname;
298 FileWriter fw = new FileWriter(filePath);
299 fw.write("Simulation of " + fname + " data file at " + new Date());
304 * Create a new version of the document.
307 * the current document publication
308 * @return the new document version publication
309 * @throws IOException
310 * if versioning is failed
311 * @throws BusinessException
312 * if versioning is failed
314 protected Publication version(final Publication pub)
315 throws BusinessException, IOException {
316 Document.Properties dprop = new Document.Properties();
317 dprop.setDocument(pub.value(), pub.getStep().getStep());
318 dprop.setLocalPath(pub.value().getTitle() + "_v1");
319 Publication newpub = _stepService.versionDocument(pub.getStep(), pub,
321 pub.getOwner().getDocums().remove(pub);
322 pub.getStep().getDocuments().remove(pub);
323 pub.getOwner().add(newpub);
324 pub.getStep().getDocuments().add(newpub);
325 String filepath = newpub.getSourceFile().asFile().getAbsolutePath();
326 createFile(filepath);
331 * Create a document and publish it in the project element.
334 * the project element
336 * the project element step
341 * @return publication of the created document
342 * @throws BusinessException
343 * if document creation is failed
344 * @throws IOException
345 * if file creation is failed
347 protected Publication addDoc(final ProjectElement aProjElem,
348 final org.splat.som.Step aStep, final String docname,
349 final DocumentType dtype) throws BusinessException, IOException {
350 HibernateTemplate ht = getHibernateTemplate();
351 // Add documents to the study activity
352 Document.Properties dprop = new Document.Properties().setAuthor(
353 aProjElem.getAuthor()).setDate(new Date()).setName(docname)
354 .setType(dtype).setFormat("py");
355 dprop.setLocalPath(dprop.getName() + "." + dprop.getFormat());
356 dprop.setStep(aStep.getStep());
357 Publication pub = _stepService.createDocument(aStep, dprop);
360 aStep.getDocuments().add(pub);
361 ht.saveOrUpdate(pub);
362 ht.save(pub.value());
363 // Add a converts relation
365 ht.saveOrUpdate(_publicationService.attach(pub, "med"));
366 String filepath = pub.getSourceFile().asFile().getAbsolutePath();
367 createFile(filepath);
368 createFile(filepath.substring(0, filepath.lastIndexOf(".")) + ".med");
373 * Get path to the user's downloads directory. The directory is created if it is not exist yet.
377 * @return absolute path to downloads directory followed by slash
379 protected String getDownloadPath(final long userId) {
380 // Prepare download directory
381 File tmpDir = _repositoryService.getDownloadDirectory(userId);
382 if (!tmpDir.exists()) {
383 Assert.assertTrue(tmpDir.mkdir(),
384 "Can't create temporary directory: "
385 + tmpDir.getAbsolutePath());
388 return tmpDir.getAbsolutePath() + "/";