// LocalScheduler_t.cxx #include "dial_sched/LocalScheduler.h" #include #include #include #include #include "dataset_util/getcwd.h" #include "dataset_util/FileName.h" #include "dataset_util/FileStatus.h" #include "dataset_util/mkdir.h" #include "dataset_util/Path.h" #include "dataset_util/Environment.h" #include "dataset_util/CommandLine.h" #include "dataset_util/DtdRegistry.h" #include "dataset_util/XmlElement.h" #include "dataset_xml/XmlParser.h" #include "dataset_id/SimpleUniqueIdGenerator.h" #include "dataset_id/ContentIdList.h" #include "dataset_id/EventIdList.h" #include "dataset_base/Dataset_t.h" #include "dataset_credential/CredentialSelectionCatalog.h" #include "dataset_credential/GssCredentialManager.h" #include "dial_job/ProcessJob.h" #include "dial_job/ProcessJobCreator.h" using std::string; using std::ostream; using std::cout; using std::endl; void msg(string msg) { cout << "----- "; cout << msg; cout << " -----" << endl; } using std::string; using dset::CredentialSelectionCatalog; using dset::GssCredentialManager; using dset::Content; using dial::Task; using dial::Application; using dial::Scheduler; using dial::LocalScheduler; using dial::JobId; using dial::JobPreferences; using dial::Job; using dial::ProcessJobCreator; string DSEP = "/"; int LocalScheduler_t() { system("rm -f resolver.dat csc.dat dial UniqueId"); system("touch debug_LocalScheduler"); string plat = Environment::initial().value("CTG_PLATFORM"); if ( plat == "rh73_gcc323" ) { msg("Skipping test of LocalScheduler on " + plat); return 0; } msg("Create DIAL directories"); system("rm -rf dial mycode.cxx result.xml UniqueId"); assert( mkdir("dial") == 0 ); msg("Create job creator"); ProcessJobCreator cre; cout << cre << endl; msg("Create DTD"); Text dset_dtd = DtdRegistry::instance("dataset").text(); Text dial_dtd = DtdRegistry::instance("dial").text(); string dset_dtdname = DtdRegistry::instance("dataset").filename(); string dial_dtdname = DtdRegistry::instance("dial").filename(); msg("Create ID directories"); SimpleUniqueIdGenerator::create_collection("Job", 401, 0); SimpleUniqueIdGenerator::create_collection("Application", 103, 0); SimpleUniqueIdGenerator::create_collection("Task", 101, 0); SimpleUniqueIdGenerator::create_collection("Dataset", 102, 1001); SimpleUniqueIdGenerator::create_collection("JobPreferences", 601, 0); SimpleUniqueIdGenerator::set_as_default(); msg("Fetch default instance of CSC."); assert( CredentialSelectionCatalog::create_default_instance() == 0 ); CredentialSelectionCatalog& sc = CredentialSelectionCatalog::default_instance(); cout << sc << endl; assert( sc.is_valid() ); string owner = "me"; assert( GssCredentialManager::set_default() == 0 ); assert( GssCredentialManager::set_owner("me") == 0 ); msg("Create result in advance"); string resfile = getcwd() + "/result.xml"; // Write result locally. { TestDataset res; res.lock(); cout << res << endl; const XmlElement* pxres = res.xml(); assert( pxres != 0 ); XmlParser parser; assert( parser.write(resfile, *pxres) == 0 ); } msg("...application"); Application app = Application::test_instance(); cout << app << endl; assert( app.is_valid() ); string appdir = "./dial/apps"; assert( mkdir(appdir) == 0 ); appdir += DSEP + app.id().to_string(); assert( mkdir(appdir) == 0 ); // Write run script. Text runtxt; runtxt.append("/bin/touch out.dat"); runtxt.append("`cat taskdir`/task.exe"); runtxt.append("cp " + resfile + " ."); string runfile = appdir + + "/run"; runtxt.write(runfile); string chcom = "chmod +x " + runfile; system(chcom.c_str()); cout << runtxt << endl; // Write task build file. Path exepath; exepath.getenv("PATH"); assert( exepath.size() != 0 ); Text buildcom; Path gpath = exepath.find("g++"); assert( gpath.size() > 0 ); string gfile = gpath.front() + DSEP + "g++"; assert( FileStatus(gfile).is_executable() ); buildcom.append(gfile + " -g -o task.exe mycode.cxx"); buildcom.append("echo Building task"); //buildcom.append("echo Argument: $*"); //buildcom.append("if [ -z \"$1\" ]; then exit 2; fi"); //buildcom.append("echo No errors >&2"); buildcom.append("touch task_installed"); string buildexe = appdir + "/build_task"; buildcom.write(buildexe); string chmod_buildexe = "chmod +x " + buildexe; system(chmod_buildexe.c_str()); msg("...task"); string tskdir = "./dial/tasks"; assert( mkdir(tskdir) == 0 ); msg("...job"); string jobdir = "./dial/jobs"; assert( mkdir(jobdir) == 0 ); msg("Create default scheduler"); { LocalScheduler sch(cre, false); cout << sch << endl; } msg("Create task builder"); Text ttb("taskbuilder"); ttb.append("#!/bin/sh"); ttb.append("echo Running from taskbuilder"); ttb.append("touch hello_from_taskbuilder"); ttb.append("COM=$1"); ttb.append("echo Command = $COM"); ttb.append("$COM from taskbuilder"); ttb.append("STAT=$?"); ttb.append("echo Command returned $STAT"); ttb.append("exit $STAT"); ttb.write(); string tbfilename = FileName(ttb.name()).fullpath_name(); msg("Create valid scheduler"); Environment env; env["DIAL_APPS"] = "./dial/apps"; env["DIAL_TASKS"] = "./dial/tasks"; env["DIAL_JOBS"] = "./dial/jobs"; env["DIAL_TASKBUILDER"] = tbfilename; LocalScheduler sch(cre, false, "", &env); cout << sch << endl; assert( sch.is_valid() ); msg("Check has application"); assert( sch.has_application(app) ); msg("Check application directory"); cout << sch.application_directory(app) << endl; assert( sch.application_directory(app) == FileName(appdir).fullpath().name() ); msg("Create task"); Text txt("mycode.cxx"); txt.append("#include "); txt.append("int main() {"); txt.append(" sleep(5);"); txt.append(" return 321;"); txt.append("}"); txt.write(); Task::NameList files; files.push_back("mycode.cxx"); Task tsk(files); cout << tsk << endl; assert( tsk.is_valid() ); assert( tsk.id().is_global() ); string tskname = tsk.id().to_string(); tskdir += DSEP + tskname; msg("Check task directory"); cout << sch.task_directory(app, tsk) << endl; msg("Check application"); assert( sch.has_application(app) ); Application badapp; assert( ! sch.has_application(badapp) ); msg("Check that task is not yet installed"); assert( ! sch.has_task(app,tsk) ); msg("Check absence of task job"); JobId tjid = sch.task_job(app, tsk); assert( ! tjid.is_valid() ); msg("Install task"); int install_stat = sch.add_task(app, tsk); if ( install_stat != 0 ) cout << sch.log() << endl; assert( install_stat == 0 ); msg("Check task job"); tjid = sch.task_job(app, tsk); assert( tjid.is_valid() ); Job& tjob = sch.job(tjid); msg("Check task build"); int iwait; for ( iwait=0; iwait<10; ++iwait ) { tjob.update(); if ( sch.has_task(app, tsk) ) break; cout << "."; cout.flush(); sleep(1); } cout << endl; cout << tjob << endl; assert( iwait < 10 ); msg("Check job count" ); assert( sch.jobs().size() == 1 ); msg("Create dataset"); EventIdList eids; eids.insert(EventIdRange(501,1,10)); assert( eids.size() == 10 ); ContentId cid1 = ContentId::register_id(202, "MyClass"); ContentIdList cids; cids.insert(cid1); assert( cids.size() == 1 ); TestDataset dst(Content("TestDataset", "test", cids, eids)); dst.lock(); cout << dst << endl; assert( dst.is_valid() ); msg("Create preferences"); JobPreferences prf; prf.lock(); msg("Submit job"); JobId jid = sch.submit(app, tsk, dst, prf); if ( ! jid.is_valid() ) cout << sch.log() << endl; assert( jid.is_valid() ); cout << sch.job(jid) << endl; msg("Wait for job to finish"); Job& job = sch.job(jid); job.update(); for ( int count=0; count<10&&job.is_running(); ++count ) { cout << "..." << count << endl; sleep(1); job.update(); } cout << sch.job(jid) << endl; assert( sch.job(jid).is_done() ); msg("Remove job"); assert( sch.has_job(jid) ); assert( sch.jobs().size() == 2 ); assert( sch.remove(jid) == 0 ); assert( sch.jobs().size() == 1 ); assert( ! sch.has_job(jid) ); cout << sch.log() << endl; msg("Create XML"); const XmlElement* pxsch = sch.xml(); assert( pxsch != 0 ); cout << *pxsch << endl; assert( pxsch->is_valid() ); msg("Check creator"); assert( Scheduler::has_creator(LocalScheduler::xml_name()) ); Scheduler* psch = Scheduler::create(*pxsch); assert( psch != 0 ); cout << *psch << endl; assert( dynamic_cast(psch) != 0 ); msg("Check DTD"); cout << LocalScheduler::dtd() << endl; assert( LocalScheduler::dtd().size() != 0 ); assert( DtdRegistry::instance("dial").has_type("LocalScheduler") ); return 0; } #ifdef CTEST_MAIN int main() { return LocalScheduler_t(); } #endif