event->eventtype = DatasourceEvent::EVENT_ADD_DATASOURCE;
event->objectalias = filename;
emit datasourceSignal(event);
+//#ifdef MED_WITH_QTTESTING
+// _dirtyAddDataSource = true;
+// while(_dirtyAddDataSource)
+// QApplication::processEvents();
+//#endif
}
// After above data source creation, python console emits a signal, forwarded by workspace, to update the GUI
void
// update Object browser
_salomeModule->getApp()->updateObjectBrowser(true);
+
+//#ifdef MED_WITH_QTTESTING
+// _dirtyAddDataSource = false;
+//#endif
}
void DatasourceController::OnAddDatasource()
#include "PVViewer_ViewModel.h"
#endif
+#include <QTimer>
+
#include <sstream>
//! The only instance of the reference to engine
MED_ORB::MED_Gen_var MEDModule::myEngine;
MEDModule::MEDModule() :
- SalomeApp_Module("MED"), _studyEditor(0), _datasourceController(0), _workspaceController(0), _presentationController(0), _processingController(0)
+ SalomeApp_Module("MED"), _studyEditor(0), _datasourceController(0), _workspaceController(0),
+ _presentationController(0), _processingController(0)
{
// Note also that we can't use the getApp() function here because
// the initialize(...) function has not been called yet.
}
}
+//void MEDModule::onEventLoopStarted()
+//{
+// if(!getApp()->isMainEventLoopStarted())
+// {
+// QTimer::singleShot(100, this, SLOT(onEventLoopStarted()));
+// return;
+// }
+//}
+
void
MEDModule::initialize( CAM_Application* app )
{
_presentationController->showDockWidgets(true);
//this->setDockLayout(StandardApp_Module::DOCKLAYOUT_LEFT_VLARGE);
+ // Mark the start of the main event loop - important for test playback:
+// QObject::connect(getApp(), SIGNAL(activated(SUIT_Application *)), this, SLOT(onEventLoopStarted(SUIT_Application *)));
+// QTimer::singleShot(0, this, SLOT(onEventLoopStarted()));
+
// return the activation status
return bOk;
}
void
MEDModule::requestSALOMETermination() const
{
+ STDLOG("Requesting SALOME termination!!");
SUIT_Session::session()->closeSession( SUIT_Session::DONT_SAVE, 1 ); // killServers = True
}
+
+
+//bool MEDModule::hasMainEventLoopStarted() const
+//{
+// return _eventLoopStarted;
+//}
void requestSALOMETermination() const;
+// bool hasMainEventLoopStarted() const;
+
public slots:
virtual bool activateModule(SUIT_Study* theStudy);
virtual bool deactivateModule(SUIT_Study* theStudy);
#include <QDir>
#include <QIcon>
#include <QTimer>
+#include <QEvent>
+
+class PlayTestEvent: public QEvent {
+public:
+ PlayTestEvent(QEvent::Type type, const std::string & filename): QEvent(type), _filename(filename) {}
+ virtual ~PlayTestEvent() {}
+ const std::string _filename;
+};
TestController::TestController(MEDModule* mod):
_salomeModule(mod),
_desk(SUIT_Session::session()->activeApplication()->desktop()),
- _tester(0), _lock_action(0)
+ _tester(0), _lock_action(0),
+ _quitEventType(QEvent::registerEventType()),
+ _playEventType(QEvent::registerEventType()),
+ _aboutToPlayTest(false)
{
STDLOG("Creating a TestController");
_tester = new pqTestUtility(_desk);
_tester->playTests(fileName);
}
-void TestController::onPlayTestScenario()
-{
- STDLOG("About to play test " << _test_scenario.toStdString());
- _tester->playTests(_test_scenario);
- STDLOG("Done playing test " << _test_scenario.toStdString());
-}
-
-void TestController::onLockViewSize()
+void TestController::onLockViewSize() const
{
pqTestingReaction::lockViewSize(_lock_action->isChecked());
}
-void TestController::onTakeSnapshot()
+void TestController::onTakeSnapshot() const
{
pqSaveScreenshotReaction::saveScreenshot();
}
void TestController::onRequestTermination()
{
// Check if test playing
- if (_tester->playingTest())
+ if (_tester->playingTest() || _aboutToPlayTest)
{
- STDLOG("Termination requested, but test still playing ...");
- QTimer::singleShot(200, this, SLOT(onRequestTermination()));
+ QEvent * e = new QEvent((QEvent::Type)_quitEventType);
+ QApplication::postEvent(this, e);
}
else
{
}
}
+void
+TestController::customEvent(QEvent * event)
+{
+ if (event->type() == _quitEventType)
+ {
+ if(!_salomeModule->getApp()->isMainEventLoopStarted())
+ // Repost (=delay)
+ QApplication::postEvent(this, new QEvent((QEvent::Type)_quitEventType));
+ else
+ onRequestTermination();
+ }
+ else if (event->type() == _playEventType)
+ {
+ PlayTestEvent * e = dynamic_cast<PlayTestEvent *>(event);
+ if (e)
+ {
+// // Wait for main event loop to start:
+ if(!_salomeModule->getApp()->isMainEventLoopStarted())
+ // Repost (=delay)
+ QApplication::postEvent(this, new PlayTestEvent((QEvent::Type)_playEventType, e->_filename));
+ else
+ {
+ STDLOG("About to play test " << e->_filename);
+ _tester->playTests(e->_filename.c_str());
+ _aboutToPlayTest = false;
+ STDLOG("Done playing test " << e->_filename);
+ }
+ }
+ }
+ else
+ { QObject::customEvent(event); }
+}
void
TestController::processWorkspaceEvent(const MEDCALC::MedEvent* event)
/* [ABN] Post an event. Indeed, calling the function directly would prevent the proper refresh of the
* GUI which also needs to go through the MED event loop (WorkspaceController::processWorkspaceEvent)
*/
- _test_scenario = QString(event->filename);
- QTimer::singleShot(100, this, SLOT(onPlayTestScenario()));
+ _aboutToPlayTest = true; // to prevent an early quit!
+ PlayTestEvent * e = new PlayTestEvent((QEvent::Type)_playEventType, std::string(event->filename));
+ QApplication::postEvent(this, e);
}
else if ( event->type == MEDCALC::EVENT_QUIT_SALOME ) {
// [ABN] again: post as an event to give a chance to other events (piled up by test
// scenarios for example) to execute:
- QTimer::singleShot(200, this, SLOT(onRequestTermination()));
+ QEvent * e = new QEvent((QEvent::Type)_quitEventType);
+ QApplication::postEvent(this, e);
}
}
void createActions();
+
+
+protected:
+ virtual void customEvent(QEvent * event);
+
public slots:
void processWorkspaceEvent(const MEDCALC::MedEvent* event);
void onRecordTest();
void onPlayTest();
- void onPlayTestScenario();
- void onLockViewSize();
- void onTakeSnapshot();
+// void onPlayTestFile();
+ void onLockViewSize() const;
+ void onTakeSnapshot() const;
void onRequestTermination();
protected:
pqTestUtility * _tester;
QAction * _lock_action;
- QString _test_scenario;
+
+private:
+ const int _playEventType;
+ const int _quitEventType;
+
+ bool _aboutToPlayTest;
};
#endif /* SRC_MEDCALC_GUI_TESTCONTROLLER_HXX_ */
baselines/test_scalarmap.png
)
+SET(_test_files
+ medfiles/test_scalarmap.med
+)
+
# Test rules - the test MEDCalcQtTesting must be run after install (since it starts SALOME)
ADD_TEST(MEDCalcQtTesting ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test_qttesting.py)
INSTALL(FILES ${_test_scenarii} DESTINATION ${SALOME_MED_INSTALL_RES_DATA}/tests/scenarios)
INSTALL(FILES ${_test_baselines} DESTINATION ${SALOME_MED_INSTALL_RES_DATA}/tests/baselines)
+INSTALL(FILES ${_test_files} DESTINATION ${SALOME_MED_INSTALL_RES_DATA}/tests/medfiles)
def GetBaselineDir():
relativeDir = "@SALOME_MED_INSTALL_RES_DATA@/tests/baselines"
return os.path.join(__getRootDir(), relativeDir)
+
+def GetMEDFileDir():
+ relativeDir = "@SALOME_MED_INSTALL_RES_DATA@/tests/medfiles"
+ return os.path.join(__getRootDir(), relativeDir)
+
<pqevent object="1STD_TabDesktop0/1QMenuBar0" command="activate" arguments="Fic&hier" />
<pqevent object="1QMenu0" command="activate" arguments="LAB_LOCK_TEST" />
<pqevent object="1STD_TabDesktop0/DatasourceToolbar/1QToolButton0" command="activate" arguments="" />
- <pqevent object="Qt-subapplication-app" command="FilesOpen" arguments="/home/ab205030/agi_BKP.med" />
+ <pqevent object="Qt-subapplication-app" command="FilesOpen" arguments="/tmp/test_scalarmap.med" />
<pqevent object="1STD_TabDesktop0/objectBrowserDock/objectBrowser/1QtxTreeView0" command="expand" arguments="0.0" />
<pqevent object="1STD_TabDesktop0/objectBrowserDock/objectBrowser/1QtxTreeView0" command="expand" arguments="0.0.0.0" />
<pqevent object="1STD_TabDesktop0/objectBrowserDock/objectBrowser/1QtxTreeView0" command="expand" arguments="0.0.0.0.0.0" />
#
# Author: A. Bruneton (CEA)
-import unittest, os
+import unittest, os, shutil
from posixpath import basename
class MEDGUITest(unittest.TestCase):
""" Return name of the test being currently executed. """
return self.id().split(".")[-1]
- def launchSalomeWithScript(self, scriptname, baseline):
+ def launchSalomeWithScript(self, scriptname):
""" TODO: review this - what is the nicest way to launch SALOME GUI from a Python script? """
import shutil, subprocess
from medcalc_testutils import GetScriptDir
# TODO: review this!
salomeCommand = os.path.join(os.environ.get("KERNEL_ROOT_DIR", ""), "bin", "salome", "runSalome.py")
+ args = "args:%s" % self._tmpDir
pth = os.path.join(GetScriptDir(), scriptname)
- # Remove a potentially already present image file from the tmp directory:
- gen_image = os.path.join("/tmp", baseline)
- try:
- shutil.rmtree(gen_image)
- except OSError:
- pass
# Launch SALOME with the test script:
- status = subprocess.call([salomeCommand, pth])
+ status = subprocess.call([salomeCommand, pth, args])
if status:
raise Exception("SALOME exited abnormally for this test!")
- try:
- # Move generated image to the temporary test directory - ideally test should produce image there directly ...
- shutil.move(gen_image, self._tmpDir)
- except IOError:
- raise Exception("Test script didn't produce expected image '%s'!" % gen_image)
def compareSnapshot(self, basename):
+ """ Compare the screenshot in the current temporary test directory with the reference baseline.
+ Assert if not matching. """
import filecmp
from medcalc_testutils import GetBaselineDir
self.assertTrue(ret, "[%s] -- Failed screenshot equality, or unable to open baseline file - directory is kept alive: %s" % (self.getTestName(), self._tmpDir))
return ret
+ def prepareScenario(self, scenario, baseline, med_file):
+ """ Copy scenario to current temporary test dir and substitute paths inside """
+ from medcalc_testutils import GetScenarioDir, GetMEDFileDir
+ scen_path = os.path.join(GetScenarioDir(), scenario)
+ scen_pth2 = os.path.join(self._tmpDir, scenario)
+ try:
+ shutil.copy(scen_path, scen_pth2)
+ except IOError:
+ raise Exception("Could not copy test scenario '%s' to local test directory!" % scen_path)
+ with open(scen_pth2,'r') as f:
+ filedata = f.read()
+ filedata = filedata.replace("/tmp/%s" % baseline, "%s/%s" % (self._tmpDir, baseline))
+ filedata = filedata.replace("/tmp/%s" % med_file, os.path.join(GetMEDFileDir(), med_file))
+ with open(scen_pth2,'w') as f:
+ f.write(filedata)
+
##
## Now the tests themselves
##
-
def testScalarMap(self):
baseline = "test_scalarmap.png"
- self.launchSalomeWithScript("test_scalarmap.py", baseline)
+ med_file = "test_scalarmap.med" # will change
+ scenario = "test_scalarmap.xml"
+ self.prepareScenario(scenario, baseline, med_file)
+ self.launchSalomeWithScript("test_scalarmap.py")
self.compareSnapshot(baseline)
Python console.
"""
-import os
+import os, sys
import SalomePyQt
from medcalc_testutils import GetScenarioDir
sgPyQt.activateModule('MED')
import medcalc # After module activation !!
-medcalc.PlayQtTestingScenario(os.path.join(GetScenarioDir(), 'test_scalarmap.xml'))
+localTestDir = sys.argv[1]
+medcalc.PlayQtTestingScenario(os.path.join(localTestDir, 'test_scalarmap.xml'))
-medcalc.RequestSALOMETermination() # not equivalent to quit()!
+#medcalc.RequestSALOMETermination() # not equivalent to quit()!