Salome HOME
Added checking of a document state when replacing a source file. Exception is thrown...
[tools/siman.git] / Workspace / Siman-Common / src / test / splat / common / BaseTest.java
1 /*****************************************************************************
2  * Company         OPEN CASCADE
3  * Application     SIMAN
4  * File            $Id$ 
5  * Creation date   12 Oct 2012
6  * @author         $Author$
7  * @version        $Revision$
8  *****************************************************************************/
9
10 package test.splat.common;
11
12 import java.io.File;
13 import java.io.FileWriter;
14 import java.io.IOException;
15 import java.util.Date;
16 import java.util.List;
17 import java.util.Map;
18
19 import javax.sql.DataSource;
20
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;
45
46 /**
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.
51  * 
52  * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
53  * 
54  */
55
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" 
63 })
64 @TransactionConfiguration(defaultRollback = true, transactionManager = "txManager")
65 @Test(singleThreaded=true, groups = {"service", "functional", "business"})
66 public class BaseTest extends TestListingAndOrder {
67
68         // ========================================= static methods
69         /**
70          * Logger for the class.
71          */
72         private static final AppLogger LOG = AppLogger.getLogger(BaseTest.class);
73         
74         /**
75          * The helper class to work with hibernate session.
76          */
77         private HibernateTemplate _hibernateTemplate;
78         
79         /**
80          * Get the hibernateTemplate.
81          * @return the hibernateTemplate
82          */
83         @Test(enabled = false)
84         public HibernateTemplate getHibernateTemplate() {
85                 return _hibernateTemplate;
86         }
87
88         // ======================================= static variables
89         /**
90          * {@inheritDoc}
91          * 
92          * @see org.springframework.test.context.testng.AbstractTransactionalTestNGSpringContextTests#setDataSource(javax.sql.DataSource)
93          */
94         @Override
95         @Autowired
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);
102         }
103
104         /**
105          * Set a hibernate session factory.
106          * @param aSessionFactory the hibernate session factory
107          */
108         @Autowired
109         @Test(enabled = false)
110         public void setSessionFactory(@Qualifier("simanSessionFactory")
111         final SessionFactory aSessionFactory) {
112                 _hibernateTemplate = new HibernateTemplate(aSessionFactory);
113         }
114         
115         /**
116          * Method for the test data creation. It is called before the first test
117          * starting.
118          */
119         @BeforeClass
120         public void initClass() {
121                 try {
122                         // Initialize UserContext
123 //                      initUserContext();
124                         
125                 } catch (Exception e) {
126                         Assert.fail("Exception occured during the testing data creation. ", e);
127                 }
128         }
129         
130         
131         /**
132          * Insert base data before each method : matricule, department, language, reference.
133          */
134         @BeforeMethod
135         public void insertBaseDataBeforeMethod() {
136                 LOG.debug(" >>>>>>>>>>>>>>> COMMON - insertBaseDataBeforeMethod");
137                 
138         }
139
140         // [PRIVATE METHOD] ------------------------------ 
141         
142         // [DATA PROVIDER METHOD : Insert / Select] ------------------------------ 
143         /**
144          * Insert data for test : document. 
145          * @param document BO
146          */
147 //      protected void insertData(final DocumentWithBLOBs document) {
148 //              // Insert document
149 //              _documentDAO.insert(document);
150 //      }
151         
152         /**
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
156          */
157         @SuppressWarnings("deprecation")
158         protected void executeAndDisplaySqlStatement(final String statement) {
159                 List<Map<String, Object>> resultSet = simpleJdbcTemplate.queryForList(statement);
160                 displayResultset(resultSet);
161         }
162         
163         /**
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
168          */
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);
173         }
174
175         /**
176          * Displays resultset in log.
177          * @param resultSet the resultset to display.
178          */
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());
183                         
184                         for (Map<String, Object> line : resultSet) {
185                                 StringBuilder logLine = new StringBuilder("[");
186                                 logLine.append(line.values());
187                                 logLine.append("[");
188                                 LOG.debug(logLine.toString());
189                         }
190                 }
191         }
192         
193         
194         // ==========================================================================
195         // NESTED TRANSACTIONS MANAGEMENT
196         // ==========================================================================
197         
198         /**
199          * Used for nested transactions management.
200          */
201         private transient TransactionStatus _nestedTxStatus;
202
203         /**
204          * The StepService. Later injected by Spring.
205          */
206         @Autowired
207         @Qualifier("stepService")
208         private transient StepService _stepService;
209
210         /**
211          * The PublicationService. Later injected by Spring.
212          */
213         @Autowired
214         @Qualifier("publicationService")
215         private transient PublicationService _publicationService;
216
217         /**
218          * The RepositoryService. Later injected by Spring.
219          */
220         @Autowired
221         @Qualifier("repositoryService")
222         private transient RepositoryService _repositoryService;
223         
224         /**
225          * Use this method to start a new transaction within an existing one. 
226      * Consider the following test scenario:
227          *   testXX():
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();
235          *        - service.XX();
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.
239          * 
240          * Consider an alternative approach:
241          *   testXX():
242          *     1: check service.XX on valid data:
243          *        - createInitialData();
244          *        - startNestedTransaction();
245          *        - service.XX();
246          *        - rollbackNestedTransaction();
247          *     2: check service.XX on invalid data:
248          *        - startNestedTransaction();
249          *        - adjustInitialData();
250          *        - service.XX();
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()     
254          */
255         protected void startNestedTransaction() {
256                 AbstractPlatformTransactionManager txManager = 
257                         (AbstractPlatformTransactionManager) applicationContext.getBean("txManager");
258                 
259                 DefaultTransactionDefinition txDefinition = new DefaultTransactionDefinition();
260                 txDefinition.setPropagationBehavior(TransactionDefinition.PROPAGATION_NESTED);
261                 
262                 _nestedTxStatus = txManager.getTransaction(txDefinition);
263 }
264         
265         /**
266          * Rollbacks the nested transaction.
267          * @see test.areva.hewis.mlst2.service.gpao.rpta.TaBaseService#startNestedTransaction()
268          */
269         protected void rollbackNestedTransaction() {
270                 AbstractPlatformTransactionManager txManager = 
271                         (AbstractPlatformTransactionManager) applicationContext.getBean("txManager");
272                 txManager.rollback(_nestedTxStatus);
273         }
274         
275
276         /**
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()
280          */
281         protected void rollbackAndRestartNestedTransaction() {
282                 rollbackNestedTransaction();
283                 startNestedTransaction();
284         }
285
286         /**
287          * Create a file.
288          * 
289          * @param fname
290          *            file name
291          * @throws IOException
292          *             if file creation failed
293          */
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());
300                 fw.close();
301         }
302
303         /**
304          * Create a new version of the document.
305          * 
306          * @param pub
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
313          */
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,
320                                 dprop);
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);
327                 return newpub;
328         }
329
330         /**
331          * Create a document and publish it in the project element.
332          * 
333          * @param aProjElem
334          *            the project element
335          * @param aStep
336          *            the project element step
337          * @param docname
338          *            document name
339          * @param dtype
340          *            document type
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
346          */
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);
358                 pub.setStep(aStep);
359                 aProjElem.add(pub);
360                 aStep.getDocuments().add(pub);
361                 ht.saveOrUpdate(pub);
362                 ht.save(pub.value());
363                 // Add a converts relation
364                 // Attach a med file
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");
369                 return pub;
370         }
371
372         /**
373          * Get path to the user's downloads directory. The directory is created if it is not exist yet.
374          * 
375          * @param userId
376          *            user id
377          * @return absolute path to downloads directory followed by slash
378          */
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());
386                 }
387         
388                 return tmpDir.getAbsolutePath() + "/";
389         }
390 }