1 // Copyright (C) 2007-2008 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.
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
22 #include "BatchTest.hxx"
24 #include "Batch_Date.hxx"
25 #include "MpiImpl.hxx"
26 #include "utilities.h"
34 BatchTest::BatchTest(const Engines::MachineDefinition& batch_descr)
36 _batch_descr = batch_descr;
39 Batch::Date date = Batch::Date(time(0));
41 int lend = _date.size() ;
45 if (_date[i] == '/' || _date[i] == '-' || _date[i] == ':' )
52 // Creating test temporary file
53 _test_filename = "/tmp/";
54 _test_filename += _date + "_test_cluster_file_";
55 _test_filename += _batch_descr.alias.in();
56 _base_filename = _date + "_test_cluster_file_" + _batch_descr.alias.in();
59 BatchTest::~BatchTest() {}
66 << "--- Testing batch Machine :" << std::endl
67 << "--- Name : " << _batch_descr.hostname << std::endl
68 << "--- Alias : " << _batch_descr.alias << std::endl
69 << "--- Protocol : " << _batch_descr.protocol << std::endl
70 << "--- User Name : " << _batch_descr.username << std::endl
71 << "--- Batch Type : " << _batch_descr.batch << std::endl
72 << "--- MPI Impl : " << _batch_descr.mpiImpl << std::endl
73 << "--- Appli Path : " << _batch_descr.applipath << std::endl
76 std::string result_connection("Not Tested");
77 std::string result_filecopy("Not Tested");
78 std::string result_getresult("Not Tested");
79 std::string result_jobsubmit_simple("Not Tested");
80 std::string result_jobsubmit_mpi("Not Tested");
81 std::string result_appli("Not Tested");
83 result_connection = test_connection();
84 result_filecopy = test_filecopy();
85 result_getresult = test_getresult();
86 result_jobsubmit_simple = test_jobsubmit_simple();
87 result_jobsubmit_mpi = test_jobsubmit_mpi();
88 result_appli = test_appli();
91 << "--- Test results" << std::endl
92 << "--- Connection : " << result_connection << std::endl
93 << "--- File copy : " << result_filecopy << std::endl
94 << "--- Get results : " << result_getresult << std::endl
95 << "--- Submit simple job : " << result_jobsubmit_simple << std::endl
96 << "--- Submit mpi job : " << result_jobsubmit_mpi << std::endl
97 << "--- Application : " << result_appli << std::endl
100 if (result_connection == "OK" &&
101 result_filecopy == "OK" &&
102 result_getresult == "OK" &&
103 result_jobsubmit_simple == "OK" &&
104 result_jobsubmit_mpi == "OK" &&
105 result_appli == "OK")
111 // For this test we use : alias, protocol, username
113 BatchTest::test_connection()
117 std::string result("Failed : ");
118 std::string alias = _batch_descr.alias.in();
119 std::string username = _batch_descr.username.in();
120 std::string protocol = _batch_descr.protocol.in();
125 result += "alias is empty !";
130 result += "username is empty !";
133 if( protocol != "rsh" && protocol != "ssh")
135 result += "protocol unknown ! (" + protocol + ")";
142 + username + "@" + alias;
145 status = system(command.c_str());
147 std::ostringstream oss;
149 result += "Error of connection on remote host ! status = ";
158 // For this test we use : alias, protocol, username
160 BatchTest::test_filecopy()
165 std::string result("Failed : ");
166 std::string alias = _batch_descr.alias.in();
167 std::string username = _batch_descr.username.in();
168 std::string protocol = _batch_descr.protocol.in();
170 // Getting home directory
171 std::string rst = get_home(&home);
177 // Writing into the tempory file
178 command = "echo Hello > " + _test_filename;
179 status = system(command.c_str());
181 std::ostringstream oss;
183 result += "Error in creating tempory file ! status = ";
190 if(protocol == "rsh")
192 command += " " + _test_filename + " "
193 + username + "@" + alias + ":" + home;
196 status = system(command.c_str());
198 std::ostringstream oss;
200 result += "Error in copy file on remote host ! status = ";
209 // For this test we use : alias, protocol, username
211 BatchTest::test_getresult()
216 std::string result("Failed : ");
217 std::string alias = _batch_descr.alias.in();
218 std::string username = _batch_descr.username.in();
219 std::string protocol = _batch_descr.protocol.in();
221 // Getting home directory
222 std::string rst = get_home(&home);
230 if(protocol == "rsh")
232 command += " " + username + "@" + alias + ":" + home
233 + "/" + _base_filename + " " + _test_filename + "_copy";
236 status = system(command.c_str());
238 std::ostringstream oss;
240 result += "Error in copy file from remote host ! status = ";
246 std::ifstream src_file(_test_filename.c_str());
249 result += "Error in reading temporary file ! filename = " + _test_filename;
252 std::string cp_filename = _test_filename + "_copy";
253 std::ifstream cp_file(cp_filename.c_str());
256 result += "Error in reading temporary copy file ! filename = " + cp_filename;
259 std::string src_firstline;
260 std::string cp_firstline;
261 std::getline(src_file, src_firstline);
262 std::getline(cp_file, cp_firstline);
265 if (src_firstline != cp_firstline)
267 result += "Error source file and copy file are not equa ! source = " + src_firstline + " copy = " + cp_firstline;
276 BatchTest::test_jobsubmit_simple()
281 std::string result("Failed : ");
282 std::string alias = _batch_descr.alias.in();
283 std::string username = _batch_descr.username.in();
284 std::string protocol = _batch_descr.protocol.in();
285 std::string batch_type = _batch_descr.batch.in();
288 if (batch_type == "lsf")
290 INFOS("test_jobsubmit_simple not yet implemented for lsf... return OK");
294 if (batch_type == "sge")
296 INFOS("test_jobsubmit_simple not yet implemented for sge... return OK");
300 if (batch_type != "pbs")
302 result += "Batch type unknown ! : " + batch_type;
306 // Getting home directory
307 std::string rst = get_home(&home);
314 std::string _test_file_simple = _test_filename + "_simple";
316 file.open(_test_file_simple.c_str(), std::ofstream::out);
317 file << "#!/bin/bash\n"
318 << "#PBS -l nodes=1\n"
319 << "#PBS -l walltime=00:01:00\n"
320 << "#PBS -o " + home + "/" + _date + "_simple_output.log\n"
321 << "#PBS -e " + home + "/" + _date + "_simple_error.log\n"
323 << "echo Error >&2\n";
328 // Build command for copy
330 if(protocol == "rsh")
332 command += " " + _test_file_simple + " "
333 + username + "@" + alias + ":" + home;
334 status = system(command.c_str());
336 std::ostringstream oss;
338 result += "Error in copy job file to remote host ! status = ";
343 // Build command for submit job
344 std::string file_job_name = _test_filename + "_jobid";
345 command = protocol + " " + username + "@" + alias + " qsub " + _base_filename + "_simple > " + file_job_name;
346 status = system(command.c_str());
348 std::ostringstream oss;
350 result += "Error in sending qsub to remote host ! status = ";
355 std::ifstream file_job(file_job_name.c_str());
358 result += "Error in reading temporary file ! filename = " + file_job_name;
361 std::getline(file_job, jobid);
364 // Wait the end of the job
365 command = protocol + " " + username + "@" + alias + " qstat -f " + jobid + " > " + file_job_name;
369 status = system(command.c_str());
370 if(status && status != 153 && status != 256*153)
372 std::ostringstream oss;
374 result += "Error in sending qstat to remote host ! status = ";
379 if(status == 153 || status == 256*153 )
388 // Build command for getting results
390 if(protocol == "rsh")
393 + username + "@" + alias + ":" + home + "/" + _date + "_simple* /tmp";
394 status = system(command.c_str());
396 std::ostringstream oss;
398 result += "error in getting file result of qsub simple to remote host ! status = ";
404 std::string normal_input;
405 std::string file_normal_name = "/tmp/" + _date + "_simple_output.log";
406 std::ifstream file_normal(file_normal_name.c_str());
409 result += "Error in reading temporary file ! filename = " + file_normal_name;
412 std::getline(file_normal, normal_input);
414 if (normal_input != "Bonjour")
416 result += "error from simple ouput file ! waiting for Bonjour and get : " + normal_input;
419 std::string error_input;
420 std::string file_error_name = "/tmp/" + _date + "_simple_error.log";
421 std::ifstream file_error(file_error_name.c_str());
424 result += "Error in reading temporary file ! filename = " + file_error_name;
427 std::getline(file_error, error_input);
429 if (error_input != "Error")
431 result += "error from simple error file ! waiting for Error and get : " + error_input;
439 BatchTest::test_jobsubmit_mpi()
445 std::string result("Failed : ");
446 std::string alias = _batch_descr.alias.in();
447 std::string username = _batch_descr.username.in();
448 std::string protocol = _batch_descr.protocol.in();
449 std::string batch_type = _batch_descr.batch.in();
450 std::string mpi_type = _batch_descr.mpiImpl.in();
453 if(mpi_type == "lam")
454 mpiImpl = new MpiImpl_LAM();
455 else if(mpi_type == "mpich1")
456 mpiImpl = new MpiImpl_MPICH1();
457 else if(mpi_type == "mpich2")
458 mpiImpl = new MpiImpl_MPICH2();
459 else if(mpi_type == "openmpi")
460 mpiImpl = new MpiImpl_OPENMPI();
461 else if(mpi_type == "slurm")
462 mpiImpl = new MpiImpl_SLURM();
465 result += "Error MPI impl not supported : " + mpi_type;
469 // LSF et SGE not yet implemented...
470 if (batch_type == "lsf")
472 INFOS("test_jobsubmit_simple not yet implemented for lsf... return OK");
477 if (batch_type == "sge")
479 INFOS("test_jobsubmit_simple not yet implemented for sge... return OK");
484 // Getting home directory
485 std::string rst = get_home(&home);
492 std::string _test_file_script = _test_filename + "_script";
493 std::ofstream file_script;
494 file_script.open(_test_file_script.c_str(), std::ofstream::out);
495 file_script << "#!/bin/bash\n"
496 << "echo HELLO MPI\n";
504 (_test_file_script.c_str(), 0x1ED);
506 std::string _test_file_mpi = _test_filename + "_mpi";
507 std::ofstream file_mpi;
508 file_mpi.open(_test_file_mpi.c_str(), std::ofstream::out);
509 file_mpi << "#!/bin/bash\n"
510 << "#PBS -l nodes=1\n"
511 << "#PBS -l walltime=00:01:00\n"
512 << "#PBS -o " << home << "/" << _date << "_mpi_output.log\n"
513 << "#PBS -e " << home << "/" << _date << "_mpi_error.log\n"
514 << mpiImpl->boot("${PBS_NODEFILE}", 1)
515 << mpiImpl->run("${PBS_NODEFILE}", 1, _base_filename + "_script")
521 // Build command for copy
523 if(protocol == "rsh")
525 command += " " + _test_file_script + " "
526 + username + "@" + alias + ":" + home;
527 status = system(command.c_str());
529 std::ostringstream oss;
531 result += "Error in copy job file to remote host ! status = ";
536 if(protocol == "rsh")
538 command += " " + _test_file_mpi + " "
539 + username + "@" + alias + ":" + home;
540 status = system(command.c_str());
542 std::ostringstream oss;
544 result += "Error in copy job file to remote host ! status = ";
549 // Build command for submit job
550 std::string file_job_name = _test_filename + "_jobid";
551 command = protocol + " " + username + "@" + alias + " qsub " + _base_filename + "_mpi > " + file_job_name;
552 status = system(command.c_str());
554 std::ostringstream oss;
556 result += "Error in sending qsub to remote host ! status = ";
561 std::ifstream file_job(file_job_name.c_str());
564 result += "Error in reading temporary file ! filename = " + file_job_name;
567 std::getline(file_job, jobid);
570 // Wait the end of the job
571 command = protocol + " " + username + "@" + alias + " qstat -f " + jobid + " > " + file_job_name;
575 status = system(command.c_str());
576 if(status && status != 153 && status != 256*153)
578 std::ostringstream oss;
580 result += "Error in sending qstat to remote host ! status = ";
585 if(status == 153 || status == 256*153 )
594 // Build command for getting results
596 if(protocol == "rsh")
599 + username + "@" + alias + ":" + home + "/" + _date + "_mpi* /tmp";
600 status = system(command.c_str());
602 std::ostringstream oss;
604 result += "error in getting file result of qsub mpi from remote host ! status = ";
610 std::string normal_input;
611 std::string file_normal_name = "/tmp/" + _date + "_mpi_output.log";
612 std::ifstream file_normal(file_normal_name.c_str());
615 result += "Error in reading temporary file ! filename = " + file_normal_name;
618 bool test_ok = false;
619 while (std::getline(file_normal, normal_input))
621 if (normal_input == "HELLO MPI")
627 result += "error from mpi ouput file ! waiting for HELLO MPI please watch /tmp/" + _date + "_mpi_output.log file";
635 BatchTest::test_appli()
640 std::string result("Failed : ");
641 std::string alias = _batch_descr.alias.in();
642 std::string username = _batch_descr.username.in();
643 std::string protocol = _batch_descr.protocol.in();
644 std::string applipath = _batch_descr.applipath.in();
646 // Getting home directory
647 std::string rst = get_home(&home);
653 std::string _test_file_appli = _test_filename + "_appli_test";
654 std::ofstream file_appli;
655 file_appli.open(_test_file_appli.c_str(), std::ofstream::out);
656 file_appli << "#!/bin/bash\n"
657 << "if [ -f " << applipath << "/runAppli ]\n"
666 // Build command for copy
668 if(protocol == "rsh")
670 command += " " + _test_file_appli + " "
671 + username + "@" + alias + ":" + home;
672 status = system(command.c_str());
674 std::ostringstream oss;
676 result += "Error in copy appli test file to remote host ! status = ";
682 command = protocol + " " + username + "@" + alias
683 + " sh " + home + "/" + _base_filename + "_appli_test > "
684 + _test_filename + "_appli_test_result";
686 status = system(command.c_str());
688 std::ostringstream oss;
690 result += "Error in launching appli test on remote host ! status = ";
696 std::string rst_appli;
697 std::string file_appli_result_name = _test_filename + "_appli_test_result";
698 std::ifstream file_appli_result(file_appli_result_name.c_str());
699 if (!file_appli_result)
701 result += "Error in reading temporary file ! filename = " + file_appli_result_name;
704 std::getline(file_appli_result, rst_appli);
705 file_appli_result.close();
707 if (rst_appli != "OK")
709 result += "Error checking application on remote host ! result = " + rst;
719 BatchTest::get_home(std::string * home)
722 std::string result = "";
724 std::string alias = _batch_descr.alias.in();
725 std::string username = _batch_descr.username.in();
726 std::string protocol = _batch_descr.protocol.in();
727 std::string file_home_name = _test_filename + "_home";
729 command = protocol + " " + username + "@" + alias + " 'echo $HOME' > " + file_home_name;
730 status = system(command.c_str());
732 std::ostringstream oss;
734 result += "Error in getting home directory ! status = ";
739 std::ifstream file_home(file_home_name.c_str());
742 result += "Error in reading temporary file ! filename = " + file_home_name;
745 std::getline(file_home, *home);