1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "BatchTest.hxx"
24 #include "Launcher.hxx"
27 #include <libbatch/MpiImpl.hxx>
30 #include "utilities.h"
38 BatchTest::BatchTest(const Engines::ResourceDefinition& batch_descr)
41 _batch_descr = batch_descr;
44 const size_t BUFSIZE = 32;
46 time_t curtime = time(NULL);
47 strftime(date, BUFSIZE, "%Y_%m_%d__%H_%M_%S", localtime(&curtime));
49 // Creating test temporary file
50 _test_filename = "/tmp/";
51 _test_filename += std::string(date) + "_test_cluster_file_";
52 _test_filename += _batch_descr.hostname.in();
53 _base_filename = std::string(date) + "_test_cluster_file_" + _batch_descr.hostname.in();
57 BatchTest::~BatchTest() {}
64 << "--- Testing batch Machine :" << std::endl
65 << "--- Name : " << _batch_descr.hostname << std::endl
66 << "--- hostname : " << _batch_descr.hostname << std::endl
67 << "--- Protocol : " << _batch_descr.protocol << std::endl
68 << "--- User Name : " << _batch_descr.username << std::endl
69 << "--- Batch Type : " << _batch_descr.batch << std::endl
70 << "--- MPI Impl : " << _batch_descr.mpiImpl << std::endl
71 << "--- Appli Path : " << _batch_descr.applipath << std::endl
74 std::string result_connection("Not Tested");
75 std::string result_filecopy("Not Tested");
76 std::string result_getresult("Not Tested");
77 std::string result_jobsubmit_simple("Not Tested");
78 std::string result_jobsubmit_mpi("Not Tested");
79 std::string result_appli("Not Tested");
81 result_connection = test_connection();
82 result_filecopy = test_filecopy();
83 result_getresult = test_getresult();
84 result_jobsubmit_simple = test_jobsubmit_simple();
85 result_jobsubmit_mpi = test_jobsubmit_mpi();
86 result_appli = test_appli();
89 << "--- Test results" << std::endl
90 << "--- Connection : " << result_connection << std::endl
91 << "--- File copy : " << result_filecopy << std::endl
92 << "--- Get results : " << result_getresult << std::endl
93 << "--- Submit simple job : " << result_jobsubmit_simple << std::endl
94 << "--- Submit mpi job : " << result_jobsubmit_mpi << std::endl
95 << "--- Application : " << result_appli << std::endl
98 if (result_connection == "OK" &&
99 result_filecopy == "OK" &&
100 result_getresult == "OK" &&
101 result_jobsubmit_simple == "OK" &&
102 result_jobsubmit_mpi == "OK" &&
103 result_appli == "OK")
109 // For this test we use : hostname, protocol, username
111 BatchTest::test_connection()
115 std::string result("Failed : ");
116 std::string hostname = _batch_descr.hostname.in();
117 std::string username = _batch_descr.username.in();
118 std::string protocol = _batch_descr.protocol.in();
123 result += "hostname is empty !";
128 result += "username is empty !";
131 if( protocol != "rsh" && protocol != "ssh")
133 result += "protocol unknown ! (" + protocol + ")";
140 + username + "@" + hostname;
143 status = system(command.c_str());
145 std::ostringstream oss;
147 result += "Error of connection on remote host ! status = ";
156 // For this test we use : hostname, protocol, username
158 BatchTest::test_filecopy()
163 std::string result("Failed : ");
164 std::string hostname = _batch_descr.hostname.in();
165 std::string username = _batch_descr.username.in();
166 std::string protocol = _batch_descr.protocol.in();
168 // Getting home directory
169 std::string rst = get_home(&home);
175 // Writing into the tempory file
176 command = "echo Hello > " + _test_filename;
177 status = system(command.c_str());
179 std::ostringstream oss;
181 result += "Error in creating tempory file ! status = ";
188 if(protocol == "rsh")
190 command += " " + _test_filename + " "
191 + username + "@" + hostname + ":" + home;
194 status = system(command.c_str());
196 std::ostringstream oss;
198 result += "Error in copy file on remote host ! status = ";
207 // For this test we use : hostname, protocol, username
209 BatchTest::test_getresult()
214 std::string result("Failed : ");
215 std::string hostname = _batch_descr.hostname.in();
216 std::string username = _batch_descr.username.in();
217 std::string protocol = _batch_descr.protocol.in();
219 // Getting home directory
220 std::string rst = get_home(&home);
228 if(protocol == "rsh")
230 command += " " + username + "@" + hostname + ":" + home
231 + "/" + _base_filename + " " + _test_filename + "_copy";
234 status = system(command.c_str());
236 std::ostringstream oss;
238 result += "Error in copy file from remote host ! status = ";
244 std::ifstream src_file(_test_filename.c_str());
247 result += "Error in reading temporary file ! filename = " + _test_filename;
250 std::string cp_filename = _test_filename + "_copy";
251 std::ifstream cp_file(cp_filename.c_str());
254 result += "Error in reading temporary copy file ! filename = " + cp_filename;
257 std::string src_firstline;
258 std::string cp_firstline;
259 std::getline(src_file, src_firstline);
260 std::getline(cp_file, cp_firstline);
263 if (src_firstline != cp_firstline)
265 result += "Error source file and copy file are not equa ! source = " + src_firstline + " copy = " + cp_firstline;
274 BatchTest::test_jobsubmit_simple()
279 std::string result("Failed : ");
280 std::string hostname = _batch_descr.hostname.in();
281 std::string username = _batch_descr.username.in();
282 std::string protocol = _batch_descr.protocol.in();
283 std::string batch_type = _batch_descr.batch.in();
286 if (batch_type == "lsf")
288 INFOS("test_jobsubmit_simple not yet implemented for lsf... return OK");
292 if (batch_type == "ccc")
294 INFOS("test_jobsubmit_simple not yet implemented for ccc... return OK");
298 if (batch_type == "slurm")
300 INFOS("test_jobsubmit_simple not yet implemented for slurm... return OK");
304 if (batch_type == "sge")
306 INFOS("test_jobsubmit_simple not yet implemented for sge... return OK");
310 if (batch_type == "oar")
312 INFOS("test_jobsubmit_simple not yet implemented for oar... return OK");
316 if (batch_type == "coorm")
318 INFOS("test_jobsubmit_simple not yet implemented for coorm... return OK");
322 if (batch_type != "pbs")
324 result += "Batch type unknown ! : " + batch_type;
328 // Getting home directory
329 std::string rst = get_home(&home);
336 std::string _test_file_simple = _test_filename + "_simple";
338 file.open(_test_file_simple.c_str(), std::ofstream::out);
339 file << "#!/bin/bash\n"
340 << "#PBS -l nodes=1\n"
341 << "#PBS -l walltime=00:01:00\n"
342 << "#PBS -o " + home + "/" + _date + "_simple_output.log\n"
343 << "#PBS -e " + home + "/" + _date + "_simple_error.log\n"
345 << "echo Error >&2\n";
350 // Build command for copy
352 if(protocol == "rsh")
354 command += " " + _test_file_simple + " "
355 + username + "@" + hostname + ":" + home;
356 status = system(command.c_str());
358 std::ostringstream oss;
360 result += "Error in copy job file to remote host ! status = ";
365 // Build command for submit job
366 std::string file_job_name = _test_filename + "_jobid";
367 command = protocol + " " + username + "@" + hostname + " qsub " + _base_filename + "_simple > " + file_job_name;
368 status = system(command.c_str());
370 std::ostringstream oss;
372 result += "Error in sending qsub to remote host ! status = ";
377 std::ifstream file_job(file_job_name.c_str());
380 result += "Error in reading temporary file ! filename = " + file_job_name;
383 std::getline(file_job, jobid);
386 // Wait the end of the job
387 command = protocol + " " + username + "@" + hostname + " qstat -f " + jobid + " > " + file_job_name;
391 status = system(command.c_str());
392 if(status && status != 153 && status != 256*153)
394 std::ostringstream oss;
396 result += "Error in sending qstat to remote host ! status = ";
401 if(status == 153 || status == 256*153 )
410 // Build command for getting results
412 if(protocol == "rsh")
415 + username + "@" + hostname + ":" + home + "/" + _date + "_simple* /tmp";
416 status = system(command.c_str());
418 std::ostringstream oss;
420 result += "error in getting file result of qsub simple to remote host ! status = ";
426 std::string normal_input;
427 std::string file_normal_name = "/tmp/" + _date + "_simple_output.log";
428 std::ifstream file_normal(file_normal_name.c_str());
431 result += "Error in reading temporary file ! filename = " + file_normal_name;
434 std::getline(file_normal, normal_input);
436 if (normal_input != "Bonjour")
438 result += "error from simple ouput file ! waiting for Bonjour and get : " + normal_input;
441 std::string error_input;
442 std::string file_error_name = "/tmp/" + _date + "_simple_error.log";
443 std::ifstream file_error(file_error_name.c_str());
446 result += "Error in reading temporary file ! filename = " + file_error_name;
449 std::getline(file_error, error_input);
451 if (error_input != "Error")
453 result += "error from simple error file ! waiting for Error and get : " + error_input;
461 BatchTest::test_jobsubmit_mpi()
468 std::string result("Failed : ");
469 std::string hostname = _batch_descr.hostname.in();
470 std::string username = _batch_descr.username.in();
471 std::string protocol = _batch_descr.protocol.in();
472 std::string batch_type = _batch_descr.batch.in();
473 std::string mpi_type = _batch_descr.mpiImpl.in();
476 if(mpi_type == "lam")
477 mpiImpl = new MpiImpl_LAM();
478 else if(mpi_type == "mpich1")
479 mpiImpl = new MpiImpl_MPICH1();
480 else if(mpi_type == "mpich2")
481 mpiImpl = new MpiImpl_MPICH2();
482 else if(mpi_type == "openmpi")
483 mpiImpl = new MpiImpl_OPENMPI();
484 else if(mpi_type == "ompi")
485 mpiImpl = new MpiImpl_OMPI();
486 else if(mpi_type == "slurmmpi")
487 mpiImpl = new MpiImpl_SLURM();
490 result += "Error MPI impl not supported : " + mpi_type;
494 // LSF et SGE not yet implemented...
495 if (batch_type == "lsf")
497 INFOS("test_jobsubmit_simple not yet implemented for lsf... return OK");
502 if (batch_type == "ccc")
504 INFOS("test_jobsubmit_simple not yet implemented for ccc... return OK");
509 if (batch_type == "slurm")
511 INFOS("test_jobsubmit_simple not yet implemented for slurm... return OK");
516 if (batch_type == "sge")
518 INFOS("test_jobsubmit_simple not yet implemented for sge... return OK");
523 // Getting home directory
524 std::string rst = get_home(&home);
531 std::string _test_file_script = _test_filename + "_script";
532 std::ofstream file_script;
533 file_script.open(_test_file_script.c_str(), std::ofstream::out);
534 file_script << "#!/bin/bash\n"
535 << "echo HELLO MPI\n";
543 (_test_file_script.c_str(), 0x1ED);
545 std::string _test_file_mpi = _test_filename + "_mpi";
546 std::ofstream file_mpi;
547 file_mpi.open(_test_file_mpi.c_str(), std::ofstream::out);
548 file_mpi << "#!/bin/bash\n"
549 << "#PBS -l nodes=1\n"
550 << "#PBS -l walltime=00:01:00\n"
551 << "#PBS -o " << home << "/" << _date << "_mpi_output.log\n"
552 << "#PBS -e " << home << "/" << _date << "_mpi_error.log\n"
553 << mpiImpl->boot("${PBS_NODEFILE}", 1)
554 << mpiImpl->run("${PBS_NODEFILE}", 1, _base_filename + "_script")
560 // Build command for copy
562 if(protocol == "rsh")
564 command += " " + _test_file_script + " "
565 + username + "@" + hostname + ":" + home;
566 status = system(command.c_str());
568 std::ostringstream oss;
570 result += "Error in copy job file to remote host ! status = ";
575 if(protocol == "rsh")
577 command += " " + _test_file_mpi + " "
578 + username + "@" + hostname + ":" + home;
579 status = system(command.c_str());
581 std::ostringstream oss;
583 result += "Error in copy job file to remote host ! status = ";
588 // Build command for submit job
589 std::string file_job_name = _test_filename + "_jobid";
590 command = protocol + " " + username + "@" + hostname + " qsub " + _base_filename + "_mpi > " + file_job_name;
591 status = system(command.c_str());
593 std::ostringstream oss;
595 result += "Error in sending qsub to remote host ! status = ";
600 std::ifstream file_job(file_job_name.c_str());
603 result += "Error in reading temporary file ! filename = " + file_job_name;
606 std::getline(file_job, jobid);
609 // Wait the end of the job
610 command = protocol + " " + username + "@" + hostname + " qstat -f " + jobid + " > " + file_job_name;
614 status = system(command.c_str());
615 if(status && status != 153 && status != 256*153)
617 std::ostringstream oss;
619 result += "Error in sending qstat to remote host ! status = ";
624 if(status == 153 || status == 256*153 )
633 // Build command for getting results
635 if(protocol == "rsh")
638 + username + "@" + hostname + ":" + home + "/" + _date + "_mpi* /tmp";
639 status = system(command.c_str());
641 std::ostringstream oss;
643 result += "error in getting file result of qsub mpi from remote host ! status = ";
649 std::string normal_input;
650 std::string file_normal_name = "/tmp/" + _date + "_mpi_output.log";
651 std::ifstream file_normal(file_normal_name.c_str());
654 result += "Error in reading temporary file ! filename = " + file_normal_name;
657 bool test_ok = false;
658 while (std::getline(file_normal, normal_input))
660 if (normal_input == "HELLO MPI")
666 result += "error from mpi ouput file ! waiting for HELLO MPI please watch /tmp/" + _date + "_mpi_output.log file";
672 throw LauncherException("Method BatchTest::test_jobsubmit_mpi is not available "
673 "(libBatch was not present at compilation time)");
678 BatchTest::test_appli()
683 std::string result("Failed : ");
684 std::string hostname = _batch_descr.hostname.in();
685 std::string username = _batch_descr.username.in();
686 std::string protocol = _batch_descr.protocol.in();
687 std::string applipath = _batch_descr.applipath.in();
689 // Getting home directory
690 std::string rst = get_home(&home);
696 std::string _test_file_appli = _test_filename + "_appli_test";
697 std::ofstream file_appli;
698 file_appli.open(_test_file_appli.c_str(), std::ofstream::out);
699 file_appli << "#!/bin/bash\n"
700 << "if [ -f " << applipath << "/runAppli ]\n"
709 // Build command for copy
711 if(protocol == "rsh")
713 command += " " + _test_file_appli + " "
714 + username + "@" + hostname + ":" + home;
715 status = system(command.c_str());
717 std::ostringstream oss;
719 result += "Error in copy appli test file to remote host ! status = ";
725 command = protocol + " " + username + "@" + hostname
726 + " sh " + home + "/" + _base_filename + "_appli_test > "
727 + _test_filename + "_appli_test_result";
729 status = system(command.c_str());
731 std::ostringstream oss;
733 result += "Error in launching appli test on remote host ! status = ";
739 std::string rst_appli;
740 std::string file_appli_result_name = _test_filename + "_appli_test_result";
741 std::ifstream file_appli_result(file_appli_result_name.c_str());
742 if (!file_appli_result)
744 result += "Error in reading temporary file ! filename = " + file_appli_result_name;
747 std::getline(file_appli_result, rst_appli);
748 file_appli_result.close();
750 if (rst_appli != "OK")
752 result += "Error checking application on remote host ! result = " + rst;
762 BatchTest::get_home(std::string * home)
765 std::string result = "";
767 std::string hostname = _batch_descr.hostname.in();
768 std::string username = _batch_descr.username.in();
769 std::string protocol = _batch_descr.protocol.in();
770 std::string file_home_name = _test_filename + "_home";
772 command = protocol + " " + username + "@" + hostname + " 'echo $HOME' > " + file_home_name;
773 status = system(command.c_str());
775 std::ostringstream oss;
777 result += "Error in getting home directory ! status = ";
782 std::ifstream file_home(file_home_name.c_str());
785 result += "Error in reading temporary file ! filename = " + file_home_name;
788 std::getline(file_home, *home);