1 /*****************************************************************************
5 * Creation date 12 Oct 2012
8 *****************************************************************************/
9 package test.splat.service;
12 import java.io.FileNotFoundException;
13 import java.io.FileWriter;
14 import java.io.IOException;
15 import java.sql.SQLException;
16 import java.util.ArrayList;
17 import java.util.Date;
18 import java.util.HashMap;
19 import java.util.List;
23 import org.splat.dal.bo.kernel.Relation;
24 import org.splat.dal.bo.kernel.User;
25 import org.splat.dal.bo.som.ConvertsRelation;
26 import org.splat.dal.bo.som.Document;
27 import org.splat.dal.bo.som.DocumentType;
28 import org.splat.dal.bo.som.KnowledgeElementType;
29 import org.splat.dal.bo.som.Publication;
30 import org.splat.dal.bo.som.Scenario;
31 import org.splat.dal.bo.som.SimulationContext;
32 import org.splat.dal.bo.som.SimulationContextType;
33 import org.splat.dal.bo.som.Study;
34 import org.splat.dal.bo.som.UsedByRelation;
35 import org.splat.dal.bo.som.UsesRelation;
36 import org.splat.dal.bo.som.Document.Properties;
37 import org.splat.dal.dao.kernel.UserDAO;
38 import org.splat.dal.dao.som.Database;
39 import org.splat.dal.dao.som.ScenarioDAO;
40 import org.splat.exception.BusinessException;
41 import org.splat.i18n.I18nUtils;
42 import org.splat.kernel.InvalidPropertyException;
43 import org.splat.kernel.MismatchException;
44 import org.splat.kernel.MissedPropertyException;
45 import org.splat.kernel.MultiplyDefinedException;
46 import org.splat.kernel.NotApplicableException;
47 import org.splat.log.AppLogger;
48 import org.splat.service.DocumentTypeService;
49 import org.splat.service.KnowledgeElementTypeService;
50 import org.splat.service.PublicationService;
51 import org.splat.service.ScenarioService;
52 import org.splat.service.SimulationContextService;
53 import org.splat.service.StepService;
54 import org.splat.service.StudyService;
55 import org.splat.service.dto.DocumentDTO;
56 import org.splat.service.dto.FileDTO;
57 import org.splat.service.dto.StepDTO;
58 import org.splat.service.technical.ProjectSettingsService;
59 import org.splat.service.technical.RepositoryService;
60 import org.splat.service.technical.StepsConfigService;
61 import org.splat.service.technical.ProjectSettingsService.Step;
62 import org.springframework.beans.factory.annotation.Autowired;
63 import org.springframework.beans.factory.annotation.Qualifier;
64 import org.springframework.orm.hibernate3.HibernateTemplate;
65 import org.testng.Assert;
66 import org.testng.annotations.Test;
67 import org.testng.reporters.Files;
69 import test.splat.common.BaseTest;
70 import test.splat.util.TestEntitiesGenerator;
73 * Test class for ScenarioService.
75 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
78 public class TestScenarioService extends BaseTest {
81 * Logger for the class.
83 private static final AppLogger LOG = AppLogger
84 .getLogger(TestScenarioService.class);
87 * The tested ScenarioService. Later injected by Spring.
90 @Qualifier("scenarioService")
91 private transient ScenarioService _scenarioService;
94 * The RepositoryService. Later injected by Spring.
97 @Qualifier("repositoryService")
98 private transient RepositoryService _repositoryService;
101 * The Scenario DAO. Later injected by Spring.
104 @Qualifier("scenarioDAO")
105 private transient ScenarioDAO _scenarioDAO;
108 * The PublicationService. Later injected by Spring.
111 @Qualifier("publicationService")
112 private transient PublicationService _publicationService;
115 * The StepService. Later injected by Spring.
118 @Qualifier("stepService")
119 private transient StepService _stepService;
122 * The SimulationContextService. Later injected by Spring.
125 @Qualifier("simulationContextService")
126 private transient SimulationContextService _simulationContextService;
129 * The ProjectSettingsService. Later injected by Spring.
132 @Qualifier("projectSettings")
133 private transient ProjectSettingsService _projectSettings;
136 * The StepsConfigService. Later injected by Spring.
139 @Qualifier("stepsConfigService")
140 private transient StepsConfigService _stepsConfigService;
143 * The DocumentTypeService. Later injected by Spring.
146 @Qualifier("documentTypeService")
147 private transient DocumentTypeService _documentTypeService;
150 * The KnowledgeElementTypeService. Later injected by Spring.
153 @Qualifier("knowledgeElementTypeService")
154 private transient KnowledgeElementTypeService _knowledgeElementTypeService;
157 * The UserDAO. Later injected by Spring.
160 @Qualifier("userDAO")
161 private transient UserDAO _userDAO;
164 * The StudyService. Later injected by Spring.
167 @Qualifier("studyService")
168 private transient StudyService _studyService;
171 * Test of getting a scenario content for building siman-salome.conf.<BR>
172 * <B>Description :</B> <BR>
173 * <i>Create a scenario and try to get an info for it.</i><BR>
174 * <B>Action : </B><BR>
175 * <i>1. call the method for an existing scenario id.</i><BR>
176 * <i>2. call the method for a not existing scenario id.</i><BR>
177 * <B>Test data : </B><BR>
178 * <i>no input parameters</i><BR>
179 * <i>no input parameters</i><BR>
181 * <B>Outcome results:</B><BR>
184 * <li>result DTO must contain list of all documents and files<BR>
186 * <li>Exception is thrown<BR>
191 * @throws InvalidPropertyException
192 * if an invalid property is used when creating objects
193 * @throws MultiplyDefinedException
194 * when trying to create an object with already existing id
195 * @throws MissedPropertyException
196 * if a mandatory property is not defined for an object to be created
197 * @throws IOException
198 * if scenario creation is failed
199 * @throws SQLException
200 * if scenario creation is failed
202 @Test(groups = { "checkout", "sevice", "functional", "business" })
203 public void testGetScenarioInfo() throws InvalidPropertyException,
204 MissedPropertyException, MultiplyDefinedException, IOException,
206 LOG.debug(">>>>> BEGIN testGetScenarioInfo()");
207 startNestedTransaction();
209 long scenarioId = createScenario();
210 // Call DAO's create method for a good transient knowledge element.
211 List<StepDTO> steps = _scenarioService.getScenarioInfo(scenarioId);
212 Assert.assertNotNull(steps, "List of steps must not be null.");
213 Assert.assertTrue(steps.size() > 0, "No steps are read.");
215 List<Step> projSteps = _stepsConfigService.getStepsOf(Scenario.class);
216 Assert.assertEquals(steps.size(), projSteps.size(),
217 "Not all steps are listed.");
219 for (StepDTO step : steps) {
220 LOG.debug("check the step " + step.getNumber() + ":\n" + step);
221 Assert.assertNotNull(step, "Step DTO must not be null.");
222 Assert.assertNotNull(step.getKey(), "Step name must not be null.");
223 Assert.assertFalse(step.getKey().isEmpty(),
224 "Step name must not empty.");
225 Assert.assertTrue(step.getNumber() > 0,
226 "Step number must be positive integer.");
227 Assert.assertNotNull(step.getDocs(),
228 "Step documents list must not be null.");
230 Step aProjStep = null;
231 for (Step projStep : projSteps) {
232 if (projStep.getNumber() == step.getNumber()) {
233 aProjStep = projStep;
238 List<DocumentType> dtypes = _documentTypeService
239 .selectTypesOf(aProjStep);
240 for (DocumentType dtype : dtypes) {
241 Assert.assertTrue(step.getDocs().size() > 0,
242 "Step documents list must not be empty.");
243 String docName = "document" + docIndex;
244 for (DocumentDTO doc : step.getDocs()) {
245 if (docName.equals(doc.getTitle())) {
246 Assert.assertTrue(doc.getId() > 0,
247 "Document id must be positive integer.");
248 Assert.assertEquals(doc.getTitle(), docName);
249 Assert.assertNotNull(doc.getFiles(),
250 "Document files list must not be null.");
252 .assertTrue(doc.getFiles().size() > 1,
253 "Document must have more then 1 attached file.");
255 for (FileDTO file : doc.getFiles()) {
256 Assert.assertNotNull(file.getPath(),
257 "File path must not be null.");
258 Assert.assertFalse(file.getPath().isEmpty(),
259 "File path must not be empty.");
261 * <mappings> <document type="geometry"> <import format="brep"/> <!-- Result Shape --> </document> <document
262 * type="model"> <import format="med"/> <!-- Result mesh without input parameters --> </document> <document
263 * type="loads"> <import format="c3m"/> <!-- Input data created interactively --> </document> <document
264 * type="results"> <import format="med"/> <!-- Calculation results source file --> </document> </mappings>
266 // Check state and processing instruction
267 String fileFormat = file.getPath().substring(
268 file.getPath().lastIndexOf('.') + 1);
270 * if (_projectSettings.doImport(dtype.getName(), fileFormat)) { Assert.assertTrue(file.isResult(), "The file
271 * must be a result file."); } else { Assert.assertFalse(file.isResult(), "The file must be a source file."); }
272 */if ((docIndex % 2) == 0) { // New
273 Assert.assertEquals(file.getState(), 'Y',
274 "File state must be actual ('Y').");
275 if (_projectSettings.doImport(dtype.getName(),
277 Assert.assertEquals(file.getProcessing(),
279 "File must be imported.");
281 Assert.assertEquals(file.getProcessing(),
283 "File must be downloaded.");
286 Assert.assertEquals(file.getState(), 'O',
287 "File state must be outdated ('O').");
289 .assertEquals(file.getProcessing(),
291 "Outdated document should not be imported but downloaded.");
300 // Call DAO's get method for a not existing id.
302 steps = _scenarioService.getScenarioInfo(-1L);
303 // getHibernateTemplate().flush();
305 .fail("Getting an object with not existing id must be failed.");
306 } catch (Exception e) {
307 LOG.debug("Expected exception is thrown: "
308 + e.getClass().getSimpleName() + ": " + e.getMessage());
310 rollbackNestedTransaction();
311 LOG.debug(">>>>> END testGetScenarioInfo()");
315 * Test check-in scenario operation to be performed after SALOME session.<BR>
316 * <B>Description :</B> <BR>
317 * <i>Create a scenario and try to check-in it with some simulated SALOME results data.<BR>
318 * After check-in verify following points:
320 * <li>scenario is no more marked as checked out</li>
321 * <li>new document versions are created for checked in documents</li>
322 * <li>presentation of the previous version is removed</li>
323 * <li>uses relations are copied correctly</li>
324 * <li>files are moved correctly</li>
325 * <li>formats of files are new if they are according to the document's type on the study step</li>
326 * <li>new documents are created for new data</li>
327 * <li>new documents have correctly generated names</li>
328 * <li>uses relations are created correctly</li>
329 * <li>files are moved correctly</li>
332 * <B>Action : </B><BR>
333 * <i>1. call the method for an existing scenario id.</i><BR>
334 * <i>2. call the method for a not existing scenario id.</i><BR>
335 * <B>Test data : </B><BR>
336 * <i>no input parameters</i><BR>
337 * <i>no input parameters</i><BR>
339 * <B>Outcome results:</B><BR>
342 * <li>New version of existing documents must be created and new documents must be imported for documents with zero id. Correct
343 * relations must be created.<BR>
345 * <li>Exception is thrown<BR>
350 * @throws InvalidPropertyException
351 * if an invalid property is used when creating objects
352 * @throws MultiplyDefinedException
353 * when trying to create an object with already existing id
354 * @throws MissedPropertyException
355 * if a mandatory property is not defined for an object to be created
356 * @throws IOException
357 * if scenario creation is failed
358 * @throws SQLException
359 * if scenario creation is failed
360 * @throws NotApplicableException
362 * @throws MismatchException
365 @Test(groups = { "checkin", "sevice", "functional", "business" })
366 public void testCheckin() throws InvalidPropertyException,
367 MissedPropertyException, MultiplyDefinedException, IOException,
368 SQLException, MismatchException, NotApplicableException {
369 LOG.debug(">>>>> BEGIN testCheckin()");
370 startNestedTransaction();
372 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
373 _projectSettings.configure("classpath:test/som.xml");
374 getHibernateTemplate().flush();
375 long scenarioId = createScenario();
376 Scenario aScen = _scenarioDAO.get(scenarioId);
377 User user = aScen.getAuthor();
378 long userId = user.getIndex();
380 // ////////////////////////////////////////////////////////
381 // Call checkin method for empty list of modules.
384 List<StepDTO> steps = _scenarioService.getScenarioInfo(scenarioId);
385 _scenarioService.checkout(aScen, user);
386 _scenarioDAO.flush();
387 // Check that scenario is no more marked as checked out
388 aScen = _scenarioDAO.get(scenarioId);
389 Assert.assertTrue(aScen.isCheckedout(),
390 "Scenario is not marked as checked out after checkout.");
392 // Prepare test data for checkin
393 // Checkin only two first steps (geom and mesh)
394 List<StepDTO> stepsToCheckin = new ArrayList<StepDTO>();
396 _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
398 _scenarioDAO.flush();
399 // Check that scenario is no more marked as checked out
400 aScen = _scenarioDAO.get(scenarioId);
401 Assert.assertFalse(aScen.isCheckedout(),
402 "Scenario is still marked as checked out after checkin.");
404 // ////////////////////////////////////////////////////////
405 // Call checkin method for good prepared transient data.
408 steps = _scenarioService.getScenarioInfo(scenarioId);
409 _scenarioService.checkout(aScen, user);
411 // Remember modification dates of all attached files
412 Map<Long, Date> dates = new HashMap<Long, Date>();
413 for (Publication p : aScen.getDocums()) {
414 for (Relation r : p.value().getRelations(ConvertsRelation.class)) {
415 org.splat.dal.bo.som.File attach = ((ConvertsRelation) r)
417 dates.put(attach.getIndex(), attach.getDate());
421 // Prepare test data for checkin
422 // Checkin only two first steps (geom and mesh)
423 for (StepDTO step : steps) {
424 // Prepare GEOM: checkin actual brep
425 StepDTO stepToCheckin = createDocDTOForModule(null, "GEOM", "brep",
426 userId, step, stepsToCheckin);
427 createDocDTOForModule(stepToCheckin, "SMESH", "med", userId, step,
431 _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
433 _scenarioDAO.flush();
434 // Check that scenario is no more marked as checked out
435 aScen = _scenarioDAO.get(scenarioId);
436 Assert.assertFalse(aScen.isCheckedout(),
437 "Scenario is still marked as checked out after checkin.");
438 boolean modifDatesChecked = false;
439 // Check that new document versions are created for checked in documents
440 for (StepDTO step : stepsToCheckin) {
441 for (DocumentDTO docDTO : step.getDocs()) {
442 if ((docDTO.getId() != 0) && (docDTO.getId() != null)) {
443 boolean found = false;
444 Document prevDoc = null;
445 Document curDoc = null;
446 Publication newPub = null;
447 for (Publication pub : aScen.getDocums()) {
448 prevDoc = pub.value().getPreviousVersion();
449 if (prevDoc != null) {
450 found = (prevDoc.getIndex() == docDTO.getId());
451 if (found) { // Found next published version of the checked in document
456 if (pub.value().getIndex() == docDTO.getId()) {
457 // Document version was not changed, old document is still published
458 curDoc = pub.value();
462 Assert.assertTrue(found || (curDoc != null),
463 "New version or new attached file of the existing checked in document \""
464 + docDTO.getTitle() + "\" (id="
466 + ") is not found in the scenario.");
467 // If previous version is found then the format must be the same
468 String newFormat = docDTO.getFiles().get(0).getPath()
470 docDTO.getFiles().get(0).getPath()
471 .lastIndexOf('.') + 1);
473 Assert.assertEquals(prevDoc.getFormat(), newFormat,
474 "Formats of versions must be same");
475 Assert.assertFalse(aScen.publishes(prevDoc));
476 // Check that presentation of the previous version is removed
477 checkFiles(docDTO, newPub);
479 // Formats of files are new if they are according to the document's type on the study step
480 if ("py".equals(prevDoc.getFormat())
481 && "geometry".equals(prevDoc.getType()
483 Assert.assertEquals(newPub.value().getFormat(),
485 Assert.assertEquals(newPub.getSourceFile()
486 .getFormat(), "brep");
487 Assert.assertEquals(newPub.getSourceFile()
488 .getRelativePath().substring(
489 newPub.getSourceFile()
491 .lastIndexOf('.') + 1),
495 // Check that uses relations are copied correctly
497 // 1. Get all uses relations of the previous document version
498 for (Relation rel : prevDoc
499 .getRelations(UsesRelation.class)) {
500 Document used = ((UsesRelation) rel).getTo();
501 // 2.1. Get the latest version of the document published in this scenario
502 Publication toBeUsed = aScen.getPublication(used);
503 if (toBeUsed == null) {
504 // Find the latest published version
505 for (Publication lastPub : aScen.getDocums()) {
506 if ((lastPub.value().getPreviousVersion() != null)
508 .getPreviousVersion()
516 if ((toBeUsed != null) && (!toBeUsed.isOutdated())) {
517 // 2.2. For each used document check that its latest not outdated version
518 // is used by the new checked in document version.
519 checkUsesRelation(newPub, toBeUsed);
522 // 1. Get all usedBy relations of the previous document version
523 for (Relation rel : prevDoc
524 .getRelations(UsedByRelation.class)) {
525 Document using = ((UsedByRelation) rel).getTo();
526 // Check that not checked in dependent documents became outdated
527 Publication usingPub = aScen.getPublication(using);
528 if (usingPub != null) { // if the document using the old version is still published
529 Assert.assertTrue(usingPub.isOutdated(),
530 "Not checked in dependent document "
531 + using.getTitle() + " ("
532 + using.getType().getName()
533 + ") must become outdated.");
537 // Otherwise the new file format must differ from the previous one
538 // and the new file must be attached to the same document
539 org.splat.dal.bo.som.File attFile = curDoc
540 .getAttachedFile(newFormat);
541 Assert.assertNotNull(attFile, "File "
542 + docDTO.getFiles().get(0).getPath()
543 + " must be attached to the document "
544 + docDTO.getTitle() + "#" + docDTO.getId());
545 Assert.assertTrue(attFile.asFile().exists(), "File "
546 + docDTO.getFiles().get(0).getPath()
547 + " attached to the document "
548 + docDTO.getTitle() + "#" + docDTO.getId()
550 LOG.debug("Source format: " + curDoc.getFormat()
551 + ", new format: " + newFormat);
552 // Check that attachment with the same format is not duplicated.
554 for (Relation conv : curDoc
555 .getRelations(ConvertsRelation.class)) {
556 if (newFormat.equals(((ConvertsRelation) conv)
557 .getTo().getFormat())) {
562 .assertEquals(attachNb, 1,
563 "Attachment with the same format must be only one.");
565 // Check that the attached file date is updated
566 if (dates.containsKey(attFile.getIndex())) {
568 .assertTrue(attFile.getDate().compareTo(
569 dates.get(attFile.getIndex())) > 0,
570 "Attachment modification date is not updated.");
571 modifDatesChecked = true;
576 // Check that new documents are created for new data
577 boolean found = false;
578 Publication newPub = null;
579 for (Publication pub : aScen.getDocums()) {
580 if (pub.value().getPreviousVersion() == null) {
581 found = (pub.value().getTitle().startsWith(pub
582 .value().getType().getName()));
583 if (found) { // Found next published version of the checked in document
584 String fcontent = Files.readFile(pub
585 .getSourceFile().asFile());
586 found = fcontent.contains(docDTO.getTitle());
589 .debug("Found new document with generated title: "
590 + pub.value().getTitle());
597 Assert.assertTrue(found,
598 "New document is not created for checked in document \""
599 + docDTO.getTitle() + "\".");
601 // Check that uses relations are created correctly
602 Assert.assertTrue(newPub.value().getTitle().startsWith(
603 newPub.value().getType().getName() + "_"),
604 "Document title newPub.value().getTitle() must start with "
605 + newPub.value().getType().getName() + "_");
607 // 1. Find the document type used by this document type
608 Set<DocumentType> usedTypes = newPub.value().getType()
610 // 2. Find documents of used types in the current study step and previous study steps
611 for (Publication pub : aScen.getDocums()) {
612 if ((pub.getStep().getNumber() <= step.getNumber())
613 && (!pub.isOutdated())
614 && usedTypes.contains(pub.value().getType())) {
615 // 3. Check that there is uses relation to the found document
616 // if it is not outdated.
617 checkUsesRelation(newPub, pub);
621 // Check that files are moved correctly
622 checkFiles(docDTO, newPub);
630 "No modification date is checked because no files were attached when attachment with same extension already exists.");
632 // ///////////////////////////////////////////////////////////
633 // Call checkin method for a not existing id.
635 _scenarioService.checkin(-1, userId, stepsToCheckin);
637 .fail("Check in for scenario with not existing id must be failed.");
638 } catch (Exception e) {
639 LOG.debug("Expected exception is thrown: "
640 + e.getClass().getSimpleName() + ": " + e.getMessage());
643 // Test checkin with empty list of steps
644 stepsToCheckin.clear();
645 _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
647 rollbackNestedTransaction();
648 LOG.debug(">>>>> END testCheckin()");
652 * Check if there is uses relation from the newPub to pub.
655 * the new publication
657 * the publication to be used
659 private void checkUsesRelation(final Publication newPub,
660 final Publication pub) {
661 boolean uses = false;
662 boolean usesExist = false;
663 for (Publication usesPub : newPub.getRelations(UsesRelation.class)) {
665 uses = (usesPub.equals(pub));
670 Assert.assertTrue(usesExist && uses, "The created document "
671 + newPub.value().getTitle() + "("
672 + newPub.value().getType().getName() + ")"
673 + " has no uses relation to the document "
674 + pub.value().getTitle() + "("
675 + pub.value().getType().getName() + ")");
679 * Check that files are moved correctly.
682 * checked in document DTO
684 * the created document publication
686 private void checkFiles(final DocumentDTO docDTO, final Publication newPub) {
687 // Check that original files are deleted
688 for (int j = 0; j < docDTO.getFiles().size(); j++) {
689 FileDTO fileDTO = docDTO.getFiles().get(j);
690 Assert.assertFalse(new File(fileDTO.getPath()).exists(), "File"
692 + " was not removed from downloads directory.");
693 String format = fileDTO.getPath().substring(
694 fileDTO.getPath().lastIndexOf('.') + 1);
696 // TODO: Check file by its internal content
697 Assert.assertTrue(newPub.getSourceFile().exists(), "File "
698 + newPub.getSourceFile().asFile().getAbsolutePath()
699 + " for the document " + docDTO.getTitle()
700 + " was not created.");
704 * Prepare a document with a file for check-in.
707 * step DTO with data for check-in
715 * checked out stepDTO
716 * @param stepsToCheckin
718 * @throws IOException
719 * if file creation failed
720 * @return step DTO with data prepared for check-in (stepTo or new if stepTo is null)
722 private StepDTO createDocDTOForModule(final StepDTO stepTo,
723 final String module, final String format, final long userId,
724 final StepDTO stepFrom, final List<StepDTO> stepsToCheckin)
726 StepDTO stepToCheckin = stepTo;
727 if (stepToCheckin == null) {
728 stepToCheckin = new StepDTO();
730 if (module.equals(stepFrom.getModule())) {
731 stepsToCheckin.add(stepToCheckin);
732 stepToCheckin.setNumber(stepFrom.getNumber());
733 for (DocumentDTO doc : stepFrom.getDocs()) {
734 if (doc.getFiles().get(0).getState() != 'O') {
735 DocumentDTO docToCheckin = stepToCheckin.addDoc(
736 doc.getId(), doc.getTitle());
737 for (FileDTO file : doc.getFiles()) {
738 if (file.getPath().endsWith(format)
739 || (file.getPath().endsWith("py") && (format
740 .equals("brep") || format.equals("med")))) {
741 // Create a file in the download directory
742 docToCheckin.addFile(createDownloadedFile(userId,
743 doc.getTitle() + "_result", format));
749 stepToCheckin.addDoc(0, "newdoc" + stepFrom.getNumber()).addFile(
750 createDownloadedFile(userId, "newdoc"
751 + stepFrom.getNumber(), "brep"));
753 return stepToCheckin;
757 * Create a file in the user's repository downloads directory.
765 * @return created file DTO
766 * @throws IOException
767 * if file creation failed
769 private FileDTO createDownloadedFile(final long userId, final String name,
770 final String format) throws IOException {
771 // Create a file in the download directory
772 return createDownloadedFile(userId, name + "." + format);
776 * Create a file in the user's repository downloads directory.
782 * @return created file DTO
783 * @throws IOException
784 * if file creation failed
786 private FileDTO createDownloadedFile(final long userId, final String fname)
788 // Create a file in the download directory
789 String filePath = getDownloadPath(userId) + fname;
790 FileWriter fw = new FileWriter(filePath);
791 fw.write("Simulation of " + fname + " file for checkin at "
794 return new FileDTO(filePath);
798 * Get path to the user's downloads directory. The directory is created if it is not exist yet.
802 * @return absolute path to downloads directory followed by slash
804 private String getDownloadPath(final long userId) {
805 // Prepare download directory
806 File tmpDir = _repositoryService.getDownloadDirectory(userId);
807 if (!tmpDir.exists()) {
808 Assert.assertTrue(tmpDir.mkdir(),
809 "Can't create temporary directory: "
810 + tmpDir.getAbsolutePath());
813 return tmpDir.getAbsolutePath() + "/";
817 * Create a persistent scenario for tests.
819 * @return a persistent scenario
820 * @throws InvalidPropertyException
821 * if an invalid property is used when creating objects
822 * @throws MultiplyDefinedException
823 * when trying to create an object with already existing id
824 * @throws MissedPropertyException
825 * if a mandatory property is not defined for an object to be created
826 * @throws IOException
827 * if document creation is failed
828 * @throws SQLException
829 * if project settings loading is failed
831 private long createScenario() throws InvalidPropertyException,
832 MissedPropertyException, MultiplyDefinedException, IOException,
834 // Create a scenario for tests
835 HibernateTemplate ht = getHibernateTemplate();
837 Database.getInstance().reset();
838 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
839 // Load workflow customization
841 _projectSettings.configure("classpath:test/som.xml");
842 } catch (FileNotFoundException e) {
843 Assert.fail("Can't find som.xml: ", e);
845 List<Step> steps = _stepsConfigService.getStepsOf(Scenario.class);
846 Assert.assertTrue(steps.size() > 0, "No steps are created.");
848 // Create a test user
849 User.Properties uprop = new User.Properties();
850 uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
851 .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
852 .addRole("TST_user").setMailAddress(
853 "noreply@salome-platform.org");
854 uprop.disableCheck();
855 User anAuthor = new User(uprop);
856 ht.saveOrUpdate(anAuthor);
858 // Create a test study
859 Study.Properties stprops = new Study.Properties().setReference(
860 "TST_SID_01").setTitle("TST_Study").setManager(anAuthor);
861 Study aStudy = new Study(stprops);
862 ht.saveOrUpdate(aStudy);
864 // Create a test scenario
865 Scenario.Properties sprops = new Scenario.Properties().setTitle(
866 "TST_Scenario").setManager(anAuthor).setOwnerStudy(aStudy);
867 Scenario aScenario = new Scenario(sprops);
868 aStudy.getScenariiList().add(aScenario);
869 ht.saveOrUpdate(anAuthor);
870 ht.saveOrUpdate(aStudy);
871 ht.saveOrUpdate(aScenario);
873 // Create documents for each scenario step
874 Document.Properties dprop = new Document.Properties().setAuthor(
875 anAuthor).setDate(new Date());
877 Publication usedPub = null;
878 Map<Long, Long> usedMap = new HashMap<Long, Long>();
879 for (Step step : steps) {
880 LOG.debug("Create scenario step: " + i);
882 org.splat.som.Step aScStep = new org.splat.som.Step(step, aScenario);
883 List<DocumentType> dtypes = _documentTypeService
884 .selectTypesOf(step);
885 for (DocumentType dtype : dtypes) {
886 // Create a document published in the scenario
887 // document<i>: document type[0] - first type used on the step
888 // <source-file>.brep
889 // <attached-file>.med
890 dprop.setName("document" + i++).setType(dtype);
892 * if (step.getNumber() > 3) { dprop.setFormat("med"); } else {
893 */dprop.setFormat("py");
895 dprop.setLocalPath(dprop.getName() + "." + dprop.getFormat());
896 Publication pub = createDoc(aScenario, aScStep, dprop, "med",
898 if (usedPub != null) {
899 pub.addDependency(usedPub);
900 ht.saveOrUpdate(pub.value());
902 usedMap.put(pub.getIndex(), usedPub.getIndex());
906 // Create another document with outdated publication
907 dprop.setName("document" + i++).setType(dtype).setFormat("py");
908 dprop.setLocalPath(dprop.getName() + "." + dprop.getFormat());
909 createDoc(aScenario, aScStep, dprop, "med", true);
912 if (dtypes.size() <= 0) {
913 LOG.debug("No document types are found for scenario step " + i);
917 // Check that the scenario and its documents have been created correctly.
919 Assert.assertNotNull(ht.find("from Document"),
920 "No documents in the database.");
921 Assert.assertTrue(ht.find("from Document").size() > 0,
922 "No documents in the database.");
924 Assert.assertNotNull(ht.find("from Publication where owner="
925 + aScenario.getIndex()), "No publications in the database.");
927 ht.find("from Publication where owner=" + aScenario.getIndex())
928 .size() > 0, "No publications in the database.");
930 for (Publication p : (List<Publication>) ht
931 .find("from Publication where owner=" + aScenario.getIndex())) {
932 LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
933 + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
935 Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
936 "The publication was not attached to the scenario.");
939 // Remove the scenario from the current hibernate session.
941 // Check that the scenario is created in the database.
942 Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
943 Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
944 Assert.assertTrue(aScen.getDocums().size() > 0,
945 "No publications in the scenario.");
947 Assert.assertTrue(i > 0,
948 "More then one document must be in the database");
950 // Check created uses relations
952 .assertTrue(usedMap.size() > 0,
953 "Uses relations must be created.");
954 boolean foundAny = false;
955 for (Long usingId : usedMap.keySet()) {
956 for (Publication pub : aScen.getDocums()) {
957 if (pub.getIndex() == usingId) {
958 boolean found = false;
959 for (Publication used : aScen.getDocums()) {
960 found = (used.getIndex() == usedMap.get(usingId));
965 Assert.assertTrue(found,
966 "Uses relation was not created in the database.");
967 foundAny = foundAny || found;
971 Assert.assertTrue(foundAny,
972 "No Uses relation was created in the database.");
974 return aScenario.getIndex();
978 * Create a document published in the scenario. <BR>
980 * document type[0] - first type used on the step <BR>
981 * <source-file>.brep <BR>
982 * <attached-file>.med
985 * the scenario to add the document to
987 * scenario step where the document to be published
989 * document properties
990 * @param attachedFileExt
991 * extension of the secon attached (exported) file
993 * outdated document flag
994 * @return the publication of the created document
995 * @throws IOException
996 * @throws MultiplyDefinedException
997 * @throws InvalidPropertyException
998 * @throws MissedPropertyException
1000 private Publication createDoc(final Scenario aScenario,
1001 final org.splat.som.Step aScStep, final Properties dprop,
1002 final String attachedFileExt, final boolean isOutdated)
1003 throws MissedPropertyException, InvalidPropertyException,
1004 MultiplyDefinedException, IOException {
1005 // Create a document published in the scenario
1006 // document<i>: document type[0] - first type used on the step
1007 // <source-file>.brep
1008 // <attached-file>.med
1009 createDownloadedFile(aScenario.getAuthor().getIndex(), dprop
1011 Publication pub = _stepService.createDocument(aScStep, dprop);
1012 Assert.assertNotNull(pub.getOwner(),
1013 "The publication must be attached to the scenario.");
1014 Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
1015 "The publication was not attached to the scenario.");
1021 HibernateTemplate ht = getHibernateTemplate();
1022 ht.saveOrUpdate(pub);
1025 createDownloadedFile(aScenario.getAuthor().getIndex(), dprop
1026 .getLocalPath().substring(0,
1027 dprop.getLocalPath().lastIndexOf(".") - 1),
1029 ht.save(pub.value());
1030 ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));
1036 * Test study creation.<BR>
1037 * <B>Description :</B> <BR>
1038 * <i>Create a study.</i><BR>
1039 * <B>Action : </B><BR>
1040 * <i>1. call the method for a not existing product.</i><BR>
1041 * <i>2. call the method for an existing username and an existing product.</i><BR>
1042 * <i>3. call the method for a not existing username expecting an exception.</i><BR>
1043 * <B>Test data : </B><BR>
1044 * <i>no input parameters</i><BR>
1046 * <B>Outcome results:</B><BR>
1049 * <li>1: The new study must be created. The new product simulation context must be created.</li>
1050 * <li>2: The new study must be created.</li>
1051 * <li>3: The new study must not be created. Exception must be thrown.</li>
1055 * @throws IOException
1056 * if application configuration loading is failed
1057 * @throws SQLException
1058 * if application configuration loading is failed
1059 * @throws BusinessException
1060 * if test data creation is failed
1062 @Test(groups = { "study", "sevice", "functional", "business" })
1063 public void testCreateStudy() throws BusinessException, IOException,
1065 LOG.debug(">>>>> BEGIN testCreateStudy()");
1066 startNestedTransaction();
1068 Database.getInstance().reset();
1069 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
1070 _projectSettings.configure("classpath:test/som.xml");
1072 // Create a test user
1073 User.Properties uprop = new User.Properties();
1074 uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
1075 .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
1076 .addRole("TST_user").setMailAddress(
1077 "noreply@salome-platform.org");
1078 uprop.disableCheck();
1079 User anAuthor = new User(uprop);
1081 getHibernateTemplate().saveOrUpdate(anAuthor);
1082 KnowledgeElementType ucase = _knowledgeElementTypeService
1083 .selectType("usecase");
1084 Assert.assertNotNull(ucase,
1085 "Knowledge type 'usecase' must be created in the database.");
1086 SimulationContextType prodtype = _simulationContextService
1087 .selectType("product");
1089 .assertNotNull(prodtype,
1090 "Simulation context type 'product' must be created in the database.");
1094 uprop.setUsername("TST_Admin").setName("TST_SimanUnitTestsAdmin")
1095 .setFirstName("TST_AdminFirstName").setDisplayName(
1096 "TST_test.admin").addRole("TST_user,sysadmin")
1097 .setMailAddress("noreply@salome-platform.org");
1098 uprop.disableCheck();
1100 getHibernateTemplate().saveOrUpdate(new User(uprop));
1101 getHibernateTemplate().flush();
1103 Study.Properties sprop = new Study.Properties();
1104 sprop.setTitle("Test study creation").setManager(anAuthor);
1105 Scenario.Properties oprop = new Scenario.Properties();
1106 oprop.setTitle("Test scenario for the created study");
1108 // Addition of the entered project context
1109 SimulationContext.Properties cprop = new SimulationContext.Properties();
1110 // Input of new project context
1111 cprop.setType(_simulationContextService.selectType("product"))
1112 .setValue("Test Simulation Context: Product");
1113 Study study = _scenarioService.createStudy(sprop, oprop, cprop);
1115 Assert.assertNotNull(study);
1116 Assert.assertTrue(study.getIndex() > 0);
1118 rollbackNestedTransaction();
1119 LOG.debug(">>>>> END testCreateStudy()");
1123 * Test study creation.<BR>
1124 * <B>Description :</B> <BR>
1125 * <i>Create a study.</i><BR>
1126 * <B>Action : </B><BR>
1127 * <i>1. call the method for a not existing product.</i><BR>
1128 * <i>2. call the method for an existing username and an existing product.</i><BR>
1129 * <i>3. call the method for a not existing username expecting an exception.</i><BR>
1130 * <B>Test data : </B><BR>
1131 * <i>no input parameters</i><BR>
1133 * <B>Outcome results:</B><BR>
1136 * <li>1: The new study must be created. The new product simulation context must be created.</li>
1137 * <li>2: The new study must be created.</li>
1138 * <li>3: The new study must not be created. Exception must be thrown.</li>
1142 * @throws IOException
1143 * if application configuration loading is failed
1144 * @throws SQLException
1145 * if application configuration loading is failed
1146 * @throws BusinessException
1147 * if test data creation is failed
1149 @Test(groups = { "study", "sevice", "functional", "business" })
1150 public void testCreateStudyFromPython() throws IOException, SQLException,
1152 LOG.debug(">>>>> BEGIN testCreateStudyFromPython()");
1153 startNestedTransaction();
1155 HibernateTemplate ht = getHibernateTemplate();
1157 Database.getInstance().reset();
1158 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
1159 _projectSettings.configure("classpath:test/som.xml");
1161 // Create a test user
1162 User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
1163 _userDAO.create(goodUser);
1164 SimulationContextType prodtype = _simulationContextService
1165 .selectType("product");
1167 .assertNotNull(prodtype,
1168 "Simulation context type 'product' must be created in the database.");
1170 String productName = "New Test Product " + new Date().toString();
1174 long studyId1 = _scenarioService.createStudy("goodUser",
1175 "Test Study 1", productName, "Test description");
1176 Assert.assertTrue(studyId1 > 0);
1181 _scenarioService.createStudy("badbadUser", "Test Study 2",
1182 productName, "Test description");
1183 Assert.fail("Study must not be created for not existing user.");
1184 } catch (InvalidPropertyException ipe) {
1185 LOG.debug("Expected exception: " + ipe.getMessage());
1190 long studyId3 = _scenarioService.createStudy("goodUser",
1191 "Test Study 3", productName, "Test description");
1192 Assert.assertTrue(studyId3 > 0);
1194 // Check that the simulation context is the same
1195 Study study1 = _studyService.selectStudy(studyId1);
1196 Study study3 = _studyService.selectStudy(studyId3);
1197 Assert.assertEquals(study1.SimulationContextIterator().next(),
1198 study3.SimulationContextIterator().next());
1200 // Check the title of the created scenario
1201 String scTitle = study1.getScenarii()[0].getTitle();
1202 Assert.assertEquals(scTitle, I18nUtils.getMessageLocaleDefault("label.scenario") + " 1");
1203 Assert.assertFalse(scTitle.equals("label.scenario 1"));
1205 rollbackNestedTransaction();
1206 LOG.debug(">>>>> END testCreateStudyFromPython()");