]> SALOME platform Git repositories - tools/libbatch.git/commitdiff
Salome HOME
Added Windows implementation for local submission based on sh and rsh (partial and...
authorbarate <barate>
Thu, 30 Apr 2009 08:38:10 +0000 (08:38 +0000)
committerbarate <barate>
Thu, 30 Apr 2009 08:38:10 +0000 (08:38 +0000)
13 files changed:
src/Local/Batch_BatchManager_Local.cxx
src/Local/Batch_BatchManager_Local.hxx
src/Local/Batch_BatchManager_Local_RSH.cxx
src/Local/Batch_BatchManager_Local_RSH.hxx
src/Local/Batch_BatchManager_Local_SH.cxx
src/Local/Batch_BatchManager_Local_SH.hxx
src/Local/Batch_BatchManager_Local_SSH.cxx
src/Local/Batch_BatchManager_Local_SSH.hxx
src/Local/Test/CMakeLists.txt
src/Local/Test/Test_Local_RSH.cxx
src/Local/Test/Test_Local_SH.cxx
src/Local/Test/Test_Local_config.h.in
src/Python/Test/Test_Python_Local_SH.py

index 3b726d69b4145e857cae4480bbf4e7f81d64fcfe..77241a9f5337244a1d4511ccb65a47c5116449d4 100644 (file)
@@ -38,6 +38,7 @@
 #include <sys/types.h>
 #ifdef WIN32
 # include <direct.h>
+#include "Batch_RunTimeException.hxx"
 #else
 # include <sys/wait.h>
 # include <unistd.h>
@@ -56,10 +57,10 @@ namespace Batch {
 
 
   // Constructeur
-  BatchManager_Local::BatchManager_Local(const FactBatchManager * parent, const char * host) throw(InvalidArgumentException,ConnexionFailureException) : BatchManager(parent, host), _connect(0), _threads_mutex(), _threads(), _thread_id_id_association_mutex(), _thread_id_id_association_cond()
-#ifndef WIN32 //TODO: porting of following functionality
-    ,_thread_id_id_association()
-#endif
+  BatchManager_Local::BatchManager_Local(const FactBatchManager * parent, const char * host)
+      throw(InvalidArgumentException,ConnexionFailureException)
+    : BatchManager(parent, host), _connect(0), _threads_mutex(), _threads(), _thread_id_id_association_mutex(),
+      _thread_id_id_association_cond(), _thread_id_id_association()
   {
     pthread_mutex_init(&_threads_mutex, NULL);
     pthread_mutex_init(&_thread_id_id_association_mutex, NULL);
@@ -268,17 +269,22 @@ namespace Batch {
   // Retourne l'Id enregistre dans l'association Thread_id / Id et le detruit immediatement
   BatchManager_Local::Id BatchManager_Local::getIdByThread_id(pthread_t thread_id)
   {
-    Id id = -1;
-
     // @@@ --------> SECTION CRITIQUE <-------- @@@
     pthread_mutex_lock(&_thread_id_id_association_mutex);
-#ifndef WIN32 //TODO: porting of following functionality
-    while (_thread_id_id_association.find(thread_id) == _thread_id_id_association.end())
-      pthread_cond_wait(&_thread_id_id_association_cond, &_thread_id_id_association_mutex);
+    bool threadIdFound = false;
+    std::list<struct ThreadIdIdAssociation>::iterator it;
+    while (!threadIdFound) {
+      for (it = _thread_id_id_association.begin() ;
+           it != _thread_id_id_association.end() && !pthread_equal(it->threadId, thread_id) ;
+           it++);
+      if (it == _thread_id_id_association.end())
+        pthread_cond_wait(&_thread_id_id_association_cond, &_thread_id_id_association_mutex);
+      else
+        threadIdFound = true;
+    }
 
-    id = _thread_id_id_association[thread_id];
-    _thread_id_id_association.erase(thread_id);
-#endif
+    Id id = it->id;
+    _thread_id_id_association.erase(it);
 
     pthread_mutex_unlock(&_thread_id_id_association_mutex);
     // @@@ --------> SECTION CRITIQUE <-------- @@@
@@ -295,15 +301,20 @@ namespace Batch {
 
     // @@@ --------> SECTION CRITIQUE <-------- @@@
     pthread_mutex_lock(&_thread_id_id_association_mutex);
-#ifndef WIN32 //TODO: porting of following functionality
-    if (_thread_id_id_association.find(thread_id) == _thread_id_id_association.end()) {
-      id = _thread_id_id_association[thread_id] = nextId();
+    std::list<struct ThreadIdIdAssociation>::iterator it;
+    for (it = _thread_id_id_association.begin() ;
+         it != _thread_id_id_association.end() && !pthread_equal(it->threadId, thread_id) ;
+         it++);
+    if (it == _thread_id_id_association.end()) {
+      struct ThreadIdIdAssociation newAssociation;
+      id = newAssociation.id = nextId();
+      newAssociation.threadId = thread_id;
+      _thread_id_id_association.push_back(newAssociation);
       pthread_cond_signal(&_thread_id_id_association_cond);
 
     } else {
       UNDER_LOCK( cerr << "ERROR : Pthread Inconstency. Two threads own the same thread_id." << endl );
     }
-#endif
     pthread_mutex_unlock(&_thread_id_id_association_mutex);
     // @@@ --------> SECTION CRITIQUE <-------- @@@
 
@@ -324,11 +335,12 @@ namespace Batch {
   // Methode d'execution du thread
   void * BatchManager_Local::ThreadAdapter::run(void * arg)
   {
-#ifndef WIN32 //TODO: porting of following functionality
+#ifndef WIN32
     // On bloque tous les signaux pour ce thread
     sigset_t setmask;
     sigfillset(&setmask);
     pthread_sigmask(SIG_BLOCK, &setmask, NULL);
+#endif
 
     // On autorise la terminaison differee du thread
     // (ces valeurs sont les valeurs par defaut mais on les force par precaution)
@@ -338,7 +350,7 @@ namespace Batch {
     // On enregistre la fonction de suppression du fils en cas d'arret du thread
     // Cette fontion sera automatiquement appelee lorsqu'une demande d'annulation
     // sera prise en compte par pthread_testcancel()
-    pid_t child;
+    Process child;
     pthread_cleanup_push(BatchManager_Local::kill_child_on_exit, static_cast<void *> (&child));
     pthread_cleanup_push(BatchManager_Local::delete_on_exit, arg);
 
@@ -376,6 +388,10 @@ namespace Batch {
     }
 
     string executionhost = string(param[EXECUTIONHOST]);
+    string user;
+    if ( (it = param.find(USER)) != param.end() ) {
+      user = string(it->second);
+    }
 
     if ( (it = param.find(INFILE)) != param.end() ) {
       Versatile V = (*it).second;
@@ -387,8 +403,12 @@ namespace Batch {
         string local    = cp.getLocal();
         string remote   = cp.getRemote();
 
-        string copy_cmd = p_ta->getBatchManager().copy_command("", local, executionhost, workdir + "/" + remote);
+        string copy_cmd = p_ta->getBatchManager().copy_command("", "", local, user,
+                                                               executionhost, workdir + "/" + remote);
         UNDER_LOCK( cout << "Copying : " << copy_cmd << endl );
+#ifdef WIN32
+        copy_cmd = string("\"") + copy_cmd + string("\"");
+#endif
 
         if (system(copy_cmd.c_str()) ) {
           // Echec de la copie
@@ -404,13 +424,13 @@ namespace Batch {
 
 
 
-#ifdef WIN32
-    //TODO
-    //Using CreateThread instead fork() POSIX function
-#else
     // On forke/exec un nouveau process pour pouvoir controler le fils
     // (plus finement qu'avec un appel system)
     // int rc = system(commande.c_str());
+#ifdef WIN32
+    child = p_ta->launchWin32ChildProcess();
+    p_ta->pere(child);
+#else
     child = fork();
     if (child < 0) { // erreur
       UNDER_LOCK( cerr << "Fork impossible (rc=" << child << ")" << endl );
@@ -424,7 +444,6 @@ namespace Batch {
 #endif
 
 
-
     // On copie les fichiers de sortie du fils
     if ( (it = param.find(OUTFILE)) != param.end() ) {
       Versatile V = (*it).second;
@@ -436,8 +455,12 @@ namespace Batch {
         string local    = cp.getLocal();
         string remote   = cp.getRemote();
 
-        string copy_cmd = p_ta->getBatchManager().copy_command(executionhost, workdir + "/" + remote, "", local);
+        string copy_cmd = p_ta->getBatchManager().copy_command(user, executionhost, workdir + "/" + remote,
+                                                               "", "", local);
         UNDER_LOCK( cout << "Copying : " << copy_cmd << endl );
+#ifdef WIN32
+        copy_cmd = string("\"") + copy_cmd + string("\"");
+#endif
 
         if (system(copy_cmd.c_str()) ) {
           // Echec de la copie
@@ -455,8 +478,11 @@ namespace Batch {
     if ( (rc == 0) || (child < 0) ) {
       std::vector<string>::const_iterator it;
       for(it=files_to_delete.begin(); it!=files_to_delete.end(); it++) {
-        string remove_cmd = p_ta->getBatchManager().remove_command(executionhost, *it);
+        string remove_cmd = p_ta->getBatchManager().remove_command(user, executionhost, *it);
         UNDER_LOCK( cout << "Removing : " << remove_cmd << endl );
+#ifdef WIN32
+        remove_cmd = string("\"") + remove_cmd + string("\"");
+#endif
         system(remove_cmd.c_str());
       }
     }
@@ -476,16 +502,14 @@ namespace Batch {
 
     UNDER_LOCK( cout << "Father is leaving" << endl );
     pthread_exit(NULL);
-#endif
     return NULL;
   }
 
 
 
 
-  void BatchManager_Local::ThreadAdapter::pere(pid_t child)
+  void BatchManager_Local::ThreadAdapter::pere(Process child)
   {
-#ifndef WIN32 //TODO: porting of following functionality
     time_t child_starttime = time(NULL);
 
     // On enregistre le fils dans la table des threads
@@ -499,12 +523,16 @@ namespace Batch {
     thread_id_sst << id;
     param[ID]         = thread_id_sst.str();
     param[STATE]      = "Running";
+#ifndef WIN32
     param[PID]        = child;
+#endif
 
     // @@@ --------> SECTION CRITIQUE <-------- @@@
     pthread_mutex_lock(&_bm._threads_mutex);
     _bm._threads[id].thread_id = thread_id;
+#ifndef WIN32
     _bm._threads[id].pid       = child;
+#endif
     _bm._threads[id].status    = RUNNING;
     _bm._threads[id].param     = param;
     _bm._threads[id].env       = env;
@@ -515,9 +543,21 @@ namespace Batch {
 
 
 
-
     // on boucle en attendant que le fils ait termine
     while (1) {
+#ifdef WIN32
+      DWORD exitCode;
+      BOOL res = GetExitCodeProcess(child, &exitCode);
+      if (exitCode != STILL_ACTIVE) {
+        pthread_mutex_lock(&_bm._threads_mutex);
+        _bm._threads[id].status       = DONE;
+        _bm._threads[id].param[STATE] = "Done";
+        pthread_mutex_unlock(&_bm._threads_mutex);
+        // @@@ --------> SECTION CRITIQUE <-------- @@@
+        UNDER_LOCK( cout << "Father sees his child is DONE: exit code = " << exitCode << endl );
+        break;
+      }
+#else
       int child_rc = 0;
       pid_t child_wait_rc = waitpid(child, &child_rc, WNOHANG /* | WUNTRACED */);
       if (child_wait_rc > 0) {
@@ -560,8 +600,7 @@ namespace Batch {
         UNDER_LOCK( cout << "Father sees his child is DEAD : " << child_wait_rc << " (Reason : " << strerror(errno) << ")" << endl );
         break;
       }
-
-
+#endif
 
       // On teste si le thread doit etre detruit
       pthread_testcancel();
@@ -615,7 +654,7 @@ namespace Batch {
     case NOP:
       UNDER_LOCK( cout << "Father does nothing to his child" << endl );
       break;
-
+#ifndef WIN32
     case HOLD:
       UNDER_LOCK( cout << "Father is sending SIGSTOP signal to his child" << endl );
       kill(child, SIGSTOP);
@@ -635,7 +674,7 @@ namespace Batch {
       UNDER_LOCK( cout << "Father is sending SIGKILL signal to his child" << endl );
       kill(child, SIGKILL);
       break;
-
+#endif
     case ALTER:
       break;
 
@@ -649,34 +688,27 @@ namespace Batch {
       // @@@ --------> SECTION CRITIQUE <-------- @@@
 
       // On fait une petite pause pour ne pas surcharger inutilement le processeur
+#ifdef WIN32
+      Sleep(1000);
+#else
       sleep(1);
-
-    }
 #endif
 
+    }
 
   }
 
 
 
+#ifndef WIN32
 
   void BatchManager_Local::ThreadAdapter::fils()
   {
-#ifndef WIN32 //TODO: porting of following functionality
     Parametre param = _job.getParametre();
     Parametre::iterator it;
 
     try {
 
-      // On se place dans le repertoire de travail
-      if ( (it = param.find(WORKDIR)) != param.end() ) {
-        string workdir = static_cast<string>( (*it).second );
-        chdir(workdir.c_str());
-      }
-
-
-
-
       // EXECUTABLE is MANDATORY, if missing, we exit with failure notification
       char * execpath = NULL;
       if (param.find(EXECUTABLE) != param.end()) {
@@ -718,9 +750,11 @@ namespace Batch {
 
 
 
+      // Create the environment for the new process. Note (RB): Here we change the environment for
+      // the process launched in local. It would seem more logical to set the environment for the
+      // remote process.
       Environnement env = _job.getEnvironnement();
 
-
       char ** envp = NULL;
       if(env.size() > 0) {
         envp = new char * [env.size() + 1]; // 1 pour le NULL terminal
@@ -795,10 +829,92 @@ namespace Batch {
     }
 
     exit(99);
-#endif
   }
 
+#else
+
+  BatchManager_Local::Process BatchManager_Local::ThreadAdapter::launchWin32ChildProcess()
+  {
+    Parametre param = _job.getParametre();
+    Parametre::iterator it;
+    PROCESS_INFORMATION pi;
+
+    try {
+
+      // EXECUTABLE is MANDATORY, if missing, we throw an exception
+      string exec_command;
+      if (param.find(EXECUTABLE) != param.end()) {
+        exec_command = _bm.exec_command(param);
+      } else {
+        throw RunTimeException("Parameter \"EXECUTABLE\" is mandatory for local batch submission");
+      }
+
+      string name = (param.find(NAME) != param.end()) ? param[NAME] : param[EXECUTABLE];
+
+      if (param.find(ARGUMENTS) != param.end()) {
+        Versatile V = param[ARGUMENTS];
+
+        for(Versatile::const_iterator it=V.begin() ; it!=V.end() ; it++) {
+          StringType argt = * static_cast<StringType *>(*it);
+          exec_command += string(" ") + string(argt);
+        }
+      }
+
 
+      UNDER_LOCK( cout << "*** exec_command = " << exec_command << endl );
+
+
+      // Create the environment for the new process. Note (RB): Here we change the environment for
+      // the process launched in local. It would seem more logical to set the environment for the
+      // remote process.
+      // Note that if no environment is specified, we reuse the current environment.
+      Environnement env = _job.getEnvironnement();
+      char * chNewEnv = NULL;
+
+      if(env.size() > 0) {
+        chNewEnv = new char[4096];
+        LPTSTR lpszCurrentVariable = chNewEnv;
+        for(Environnement::const_iterator it=env.begin() ; it!=env.end() ; it++) {
+          const string  & key   = (*it).first;
+          const string  & value = (*it).second;
+          string envvar = key + "=" + value;
+          envvar.copy(lpszCurrentVariable, envvar.size());
+          lpszCurrentVariable[envvar.size()] = '\0';
+          lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
+        }
+        // Terminate the block with a NULL byte.
+        *lpszCurrentVariable = '\0';
+      }
+
+
+      STARTUPINFO si;
+      ZeroMemory( &si, sizeof(si) );
+      si.cb = sizeof(si);
+      ZeroMemory( &pi, sizeof(pi) );
+
+      // Copy the command to a non-const buffer
+      size_t str_size = exec_command.size();
+      char buffer[str_size+1];
+      exec_command.copy(buffer,str_size);
+      buffer[str_size]='\0';
+
+      // launch the new process
+      BOOL res = CreateProcess(NULL, buffer, NULL, NULL, FALSE,
+                               0, chNewEnv, NULL, &si, &pi);
+
+      if (!res) throw RunTimeException("Error while creating new process");
+
+      CloseHandle(pi.hThread);
+
+    } catch (GenericException & e) {
+
+      std::cerr << "Caught exception : " << e.type << " : " << e.message << std::endl;
+    }
+
+    return pi.hProcess;
+  }
+
+#endif
 
 
   void BatchManager_Local::kill_child_on_exit(void * p_pid)
index 33f9dfa3a681715e42a56be89069aad6cd0b1ca6..a7e70de2ccb2665201c6d9f205ce76ecd4376666 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "Batch_Defines.hxx"
 
-#include <vector>
+#include <list>
 #include <map>
 #include <queue>
 #include <pthread.h>
@@ -56,6 +56,11 @@ namespace Batch {
   class BATCH_EXPORT BatchManager_Local : public BatchManager
   {
   private:
+#ifdef WIN32
+    typedef HANDLE Process;
+#else
+    typedef pid_t Process;
+#endif
     friend class ThreadAdapter;
     class ThreadAdapter{
     public:
@@ -68,8 +73,12 @@ namespace Batch {
       const Job_Local _job;
 
     private:
-      void pere(pid_t child);
+      void pere(Process child);
+#ifndef WIN32
       void fils();
+#else
+      Process launchWin32ChildProcess();
+#endif
 
     };
 
@@ -133,19 +142,27 @@ namespace Batch {
     std::map<Id, Child > _threads;
 
     // Methode abstraite qui renvoie la commande de copie du fichier source en destination
-    virtual std::string copy_command( const std::string & host_source,
-                                     const std::string & source,
-                                     const std::string & host_destination,
-                                     const std::string & destination) const = 0;
+    virtual std::string copy_command( const std::string & user_source,
+                                      const std::string & host_source,
+                                      const std::string & source,
+                                      const std::string & user_destination,
+                                      const std::string & host_destination,
+                                      const std::string & destination) const = 0;
 
     // Methode abstraite qui renvoie la commande a executer
     virtual std::string exec_command(Parametre & param) const = 0;
 
     // Methode abstraite qui renvoie la commande d'effacement du fichier
-    virtual std::string remove_command( const std::string & host_destination,
-                                       const std::string & destination) const = 0;
+    virtual std::string remove_command( const std::string & user_destination,
+                                        const std::string & host_destination,
+                                        const std::string & destination) const = 0;
 
   private:
+    struct ThreadIdIdAssociation {
+      pthread_t threadId;
+      Id id;
+    };
+
     virtual pthread_t submit(const Job_Local & job);
     virtual void cancel(pthread_t thread_id);
     static  void kill_child_on_exit(void * p_pid);
@@ -155,10 +172,7 @@ namespace Batch {
     Id registerThread_id(pthread_t thread_id);
     pthread_mutex_t _thread_id_id_association_mutex;
     pthread_cond_t  _thread_id_id_association_cond;
-#ifndef WIN32 //TODO: porting of following functionality
-    //reason: pthread_t on win32 is a struct of pointer and int members
-    std::map<pthread_t, Id> _thread_id_id_association;
-#endif
+    std::list<struct ThreadIdIdAssociation> _thread_id_id_association;
 
 #ifdef SWIG
   public:
index 56c6e45bcaa6354511661ec271465f7d27229679..54cae559a80bedb9d475763324e7845c974633aa 100644 (file)
 
 #include "Batch_config.h"
 
-#ifndef RM
-#error "RM undefined. You must set RM to a valid path to a rm-like command."
-#endif
-
 #ifndef RCP
 #error "RCP undefined. You must set RCP to a valid path to a rcp-like command."
 #endif
@@ -81,22 +77,43 @@ namespace Batch {
 
 
   // Methode abstraite qui renvoie la commande de copie du fichier source en destination
-  string BatchManager_Local_RSH::copy_command(const string & host_source, const string & source, const string & host_destination, const string & destination) const
+  string BatchManager_Local_RSH::copy_command(const std::string & user_source,
+                                              const std::string & host_source,
+                                              const std::string & source,
+                                              const std::string & user_destination,
+                                              const std::string & host_destination,
+                                              const std::string & destination) const
   {
     ostringstream fullsource;
     if (host_source.size() != 0) {
-      fullsource << host_source << ":";
+      if (user_source.size() != 0) {
+#ifdef WIN32
+        fullsource << host_source << "." << user_source << ":";
+#else
+        fullsource << user_source << "@" << host_source << ":";
+#endif
+      } else {
+        fullsource << host_source << ":";
+      }
     }
     fullsource << source;
 
     ostringstream fulldestination;
     if (host_destination.size() != 0) {
-      fulldestination << host_destination << ":";
+      if (user_destination.size() != 0) {
+#ifdef WIN32
+        fulldestination << host_destination << "." << user_destination << ":";
+#else
+        fulldestination << user_destination << "@" << host_destination << ":";
+#endif
+      } else {
+        fulldestination << host_destination << ":";
+      }
     }
     fulldestination << destination;
 
     ostringstream copy_cmd;
-    copy_cmd << RCP << " " << fullsource.str() << " " << fulldestination.str();
+    copy_cmd << "\"" << RCP << "\" " << fullsource.str() << " " << fulldestination.str();
     return copy_cmd.str();
   }
 
@@ -104,8 +121,7 @@ namespace Batch {
   string BatchManager_Local_RSH::exec_command(Parametre & param) const
   {
     ostringstream exec_sub_cmd;
-    exec_sub_cmd << "cd " << param[WORKDIR] << ";";
-    exec_sub_cmd << param[EXECUTABLE];
+    exec_sub_cmd << "cd " << param[WORKDIR] << " && " << param[EXECUTABLE];
 
     if (param.find(ARGUMENTS) != param.end()) {
       Versatile V = param[ARGUMENTS];
@@ -139,12 +155,23 @@ namespace Batch {
   }
 
   // Methode qui renvoie la commande d'effacement du fichier
-  string BatchManager_Local_RSH::remove_command(const string & host_destination, const string & destination) const
+  string BatchManager_Local_RSH::remove_command(const std::string & user_destination,
+                                                const std::string & host_destination,
+                                                const std::string & destination) const
   {
-    string host = (host_destination.size()) ? host_destination : "localhost:";
+    string fulldestination = (host_destination.size()) ? host_destination : "localhost";
+    if (user_destination.size() != 0) {
+      fulldestination += " -l " + user_destination;
+    }
 
+    // We consider here that the remote system is UNIX-like and has a "rm" command. Using the
+    // RM macro would be pointless here since the remote system is different from the local one.
     ostringstream remove_cmd;
-    remove_cmd << RSH << " " << host << " \"" << RM << " " << destination << "\"";
+    remove_cmd << "\"" << RSH << "\" " << fulldestination;
+#ifdef WIN32
+    remove_cmd << " -n";
+#endif
+    remove_cmd << " rm " << destination;
     return remove_cmd.str();
   }
 }
index c5c6604259152f06cc3dd1679246619f17b6a0c6..235e3d802309fb52fca8c436a8aca553b770a427 100644 (file)
@@ -20,7 +20,7 @@
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 /*
- * BatchManager_Local_RSH.hxx : 
+ * BatchManager_Local_RSH.hxx :
  *
  * Auteur : Ivan DUTKA-MALEN - EDF R&D
  * Mail   : mailto:ivan.dutka-malen@der.edf.fr
@@ -62,18 +62,21 @@ namespace Batch {
     virtual ~BatchManager_Local_RSH();
 
   protected:
-    // Methode abstraite qui renvoie la commande de copie du fichier source en destination
-    virtual std::string copy_command( const std::string & host_source,
-                                     const std::string & source,
-                                     const std::string & host_destination,
-                                     const std::string & destination) const;
+    // Methode qui renvoie la commande de copie du fichier source en destination
+    virtual std::string copy_command( const std::string & user_source,
+                                      const std::string & host_source,
+                                      const std::string & source,
+                                      const std::string & user_destination,
+                                      const std::string & host_destination,
+                                      const std::string & destination) const;
 
-    // Methode abstraite qui renvoie la commande a executer
+    // Methode qui renvoie la commande a executer
     virtual std::string exec_command(Parametre & param) const;
 
     // Methode qui renvoie la commande d'effacement du fichier
-    virtual std::string remove_command( const std::string & host_destination,
-                                       const std::string & destination) const;
+    virtual std::string remove_command( const std::string & user_destination,
+                                        const std::string & host_destination,
+                                        const std::string & destination) const;
 
   };
 
index c71847b4b972793ba7c1902a07a95739340e6716..db4e9cce61b6bf80954c3925f45a8d4f729dd704 100644 (file)
@@ -81,10 +81,15 @@ namespace Batch {
 
 
   // Methode qui renvoie la commande de copie du fichier source en destination
-  string BatchManager_Local_SH::copy_command(const string & host_source, const string & source, const string & host_destination, const string & destination) const
+  string BatchManager_Local_SH::copy_command(const std::string & user_source,
+                                             const std::string & host_source,
+                                             const std::string & source,
+                                             const std::string & user_destination,
+                                             const std::string & host_destination,
+                                             const std::string & destination) const
   {
     ostringstream copy_cmd;
-    copy_cmd << CP << " " << source << " " << destination;
+    copy_cmd << "\"" << CP << "\" \"" << source << "\" \"" << destination << "\"";
     return copy_cmd.str();
   }
 
@@ -92,16 +97,22 @@ namespace Batch {
   string BatchManager_Local_SH::exec_command(Parametre & param) const
   {
     ostringstream exec_sub_cmd;
-    exec_sub_cmd << param[EXECUTABLE];
+#ifdef WIN32
+    exec_sub_cmd << "\"";
+#endif
+    exec_sub_cmd << "cd " << param[WORKDIR] << " && " << param[EXECUTABLE];
 
     if (param.find(ARGUMENTS) != param.end()) {
       Versatile V = param[ARGUMENTS];
       for(Versatile::const_iterator it=V.begin(); it!=V.end(); it++) {
-       StringType argt = * static_cast<StringType *>(*it);
-       string     arg  = argt;
-       exec_sub_cmd << " " << arg;
+        StringType argt = * static_cast<StringType *>(*it);
+        string     arg  = argt;
+        exec_sub_cmd << " " << arg;
       }
     }
+#ifdef WIN32
+    exec_sub_cmd << "\"";
+#endif
 
     param[ARGUMENTS]  = "-c";
     param[ARGUMENTS] += exec_sub_cmd.str();
@@ -110,10 +121,12 @@ namespace Batch {
   }
 
   // Methode qui renvoie la commande d'effacement du fichier
-  string BatchManager_Local_SH::remove_command(const string & host_destination, const string & destination) const
+  string BatchManager_Local_SH::remove_command(const std::string & user_destination,
+                                               const std::string & host_destination,
+                                               const std::string & destination) const
   {
     ostringstream remove_cmd;
-    remove_cmd << RM << " " << destination;
+    remove_cmd << "\"" << RM << "\" \"" << destination << "\"";
     return remove_cmd.str();
   }
 
index 23b59097a5b13f3979cce2a3d5c622c058af131d..34c02ec6ad56fd6ce2913fdc7c9002da7caa77d9 100644 (file)
@@ -20,7 +20,7 @@
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 /*
- * BatchManager_Local_SH.hxx : 
+ * BatchManager_Local_SH.hxx :
  *
  * Auteur : Ivan DUTKA-MALEN - EDF R&D
  * Mail   : mailto:ivan.dutka-malen@der.edf.fr
@@ -63,17 +63,20 @@ namespace Batch {
 
   protected:
     // Methode qui renvoie la commande de copie du fichier source en destination
-    virtual std::string copy_command( const std::string & host_source,
-                                     const std::string & source,
-                                     const std::string & host_destination,
-                                     const std::string & destination) const;
+    virtual std::string copy_command( const std::string & user_source,
+                                      const std::string & host_source,
+                                      const std::string & source,
+                                      const std::string & user_destination,
+                                      const std::string & host_destination,
+                                      const std::string & destination) const;
 
     // Methode qui renvoie la commande a executer
     virtual std::string exec_command(Parametre & param) const;
 
     // Methode qui renvoie la commande d'effacement du fichier
-    virtual std::string remove_command( const std::string & host_destination,
-                                       const std::string & destination) const;
+    virtual std::string remove_command( const std::string & user_destination,
+                                        const std::string & host_destination,
+                                        const std::string & destination) const;
 
   };
 
index 70b0d9e8f764d302f44f02285bb5aaab18cf875f..f829d607cb9501c72554cfd26e36d9c3350bb61d 100644 (file)
@@ -82,7 +82,12 @@ namespace Batch {
 
 
   // Methode abstraite qui renvoie la commande de copie du fichier source en destination
-  string BatchManager_Local_SSH::copy_command(const string & host_source, const string & source, const string & host_destination, const string & destination) const
+  string BatchManager_Local_SSH::copy_command(const std::string & user_source,
+                                              const std::string & host_source,
+                                              const std::string & source,
+                                              const std::string & user_destination,
+                                              const std::string & host_destination,
+                                              const std::string & destination) const
   {
     ostringstream fullsource;
     if (host_source.size() != 0) {
@@ -142,7 +147,9 @@ namespace Batch {
   }
 
   // Methode qui renvoie la commande d'effacement du fichier
-  string BatchManager_Local_SSH::remove_command(const string & host_destination, const string & destination) const
+  string BatchManager_Local_SSH::remove_command(const std::string & user_destination,
+                                                const std::string & host_destination,
+                                                const std::string & destination) const
   {
     string host = (host_destination.size()) ? host_destination : "localhost:";
 
index 12772fb46e2aa9d45370c656c550729274cc4704..c5afaae6cb000752b36e7606a5e324b62adb63ce 100644 (file)
@@ -20,7 +20,7 @@
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 /*
- * BatchManager_Local_SSH.hxx : 
+ * BatchManager_Local_SSH.hxx :
  *
  * Auteur : Ivan DUTKA-MALEN - EDF R&D
  * Mail   : mailto:ivan.dutka-malen@der.edf.fr
@@ -62,18 +62,21 @@ namespace Batch {
     virtual ~BatchManager_Local_SSH();
 
   protected:
-    // Methode abstraite qui renvoie la commande de copie du fichier source en destination
-    virtual std::string copy_command( const std::string & host_source,
-                                     const std::string & source,
-                                     const std::string & host_destination,
-                                     const std::string & destination) const;
+    // Methode qui renvoie la commande de copie du fichier source en destination
+    virtual std::string copy_command( const std::string & user_source,
+                                      const std::string & host_source,
+                                      const std::string & source,
+                                      const std::string & user_destination,
+                                      const std::string & host_destination,
+                                      const std::string & destination) const;
 
-    // Methode abstraite qui renvoie la commande a executer
+    // Methode qui renvoie la commande a executer
     virtual std::string exec_command(Parametre & param) const;
 
     // Methode qui renvoie la commande d'effacement du fichier
-    virtual std::string remove_command( const std::string & host_destination,
-                                       const std::string & destination) const;
+    virtual std::string remove_command( const std::string & user_destination,
+                                        const std::string & host_destination,
+                                        const std::string & destination) const;
 
   };
 
index cc95e45865ecad610994d1abe733181b944c17b9..548a88eeed8883e62e77e4411f0282c068e2198e 100644 (file)
 #
 
 # Declare the configuration variables for the test scripts
+SET (TEST_LOCAL_SH_WORK_DIR "/tmp" CACHE STRING
+     "Work directory for SH Batch test (only necessary for test target)")
+
 SET (TEST_LOCAL_RSH_EXECUTION_HOST "localhost" CACHE STRING
      "Execution host for RSH Batch test (only necessary for test target)")
+SET (TEST_LOCAL_RSH_USER $ENV{USER} CACHE STRING
+     "User name on the execution host for RSH Batch test (only necessary for test target)")
 SET (TEST_LOCAL_RSH_WORK_DIR "/tmp" CACHE STRING
      "Work directory for RSH Batch test (only necessary for test target)")
 
index 5bd5c05a311823d1f89d72df27c811804c9fdfd7..e5e2e4f0833122baa0dba4646a3a167ee98cb21b 100644 (file)
@@ -54,7 +54,7 @@ int main(int argc, char** argv)
     Job job;
     // ... and its parameters ...
     Parametre p;
-    p["EXECUTABLE"]    = "./copied-test-script.sh";
+    p["EXECUTABLE"]    = "source copied-test-script.sh";
     p["NAME"]          = "Test_Local_RSH";
     p["WORKDIR"]       = TEST_LOCAL_RSH_WORK_DIR;
     p["INFILE"]        = Couple("seta.sh", "copied-seta.sh");
@@ -62,6 +62,7 @@ int main(int argc, char** argv)
     p["INFILE"]       += Couple("test-script.sh", "copied-test-script.sh");
     p["OUTFILE"]       = Couple("result.txt", "orig-result.txt");
     p["EXECUTIONHOST"] = TEST_LOCAL_RSH_EXECUTION_HOST;
+    p["USER"]          = TEST_LOCAL_RSH_USER;
     job.setParametre(p);
     // ... and its environment
     Environnement e;
index 1df79239f7a816651a78ad1d636cb2f960c1b3c3..2cdcea98c25d1414b5818e9911f783c804835946 100644 (file)
@@ -56,7 +56,7 @@ int main(int argc, char** argv)
     Parametre p;
     p["EXECUTABLE"] = "./copied-test-script.sh";
     p["NAME"]       = "Test_Local_SH";
-    p["WORKDIR"]    = "/tmp";
+    p["WORKDIR"]    = TEST_LOCAL_SH_WORK_DIR;
     p["INFILE"]     = Couple("seta.sh", "copied-seta.sh");
     p["INFILE"]    += Couple("setb.sh", "copied-setb.sh");
     p["INFILE"]    += Couple("test-script.sh", "copied-test-script.sh");
@@ -80,7 +80,7 @@ int main(int argc, char** argv)
 
     // Wait for the end of the job
     string state = "Unknown";
-    for (int i=0 ; i<10 && state != "Done" ; i++) {
+    for (int i=0 ; i<20 && state != "Done" ; i++) {
       usleep(100000);
       Versatile paramState = jobid.queryJob().getParametre()["STATE"];
       state = (paramState.size() > 0) ? paramState.str() : "Unknown";
index 33da7f8a50f8a0a3f07dfe5c97b69ab05e0e7888..f584f7288d248329be7b8be7131d1dc954c71328 100644 (file)
 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
 
+#define TEST_LOCAL_SH_WORK_DIR "${TEST_LOCAL_SH_WORK_DIR}"
+
 #define TEST_LOCAL_RSH_EXECUTION_HOST "${TEST_LOCAL_RSH_EXECUTION_HOST}"
+#define TEST_LOCAL_RSH_USER "${TEST_LOCAL_RSH_USER}"
 #define TEST_LOCAL_RSH_WORK_DIR "${TEST_LOCAL_RSH_WORK_DIR}"
 
 #define TEST_LOCAL_SSH_EXECUTION_HOST "${TEST_LOCAL_SSH_EXECUTION_HOST}"
index fddae1d3fafd4e2d2ac42856e858f09adfdeed56..e5c2d0adcb68e69dc27621dbcc8c08cebeeeb0e9 100644 (file)
@@ -70,7 +70,7 @@ def work():
     # Wait for the end of the job
     state = 'Unknown'
     i=0
-    while state != 'Done' and i<10:
+    while state != 'Done' and i<20:
         time.sleep(0.1)
         i+=1
         jinfo = jobid.queryJob()