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.Iterator;
20 import java.util.List;
24 import org.splat.dal.bo.kernel.Relation;
25 import org.splat.dal.bo.kernel.User;
26 import org.splat.dal.bo.som.ConvertsRelation;
27 import org.splat.dal.bo.som.Document;
28 import org.splat.dal.bo.som.DocumentType;
29 import org.splat.dal.bo.som.KnowledgeElementType;
30 import org.splat.dal.bo.som.Publication;
31 import org.splat.dal.bo.som.Scenario;
32 import org.splat.dal.bo.som.SimulationContext;
33 import org.splat.dal.bo.som.SimulationContextType;
34 import org.splat.dal.bo.som.Study;
35 import org.splat.dal.bo.som.UsedByRelation;
36 import org.splat.dal.bo.som.UsesRelation;
37 import org.splat.dal.bo.som.Document.Properties;
38 import org.splat.dal.dao.kernel.UserDAO;
39 import org.splat.dal.dao.som.Database;
40 import org.splat.dal.dao.som.ScenarioDAO;
41 import org.splat.exception.BusinessException;
42 import org.splat.i18n.I18nUtils;
43 import org.splat.kernel.InvalidPropertyException;
44 import org.splat.kernel.MismatchException;
45 import org.splat.kernel.MissedPropertyException;
46 import org.splat.kernel.MultiplyDefinedException;
47 import org.splat.kernel.NotApplicableException;
48 import org.splat.log.AppLogger;
49 import org.splat.service.DocumentTypeService;
50 import org.splat.service.KnowledgeElementTypeService;
51 import org.splat.service.PublicationService;
52 import org.splat.service.ScenarioService;
53 import org.splat.service.SimulationContextService;
54 import org.splat.service.StepService;
55 import org.splat.service.StudyService;
56 import org.splat.service.dto.DocumentDTO;
57 import org.splat.service.dto.FileDTO;
58 import org.splat.service.dto.StepDTO;
59 import org.splat.service.technical.ProjectSettingsService;
60 import org.splat.service.technical.RepositoryService;
61 import org.splat.service.technical.StepsConfigService;
62 import org.splat.service.technical.ProjectSettingsService.Step;
63 import org.springframework.beans.factory.annotation.Autowired;
64 import org.springframework.beans.factory.annotation.Qualifier;
65 import org.springframework.orm.hibernate3.HibernateTemplate;
66 import org.testng.Assert;
67 import org.testng.annotations.Test;
68 import org.testng.reporters.Files;
70 import test.splat.common.BaseTest;
71 import test.splat.util.TestEntitiesGenerator;
74 * Test class for ScenarioService.
76 * @author <a href="mailto:roman.kozlov@opencascade.com">Roman Kozlov (RKV)</a>
79 public class TestScenarioService extends BaseTest {
82 * Logger for the class.
84 private static final AppLogger LOG = AppLogger
85 .getLogger(TestScenarioService.class);
88 * The tested ScenarioService. Later injected by Spring.
91 @Qualifier("scenarioService")
92 private transient ScenarioService _scenarioService;
95 * The RepositoryService. Later injected by Spring.
98 @Qualifier("repositoryService")
99 private transient RepositoryService _repositoryService;
102 * The Scenario DAO. Later injected by Spring.
105 @Qualifier("scenarioDAO")
106 private transient ScenarioDAO _scenarioDAO;
109 * The PublicationService. Later injected by Spring.
112 @Qualifier("publicationService")
113 private transient PublicationService _publicationService;
116 * The StepService. Later injected by Spring.
119 @Qualifier("stepService")
120 private transient StepService _stepService;
123 * The SimulationContextService. Later injected by Spring.
126 @Qualifier("simulationContextService")
127 private transient SimulationContextService _simulationContextService;
130 * The ProjectSettingsService. Later injected by Spring.
133 @Qualifier("projectSettings")
134 private transient ProjectSettingsService _projectSettings;
137 * The StepsConfigService. Later injected by Spring.
140 @Qualifier("stepsConfigService")
141 private transient StepsConfigService _stepsConfigService;
144 * The DocumentTypeService. Later injected by Spring.
147 @Qualifier("documentTypeService")
148 private transient DocumentTypeService _documentTypeService;
151 * The KnowledgeElementTypeService. Later injected by Spring.
154 @Qualifier("knowledgeElementTypeService")
155 private transient KnowledgeElementTypeService _knowledgeElementTypeService;
158 * The UserDAO. Later injected by Spring.
161 @Qualifier("userDAO")
162 private transient UserDAO _userDAO;
165 * The StudyService. Later injected by Spring.
168 @Qualifier("studyService")
169 private transient StudyService _studyService;
172 * Test of getting a scenario content for building siman-salome.conf.<BR>
173 * <B>Description :</B> <BR>
174 * <i>Create a scenario and try to get an info for it.</i><BR>
175 * <B>Action : </B><BR>
176 * <i>1. call the method for an existing scenario id.</i><BR>
177 * <i>2. call the method for a not existing scenario id.</i><BR>
178 * <B>Test data : </B><BR>
179 * <i>no input parameters</i><BR>
180 * <i>no input parameters</i><BR>
182 * <B>Outcome results:</B><BR>
185 * <li>result DTO must contain list of all documents and files<BR>
187 * <li>Exception is thrown<BR>
192 * @throws InvalidPropertyException
193 * if an invalid property is used when creating objects
194 * @throws MultiplyDefinedException
195 * when trying to create an object with already existing id
196 * @throws MissedPropertyException
197 * if a mandatory property is not defined for an object to be created
198 * @throws IOException
199 * if scenario creation is failed
200 * @throws SQLException
201 * if scenario creation is failed
203 @Test(groups = { "checkout", "sevice", "functional", "business" })
204 public void testGetScenarioInfo() throws InvalidPropertyException,
205 MissedPropertyException, MultiplyDefinedException, IOException,
207 LOG.debug(">>>>> BEGIN testGetScenarioInfo()");
208 startNestedTransaction();
210 long scenarioId = createScenario();
211 // Call DAO's create method for a good transient knowledge element.
212 List<StepDTO> steps = _scenarioService.getScenarioInfo(scenarioId);
213 Assert.assertNotNull(steps, "List of steps must not be null.");
214 Assert.assertTrue(steps.size() > 0, "No steps are read.");
216 List<Step> projSteps = _stepsConfigService.getStepsOf(Scenario.class);
217 Assert.assertEquals(steps.size(), projSteps.size(),
218 "Not all steps are listed.");
220 for (StepDTO step : steps) {
221 LOG.debug("check the step " + step.getNumber() + ":\n" + step);
222 Assert.assertNotNull(step, "Step DTO must not be null.");
223 Assert.assertNotNull(step.getKey(), "Step name must not be null.");
224 Assert.assertFalse(step.getKey().isEmpty(),
225 "Step name must not empty.");
226 Assert.assertTrue(step.getNumber() > 0,
227 "Step number must be positive integer.");
228 Assert.assertNotNull(step.getDocs(),
229 "Step documents list must not be null.");
231 Step aProjStep = null;
232 for (Step projStep : projSteps) {
233 if (projStep.getNumber() == step.getNumber()) {
234 aProjStep = projStep;
239 List<DocumentType> dtypes = _documentTypeService
240 .selectTypesOf(aProjStep);
241 for (DocumentType dtype : dtypes) {
242 Assert.assertTrue(step.getDocs().size() > 0,
243 "Step documents list must not be empty.");
244 String docName = "document" + docIndex;
245 for (DocumentDTO doc : step.getDocs()) {
246 if (docName.equals(doc.getTitle())) {
247 Assert.assertTrue(doc.getId() > 0,
248 "Document id must be positive integer.");
249 Assert.assertEquals(doc.getTitle(), docName);
250 Assert.assertNotNull(doc.getFiles(),
251 "Document files list must not be null.");
253 .assertTrue(doc.getFiles().size() > 1,
254 "Document must have more then 1 attached file.");
256 for (FileDTO file : doc.getFiles()) {
257 Assert.assertNotNull(file.getPath(),
258 "File path must not be null.");
259 Assert.assertFalse(file.getPath().isEmpty(),
260 "File path must not be empty.");
262 * <mappings> <document type="geometry"> <import format="brep"/> <!-- Result Shape --> </document> <document
263 * type="model"> <import format="med"/> <!-- Result mesh without input parameters --> </document> <document
264 * type="loads"> <import format="c3m"/> <!-- Input data created interactively --> </document> <document
265 * type="results"> <import format="med"/> <!-- Calculation results source file --> </document> </mappings>
267 // Check state and processing instruction
268 String fileFormat = file.getPath().substring(
269 file.getPath().lastIndexOf('.') + 1);
271 * if (_projectSettings.doImport(dtype.getName(), fileFormat)) { Assert.assertTrue(file.isResult(), "The file
272 * must be a result file."); } else { Assert.assertFalse(file.isResult(), "The file must be a source file."); }
273 */if ((docIndex % 2) == 0) { // New
274 Assert.assertEquals(file.getState(), 'Y',
275 "File state must be actual ('Y').");
276 if (_projectSettings.doImport(dtype.getName(),
278 Assert.assertEquals(file.getProcessing(),
280 "File must be imported.");
282 Assert.assertEquals(file.getProcessing(),
284 "File must be downloaded.");
287 Assert.assertEquals(file.getState(), 'O',
288 "File state must be outdated ('O').");
290 .assertEquals(file.getProcessing(),
292 "Outdated document should not be imported but downloaded.");
301 // Call DAO's get method for a not existing id.
303 steps = _scenarioService.getScenarioInfo(-1L);
304 // getHibernateTemplate().flush();
306 .fail("Getting an object with not existing id must be failed.");
307 } catch (Exception e) {
308 LOG.debug("Expected exception is thrown: "
309 + e.getClass().getSimpleName() + ": " + e.getMessage());
311 rollbackNestedTransaction();
312 LOG.debug(">>>>> END testGetScenarioInfo()");
316 * Test check-in scenario operation to be performed after SALOME session.<BR>
317 * <B>Description :</B> <BR>
318 * <i>Create a scenario and try to check-in it with some simulated SALOME results data.<BR>
319 * After check-in verify following points:
321 * <li>scenario is no more marked as checked out</li>
322 * <li>new document versions are created for checked in documents</li>
323 * <li>presentation of the previous version is removed</li>
324 * <li>uses relations are copied correctly</li>
325 * <li>files are moved correctly</li>
326 * <li>formats of files are new if they are according to the document's type on the study step</li>
327 * <li>new documents are created for new data</li>
328 * <li>new documents have correctly generated names</li>
329 * <li>uses relations are created correctly</li>
330 * <li>files are moved correctly</li>
333 * <B>Action : </B><BR>
334 * <i>1. call the method for an existing scenario id.</i><BR>
335 * <i>2. call the method for a not existing scenario id.</i><BR>
336 * <B>Test data : </B><BR>
337 * <i>no input parameters</i><BR>
338 * <i>no input parameters</i><BR>
340 * <B>Outcome results:</B><BR>
343 * <li>New version of existing documents must be created and new documents must be imported for documents with zero id. Correct
344 * relations must be created.<BR>
346 * <li>Exception is thrown<BR>
351 * @throws InvalidPropertyException
352 * if an invalid property is used when creating objects
353 * @throws MultiplyDefinedException
354 * when trying to create an object with already existing id
355 * @throws MissedPropertyException
356 * if a mandatory property is not defined for an object to be created
357 * @throws IOException
358 * if scenario creation is failed
359 * @throws SQLException
360 * if scenario creation is failed
361 * @throws NotApplicableException
363 * @throws MismatchException
366 @Test(groups = { "checkin", "sevice", "functional", "business" })
367 public void testCheckin() throws InvalidPropertyException,
368 MissedPropertyException, MultiplyDefinedException, IOException,
369 SQLException, MismatchException, NotApplicableException {
370 LOG.debug(">>>>> BEGIN testCheckin()");
371 startNestedTransaction();
373 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
374 _projectSettings.configure("classpath:test/som.xml");
375 getHibernateTemplate().flush();
376 long scenarioId = createScenario();
377 Scenario aScen = _scenarioDAO.get(scenarioId);
378 User user = aScen.getAuthor();
379 long userId = user.getIndex();
381 // ////////////////////////////////////////////////////////
382 // Call checkin method for empty list of modules.
385 List<StepDTO> steps = _scenarioService.getScenarioInfo(scenarioId);
386 _scenarioService.checkout(aScen, user);
387 _scenarioDAO.flush();
388 // Check that scenario is no more marked as checked out
389 aScen = _scenarioDAO.get(scenarioId);
390 Assert.assertTrue(aScen.isCheckedout(),
391 "Scenario is not marked as checked out after checkout.");
393 // Prepare test data for checkin
394 // Checkin only two first steps (geom and mesh)
395 List<StepDTO> stepsToCheckin = new ArrayList<StepDTO>();
397 _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
399 _scenarioDAO.flush();
400 // Check that scenario is no more marked as checked out
401 aScen = _scenarioDAO.get(scenarioId);
402 Assert.assertFalse(aScen.isCheckedout(),
403 "Scenario is still marked as checked out after checkin.");
405 // ////////////////////////////////////////////////////////
406 // Call checkin method for good prepared transient data.
409 steps = _scenarioService.getScenarioInfo(scenarioId);
410 _scenarioService.checkout(aScen, user);
412 // Remember modification dates of all attached files
413 Map<Long, Date> dates = new HashMap<Long, Date>();
414 for (Publication p : aScen.getDocums()) {
415 for (Relation r : p.value().getRelations(ConvertsRelation.class)) {
416 org.splat.dal.bo.som.File attach = ((ConvertsRelation) r)
418 dates.put(attach.getIndex(), attach.getDate());
422 // Prepare test data for checkin
423 // Checkin only two first steps (geom and mesh)
424 for (StepDTO step : steps) {
425 // Prepare GEOM: checkin actual brep
426 StepDTO stepToCheckin = createDocDTOForModule(null, "GEOM", "brep",
427 userId, step, stepsToCheckin);
428 createDocDTOForModule(stepToCheckin, "SMESH", "med", userId, step,
432 _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
434 _scenarioDAO.flush();
435 // Check that scenario is no more marked as checked out
436 aScen = _scenarioDAO.get(scenarioId);
437 Assert.assertFalse(aScen.isCheckedout(),
438 "Scenario is still marked as checked out after checkin.");
439 boolean modifDatesChecked = false;
440 // Check that new document versions are created for checked in documents
441 for (StepDTO step : stepsToCheckin) {
442 for (DocumentDTO docDTO : step.getDocs()) {
443 if ((docDTO.getId() != 0) && (docDTO.getId() != null)) {
444 boolean found = false;
445 Document prevDoc = null;
446 Document curDoc = null;
447 Publication newPub = null;
448 for (Publication pub : aScen.getDocums()) {
449 prevDoc = pub.value().getPreviousVersion();
450 if (prevDoc != null) {
451 found = (prevDoc.getIndex() == docDTO.getId());
452 if (found) { // Found next published version of the checked in document
457 if (pub.value().getIndex() == docDTO.getId()) {
458 // Document version was not changed, old document is still published
459 curDoc = pub.value();
463 Assert.assertTrue(found || (curDoc != null),
464 "New version or new attached file of the existing checked in document \""
465 + docDTO.getTitle() + "\" (id="
467 + ") is not found in the scenario.");
468 // If previous version is found then the format must be the same
469 String newFormat = docDTO.getFiles().get(0).getPath()
471 docDTO.getFiles().get(0).getPath()
472 .lastIndexOf('.') + 1);
474 Assert.assertEquals(prevDoc.getFormat(), newFormat,
475 "Formats of versions must be same");
476 Assert.assertFalse(aScen.publishes(prevDoc));
477 // Check that presentation of the previous version is removed
478 checkFiles(docDTO, newPub);
480 // Formats of files are new if they are according to the document's type on the study step
481 if ("py".equals(prevDoc.getFormat())
482 && "geometry".equals(prevDoc.getType()
484 Assert.assertEquals(newPub.value().getFormat(),
486 Assert.assertEquals(newPub.getSourceFile()
487 .getFormat(), "brep");
488 Assert.assertEquals(newPub.getSourceFile()
489 .getRelativePath().substring(
490 newPub.getSourceFile()
492 .lastIndexOf('.') + 1),
496 // Check that uses relations are copied correctly
498 // 1. Get all uses relations of the previous document version
499 for (Relation rel : prevDoc
500 .getRelations(UsesRelation.class)) {
501 Document used = ((UsesRelation) rel).getTo();
502 // 2.1. Get the latest version of the document published in this scenario
503 Publication toBeUsed = aScen.getPublication(used);
504 if (toBeUsed == null) {
505 // Find the latest published version
506 for (Publication lastPub : aScen.getDocums()) {
507 if ((lastPub.value().getPreviousVersion() != null)
509 .getPreviousVersion()
517 if ((toBeUsed != null) && (!toBeUsed.isOutdated())) {
518 // 2.2. For each used document check that its latest not outdated version
519 // is used by the new checked in document version.
520 checkUsesRelation(newPub, toBeUsed);
523 // 1. Get all usedBy relations of the previous document version
524 for (Relation rel : prevDoc
525 .getRelations(UsedByRelation.class)) {
526 Document using = ((UsedByRelation) rel).getTo();
527 // Check that not checked in dependent documents became outdated
528 Publication usingPub = aScen.getPublication(using);
529 if (usingPub != null) { // if the document using the old version is still published
530 Assert.assertTrue(usingPub.isOutdated(),
531 "Not checked in dependent document "
532 + using.getTitle() + " ("
533 + using.getType().getName()
534 + ") must become outdated.");
538 // Otherwise the new file format must differ from the previous one
539 // and the new file must be attached to the same document
540 org.splat.dal.bo.som.File attFile = curDoc
541 .getAttachedFile(newFormat);
542 Assert.assertNotNull(attFile, "File "
543 + docDTO.getFiles().get(0).getPath()
544 + " must be attached to the document "
545 + docDTO.getTitle() + "#" + docDTO.getId());
546 Assert.assertTrue(attFile.asFile().exists(), "File "
547 + docDTO.getFiles().get(0).getPath()
548 + " attached to the document "
549 + docDTO.getTitle() + "#" + docDTO.getId()
551 LOG.debug("Source format: " + curDoc.getFormat()
552 + ", new format: " + newFormat);
553 // Check that attachment with the same format is not duplicated.
555 for (Relation conv : curDoc
556 .getRelations(ConvertsRelation.class)) {
557 if (newFormat.equals(((ConvertsRelation) conv)
558 .getTo().getFormat())) {
563 .assertEquals(attachNb, 1,
564 "Attachment with the same format must be only one.");
566 // Check that the attached file date is updated
567 if (dates.containsKey(attFile.getIndex())) {
569 .assertTrue(attFile.getDate().compareTo(
570 dates.get(attFile.getIndex())) > 0,
571 "Attachment modification date is not updated.");
572 modifDatesChecked = true;
577 // Check that new documents are created for new data
578 boolean found = false;
579 Publication newPub = null;
580 for (Publication pub : aScen.getDocums()) {
581 if (pub.value().getPreviousVersion() == null) {
582 found = (pub.value().getTitle().startsWith(pub
583 .value().getType().getName()));
584 if (found) { // Found next published version of the checked in document
585 String fcontent = Files.readFile(pub
586 .getSourceFile().asFile());
587 found = fcontent.contains(docDTO.getTitle());
590 .debug("Found new document with generated title: "
591 + pub.value().getTitle());
598 Assert.assertTrue(found,
599 "New document is not created for checked in document \""
600 + docDTO.getTitle() + "\".");
602 // Check that uses relations are created correctly
603 Assert.assertTrue(newPub.value().getTitle().startsWith(
604 newPub.value().getType().getName() + "_"),
605 "Document title newPub.value().getTitle() must start with "
606 + newPub.value().getType().getName() + "_");
608 // 1. Find the document type used by this document type
609 Set<DocumentType> usedTypes = newPub.value().getType()
611 // 2. Find documents of used types in the current study step and previous study steps
612 for (Publication pub : aScen.getDocums()) {
613 if ((pub.getStep().getNumber() <= step.getNumber())
614 && (!pub.isOutdated())
615 && usedTypes.contains(pub.value().getType())) {
616 // 3. Check that there is uses relation to the found document
617 // if it is not outdated.
618 checkUsesRelation(newPub, pub);
622 // Check that files are moved correctly
623 checkFiles(docDTO, newPub);
631 "No modification date is checked because no files were attached when attachment with same extension already exists.");
633 // ///////////////////////////////////////////////////////////
634 // Call checkin method for a not existing id.
636 _scenarioService.checkin(-1, userId, stepsToCheckin);
638 .fail("Check in for scenario with not existing id must be failed.");
639 } catch (Exception e) {
640 LOG.debug("Expected exception is thrown: "
641 + e.getClass().getSimpleName() + ": " + e.getMessage());
644 // Test checkin with empty list of steps
645 stepsToCheckin.clear();
646 _scenarioService.checkin(scenarioId, userId, stepsToCheckin);
648 rollbackNestedTransaction();
649 LOG.debug(">>>>> END testCheckin()");
653 * Check if there is uses relation from the newPub to pub.
656 * the new publication
658 * the publication to be used
660 private void checkUsesRelation(final Publication newPub,
661 final Publication pub) {
662 boolean uses = false;
663 boolean usesExist = false;
664 for (Publication usesPub : newPub.getRelations(UsesRelation.class)) {
666 uses = (usesPub.equals(pub));
671 Assert.assertTrue(usesExist && uses, "The created document "
672 + newPub.value().getTitle() + "("
673 + newPub.value().getType().getName() + ")"
674 + " has no uses relation to the document "
675 + pub.value().getTitle() + "("
676 + pub.value().getType().getName() + ")");
680 * Check that files are moved correctly.
683 * checked in document DTO
685 * the created document publication
687 private void checkFiles(final DocumentDTO docDTO, final Publication newPub) {
688 // Check that original files are deleted
689 for (int j = 0; j < docDTO.getFiles().size(); j++) {
690 FileDTO fileDTO = docDTO.getFiles().get(j);
691 Assert.assertFalse(new File(fileDTO.getPath()).exists(), "File"
693 + " was not removed from downloads directory.");
694 String format = fileDTO.getPath().substring(
695 fileDTO.getPath().lastIndexOf('.') + 1);
697 // TODO: Check file by its internal content
698 Assert.assertTrue(newPub.getSourceFile().exists(), "File "
699 + newPub.getSourceFile().asFile().getAbsolutePath()
700 + " for the document " + docDTO.getTitle()
701 + " was not created.");
705 * Prepare a document with a file for check-in.
708 * step DTO with data for check-in
716 * checked out stepDTO
717 * @param stepsToCheckin
719 * @throws IOException
720 * if file creation failed
721 * @return step DTO with data prepared for check-in (stepTo or new if stepTo is null)
723 private StepDTO createDocDTOForModule(final StepDTO stepTo,
724 final String module, final String format, final long userId,
725 final StepDTO stepFrom, final List<StepDTO> stepsToCheckin)
727 StepDTO stepToCheckin = stepTo;
728 if (stepToCheckin == null) {
729 stepToCheckin = new StepDTO();
731 if (module.equals(stepFrom.getModule())) {
732 stepsToCheckin.add(stepToCheckin);
733 stepToCheckin.setNumber(stepFrom.getNumber());
734 for (DocumentDTO doc : stepFrom.getDocs()) {
735 if (doc.getFiles().get(0).getState() != 'O') {
736 DocumentDTO docToCheckin = stepToCheckin.addDoc(
737 doc.getId(), doc.getTitle());
738 for (FileDTO file : doc.getFiles()) {
739 if (file.getPath().endsWith(format)
740 || (file.getPath().endsWith("py") && (format
741 .equals("brep") || format.equals("med")))) {
742 // Create a file in the download directory
743 docToCheckin.addFile(createDownloadedFile(userId,
744 doc.getTitle() + "_result", format));
750 stepToCheckin.addDoc(0, "newdoc" + stepFrom.getNumber()).addFile(
751 createDownloadedFile(userId, "newdoc"
752 + stepFrom.getNumber(), "brep"));
754 return stepToCheckin;
758 * Create a file in the user's repository downloads directory.
766 * @return created file DTO
767 * @throws IOException
768 * if file creation failed
770 private FileDTO createDownloadedFile(final long userId, final String name,
771 final String format) throws IOException {
772 // Create a file in the download directory
773 return createDownloadedFile(userId, name + "." + format);
777 * Create a file in the user's repository downloads directory.
783 * @return created file DTO
784 * @throws IOException
785 * if file creation failed
787 private FileDTO createDownloadedFile(final long userId, final String fname)
789 // Create a file in the download directory
790 String filePath = getDownloadPath(userId) + fname;
791 FileWriter fw = new FileWriter(filePath);
792 fw.write("Simulation of " + fname + " file for checkin at "
795 return new FileDTO(filePath);
799 * Get path to the user's downloads directory. The directory is created if it is not exist yet.
803 * @return absolute path to downloads directory followed by slash
805 private String getDownloadPath(final long userId) {
806 // Prepare download directory
807 File tmpDir = _repositoryService.getDownloadDirectory(userId);
808 if (!tmpDir.exists()) {
809 Assert.assertTrue(tmpDir.mkdir(),
810 "Can't create temporary directory: "
811 + tmpDir.getAbsolutePath());
814 return tmpDir.getAbsolutePath() + "/";
818 * Create a persistent scenario for tests.
820 * @return a persistent scenario
821 * @throws InvalidPropertyException
822 * if an invalid property is used when creating objects
823 * @throws MultiplyDefinedException
824 * when trying to create an object with already existing id
825 * @throws MissedPropertyException
826 * if a mandatory property is not defined for an object to be created
827 * @throws IOException
828 * if document creation is failed
829 * @throws SQLException
830 * if project settings loading is failed
832 private long createScenario() throws InvalidPropertyException,
833 MissedPropertyException, MultiplyDefinedException, IOException,
835 // Create a scenario for tests
836 HibernateTemplate ht = getHibernateTemplate();
838 Database.getInstance().reset();
839 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
840 // Load workflow customization
842 _projectSettings.configure("classpath:test/som.xml");
843 } catch (FileNotFoundException e) {
844 Assert.fail("Can't find som.xml: ", e);
846 List<Step> steps = _stepsConfigService.getStepsOf(Scenario.class);
847 Assert.assertTrue(steps.size() > 0, "No steps are created.");
849 // Create a test user
850 User.Properties uprop = new User.Properties();
851 uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
852 .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
853 .addRole("TST_user").setMailAddress(
854 "noreply@salome-platform.org");
855 uprop.disableCheck();
856 User anAuthor = new User(uprop);
857 ht.saveOrUpdate(anAuthor);
859 // Create a test study
860 Study.Properties stprops = new Study.Properties().setReference(
861 "TST_SID_01").setTitle("TST_Study").setManager(anAuthor);
862 Study aStudy = new Study(stprops);
863 ht.saveOrUpdate(aStudy);
865 // Create a test scenario
866 Scenario.Properties sprops = new Scenario.Properties().setTitle(
867 "TST_Scenario").setManager(anAuthor).setOwnerStudy(aStudy);
868 Scenario aScenario = new Scenario(sprops);
869 aStudy.getScenariiList().add(aScenario);
870 ht.saveOrUpdate(anAuthor);
871 ht.saveOrUpdate(aStudy);
872 ht.saveOrUpdate(aScenario);
874 // Create documents for each scenario step
875 Document.Properties dprop = new Document.Properties().setAuthor(
876 anAuthor).setDate(new Date());
878 Publication usedPub = null;
879 Map<Long, Long> usedMap = new HashMap<Long, Long>();
880 for (Step step : steps) {
881 LOG.debug("Create scenario step: " + i);
883 org.splat.som.Step aScStep = new org.splat.som.Step(step, aScenario);
884 List<DocumentType> dtypes = _documentTypeService
885 .selectTypesOf(step);
886 for (DocumentType dtype : dtypes) {
887 // Create a document published in the scenario
888 // document<i>: document type[0] - first type used on the step
889 // <source-file>.brep
890 // <attached-file>.med
891 dprop.setName("document" + i++).setType(dtype);
893 * if (step.getNumber() > 3) { dprop.setFormat("med"); } else {
894 */dprop.setFormat("py");
896 dprop.setLocalPath(dprop.getName() + "." + dprop.getFormat());
897 Publication pub = createDoc(aScenario, aScStep, dprop, "med",
899 if (usedPub != null) {
900 pub.addDependency(usedPub);
901 ht.saveOrUpdate(pub.value());
903 usedMap.put(pub.getIndex(), usedPub.getIndex());
907 // Create another document with outdated publication
908 dprop.setName("document" + i++).setType(dtype).setFormat("py");
909 dprop.setLocalPath(dprop.getName() + "." + dprop.getFormat());
910 createDoc(aScenario, aScStep, dprop, "med", true);
913 if (dtypes.size() <= 0) {
914 LOG.debug("No document types are found for scenario step " + i);
918 // Check that the scenario and its documents have been created correctly.
920 Assert.assertNotNull(ht.find("from Document"),
921 "No documents in the database.");
922 Assert.assertTrue(ht.find("from Document").size() > 0,
923 "No documents in the database.");
925 Assert.assertNotNull(ht.find("from Publication where owner="
926 + aScenario.getIndex()), "No publications in the database.");
928 ht.find("from Publication where owner=" + aScenario.getIndex())
929 .size() > 0, "No publications in the database.");
931 for (Publication p : (List<Publication>) ht
932 .find("from Publication where owner=" + aScenario.getIndex())) {
933 LOG.debug("Publication found: [id=" + p.getIndex() + ", owner="
934 + p.getOwner().getIndex() + ", doc=" + p.value().getIndex()
936 Assert.assertEquals(p.getOwner().getIndex(), aScenario.getIndex(),
937 "The publication was not attached to the scenario.");
940 // Remove the scenario from the current hibernate session.
942 // Check that the scenario is created in the database.
943 Scenario aScen = ht.load(Scenario.class, aScenario.getIndex());
944 Assert.assertNotNull(aScen, "Scenario was not saved in the database.");
945 Assert.assertTrue(aScen.getDocums().size() > 0,
946 "No publications in the scenario.");
948 Assert.assertTrue(i > 0,
949 "More then one document must be in the database");
951 // Check created uses relations
953 .assertTrue(usedMap.size() > 0,
954 "Uses relations must be created.");
955 boolean foundAny = false;
956 for (Long usingId : usedMap.keySet()) {
957 for (Publication pub : aScen.getDocums()) {
958 if (pub.getIndex() == usingId) {
959 boolean found = false;
960 for (Publication used : aScen.getDocums()) {
961 found = (used.getIndex() == usedMap.get(usingId));
966 Assert.assertTrue(found,
967 "Uses relation was not created in the database.");
968 foundAny = foundAny || found;
972 Assert.assertTrue(foundAny,
973 "No Uses relation was created in the database.");
975 return aScenario.getIndex();
979 * Create a document published in the scenario. <BR>
981 * document type[0] - first type used on the step <BR>
982 * <source-file>.brep <BR>
983 * <attached-file>.med
986 * the scenario to add the document to
988 * scenario step where the document to be published
990 * document properties
991 * @param attachedFileExt
992 * extension of the secon attached (exported) file
994 * outdated document flag
995 * @return the publication of the created document
996 * @throws IOException
997 * @throws MultiplyDefinedException
998 * @throws InvalidPropertyException
999 * @throws MissedPropertyException
1001 private Publication createDoc(final Scenario aScenario,
1002 final org.splat.som.Step aScStep, final Properties dprop,
1003 final String attachedFileExt, final boolean isOutdated)
1004 throws MissedPropertyException, InvalidPropertyException,
1005 MultiplyDefinedException, IOException {
1006 // Create a document published in the scenario
1007 // document<i>: document type[0] - first type used on the step
1008 // <source-file>.brep
1009 // <attached-file>.med
1010 createDownloadedFile(aScenario.getAuthor().getIndex(), dprop
1012 Publication pub = _stepService.createDocument(aScStep, dprop);
1013 Assert.assertNotNull(pub.getOwner(),
1014 "The publication must be attached to the scenario.");
1015 Assert.assertEquals(pub.getOwner().getIndex(), aScenario.getIndex(),
1016 "The publication was not attached to the scenario.");
1022 HibernateTemplate ht = getHibernateTemplate();
1023 ht.saveOrUpdate(pub);
1026 createDownloadedFile(aScenario.getAuthor().getIndex(), dprop
1027 .getLocalPath().substring(0,
1028 dprop.getLocalPath().lastIndexOf(".") - 1),
1030 ht.save(pub.value());
1031 ht.saveOrUpdate(_publicationService.attach(pub, attachedFileExt));
1037 * Test study creation.<BR>
1038 * <B>Description :</B> <BR>
1039 * <i>Create a study.</i><BR>
1040 * <B>Action : </B><BR>
1041 * <i>1. call the method for a not existing product.</i><BR>
1042 * <i>2. call the method for an existing username and an existing product.</i><BR>
1043 * <i>3. call the method for a not existing username expecting an exception.</i><BR>
1044 * <B>Test data : </B><BR>
1045 * <i>no input parameters</i><BR>
1047 * <B>Outcome results:</B><BR>
1050 * <li>1: The new study must be created. The new product simulation context must be created.</li>
1051 * <li>2: The new study must be created.</li>
1052 * <li>3: The new study must not be created. Exception must be thrown.</li>
1056 * @throws IOException
1057 * if application configuration loading is failed
1058 * @throws SQLException
1059 * if application configuration loading is failed
1060 * @throws BusinessException
1061 * if test data creation is failed
1063 @Test(groups = { "study", "sevice", "functional", "business" })
1064 public void testCreateStudy() throws BusinessException, IOException,
1066 LOG.debug(">>>>> BEGIN testCreateStudy()");
1067 startNestedTransaction();
1069 Database.getInstance().reset();
1070 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
1071 _projectSettings.configure("classpath:test/som.xml");
1073 // Create a test user
1074 User.Properties uprop = new User.Properties();
1075 uprop.setUsername("TST_Username").setName("TST_SimanUnitTestsUser")
1076 .setFirstName("TST_FirstName").setDisplayName("TST_test.user")
1077 .addRole("TST_user").setMailAddress(
1078 "noreply@salome-platform.org");
1079 uprop.disableCheck();
1080 User anAuthor = new User(uprop);
1082 getHibernateTemplate().saveOrUpdate(anAuthor);
1083 KnowledgeElementType ucase = _knowledgeElementTypeService
1084 .selectType("usecase");
1085 Assert.assertNotNull(ucase,
1086 "Knowledge type 'usecase' must be created in the database.");
1087 SimulationContextType prodtype = _simulationContextService
1088 .selectType("product");
1090 .assertNotNull(prodtype,
1091 "Simulation context type 'product' must be created in the database.");
1095 uprop.setUsername("TST_Admin").setName("TST_SimanUnitTestsAdmin")
1096 .setFirstName("TST_AdminFirstName").setDisplayName(
1097 "TST_test.admin").addRole("TST_user,sysadmin")
1098 .setMailAddress("noreply@salome-platform.org");
1099 uprop.disableCheck();
1101 getHibernateTemplate().saveOrUpdate(new User(uprop));
1102 getHibernateTemplate().flush();
1104 Study.Properties sprop = new Study.Properties();
1105 sprop.setTitle("Test study creation").setManager(anAuthor);
1106 Scenario.Properties oprop = new Scenario.Properties();
1107 oprop.setTitle("Test scenario for the created study");
1109 // Addition of the entered project context
1110 SimulationContext.Properties cprop = new SimulationContext.Properties();
1111 // Input of new project context
1112 cprop.setType(_simulationContextService.selectType("product"))
1113 .setValue("Test Simulation Context: Product");
1114 Study study = _scenarioService.createStudy(sprop, oprop, cprop);
1116 Assert.assertNotNull(study);
1117 Assert.assertTrue(study.getIndex() > 0);
1119 rollbackNestedTransaction();
1120 LOG.debug(">>>>> END testCreateStudy()");
1124 * Test study creation.<BR>
1125 * <B>Description :</B> <BR>
1126 * <i>Create a study.</i><BR>
1127 * <B>Action : </B><BR>
1128 * <i>1. call the method for a not existing product.</i><BR>
1129 * <i>2. call the method for an existing username and an existing product.</i><BR>
1130 * <i>3. call the method for a not existing username expecting an exception.</i><BR>
1131 * <B>Test data : </B><BR>
1132 * <i>no input parameters</i><BR>
1134 * <B>Outcome results:</B><BR>
1137 * <li>1: The new study must be created. The new product simulation context must be created.</li>
1138 * <li>2: The new study must be created.</li>
1139 * <li>3: The new study must not be created. Exception must be thrown.</li>
1143 * @throws IOException
1144 * if application configuration loading is failed
1145 * @throws SQLException
1146 * if application configuration loading is failed
1147 * @throws BusinessException
1148 * if test data creation is failed
1150 @Test(groups = { "study", "sevice", "functional", "business" })
1151 public void testCreateStudyFromPython() throws IOException, SQLException,
1153 LOG.debug(">>>>> BEGIN testCreateStudyFromPython()");
1154 startNestedTransaction();
1156 HibernateTemplate ht = getHibernateTemplate();
1158 Database.getInstance().reset();
1159 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
1160 _projectSettings.configure("classpath:test/som.xml");
1162 // Create a test user
1163 User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
1164 _userDAO.create(goodUser);
1165 SimulationContextType prodtype = _simulationContextService
1166 .selectType("product");
1168 .assertNotNull(prodtype,
1169 "Simulation context type 'product' must be created in the database.");
1171 String productName = "New Test Product " + new Date().toString();
1175 long studyId1 = _scenarioService.createStudy("goodUser",
1176 "Test Study 1", productName, "Test description");
1177 Assert.assertTrue(studyId1 > 0);
1182 _scenarioService.createStudy("badbadUser", "Test Study 2",
1183 productName, "Test description");
1184 Assert.fail("Study must not be created for not existing user.");
1185 } catch (InvalidPropertyException ipe) {
1186 LOG.debug("Expected exception: " + ipe.getMessage());
1191 long studyId3 = _scenarioService.createStudy("goodUser",
1192 "Test Study 3", productName, "Test description");
1193 Assert.assertTrue(studyId3 > 0);
1195 // Check that the simulation context is the same
1196 Study study1 = _studyService.selectStudy(studyId1);
1197 Study study3 = _studyService.selectStudy(studyId3);
1198 Assert.assertEquals(study1.SimulationContextIterator().next(), study3
1199 .SimulationContextIterator().next());
1201 // Check the title of the created scenario
1202 String scTitle = study1.getScenarii()[0].getTitle();
1203 Assert.assertEquals(scTitle, I18nUtils
1204 .getMessageLocaleDefault("label.scenario")
1206 Assert.assertFalse(scTitle.equals("label.scenario 1"));
1208 rollbackNestedTransaction();
1209 LOG.debug(">>>>> END testCreateStudyFromPython()");
1213 * Test assigning a simulation context to a study.<BR>
1214 * <B>Description :</B> <BR>
1215 * <i>Create a study and assign a simulation context to it.</i><BR>
1216 * <B>Action : </B><BR>
1217 * <i>1. call the method for not existing study id.</i><BR>
1218 * <i>2. call the method for not existing context type and context value.</i><BR>
1219 * <i>3. call the method for existing context type and context value.</i><BR>
1220 * <i>4. call the method for existing context type and not existing context value.</i><BR>
1221 * <i>5. call the method for empty context type.</i><BR>
1222 * <i>6. call the method for empty context value.</i><BR>
1223 * <B>Test data : </B><BR>
1224 * <i>no input parameters</i><BR>
1226 * <B>Outcome results:</B><BR>
1229 * <li>1: Exception must be thrown.</li>
1230 * <li>2: The new context type and value must be created. The new context must be assigned to the study first step.</li>
1231 * <li>3: The existing context must be assigned to the study first step.</li>
1232 * <li>4: The new context value must be created. The new context must be assigned to the study first step.</li>
1233 * <li>5: Exception must be thrown.</li>
1234 * <li>6: Exception must be thrown.</li>
1238 * @throws IOException
1239 * if application configuration loading is failed
1240 * @throws SQLException
1241 * if application configuration loading is failed
1242 * @throws BusinessException
1243 * if test data creation is failed
1245 @Test(groups = { "study", "sevice", "functional", "business" })
1246 public void testAssignStudyContextFromPython() throws IOException,
1247 SQLException, BusinessException {
1248 LOG.debug(">>>>> BEGIN testAssignStudyContextFromPython()");
1249 startNestedTransaction();
1251 HibernateTemplate ht = getHibernateTemplate();
1253 Database.getInstance().reset();
1254 _projectSettings.getAllSteps().clear(); // Clear config to be able to load it again
1255 _projectSettings.configure("classpath:test/som.xml");
1257 // Create a test user
1258 User goodUser = TestEntitiesGenerator.getTestUser("goodUser");
1259 _userDAO.create(goodUser);
1260 SimulationContextType prodtype = _simulationContextService
1261 .selectType("product");
1263 .assertNotNull(prodtype,
1264 "Simulation context type 'product' must be created in the database.");
1266 String productName = "New Test Product " + new Date().toString();
1270 long studyId1 = _scenarioService.createStudy("goodUser",
1271 "Test Study 1", productName, "Test description");
1272 Assert.assertTrue(studyId1 > 0);
1277 // //////// START OF TESTS
1278 // 1. call the method for not existing study id.</i><BR>
1280 _scenarioService.assignStudyContext(-1L, "new context type",
1281 "new context value");
1282 Assert.fail("Not existing study must not be found.");
1283 } catch (InvalidPropertyException ipe) {
1284 LOG.debug("Expected exception: " + ipe.getMessage());
1287 // 2. call the method for not existing context type and context value.</i><BR>
1288 _scenarioService.assignStudyContext(studyId1, "new context type",
1289 "new context value");
1294 // Check the assigned simulation context
1295 checkCtx(studyId1, "new context type", "new context value");
1297 // 3. call the method for existing context type and context value.</i><BR>
1298 _scenarioService.assignStudyContext(studyId1, "new context type",
1299 "new context value");
1304 // Check the assigned simulation context
1305 checkCtx(studyId1, "new context type", "new context value");
1307 // 4. call the method for existing context type and not existing context value.</i><BR>
1308 _scenarioService.assignStudyContext(studyId1, "new context type",
1309 "new context value1");
1314 // Check the assigned simulation context
1315 checkCtx(studyId1, "new context type", "new context value1");
1317 // 5. call the method for empty context type.</i><BR>
1319 _scenarioService.assignStudyContext(studyId1, "",
1320 "new context value");
1321 Assert.fail("Empty context type name must be forbidden.");
1322 } catch (InvalidPropertyException ipe) {
1323 LOG.debug("Expected exception: " + ipe.getMessage());
1325 // 6. call the method for empty context value.</i><BR>
1327 _scenarioService.assignStudyContext(studyId1, "new context type",
1329 Assert.fail("Empty context value must be forbidden.");
1330 } catch (InvalidPropertyException ipe) {
1331 LOG.debug("Expected exception: " + ipe.getMessage());
1334 rollbackNestedTransaction();
1335 LOG.debug(">>>>> END testAssignStudyContextFromPython()");
1339 * Check if the context is assigned to the study.
1344 * the context type name
1348 private void checkCtx(final long studyId1, final String ctxType,
1349 final String ctxValue) {
1350 // Check the assigned simulation context
1351 Study study1 = _studyService.selectStudy(studyId1);
1352 Iterator<SimulationContext> it = study1.SimulationContextIterator();
1353 SimulationContext ctx;
1354 boolean isFound = false;
1355 while ((!isFound) && it.hasNext()) {
1357 isFound = ctx.getType().getName().equals(ctxType)
1358 && ctx.getValue().equals(ctxValue);
1360 Assert.assertTrue(isFound, "Context must be assigned to the study.");