// ************************************************************************* // // * * // // * s t r e s s P r o o f * // // * * // // * This file contains a set of test of PROOF related functionality. * // // * The tests can be run as a standalone program or with the interpreter. * // // * To run as a standalone program: * // // * * // // * $ cd $ROOTSYS/test * // // * $ make stressProof * // // * * // // * Run stressProof with '-h' to get the list of supported options * // // * $ ./stressProof -h * // // * * // // * To run interactively: * // // * $ root * // // * root[] .include $ROOTSYS/tutorials * // // * root[] .L stressProof.cxx+ * // // * root[] stressProof(master, tests, wrks, verbose, logfile, dyn, \ * // // * dyn, skipds, h1src, eventsrc, dryrun) * // // * * // // * The arguments have the same meaning as above except for * // // * verbose [Int_t] increasing verbosity (0 == minimal) * // // * dyn [Bool_t] if kTRUE run in dynamic startup mode * // // * skipds [Bool_t] if kTRUE the dataset related tests are skipped * // // * * // // * A certain number of swithces can also be controlled via environment * // // * variables: check './stressProof -h' * // // * * // // * The stressProof function returns 0 on success, 1 on failure. * // // * * // // * The successful output looks like this: * // // * * // // * ****************************************************************** * // // * * Starting P R O O F - S T R E S S suite * * // // * ****************************************************************** * // // * * Log file: /tmp/ProofStress_XrcwBe * // // * ****************************************************************** * // // * Test 1 : Open a session ................................... OK * * // // * Test 2 : Get session logs ................................. OK * * // // * Test 3 : Simple random number generation .................. OK * * // // * Test 4 : Dataset handling with H1 files ................... OK * * // // * Test 5 : H1: chain processing ............................. OK * * // // * Test 6 : H1: file collection processing ................... OK * * // // * Test 7 : H1: file collection, TPacketizer ................. OK * * // // * Test 8 : H1: by-name processing ........................... OK * * // // * Test 9 : H1: multi dataset processing ..................... OK * * // // * Test 10 : H1: multi dataset and entry list ................. OK * * // // * Test 11 : Package management with 'event' .................. OK * * // // * Test 12 : Package argument passing ......................... OK * * // // * Test 13 : Simple 'event' generation ........................ OK * * // // * Test 14 : Input data propagation ........................... OK * * // // * Test 15 : H1, Simple: async mode :.......................... OK * * // // * Test 16 : Admin functionality .............................. OK * * // // * Test 17 : Dynamic sub-mergers functionality ................ OK * * // // * Test 18 : Event range processing ........................... OK * * // // * Test 19 : Event range, TPacketizer ......................... OK * * // // * Test 20 : File-resident output: merge ...................... OK * * // // * Test 21 : File-resident output: merge w/ submergers ........ OK * * // // * Test 22 : File-resident output: create dataset ............. OK * * // // * Test 23 : File-resident output: multi trees ................ OK * * // // * Test 24 : TTree friends (and TPacketizerFile) .............. OK * * // // * Test 25 : TTree friends, same file ......................... OK * * // // * Test 26 : Handling output via file ......................... OK * * // // * Test 27 : Simple: selector by object ....................... OK * * // // * Test 28 : H1 dataset: selector by object ................... OK * * // // * * All registered tests have been passed :-) * * // // * ****************************************************************** * // // * * // // * The application redirects the processing logs to a log file which is * // // * normally deleted at the end of a successful run; if the test fails * // // * the caller is asked if she/he wants to keep the log file; if the * // // * specifies a log file path of her/his choice, the log file is never * // // * deleted. * // // * * // // * SKIPPED means that the test cannot be run. * // // * * // // * New tests can be easily added by providing a function performing the * // // * test and a name for the test; see examples below. * // // * * // // * It is also possible to trigger the automatic PROOF valgrind setup by * // // * means of the env GETPROOF_VALGRIND. * // // * E.g. to run the master in valgrind do * // // * * // // * $ export GETPROOF_VALGRIND="valgrind=master" * // // * or * // // * $ export GETPROOF_VALGRIND="valgrind=workers" * // // * * // // * before running stressProof. The syntax is the same as for standard * // // * PROOF valgrind runs. See * // // * http://root.cern.ch/drupal/content/running-proof-query-valgrind * // // * * // // ************************************************************************* // #include #include #include #include #ifdef WIN32 #include #endif #include "Getline.h" #include "TApplication.h" #include "TChain.h" #include "TDataMember.h" #include "TDSet.h" #include "TFile.h" #include "TFileCollection.h" #include "TFileInfo.h" #include "TH1F.h" #include "TH2F.h" #include "THashList.h" #include "TList.h" #include "TMacro.h" #include "TMap.h" #include "TMath.h" #include "TMethodCall.h" #include "TNamed.h" #include "TNtuple.h" #include "TParameter.h" #include "TProof.h" #include "TProofLog.h" #include "TProofMgr.h" #include "TProofOutputFile.h" #include "TQueryResult.h" #include "TStopwatch.h" #include "TString.h" #include "TSystem.h" #include "TROOT.h" #include "TSelector.h" #include "proof/getProof.C" #define PT_NUMTEST 28 static const char *urldef = "proof://localhost:40000"; static TString gtutdir; static TString gsandbox; static Int_t gverbose = 1; static TString gverbproof("kAll"); static TString glogfile; static Int_t gpoints = 0; static Bool_t guseprogress = kTRUE; static Int_t totpoints = 53; static RedirectHandle_t gRH; static RedirectHandle_t gRHAdmin; static Double_t gH1Time = 0; static Double_t gSimpleTime = 0; static Double_t gEventTime = 0; static Int_t gH1Cnt = 0; static Int_t gSimpleCnt = 0; static Int_t gEventCnt = 0; static TStopwatch gTimer; static Bool_t gTimedOut = kFALSE; static Bool_t gDynamicStartup = kFALSE; static Bool_t gLocalCluster = kTRUE; static Bool_t gSkipDataSetTest = kTRUE; static Bool_t gUseParallelUnzip = kFALSE; static Bool_t gClearCache = kFALSE; static TString gh1src("http://root.cern.ch/files/h1"); static Bool_t gh1ok = kTRUE; static Bool_t gh1local = kFALSE; static char gh1sep = '/'; static const char *gh1file[] = { "dstarmb.root", "dstarp1a.root", "dstarp1b.root", "dstarp2.root" }; static TString geventsrc("http://root.cern.ch/files/data"); static Bool_t geventok = kTRUE; static Bool_t geventlocal = kFALSE; static Int_t geventnf = 10; static Long64_t gEventNum = 200000; static Long64_t gEventFst = 65000; static Long64_t gEventSiz = 100000; static TStopwatch gStopwatch; // The selectors static TString gTutDir = "$ROOTSYS/tutorials"; // default path static TList gSelectors; static TString gH1Sel("/tree/h1analysis.C"); static TString gEventSel("/proof/ProofEvent.C"); static TString gEventProcSel("/proof/ProofEventProc.C"); static TString gSimpleSel("/proof/ProofSimple.C"); static TString gTestsSel("/proof/ProofTests.C"); static TString gNtupleSel("/proof/ProofNtuple.C"); static TString gFriendsSel("/proof/ProofFriends.C"); static TString gAuxSel("/proof/ProofAux.C"); // Special class static TString gProcFileElem("/proof/ProcFileElements.C"); // Special files static TString gEmptyInclude("/proof/EmptyInclude.h"); static TString gNtpRndm("/proof/ntprndm.root"); // Special packages static TString gPackEvent("/proof/event.par"); static TString gPack1("/proof/packtest1.par"); static TString gPack2("/proof/packtest2.par"); int stressProof(const char *url = 0, const char *tests = 0, Int_t nwrks = -1, const char *verbose = "1", const char *logfile = 0, Bool_t dyn = kFALSE, Bool_t skipds = kTRUE, const char *h1src = 0, const char *eventsrc = 0, Bool_t dryrun = kFALSE, Bool_t showcpu = kFALSE, Bool_t clearcache = kFALSE, Bool_t useprogress = kTRUE, const char *tutdir = 0, Bool_t cleanlog = kFALSE, Bool_t keeplog = kTRUE); //_____________________________batch only_____________________ #ifndef __CINT__ int main(int argc,const char *argv[]) { // Request for help? if (argc > 1 && !strcmp(argv[1],"-h")) { printf(" \n"); printf(" PROOF test suite\n"); printf(" \n"); printf(" Usage:\n"); printf(" \n"); printf(" $ ./stressProof [-h] [-n ] [-d [scope:]level] [-l logfile] [-dyn] [-ds]\n"); printf(" [-t tests] [-h1 h1src] [-event src] [-dryrun] [-g] [-cpu]\n"); printf(" [-clearcache] [-noprogress] [-tut tutdir] [master]\n"); printf(" \n"); printf(" Optional arguments:\n"); printf(" -h prints this menu\n"); printf(" master entry point of the cluster where to run the test\n"); printf(" in the form '[user@]host.domain[:port]'; default 'localhost:40000'\n"); printf(" or the env STRESSPROOF_URL\n"); printf(" -n wrks number of workers to be started when running on the local host;\n"); printf(" default is the nuber of local cores\n"); printf(" -d [scope:]level\n"); printf(" verbosity scope and level; default level is 1; scope refers to PROOF debug\n"); printf(" options (see TProofDebug.h) and is enabled only is level > 1 (default kAll).\n"); printf(" -l logfile file where to redirect the processing logs; must be writable;\n"); printf(" default is a temporary file deleted at the end of the test\n"); printf(" in case of success. Some format specifiers can be used in the file name:\n"); printf(" - %%p is replaced by the current process ID; \n"); printf(" - %%tmp is replaced by the temporary directory; \n"); printf(" - %%d is replaced by date and time at test startup in the form YYYYMMDD-HHMM, \n"); printf(" e.g. 20120904-1138. \n"); printf(" The log file path can be also passed via the env STRESSPROOF_LOGFILE.\n"); printf(" In case of failure, the log files of the nodes (master and workers) are saved into\n"); printf(" a file called .nodes .\n"); printf(" -c,-cleanlog Delete the logfile specified via '-l' in case of a successful run; by default\n"); printf(" the file specified by '-l' is kept in all cases (default log files are deleted\n"); printf(" on success); adding this switch allows to keep a user-defined log file only\n"); printf(" in case of error.\n"); printf(" -k,-keeplog Keep all logfiles, including the ones fro the PROOF nodes (in one single file).\n"); printf(" The paths are printed on the screen.\n"); printf(" -dyn run the test in dynamicStartup mode\n"); printf(" -ds force the dataset test if skipped by default\n"); printf(" -t tests run only tests in the comma-separated list and those from which they\n"); printf(" depend; ranges can be given with 'first-last' syntax, e.g. '3,6-9,23'\n"); printf(" to run tests 3, 6, 7, 8, 9 and 23. Can be also given via the env STRESSPROOF_TESTS.\n"); printf(" -h1 h1src specify a location for the H1 files; use h1src=\"download\" to download\n"); printf(" to a temporary location (or h1src=\"download=/path/for/local/h1\" to download\n"); printf(" to /path/for/local/h1; by default the files are read directly from the\n"); printf(" ROOT http server; however this may give failures if the connection is slow.\n"); printf(" If h1src ends with '.zip' the program assumes that the 4 files are concatenated\n"); printf(" in a single zip archive and are accessible with the standard archive syntax.\n"); printf(" Can be also passed via the env STRESSPROOF_H1SRC.\n"); printf(" -event src\n"); printf(" specify a location for the 'event' files; use src=\"download\" to download\n"); printf(" to a temporary location (or eventsrc=\"download=/path/for/local/event\" to download\n"); printf(" to /path/for/local/event; by default the files are read directly from the\n"); printf(" ROOT http server; however this may give failures if the connection is slow\n"); printf(" Can be also passed via the env STRESSPROOF_EVENT.\n"); printf(" -punzip use parallel unzipping for data-driven processing.\n"); printf(" -dryrun only show which tests would be run.\n"); printf(" -g enable graphics; default is to run in text mode.\n"); printf(" -cpu show CPU times used by each successful test; used for calibration.\n"); printf(" -clearcache clear memory cache associated with the files processed when local.\n"); printf(" -noprogress do not show progress (escaped chars may confuse some wrapper applications)\n"); printf(" -tut tutdir specify alternative location for the ROOT tutorials; allows to run multiple\n"); printf(" concurrent instances of stressProof, for tests, for example.\n"); printf(" Can be also passed via the env STRESSPROOF_TUTORIALDIR.\n"); printf(" \n"); gSystem->Exit(0); } // Parse options const char *url = 0; Int_t nWrks = -1; const char *verbose = "1"; Bool_t enablegraphics = kFALSE; Bool_t dryrun = kFALSE; Bool_t showcpu = kFALSE; Bool_t clearcache = kFALSE; Bool_t useprogress = kTRUE; Bool_t cleanlog = kFALSE; Bool_t keeplog = kFALSE; const char *logfile = 0; const char *h1src = 0; const char *eventsrc = 0; const char *tests = 0; const char *tutdir = 0; Int_t i = 1; while (i < argc) { if (!strcmp(argv[i],"-h")) { // Ignore if not first argument i++; } else if (!strcmp(argv[i],"-n")) { if (i+1 == argc || argv[i+1][0] == '-') { printf(" -n should be followed by the number of workers: ignoring \n"); i++; } else { nWrks = atoi(argv[i+1]); i += 2; } } else if (!strcmp(argv[i],"-d")) { if (i+1 == argc || argv[i+1][0] == '-') { printf(" -d should be followed by the debug '[scope:]level': ignoring \n"); i++; } else { verbose = argv[i+1]; i += 2; } } else if (!strcmp(argv[i],"-l")) { if (i+1 == argc || argv[i+1][0] == '-') { printf(" -l should be followed by a path: ignoring \n"); i++; } else { logfile = argv[i+1]; i += 2; } } else if (!strncmp(argv[i],"-c",2) || !strncmp(argv[i],"-cleanlog",11)) { cleanlog = kTRUE; i++; } else if (!strncmp(argv[i],"-k",2) || !strncmp(argv[i],"-keeplog",10)) { keeplog = kTRUE; i++; } else if (!strncmp(argv[i],"-v",2)) { // For backward compatibility if (!strncmp(argv[i],"-vv",3)) verbose = "2"; if (!strncmp(argv[i],"-vvv",4)) verbose = "3"; i++; } else if (!strncmp(argv[i],"-dyn",4)) { gDynamicStartup = kTRUE; i++; } else if (!strncmp(argv[i],"-ds",3)) { gSkipDataSetTest = kFALSE; i++; } else if (!strncmp(argv[i],"-punzip",7)) { gUseParallelUnzip = kTRUE; i++; } else if (!strcmp(argv[i],"-t")) { if (i+1 == argc || argv[i+1][0] == '-') { printf(" -t should be followed by a string or a number: ignoring \n"); i++; } else { tests = argv[i+1]; i += 2; } } else if (!strcmp(argv[i],"-h1")) { if (i+1 == argc || argv[i+1][0] == '-') { printf(" -h1 should be followed by a path: ignoring \n"); i++; } else { h1src = argv[i+1]; i += 2; } } else if (!strcmp(argv[i],"-event")) { if (i+1 == argc || argv[i+1][0] == '-') { printf(" -event should be followed by a path: ignoring \n"); i++; } else { eventsrc = argv[i+1]; i += 2; } } else if (!strncmp(argv[i],"-g",2)) { enablegraphics = kTRUE; i++; } else if (!strncmp(argv[i],"-dryrun",7)) { dryrun = kTRUE; i++; } else if (!strncmp(argv[i],"-cpu",4)) { showcpu = kTRUE; i++; } else if (!strncmp(argv[i],"-clearcache",11)) { clearcache = kTRUE; i++; } else if (!strncmp(argv[i],"-noprogress",11)) { useprogress = kFALSE; i++; } else if (!strcmp(argv[i],"-tut")) { if (i+1 == argc || argv[i+1][0] == '-') { printf(" -tut should be followed by a path: ignoring \n"); i++; } else { tutdir = argv[i+1]; i += 2; } } else { url = argv[i]; i++; } } // Enable graphics if required if (enablegraphics) { new TApplication("stressProof", 0, 0); } else { gROOT->SetBatch(kTRUE); } int rc = stressProof(url, tests, nWrks, verbose, logfile, gDynamicStartup, gSkipDataSetTest, h1src, eventsrc, dryrun, showcpu, clearcache, useprogress, tutdir, cleanlog, keeplog); gSystem->Exit(rc); } #endif //_____________________________________________________________________________ Int_t PutPoint() { // Print one '.' and count it printf("."); return ++gpoints; } //______________________________________________________________________________ void PrintStressProgress(Long64_t total, Long64_t processed, Float_t, Long64_t) { // Print some progress information gSystem->RedirectOutput(0, 0, &gRH); char pc[2] = { '.', ':'}; static int lstpc = 1; int ns = 0; if (processed < total) { ns += 6; fprintf(stderr, "%c %2.0f %%", pc[(lstpc++)%2], (total ? ((100.0*processed)/total) : 100.0)); } while (ns--) fprintf(stderr, "\b"); gSystem->RedirectOutput(glogfile, "a", &gRH); } //______________________________________________________________________________ void PrintEmptyProgress(Long64_t, Long64_t, Float_t, Long64_t) { // Dummy PrintProgress return; } // Guard class class SwitchProgressGuard { public: SwitchProgressGuard(Bool_t force = kFALSE) { if (guseprogress || force) { gProof->SetPrintProgress(&PrintStressProgress); } else { gProof->SetPrintProgress(&PrintEmptyProgress); } } ~SwitchProgressGuard() { gProof->SetPrintProgress(0); } }; //______________________________________________________________________________ void CleanupSelector(const char *selpath) { // Remove all non source files associated with seletor at path 'selpath' if (!selpath) return; TString dirpath(gSystem->DirName(selpath)); if (gSystem->AccessPathName(dirpath)) return; TString selname(gSystem->BaseName(selpath)); selname.ReplaceAll(".C", "_C"); void *dirp = gSystem->OpenDirectory(dirpath); if (!dirp) return; TString fn; const char *e = 0; while ((e = gSystem->GetDirEntry(dirp))) { if (!strncmp(e, selname.Data(), selname.Length())) { // Cleanup this entry fn.Form("%s/%s", dirpath.Data(), e); gSystem->Unlink(fn); } } } //_____________________________________________________________________________ void AssertParallelUnzip() { // Set the parallel unzip option if (gUseParallelUnzip) { gProof->SetParameter("PROOF_UseParallelUnzip", (Int_t)1); } else { gProof->SetParameter("PROOF_UseParallelUnzip", (Int_t)0); } } //______________________________________________________________________________ void ReleaseCache(const char *fn) { // Release the memory cache associated with file 'fn'. #if defined(R__LINUX) TString filename(fn); Int_t fd; fd = open(filename.Data(), O_RDONLY); if (fd > -1) { fdatasync(fd); posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED); close(fd); } else { fprintf(stderr, "cannot open file '%s' for cache clean up; errno=%d \n", filename.Data(), errno); } #else fprintf(stderr, "ReleaseCache: dummy function: file '%s' untouched ...\n", fn); #endif // Done return; } // // Auxilliary classes for testing // class RunTimes { public: Double_t fCpu; Double_t fReal; RunTimes(Double_t c = -1., Double_t r = -1.) : fCpu(c), fReal(r) { } RunTimes &operator=(const RunTimes &rt) { fCpu = rt.fCpu; fReal = rt.fReal; return *this; } void Set(Double_t c = -1., Double_t r = -1.) { if (c > -1.) fCpu = c; if (r > -1.) fReal = r; } void Print(const char *tag = "") { printf("%s real: %f s, cpu: %f s\n", tag, fReal, fCpu); } }; RunTimes operator-(const RunTimes &rt1, const RunTimes &rt2) { RunTimes rt(rt1.fCpu - rt2.fCpu, rt1.fReal - rt2.fReal); return rt; } static RunTimes gProofTimesZero(0.,0.); typedef Int_t (*ProofTestFun_t)(void *, RunTimes &); class ProofTest : public TNamed { private: Int_t fSeq; // Sequential number for the test ProofTestFun_t fFun; // Function to be executed for the test void *fArgs; // Arguments to be passed to the function TString fDeps; // Test dependencies, e.g. "1,3" TString fSels; // Selectors used, e.g. "h1analysis,ProofSimple" Int_t fDepFrom; // Index for looping over deps Int_t fSelFrom; // Index for looping over selectors Bool_t fEnabled; // kTRUE if this test is enabled Double_t fCpuTime; // CPU time used by the test Double_t fRealTime; // Real time used by the test Double_t fRefReal; // Ref Real time used for PROOF marks Double_t fProofMarks; // PROOF marks Bool_t fUseForMarks; // Use in the calculation of the average PROOF marks static Double_t gRefReal[PT_NUMTEST]; // Reference Cpu times public: ProofTest(const char *n, Int_t seq, ProofTestFun_t f, void *a = 0, const char *d = "", const char *sel = "", Bool_t useForMarks = kFALSE) : TNamed(n,""), fSeq(seq), fFun(f), fArgs(a), fDeps(d), fSels(sel), fDepFrom(0), fSelFrom(0), fEnabled(kTRUE), fCpuTime(-1.), fRealTime(-1.), fProofMarks(-1.), fUseForMarks(useForMarks) { fRefReal = gRefReal[fSeq-1]; } virtual ~ProofTest() { } void Disable() { fEnabled = kFALSE; } void Enable() { fEnabled = kTRUE; } Bool_t IsEnabled() const { return fEnabled; } Int_t NextDep(Bool_t reset = kFALSE); Int_t NextSel(TString &sel, Bool_t reset = kFALSE); Int_t Num() const { return fSeq; } Int_t Run(Bool_t dryrun = kFALSE, Bool_t showcpu = kFALSE); Double_t ProofMarks() const { return fProofMarks; } Bool_t UseForMarks() const { return fUseForMarks; } }; // Reference time measured on a HP DL580 24 core (4 x Intel(R) Xeon(R) CPU X7460 // @ 2.132 GHz, 48GB RAM, 1 Gb/s NIC) with 4 workers. Double_t ProofTest::gRefReal[PT_NUMTEST] = { 3.047808, // #1: Open a session 0.021979, // #2: Get session logs 4.779971, // #3: Simple random number generation 0.276155, // #4: Dataset handling with H1 files 5.355514, // #5: H1: chain processing 2.414207, // #6: H1: file collection processing 3.381990, // #7: H1: file collection, TPacketizer 3.227942, // #8: H1: by-name processing 3.944204, // #9: H1: multi dataset processing 9.146988, // #10: H1: multi dataset and entry list 2.703881, // #11: Package management with 'event' 3.814625, // #12: Package argument passing 9.028315, // #13: Simple 'event' generation 0.123514, // #14: Input data propagation 0.129757, // #15: H1, Simple: async mode 0.349625, // #16: Admin functionality 0.989456, // #17: Dynamic sub-mergers functionality 11.23798, // #18: Event range processing 6.087582, // #19: Event range, TPacketizer 2.489555, // #20: File-resident output: merge 0.180897, // #21: File-resident output: merge w/ submergers 1.417233, // #22: File-resident output: create dataset 0.000000, // #23: File-resident output: multi trees 7.452465, // #24: TTree friends (and TPacketizerFile) 0.259239, // #25: TTree friends, same file 6.868858, // #26: Simple generation: merge-via-file 6.362017, // #27: Simple random number generation by TSelector object 5.519631 // #28: H1: by-object processing }; // // Timer to stop asynchronous actions // class TTimeOutTimer : public TTimer { public: TTimeOutTimer(Long_t ms); Bool_t Notify(); }; TTimeOutTimer::TTimeOutTimer(Long_t ms) : TTimer(ms, kTRUE) { //constructor gSystem->AddTimer(this); } Bool_t TTimeOutTimer::Notify() { //notifier gTimedOut = kTRUE; Remove(); // one shot only return kTRUE; } //------------------------------------------------------------------------------ //_____________________________________________________________________________ Int_t ProofTest::NextDep(Bool_t reset) { // Return index of next dependency or -1 if none (or no more) // If reset is kTRUE, reset the internal counter before acting. if (reset) fDepFrom = 0; TString tkn; if (fDeps.Tokenize(tkn, fDepFrom, ",")) { if (tkn.IsDigit()) return tkn.Atoi(); } // Not found return -1; } //_____________________________________________________________________________ Int_t ProofTest::NextSel(TString &sel, Bool_t reset) { // Return index of next dependency or -1 if none (or no more) // If reset is kTRUE, reset the internal counter before acting. if (reset) fSelFrom = 0; if (fSels.Tokenize(sel, fSelFrom, ",")) { if (!sel.IsNull()) return 0; } // Not found return -1; } //_____________________________________________________________________________ Int_t ProofTest::Run(Bool_t dryrun, Bool_t showcpu) { // Generic stress steering function; returns 0 on success, -1 on error gpoints = 0; printf(" Test %2d : %s ", fSeq, GetName()); PutPoint(); Int_t rc = 0; if (!dryrun) { gSystem->RedirectOutput(glogfile, "a", &gRH); RunTimes tt; gStopwatch.Start(); rc = (*fFun)(fArgs, tt); gStopwatch.Stop(); fCpuTime = tt.fCpu; fRealTime = tt.fReal; // Proof marks if (fRefReal > 0) fProofMarks = (fRealTime > 0) ? 1000 * fRefReal / fRealTime : -1; gSystem->RedirectOutput(0, 0, &gRH); if (rc == 0) { Int_t np = totpoints - strlen(GetName()) - strlen(" OK *"); while (np--) { printf("."); } if (showcpu) { printf(" OK * (rt: %f s, cpu: %f s, marks: %.2f)\n", fRealTime, fCpuTime, fProofMarks); } else { printf(" OK *\n"); } } else if (rc == 1) { Int_t np = totpoints - strlen(GetName()) - strlen(" SKIPPED *"); while (np--) { printf("."); } printf(" SKIPPED *\n"); } else { Int_t np = totpoints - strlen(GetName()) - strlen(" FAILED *"); while (np--) { printf("."); } printf(" FAILED *\n"); gSystem->ShowOutput(&gRH); } } else { if (fEnabled) { Int_t np = totpoints - strlen(GetName()) - strlen(" ENABLED *"); while (np--) { printf("."); } printf(" ENABLED *\n"); } else { Int_t np = totpoints - strlen(GetName()) - strlen(" DISABLED *"); while (np--) { printf("."); } printf(" DISABLED *\n"); } } // Done return rc; } // Test functions Int_t PT_Open(void *, RunTimes &); Int_t PT_GetLogs(void *, RunTimes &); Int_t PT_Simple(void *, RunTimes &); Int_t PT_H1Http(void *, RunTimes &); Int_t PT_H1FileCollection(void *, RunTimes &); Int_t PT_H1DataSet(void *, RunTimes &); Int_t PT_H1MultiDataSet(void *, RunTimes &); Int_t PT_H1MultiDSetEntryList(void *, RunTimes &); Int_t PT_DataSets(void *, RunTimes &); Int_t PT_Packages(void *, RunTimes &); Int_t PT_Event(void *, RunTimes &); Int_t PT_InputData(void *, RunTimes &); Int_t PT_H1SimpleAsync(void *arg, RunTimes &); Int_t PT_AdminFunc(void *arg, RunTimes &); Int_t PT_PackageArguments(void *, RunTimes &); Int_t PT_EventRange(void *, RunTimes &); Int_t PT_POFNtuple(void *, RunTimes &); Int_t PT_POFDataset(void *, RunTimes &); Int_t PT_Friends(void *, RunTimes &); Int_t PT_SimpleByObj(void *, RunTimes &); Int_t PT_H1ChainByObj(void *, RunTimes &); Int_t PT_AssertTutorialDir(const char *tutdir); Int_t PT_MultiTrees(void *, RunTimes &); Int_t PT_OutputHandlingViaFile(void *, RunTimes &); // Auxilliary functions void PT_GetLastTimes(RunTimes &tt) { // Get in tt the Cpu and Real times used during the run // The runtimes gStopwatch.Stop(); tt.fCpu = gStopwatch.CpuTime(); tt.fReal = gStopwatch.RealTime(); } void PT_GetLastProofTimes(RunTimes &tt) { // Get in tt the Cpu and Real times used by PROOF since last call if (gProof->IsLite()) { PT_GetLastTimes(tt); return; } // Update the statistics gProof->GetStatistics(kFALSE); // The runtimes RunTimes proofTimesCurrent(gProof->GetCpuTime(), gProof->GetRealTime()); tt = proofTimesCurrent - gProofTimesZero; gProofTimesZero = proofTimesCurrent; } // Arguments structures typedef struct ptopenargs { // Open const char *url; Int_t nwrks; } PT_Open_Args_t; // Packetizer parameters typedef struct ptpacketizer { const char *fName; Int_t fType; } PT_Packetizer_t; // Options typedef struct ptoption { Int_t fOne; Int_t fTwo; } PT_Option_t; static PT_Packetizer_t gStd_Old = { "TPacketizer", 0 }; //_____________________________________________________________________________ int stressProof(const char *url, const char *tests, Int_t nwrks, const char *verbose, const char *logfile, Bool_t dyn, Bool_t skipds, const char *h1src, const char *eventsrc, Bool_t dryrun, Bool_t showcpu, Bool_t clearcache, Bool_t useprogress, const char *tutdir, Bool_t cleanlog, Bool_t keeplog) { printf("******************************************************************\n"); printf("* Starting P R O O F - S T R E S S suite *\n"); printf("******************************************************************\n"); // Use defaults or environment settings where required if (!url) { url = getenv("STRESSPROOF_URL"); if (!url) url = urldef; } // Set dynamic mode gDynamicStartup = (!strcmp(url,"lite://")) ? kFALSE : dyn; // Set verbosity TString vv(verbose); Ssiz_t icol = kNPOS; if ((icol = vv.Index(":")) != kNPOS) { TString sv = vv(icol+1, vv.Length() - icol -1); gverbose = sv.Atoi(); vv.Remove(icol); gverbproof = vv; } else { gverbose = vv.Atoi(); } // No progress bar if not tty or explicitly not requested (i.e. for ctest) guseprogress = useprogress; if (isatty(0) == 0 || isatty(1) == 0) guseprogress = kFALSE; if (!guseprogress) { if (!useprogress) { printf("* Progress not shown (explicit request) *\n"); } else { printf("* Progress not shown (not tty) *\n"); } printf("******************************************************************\n"); } // Notify/warn about the dynamic startup option, if any TUrl uu(url), udef(urldef); Bool_t extcluster = ((strcmp(uu.GetHost(), udef.GetHost()) || (uu.GetPort() != udef.GetPort())) && strcmp(url,"lite://"))? kTRUE : kFALSE; if (gDynamicStartup && gverbose > 0) { // Check url if (extcluster) { printf("* WARNING: request to run a test with per-job scheduling on *\n"); printf("* an external cluster: %s .\n", url); printf("* Make sure the dynamic option is set. *\n"); printf("* *\n"); gDynamicStartup = kFALSE; } else { printf("* Runnning in dynamic mode (per-job scheduling) *\n"); } printf("* Tests #15, #22, #23, #26 skipped in dynamic mode **\n"); printf("******************************************************************\n"); } if (dryrun) { printf("* Dry-run: only showing what would be done *\n"); printf("******************************************************************\n"); } // Cluster locality gLocalCluster = (!extcluster || !strcmp(url, "lite://")) ? kFALSE : kTRUE; // Dataset option if (!skipds) { gSkipDataSetTest = kFALSE; } else { gSkipDataSetTest = gLocalCluster; } // Clear cache gClearCache = clearcache; // Log file path Bool_t usedeflog = kTRUE; FILE *flog = 0; if (!logfile) logfile = getenv("STRESSPROOF_LOGFILE"); if (logfile && strlen(logfile) > 0 && !dryrun) { usedeflog = kFALSE; glogfile = logfile; if (glogfile.Contains("%tmp")) glogfile.ReplaceAll("%tmp", gSystem->TempDirectory()); if (glogfile.Contains("%p")) { TString apid = TString::Format("%d", gSystem->GetPid()); glogfile.ReplaceAll("%p", apid); } if (glogfile.Contains("%d")) { TString d(TDatime().AsSQLString()); d.Remove(d.Last(':')); d.ReplaceAll("-", ""); d.ReplaceAll(":", ""); d.ReplaceAll(" ", "-"); glogfile.ReplaceAll("%d", d); } if (!gSystem->AccessPathName(glogfile, kFileExists)) { if (gSystem->AccessPathName(glogfile, kWritePermission)) { printf(" >>> Cannot write to log file %s - ignore file request\n", logfile); usedeflog = kTRUE; } } else { // Create the file if (!(flog = fopen(logfile, "w"))) { printf(" >>> Cannot create log file %s - ignore file request\n", logfile); usedeflog = kTRUE; } } } if (usedeflog && !dryrun) { glogfile = "ProofStress_"; if (!(flog = gSystem->TempFileName(glogfile, gSystem->TempDirectory()))) { printf(" >>> Cannot create a temporary log file on %s - exit\n", gSystem->TempDirectory()); return 1; } fclose(flog); } if (gverbose > 0) { printf("* Log file: %s\n", glogfile.Data()); if (cleanlog) printf("* (NB: file will be removed if test is successful) *\n"); printf("******************************************************************\n"); } if (gSkipDataSetTest && gverbose > 0) { printf("* Test for dataset handling (#4, #8-10) skipped **\n"); printf("******************************************************************\n"); } if (gUseParallelUnzip && gverbose > 0) { printf("* Using parallel unzip where relevant **\n"); printf("******************************************************************\n"); } if (!strcmp(url,"lite://") && gverbose > 0) { printf("* PROOF-Lite session (tests #15 and #16 skipped) **\n"); printf("******************************************************************\n"); } if (!h1src) h1src = getenv("STRESSPROOF_H1SRC"); if (h1src && strlen(h1src)) { if (!strcmp(h1src, "download") && extcluster) { if (gverbose > 0) { printf("* External clusters: ignoring download request of H1 files\n"); printf("******************************************************************\n"); } } else if (!gh1src.BeginsWith(h1src)) { if (gverbose > 0) { printf("* Taking 'h1' files from: %s\n", h1src); printf("******************************************************************\n"); } gh1src = h1src; gh1ok = kFALSE; } } if (!eventsrc) eventsrc = getenv("STRESSPROOF_EVENT"); if (eventsrc && strlen(eventsrc)) { if (!strcmp(eventsrc, "download") && extcluster) { if (gverbose > 0) { printf("* External clusters: ignoring download request of 'event' files\n"); printf("******************************************************************\n"); } } else if (!geventsrc.BeginsWith(eventsrc)) { if (gverbose > 0) { printf("* Taking 'event' files from: %s\n", eventsrc); printf("******************************************************************\n"); } geventsrc = eventsrc; geventok = kFALSE; } } if (!tutdir) tutdir = getenv("STRESSPROOF_TUTORIALDIR"); if (tutdir && strlen(tutdir)) { if (!(gTutDir == tutdir)) { if (gverbose > 0) { printf("* Taking tutorial files from: %s\n", tutdir); printf("******************************************************************\n"); } gTutDir = tutdir; } } if (clearcache && gverbose > 0) { printf("* Clearing cache associated to files, if possible ... **\n"); printf("******************************************************************\n"); } if (keeplog && gverbose > 0) { printf("* Keeping logfiles (paths specified at the end) **\n"); printf("******************************************************************\n"); } // // Reset dataset settings gEnv->SetValue("Proof.DataSetManager",""); // // Register tests // TList *testList = new TList; // Simple open PT_Open_Args_t PToa = { url, nwrks }; testList->Add(new ProofTest("Open a session", 1, &PT_Open, (void *)&PToa)); // Get logs testList->Add(new ProofTest("Get session logs", 2, &PT_GetLogs, (void *)&PToa, "1")); // Simple histogram generation testList->Add(new ProofTest("Simple random number generation", 3, &PT_Simple, 0, "1", "ProofSimple", kTRUE)); // Test of data set handling with the H1 http files testList->Add(new ProofTest("Dataset handling with H1 files", 4, &PT_DataSets, 0, "1")); // H1 analysis over HTTP (chain) testList->Add(new ProofTest("H1: chain processing", 5, &PT_H1Http, 0, "1", "h1analysis", kTRUE)); // H1 analysis over HTTP (file collection) testList->Add(new ProofTest("H1: file collection processing", 6, &PT_H1FileCollection, 0, "1", "h1analysis", kTRUE)); // H1 analysis over HTTP: classic packetizer testList->Add(new ProofTest("H1: file collection, TPacketizer", 7, &PT_H1FileCollection, (void *)&gStd_Old, "1", "h1analysis", kTRUE)); // H1 analysis over HTTP by dataset name testList->Add(new ProofTest("H1: by-name processing", 8, &PT_H1DataSet, 0, "1,4", "h1analysis", kTRUE)); // H1 analysis over HTTP by dataset name split in two testList->Add(new ProofTest("H1: multi dataset processing", 9, &PT_H1MultiDataSet, 0, "1,4", "h1analysis", kTRUE)); // H1 analysis over HTTP by dataset name testList->Add(new ProofTest("H1: multi dataset and entry list", 10, &PT_H1MultiDSetEntryList, 0, "1,4", "h1analysis", kTRUE)); // Test package management with 'event' testList->Add(new ProofTest("Package management with 'event'", 11, &PT_Packages, 0, "1")); // Test package argument passing testList->Add(new ProofTest("Package argument passing", 12, &PT_PackageArguments, 0, "1", "ProofTests")); // Simple event analysis testList->Add(new ProofTest("Simple 'event' generation", 13, &PT_Event, 0, "1,11", "ProofEvent", kTRUE)); // Test input data propagation (it only works in the static startup mode) testList->Add(new ProofTest("Input data propagation", 14, &PT_InputData, 0, "1", "ProofTests")); // Test asynchronous running testList->Add(new ProofTest("H1, Simple: async mode", 15, &PT_H1SimpleAsync, 0, "1,3,5", "h1analysis,ProofSimple", kTRUE)); // Test admin functionality testList->Add(new ProofTest("Admin functionality", 16, &PT_AdminFunc, 0, "1")); // Test merging via submergers PT_Option_t pfoptm = {1, 0}; testList->Add(new ProofTest("Dynamic sub-mergers functionality", 17, &PT_Simple, (void *)&pfoptm, "1", "ProofSimple", kTRUE)); // Test range chain and dataset processing EventProc testList->Add(new ProofTest("Event range processing", 18, &PT_EventRange, 0, "1,11", "ProofEventProc,ProcFileElements", kTRUE)); // Test range chain and dataset processing EventProc with TPacketizer testList->Add(new ProofTest("Event range, TPacketizer", 19, &PT_EventRange, (void *)&gStd_Old, "1,11", "ProofEventProc,ProcFileElements", kTRUE)); // Test TProofOutputFile technology for ntuple creation testList->Add(new ProofTest("File-resident output: merge", 20, &PT_POFNtuple, 0, "1", "ProofNtuple", kTRUE)); // Test TProofOutputFile technology for ntuple creation using submergers testList->Add(new ProofTest("File-resident output: merge w/ submergers", 21, &PT_POFNtuple, (void *)&pfoptm, "1", "ProofNtuple", kTRUE)); // Test TProofOutputFile technology for dataset creation (tests TProofDraw too) testList->Add(new ProofTest("File-resident output: create dataset", 22, &PT_POFDataset, 0, "1", "ProofNtuple", kTRUE)); // Test selecting different TTrees in same files testList->Add(new ProofTest("File-resident output: multi trees", 23, &PT_MultiTrees, 0, "1,22", "ProofNtuple", kTRUE)); // Test TPacketizerFile and TTree friends in separate files testList->Add(new ProofTest("TTree friends (and TPacketizerFile)", 24, &PT_Friends, 0, "1", "ProofFriends,ProofAux", kTRUE)); // Test TPacketizerFile and TTree friends in same file Bool_t sameFile = kTRUE; testList->Add(new ProofTest("TTree friends, same file", 25, &PT_Friends, (void *)&sameFile, "1", "ProofFriends,ProofAux", kTRUE)); // Test handling output via file testList->Add(new ProofTest("Handling output via file", 26, &PT_OutputHandlingViaFile, 0, "1", "ProofSimple", kTRUE)); // Simple histogram generation by TSelector object testList->Add(new ProofTest("Simple: selector by object", 27, &PT_SimpleByObj, 0, "1", "ProofSimple", kTRUE)); // H1 analysis over HTTP by TSeletor object testList->Add(new ProofTest("H1 chain: selector by object", 28, &PT_H1ChainByObj, 0, "1", "h1analysis", kTRUE)); // The selectors if (PT_AssertTutorialDir(gTutDir) != 0) { printf("* Some of the tutorial files are missing! Stop\n"); return 1; } gSelectors.Add(new TNamed("h1analysis", gH1Sel.Data())); gSelectors.Add(new TNamed("ProofEvent", gEventSel.Data())); gSelectors.Add(new TNamed("ProofEventProc", gEventProcSel.Data())); gSelectors.Add(new TNamed("ProofSimple", gSimpleSel.Data())); gSelectors.Add(new TNamed("ProofTests", gTestsSel.Data())); gSelectors.Add(new TNamed("ProcFileElements", gProcFileElem.Data())); gSelectors.Add(new TNamed("ProofNtuple", gNtupleSel.Data())); gSelectors.Add(new TNamed("ProofFriends", gFriendsSel.Data())); gSelectors.Add(new TNamed("ProofAux", gAuxSel.Data())); if (gverbose > 0) { if (!dryrun) { printf("* Cleaning-up all non-source files associated to:\n"); } else { printf("* Would clean-up all non-source files associated to:\n"); } } // Check what to run ProofTest *t = 0, *treq = 0; TIter nxt(testList); Bool_t all = kTRUE; if (!tests) tests = getenv("STRESSPROOF_TESTS"); if (tests && strlen(tests)) { TString tts(tests), tsg, ts, ten; Ssiz_t from = 0; while (tts.Tokenize(tsg, from, ",")) { if (tsg.CountChar('-') > 1) { printf("* **\r"); printf("* Wrong syntax for test range specification: %s\n", tsg.Data()); continue; } Ssiz_t fromg = 0; Int_t test = -1, last = -1; while (tsg.Tokenize(ts, fromg, "-")) { if (!ts.IsDigit()) { printf("* **\r"); printf("* Test string is not a digit: %s\n", ts.Data()); continue; } if (test < 0) { test = ts.Atoi(); } else { last = ts.Atoi(); } } if (test <= 0) { printf("* **\r"); printf("* Non-positive test number: %d\n", test); continue; } const int tmx = PT_NUMTEST; if (test > tmx) { printf("* **\r"); printf("* Unknown test number: %d\n", test); continue; } if (last > tmx) { printf("* **\r"); printf("* Upper test range too large: %d - rescaling\n", last); last = tmx; } else if (last <= 0) { last = test; } // For final notification if (ten != "") ten += ","; ten += tsg; // Ok, now we can enable if (all) { all = kFALSE; // Disable first all the tests while ((t = (ProofTest *)nxt())) { t->Disable(); } } // Process one by one all enabled tests TString cleaned; for (Int_t xt = test; xt <= last; xt++) { // Locate the ProofTest instance nxt.Reset(); while ((t = (ProofTest *)nxt())) { if (t->Num() == xt) treq = t; } if (!treq) { printf("* **\r"); printf("* Test %2d not found among the registered tests - exiting\n", xt); printf("******************************************************************\n"); return 1; } // Enable the required tests Int_t tn = -1; while ((tn = treq->NextDep()) > 0) { nxt.Reset(); while ((t = (ProofTest *)nxt())) { if (t->Num() == tn) { t->Enable(); break; } } } // Reset associated selectors TString sel, tit; while ((treq->NextSel(sel)) == 0) { TNamed *nm = (TNamed *) gSelectors.FindObject(sel.Data()); if (nm && cleaned.Index(nm->GetTitle()) == kNPOS) { if (!dryrun) CleanupSelector(nm->GetTitle()); if (gverbose > 0) { tit = nm->GetName(); tit.Resize(18); printf("* %s in %s\n", tit.Data(), gSystem->DirName(nm->GetTitle())); } cleaned += TString::Format(":%s:", nm->GetTitle()); } } // Enable the required test treq->Enable(); } } if (!all && !dryrun) { // Notify the enabled tests printf("* **\r"); printf("* Running only test(s) %s (and related)\n", ten.Data()); printf("******************************************************************\n"); } } if (all) { // Clean all the selectors TString tit; TIter nxs(&gSelectors); TNamed *nm = 0; while ((nm = (TNamed *)nxs())) { if (!dryrun) CleanupSelector(nm->GetTitle()); if (gverbose > 0) { tit = nm->GetName(); tit.Resize(18); printf("* %s in %s\n", tit.Data(), gSystem->DirName(nm->GetTitle())); } } } if (gverbose > 0) printf("******************************************************************\n"); // If a dry-run show what we would do and exit if (dryrun) { nxt.Reset(); while ((t = (ProofTest *)nxt())) { t->Run(kTRUE); } printf("******************************************************************\n"); return 0; } // Add the ACLiC option to the selector strings gH1Sel += "+"; gEventSel += "+"; gEventProcSel += "+"; gSimpleSel += "+"; gTestsSel += "+"; gProcFileElem += "+"; gNtupleSel += "+"; gFriendsSel += "+"; gAuxSel += "+"; // // Run the tests // Bool_t failed = kFALSE; nxt.Reset(); while ((t = (ProofTest *)nxt())) if (t->IsEnabled()) { if (t->Run(kFALSE, showcpu) < 0) { failed = kTRUE; break; } } // Done Bool_t kept = ((usedeflog || cleanlog) && !keeplog) ? kFALSE : kTRUE; if (failed) { kept = kTRUE; if (usedeflog && !gROOT->IsBatch() && !keeplog) { const char *answer = Getline(" Some tests failed: would you like to keep the log file (N,Y)? [Y] "); if (answer && (answer[0] == 'N' || answer[0] == 'n')) { // Remove log file gSystem->Unlink(glogfile); kept = kFALSE; } } } else { printf("* All registered tests have been passed :-) *\n"); } if (kept) { TString logfiles(glogfile); // Save also the logs from the workers TProofMgr *mgr = gProof ? gProof->GetManager() : 0; if (mgr) { gSystem->RedirectOutput(glogfile, "a", &gRH); TProofLog *pl = mgr->GetSessionLogs(); if (pl) { logfiles += ".nodes"; pl->Retrieve("*", TProofLog::kAll, logfiles); gSystem->RedirectOutput(0, 0, &gRH); SafeDelete(pl); } else { gSystem->RedirectOutput(0, 0, &gRH); printf("+++ Warning: could not get the session logs\n"); } } else { printf("+++ Warning: could not attach to manager to get the session logs\n"); } printf("******************************************************************\n"); printf(" Main log file kept at %s (Proof logs in %s)\n", glogfile.Data(), logfiles.Data()); } else { // Remove log file if not passed by the user gSystem->Unlink(glogfile); } printf("******************************************************************\n"); if (gProof) { // Get average of single PROOF marks int navg = 0; double avgmarks = -1.; nxt.Reset(); if (gverbose > 1) printf(" PROOFMARKS for single tests (-1 if unmeasured): \n"); while ((t = (ProofTest *)nxt())) if (t->IsEnabled()) { if (gverbose > 1) printf(" %d:\t %.2f \n", t->Num(), t->ProofMarks()); if (t->UseForMarks() && t->ProofMarks() > 0) { navg++; avgmarks += t->ProofMarks(); } } if (navg > 0) avgmarks /= navg; gProof->GetStatistics((gverbose > 0)); // Reference time measured on a HP DL580 24 core (4 x Intel(R) Xeon(R) CPU X7460 // @ 2.132 GHz, 48GB RAM, 1 Gb/s NIC) with 4 workers. const double reftime = 70.169; double glbmarks = (gProof->GetRealTime() > 0) ? 1000 * reftime / gProof->GetRealTime() : -1; printf(" ROOTMARKS = %.2f (overall: %.2f) ROOT version: %s\t%s@%s\n", avgmarks, glbmarks, gROOT->GetVersion(), gROOT->GetGitBranch(), gROOT->GetGitCommit()); // Average from the single tests printf("******************************************************************\n"); } // If not PROOF-Lite, stop the daemon used for the test if (gProof && !gProof->IsLite() && !extcluster && gROOT->IsBatch()) { // Get the manager TProofMgr *mgr = gProof->GetManager(); // Close the instance gProof->Close("S"); delete gProof; // Delete the manager SafeDelete(mgr); // The daemon runs on a port shifted by 1 if (killXrootdAt(uu.GetPort()+1, "xpdtut") != 0) { printf("+++ Warning: test daemon probably still running!\n"); } } // Done return (failed ? 1 : 0); } //_____________________________________________________________________________ Int_t PT_H1ReleaseCache(const char *h1src) { // Release memory cache associated with the H1 files at 'h1src', if it // makes any sense, i.e. are local ... if (!h1src || strlen(h1src) <= 0) { printf("\n >>> Test failure: src dir undefined\n"); return -1; } // If non-local, nothing to do if (!gh1local) return 0; TString src; if (gh1sep == '/') { // Loop through the files for (Int_t i = 0; i < 4; i++) { src.Form("%s/%s", h1src, gh1file[i]); ReleaseCache(src.Data()); } } else { // Release the zip file ... ReleaseCache(h1src); } // Done return 0; } //_____________________________________________________________________________ Int_t PT_H1AssertFiles(const char *h1src) { // Make sure that the needed H1 files are available at 'src' // If 'src' is "download", the files are download under /h1 if (!h1src || strlen(h1src) <= 0) { printf("\n >>> Test failure: src dir undefined\n"); return -1; } // Locality TUrl u(h1src, kTRUE); gh1local = (!strcmp(u.GetProtocol(), "file")) ? kTRUE : kFALSE; gh1sep = '/'; // Special cases if (!strncmp(h1src,"download",8)) { if (strcmp(h1src,"download")) { gh1src = h1src; gh1src.ReplaceAll("download=", ""); } if (gh1src.IsNull() || gSystem->AccessPathName(gh1src, kWritePermission)) gh1src = TString::Format("%s/h1", gtutdir.Data()); if (gSystem->AccessPathName(gh1src)) { if (gSystem->MakeDirectory(gh1src) != 0) { printf("\n >>> Test failure: could not create dir %s\n", gh1src.Data()); return -1; } } // Copy the files now Int_t i = 0; for (i = 0; i < 4; i++) { TString src = TString::Format("http://root.cern.ch/files/h1/%s", gh1file[i]); TString dst = TString::Format("%s/%s", gh1src.Data(), gh1file[i]); if (!TFile::Cp(src, dst)) { printf("\n >>> Test failure: problems retrieving %s\n", src.Data()); return -1; } gSystem->RedirectOutput(0, 0, &gRH); printf("%d\b", i); gSystem->RedirectOutput(glogfile, "a", &gRH); } gh1local = kTRUE; // Done gh1ok = kTRUE; return 0; } else if (TString(h1src).EndsWith(".zip")) { // The files are in a zip archive ... if (gSystem->AccessPathName(h1src)) { printf("\n >>> Test failure: file %s does not exist\n", h1src); return -1; } Int_t i = 0; for (i = 0; i < 4; i++) { TString src = TString::Format("%s#%s", h1src, gh1file[i]); TFile *f = TFile::Open(src); if (!f || (f && f->IsZombie())) { printf("\n >>> Test failure: file %s not found in archive %s\n", src.Data(), h1src); return -1; } if (guseprogress) { gSystem->RedirectOutput(0, 0, &gRH); printf("%d\b", i); gSystem->RedirectOutput(glogfile, "a", &gRH); } } gh1sep = '#'; } else { // Make sure the files exist at 'src' Int_t i = 0; for (i = 0; i < 4; i++) { TString src = TString::Format("%s/%s", h1src, gh1file[i]); if (gSystem->AccessPathName(src)) { printf("\n >>> Test failure: file %s does not exist\n", src.Data()); return -1; } if (guseprogress) { gSystem->RedirectOutput(0, 0, &gRH); printf("%d\b", i); gSystem->RedirectOutput(glogfile, "a", &gRH); } } } gh1src = h1src; // Done gh1ok = kTRUE; return 0; } //_____________________________________________________________________________ Int_t PT_EventReleaseCache(const char *eventsrc, Int_t nf = 10) { // Release memory cache associated with the event files at 'eventsrc', if it // makes any sense, i.e. are local ... if (!eventsrc || strlen(eventsrc) <= 0) { printf("\n >>> Test failure: src dir undefined\n"); return -1; } if (nf > 50) { printf("\n >>> Test failure: max 50 event files can be checked\n"); return -1; } // If non-local, nothing to do if (!geventlocal) return 0; TString src; // Loop through the files for (Int_t i = 0; i < nf; i++) { src.Form("%s/event_%d.root", eventsrc, i+1); ReleaseCache(src.Data()); } // Done return 0; } //_____________________________________________________________________________ Int_t PT_EventAssertFiles(const char *eventsrc, Int_t nf = 10) { // Make sure that the needed 'event' files are available at 'src' // If 'src' is "download", the files are download under /event . // By default 10 files are checked; maximum is 50 (idx 1->50 not 0->49). if (!eventsrc || strlen(eventsrc) <= 0) { printf("\n >>> Test failure: src dir undefined\n"); return -1; } if (nf > 50) { printf("\n >>> Test failure: max 50 event files can be checked\n"); return -1; } // Locality TUrl u(eventsrc, kTRUE); geventlocal = (!strcmp(u.GetProtocol(), "file")) ? kTRUE : kFALSE; // Special case if (!strncmp(eventsrc,"download",8)) { if (strcmp(eventsrc,"download")) { geventsrc = eventsrc; geventsrc.ReplaceAll("download=", ""); } if (geventsrc.IsNull() || gSystem->AccessPathName(geventsrc, kWritePermission)) geventsrc = TString::Format("%s/event", gtutdir.Data()); if (gSystem->AccessPathName(geventsrc)) { if (gSystem->MakeDirectory(geventsrc) != 0) { printf("\n >>> Test failure: could not create dir %s\n", geventsrc.Data()); return -1; } } // Copy the files now Int_t i = 0; for (i = 0; i < nf; i++) { TString src = TString::Format("http://root.cern.ch/files/data/event_%d.root", i+1); TString dst = TString::Format("%s/event_%d.root", geventsrc.Data(), i+1); if (!TFile::Cp(src, dst)) { printf("\n >>> Test failure: problems retrieving %s\n", src.Data()); return -1; } if (guseprogress) { gSystem->RedirectOutput(0, 0, &gRH); printf("%d\b", i); gSystem->RedirectOutput(glogfile, "a", &gRH); } } geventlocal = kTRUE; // Done geventok = kTRUE; return 0; } // Make sure the files exist at 'src' Int_t i = 0; for (i = 0; i < nf; i++) { TString src = TString::Format("%s/event_%d.root", eventsrc, i+1); if (gSystem->AccessPathName(src)) { printf("\n >>> Test failure: file %s does not exist\n", src.Data()); return -1; } if (guseprogress) { gSystem->RedirectOutput(0, 0, &gRH); printf("%d\b", i); gSystem->RedirectOutput(glogfile, "a", &gRH); } } geventsrc = eventsrc; // Done geventok = kTRUE; return 0; } //_____________________________________________________________________________ Int_t PT_AssertTutorialDir(const char *tutdir) { // Make sure that the needed files are available under the specified // tutorial directory, setting the relevant variables if (!tutdir || strlen(tutdir) <= 0) { printf("\n >>> Test failure: dir undefined\n"); return -1; } TString path; // Selectors gH1Sel.Insert(0, tutdir); gSystem->ExpandPathName(gH1Sel); if (gSystem->AccessPathName(gH1Sel)) return -1; // gEventSel.Insert(0, tutdir); gSystem->ExpandPathName(gEventSel); if (gSystem->AccessPathName(gEventSel)) return -1; // gEventProcSel.Insert(0, tutdir); gSystem->ExpandPathName(gEventProcSel); if (gSystem->AccessPathName(gEventProcSel)) return -1; // gSimpleSel.Insert(0, tutdir); gSystem->ExpandPathName(gSimpleSel); if (gSystem->AccessPathName(gSimpleSel)) return -1; // gTestsSel.Insert(0, tutdir); gSystem->ExpandPathName(gTestsSel); if (gSystem->AccessPathName(gTestsSel)) return -1; // gNtupleSel.Insert(0, tutdir); gSystem->ExpandPathName(gNtupleSel); if (gSystem->AccessPathName(gNtupleSel)) return -1; // gFriendsSel.Insert(0, tutdir); gSystem->ExpandPathName(gFriendsSel); if (gSystem->AccessPathName(gFriendsSel)) return -1; // gAuxSel.Insert(0, tutdir); gSystem->ExpandPathName(gAuxSel); if (gSystem->AccessPathName(gAuxSel)) return -1; // Special class gProcFileElem.Insert(0, tutdir); gSystem->ExpandPathName(gProcFileElem); if (gSystem->AccessPathName(gProcFileElem)) return -1; // Special files gEmptyInclude.Insert(0, tutdir); gSystem->ExpandPathName(gEmptyInclude); if (gSystem->AccessPathName(gEmptyInclude)) return -1; // gNtpRndm.Insert(0, tutdir); gSystem->ExpandPathName(gNtpRndm); if (gSystem->AccessPathName(gNtpRndm)) return -1; // Special packages gPackEvent.Insert(0, tutdir); gSystem->ExpandPathName(gPackEvent); if (gSystem->AccessPathName(gPackEvent)) return -1; // gPack1.Insert(0, tutdir); gSystem->ExpandPathName(gPack1); if (gSystem->AccessPathName(gPack1)) return -1; // gPack2.Insert(0, tutdir); gSystem->ExpandPathName(gPack2); if (gSystem->AccessPathName(gPack2)) return -1; // Done return 0; } //_____________________________________________________________________________ Int_t PT_CheckSimple(TQueryResult *qr, Long64_t nevt, Int_t nhist) { // Check the result of the ProofSimple analysis if (!qr) { printf("\n >>> Test failure: query result not found\n"); return -1; } // Make sure the number of processed entries is the one expected PutPoint(); if (qr->GetEntries() != nevt) { printf("\n >>> Test failure: wrong number of entries processed: %lld (expected %lld)\n", qr->GetEntries(), nevt); return -1; } // Make sure the output list is there PutPoint(); TList *out = qr->GetOutputList(); if (!out) { printf("\n >>> Test failure: output list not found\n"); return -1; } // Get the histos PutPoint(); TH1F **hist = new TH1F*[nhist]; for (Int_t i=0; i < nhist; i++) { hist[i] = dynamic_cast(TProof::GetOutput(Form("h%d",i), out)); if (!hist[i]) { printf("\n >>> Test failure: 'h%d' histo not found\n", i); return -1; } } // Check the mean values PutPoint(); for (Int_t i=0; i < nhist; i++) { Double_t ave = hist[i]->GetMean(); Double_t rms = hist[i]->GetRMS(); if (TMath::Abs(ave) > 5 * rms / TMath::Sqrt(hist[i]->GetEntries())) { printf("\n >>> Test failure: 'h%d' histo: mean > 5 * RMS/Sqrt(N)\n", i); return -1; } } // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_CheckSimpleNtuple(TQueryResult *qr, Long64_t nevt, const char *dsname) { // Check the ntuple created by the ProofSimple analysis if (!qr) { printf("\n >>> Test failure: query result not found\n"); return -1; } // Make sure the output list is there PutPoint(); TList *out = qr->GetOutputList(); if (!out) { printf("\n >>> Test failure: output list not found\n"); return -1; } // Get the file collection PutPoint(); TFileCollection *fc = dynamic_cast(out->FindObject(dsname)); if (!fc) { printf("\n >>> Test failure: TFileCollection for dataset '%s' not" " found in the output list\n", dsname); return -1; } // Check the default tree name const char *tname = "/ntuple"; PutPoint(); if (!fc->GetDefaultTreeName() || strcmp(fc->GetDefaultTreeName(), tname)) { printf("\n >>> Test failure: default tree name does not match (%s != %s)\n", fc->GetDefaultTreeName(), tname); return -1; } // Check the number of entries PutPoint(); if (fc->GetTotalEntries(tname) != nevt) { printf("\n >>> Test failure: number of entries does not match (%lld != %lld)\n", fc->GetTotalEntries(tname), nevt); return -1; } // Check 'pz' histo TH1F *hpx = new TH1F("PT_px", "PT_px", 20, -5., 5.); PutPoint(); gProof->DrawSelect(dsname, "px >> PT_px"); if (TMath::Abs(hpx->GetMean()) > 5 * hpx->GetRMS() / TMath::Sqrt(hpx->GetEntries())) { printf("\n >>> Test failure: 'hpx' histo: mean > 5 * RMS/Sqrt(N) (%f,%f)\n", hpx->GetMean(), hpx->GetRMS()); return -1; } // Check 'pz' histo TH1F *hpz = new TH1F("PT_pz", "PT_pz", 20, 0., 20.); PutPoint(); gProof->DrawSelect(dsname, "pz >> PT_pz"); if (TMath::Abs(hpz->GetMean() - 2.) > 5 * 2. / TMath::Sqrt(hpz->GetEntries())) { printf("\n >>> Test failure: 'hpz' histo: (mean - 2) > 5 * RMS/Sqrt(N) (%f,%f)\n", hpz->GetMean(), hpz->GetRMS()); return -1; } // Check 'random' histo TH1F *hpr = new TH1F("PT_rndm", "PT_rndm", 20, 0., 20.); PutPoint(); gProof->DrawSelect(dsname, "random >> PT_rndm"); if (TMath::Abs(hpr->GetMean() - .5) > 5 * .5 / TMath::Sqrt(hpr->GetEntries())) { printf("\n >>> Test failure: 'hpr' histo: (mean - .5) > 5 * RMS/Sqrt(N) (%f,%f)\n", hpr->GetMean(), hpr->GetRMS()); return -1; } SafeDelete(hpx); SafeDelete(hpz); SafeDelete(hpr); // Clear dsname gProof->ClearData(TProof::kDataset |TProof::kForceClear, dsname); // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_CheckH1(TQueryResult *qr, Int_t irun = 0) { // Check the result of the H1 analysis if (!qr) { printf("\n >>> Test failure: output list not found\n"); return -1; } // Make sure the number of processed entries is the one expected PutPoint(); Long64_t runEntries[2] = {283813, 7525}; if (qr->GetEntries() != runEntries[irun]) { printf("\n >>> Test failure: wrong number of entries processed: %lld (expected %lld)\n", qr->GetEntries(), runEntries[irun]); return -1; } // Make sure the output list is there PutPoint(); TList *out = qr->GetOutputList(); if (!out) { printf("\n >>> Test failure: output list not found\n"); return -1; } // Check the 'hdmd' histo PutPoint(); TH1F *hdmd = dynamic_cast(out->FindObject("hdmd")); if (!hdmd) { printf("\n >>> Test failure: 'hdmd' histo not found\n"); return -1; } if ((Int_t)(hdmd->GetEntries()) != 7525) { printf("\n >>> Test failure: 'hdmd' histo: wrong number" " of entries (%d: expected 7525) \n",(Int_t)(hdmd->GetEntries())); return -1; } if (TMath::Abs((hdmd->GetMean() - 0.15512023) / 0.15512023) > 0.001) { printf("\n >>> Test failure: 'hdmd' histo: wrong mean" " (%f: expected 0.15512023) \n", hdmd->GetMean()); return -1; } PutPoint(); TH2F *h2 = dynamic_cast(out->FindObject("h2")); if (!h2) { printf("\n >>> Test failure: 'h2' histo not found\n"); return -1; } if ((Int_t)(h2->GetEntries()) != 7525) { printf("\n >>> Test failure: 'h2' histo: wrong number" " of entries (%d: expected 7525) \n",(Int_t)(h2->GetEntries())); return -1; } if (TMath::Abs((h2->GetMean() - 0.15245688) / 0.15245688) > 0.001) { printf("\n >>> Test failure: 'h2' histo: wrong mean" " (%f: expected 0.15245688) \n", h2->GetMean()); return -1; } // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_CheckEvent(TQueryResult *qr, const char *pack = "TPacketizerAdaptive") { // Check the result of the EventProc analysis if (!qr) { printf("\n >>> Test failure: %s: output list not found\n", pack); return -1; } // Make sure the output list is there PutPoint(); TList *out = qr->GetOutputList(); if (!out) { printf("\n >>> Test failure: %s: output list not found\n", pack); return -1; } // Check the 'hdmd' histo PutPoint(); TNamed *nout = dynamic_cast(out->FindObject("Range_Check")); if (!nout) { printf("\n >>> Test failure: %s: 'Range_Check' named object not found\n", pack); return -1; } if (strcmp(nout->GetTitle(), "OK")) { printf("\n >>> Test failure: %s: 'Range_Check': wrong result: %s \n", pack, nout->GetTitle()); return -1; } // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_CheckNtuple(TQueryResult *qr, Long64_t nevt) { // Check the result of the ProofNtuple analysis if (!qr) { printf("\n >>> Test failure: query result not found\n"); return -1; } // Make sure the number of processed entries is the one expected PutPoint(); if (qr->GetEntries() != nevt) { printf("\n >>> Test failure: wrong number of entries processed: %lld (expected %lld)\n", qr->GetEntries(), nevt); return -1; } // Make sure the output list is there PutPoint(); TList *out = qr->GetOutputList(); if (!out) { printf("\n >>> Test failure: output list not found\n"); return -1; } // Get the ntuple form the file TProofOutputFile *pof = dynamic_cast(out->FindObject("SimpleNtuple.root")); if (!pof) { printf("\n >>> Test failure: TProofOutputFile not found in the output list\n"); return -1; } // Get the file full path TString outputFile(pof->GetOutputFileName()); TString outputName(pof->GetName()); outputName += ".root"; // Read the ntuple from the file TFile *f = TFile::Open(outputFile); if (!f || (f && f->IsZombie())) { printf("\n >>> Test failure: could not open file: %s", outputFile.Data()); return -1; } // Get the ntuple PutPoint(); TNtuple *ntp = dynamic_cast(f->Get("ntuple")); if (!ntp) { printf("\n >>> Test failure: 'ntuple' not found\n"); return -1; } // Check the ntuple content by filling some histos TH1F *h1s[3] = {0}; h1s[0] = new TH1F("h1_1", "3*px+2 with px**2+py**2>1", 50, -15., 15.); h1s[1] = new TH1F("h1_2", "2*px+2 with pz>2", 50, -10., 10.); h1s[2] = new TH1F("h1_3", "1.3*px+2 with (px^2+py^2>4) && py>0", 50, 0., 8.); Float_t px, py, pz; Float_t *pp = ntp->GetArgs(); Long64_t ent = 0; while (ent < ntp->GetEntries()) { ntp->GetEntry(ent); px = pp[0]; py = pp[1]; pz = pp[2]; // Fill the histos if (px*px+py*py > 1.) h1s[0]->Fill(3.*px + 2.); if (pz > 2.) h1s[1]->Fill(2.*px + 2.); if (px*px+py*py > 4. && py > 0.) h1s[2]->Fill(1.3*px + 2.); // Go next ent++; } Int_t rch1s = 0; TString emsg; // Check the histogram entries and mean values Int_t hent[3] = { 620, 383, 72}; Double_t hmea[3] = { 1.992, 2.062 , 3.126}; for (Int_t i = 0; i < 3; i++) { if ((Int_t)(h1s[i]->GetEntries()) != hent[i]) { emsg.Form("'%s' histo: wrong number of entries (%d: expected %d)", h1s[i]->GetName(), (Int_t)(h1s[i]->GetEntries()), hent[i]); rch1s = -1; break; } if (TMath::Abs((h1s[i]->GetMean() - hmea[i]) / hmea[i]) > 0.001) { emsg.Form("'%s' histo: wrong mean (%f: expected %f)", h1s[i]->GetName(), h1s[i]->GetMean(), hmea[i]); rch1s = -1; break; } } // Cleanup for (Int_t i = 0; i < 3; i++) delete h1s[i]; f->Close(); delete f; // Check the result if (rch1s != 0) { printf("\n >>> Test failure: %s\n", emsg.Data()); return -1; } // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_CheckDataset(TQueryResult *qr, Long64_t nevt) { // Check the result of the ProofNtuple analysis creating a dataset // Uses and check also TProofDraw if (!qr) { printf("\n >>> Test failure: query result not found\n"); return -1; } // Make sure the number of processed entries is the one expected PutPoint(); if (qr->GetEntries() != nevt) { printf("\n >>> Test failure: wrong number of entries processed: %lld (expected %lld)\n", qr->GetEntries(), nevt); return -1; } const char *dsname = "testNtuple"; // Make sure that the dataset exists PutPoint(); if (!gProof->ExistsDataSet(dsname)) { gProof->ShowDataSets(); printf("\n >>> Test failure: dataset '%s' not found in the repository\n", dsname); return -1; } // ... and that the default tree is 'ntuple' gProof->SetDataSetTreeName(dsname, "ntuple"); // Create the histos TH1F *h1s[3] = {0}; h1s[0] = new TH1F("h1s0", "3*px+2 with px**2+py**2>1", 50, -15., 15.); h1s[1] = new TH1F("h1s1", "2*px+2 with pz>2", 50, -10., 10.); h1s[2] = new TH1F("h1s2", "1.3*px+2 with (px^2+py^2>4) && py>0", 50, 0., 8.); // Fill the histos using TProofDraw PutPoint(); { SwitchProgressGuard spg; gProof->DrawSelect(dsname, "3*px+2 >> h1s0","px**2+py**2>1"); PutPoint(); gProof->DrawSelect(dsname, "2*px+2 >> h1s1","pz>2"); PutPoint(); gProof->DrawSelect(dsname, "1.3*px+2 >> h1s2","(px^2+py^2>4) && py>0"); } Int_t rch1s = 0; TString emsg; // Check the histogram entries and mean values Float_t hent[3] = { .607700, .364900, .065100}; Double_t hmea[3] = { 2.022, 2.046 , 3.043}; Double_t prec = 10. / TMath::Sqrt(nevt); // ~10 sigma ... conservative for (Int_t i = 0; i < 3; i++) { Double_t ent = h1s[i]->GetEntries(); if (TMath::Abs(ent - hent[i] * nevt) / ent > prec) { emsg.Form("'%s' histo: wrong number" " of entries (%lld: expected %lld)", h1s[i]->GetName(), (Long64_t) ent, (Long64_t)(hent[i] *nevt)); rch1s = -1; break; } Double_t mprec = 5 * h1s[i]->GetRMS() / TMath::Sqrt(h1s[i]->GetEntries()) ; if (TMath::Abs((h1s[i]->GetMean() - hmea[i]) / hmea[i]) > mprec ) { emsg.Form("'%s' histo: wrong mean (%f: expected %f - RMS: %f)", h1s[i]->GetName(), h1s[i]->GetMean(), hmea[i], h1s[i]->GetRMS()); rch1s = -1; break; } } // Cleanup for (Int_t i = 0; i < 3; i++) delete h1s[i]; // Check the result if (rch1s != 0) { printf("\n >>> Test failure: %s\n", emsg.Data()); return -1; } // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_CheckFriends(TQueryResult *qr, Long64_t nevt) { // Check the result of the ProofFriends analysis if (!qr) { printf("\n >>> Test failure: query result not found\n"); return -1; } // Make sure the number of processed entries is the one expected PutPoint(); if (qr->GetEntries() != nevt) { printf("\n >>> Test failure: wrong number of entries processed: %lld (expected %lld)\n", qr->GetEntries(), nevt); return -1; } // Make sure the output list is there PutPoint(); TList *out = qr->GetOutputList(); if (!out) { printf("\n >>> Test failure: output list not found\n"); return -1; } TString emsg; // Check the histogram entries and mean values Int_t rchs = 0; const char *hnam[4] = { "histo1", "histo2", "histo3", "histo4" }; const char *hcls[4] = { "TH2F", "TH1F", "TH1F", "TH2F" }; Float_t hent[4] = { 1., .227, .0260, .0260}; TObject *o = 0; Double_t ent = -1; Double_t prec = 1. / TMath::Sqrt(nevt); for (Int_t i = 0; i < 4; i++) { if (!(o = out->FindObject(hnam[i]))) { emsg.Form("object '%s' not found", hnam[i]); rchs = -1; break; } if (strcmp(o->IsA()->GetName(), hcls[i])) { emsg.Form("object '%s' is not '%s'", hnam[i], hcls[i]); rchs = -1; break; } if (!strcmp(hcls[i], "TH1F")) { ent = ((TH1F *)o)->GetEntries(); } else { ent = ((TH2F *)o)->GetEntries(); } if (TMath::Abs(ent - hent[i] * nevt) / (Double_t)ent > prec) { emsg.Form("'%s' histo: wrong number of entries (%lld: expected %lld) \n", o->GetName(), (Long64_t) ent, (Long64_t) (hent[i] * nevt)); rchs = -1; break; } } if (rchs != 0) { printf("\n >>> Test failure: %s\n", emsg.Data()); return -1; } // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_Open(void *args, RunTimes &tt) { // Test session opening // Checking arguments PutPoint(); PT_Open_Args_t *PToa = (PT_Open_Args_t *)args; if (!PToa) { printf("\n >>> Test failure: invalid arguments: %p\n", args); return -1; } // Temp dir for PROOF tutorials PutPoint(); TString tmpdir(gSystem->TempDirectory()), us; #if defined(R__MACOSX) // Force '/tmp' under macosx, to avoid problems with lengths and symlinks tmpdir = "/tmp"; #endif UserGroup_t *ug = gSystem->GetUserInfo(gSystem->GetUid()); if (!tmpdir.EndsWith(us.Data())) { if (ug) { us.Form("/%s", ug->fUser.Data()); tmpdir += us; delete ug; } else { printf("\n >>> Test failure: could not get user info"); return -1; } } #if !defined(R__MACOSX) gtutdir.Form("%s/.proof-tutorial", tmpdir.Data()); #else gtutdir.Form("%s/.proof", tmpdir.Data()); #endif if (gSystem->AccessPathName(gtutdir)) { if (gSystem->mkdir(gtutdir, kTRUE) != 0) { printf("\n >>> Test failure: could not assert/create the temporary directory" " for the tutorial (%s)", gtutdir.Data()); return -1; } } // String to initialize the dataset manager TString dsetmgrstr; dsetmgrstr.Form("file dir:%s/datasets opt:-Cq:As:Sb:", gtutdir.Data()); gEnv->SetValue("Proof.DataSetManager", dsetmgrstr.Data()); // String to initialize the package dir TString packdir; packdir.Form("%s/packages", gtutdir.Data()); gEnv->SetValue("Proof.PackageDir", packdir.Data()); // Get the PROOF Session PutPoint(); TProof *p = getProof(PToa->url, PToa->nwrks, gtutdir.Data(), "force", gDynamicStartup, kTRUE); if (!p || !(p->IsValid())) { printf("\n >>> Test failure: could not start the session\n"); return -1; } // Re-check locality: if the logged user name is different from the local one, we may // not have all the rights we need, so we go no-local if (gLocalCluster) { UserGroup_t *pw = gSystem->GetUserInfo(); if (pw) { if (strcmp(pw->fUser, p->GetUser())) gLocalCluster = kFALSE; delete pw; } } // Check if it is in dynamic startup mode Int_t dyn = 0; p->GetRC("Proof.DynamicStartup", dyn); if (dyn != 0) gDynamicStartup = kTRUE; // Set debug level, if required if (gverbose > 1) { Int_t debugscope = getDebugEnum(gverbproof.Data()); p->SetLogLevel(gverbose, debugscope); } PutPoint(); if (PToa->nwrks > 0 && p->GetParallel() != PToa->nwrks) { printf("\n >>> Test failure: number of workers different from requested\n"); return -1; } // Clear Cache p->ClearCache(); // Get some useful info about the cluster (the sandbox dir ...) gSystem->RedirectOutput(0, 0, &gRH); TString testPrint(TString::Format("%s/testPrint.log", gtutdir.Data())); gSystem->RedirectOutput(testPrint, "w", &gRHAdmin); gProof->Print(); gSystem->RedirectOutput(0, 0, &gRHAdmin); gSystem->RedirectOutput(glogfile, "a", &gRH); TMacro macroPrint(testPrint); TObjString *os = macroPrint.GetLineWith("Working directory:"); if (!os) { printf("\n >>> Test failure: problem parsing output from Print()\n"); return -1; } Int_t from = strlen("Working directory:") + 1; while (os->GetString().Tokenize(gsandbox, from, " ")) { if (!gsandbox.IsNull()) break; } if (gsandbox.IsNull()) { printf("\n >>> Test failure: no sandbox dir found\n"); return -1; } gsandbox = gSystem->DirName(gsandbox); gsandbox = gSystem->DirName(gsandbox); PutPoint(); // Fill times PT_GetLastTimes(tt); // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_GetLogs(void *args, RunTimes &tt) { // Test log retrieving // Checking arguments PutPoint(); PT_Open_Args_t *PToa = (PT_Open_Args_t *)args; if (!PToa) { printf("\n >>> Test failure: invalid arguments: %p\n", args); return -1; } PutPoint(); TProofLog *pl = TProof::Mgr(PToa->url)->GetSessionLogs(); if (!pl) { printf("\n >>> Test failure: could not get the logs from last session\n"); return -1; } PutPoint(); if (PToa->nwrks > 0 && pl->GetListOfLogs()->GetSize() != (PToa->nwrks + 1)) { printf("\n >>> Test failure: number of logs different from workers of workers + 1\n"); return -1; } // Fill times PT_GetLastTimes(tt); // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_Simple(void *opts, RunTimes &tt) { // Test run for the ProofSimple analysis (see tutorials) // Checking arguments PutPoint(); if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } PT_Option_t *ptopt = (PT_Option_t *) opts; // Setup submergers if required if (ptopt && ptopt->fOne > 0) { gProof->SetParameter("PROOF_UseMergers", 0); } // Setup save-to-file, if required TString opt = (ptopt && ptopt->fTwo > 0) ? "stf" : "" ; // Define the number of events and histos Long64_t nevt = 1000000; Int_t nhist = 16; // The number of histograms is added as parameter in the input list gProof->SetParameter("ProofSimple_NHist", (Long_t)nhist); // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Process PutPoint(); { SwitchProgressGuard spg; gTimer.Start(); gProof->Process(gSimpleSel.Data(), nevt, opt); gTimer.Stop(); } // Count gSimpleCnt++; gSimpleTime += gTimer.RealTime(); // Remove any setting related to submergers gProof->DeleteParameters("PROOF_UseMergers"); // The runtimes PT_GetLastProofTimes(tt); // Check the results PutPoint(); return PT_CheckSimple(gProof->GetQueryResult(), nevt, nhist); } //_____________________________________________________________________________ Int_t PT_OutputHandlingViaFile(void *opts, RunTimes &tt) { // Test output handling via file using ProofSimple (see tutorials) // Checking arguments PutPoint(); if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } // Not yet supported in dynamic mode if (gDynamicStartup) { return 1; } PutPoint(); PT_Option_t *ptopt = (PT_Option_t *) opts; // Setup submergers if required if (ptopt && ptopt->fOne > 0) { gProof->SetParameter("PROOF_UseMergers", 0); } // Setup save-to-file, if required TString opt = (ptopt && ptopt->fTwo > 0) ? "stf" : "" ; // Define the number of events and histos Long64_t nevt = 1000000 * gProof->GetParallel(); Int_t nhist = 16; // The number of histograms is added as parameter in the input list gProof->SetParameter("ProofSimple_NHist", (Long_t)nhist); // Merged file pptions to be tested const char *testopt[4] = { "stf", "of=proofsimple.root", "of=proofsimple.root;stf", "of=master:proofsimple.root" }; for (Int_t i = 0; i < 4; i++) { // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Save results to file 'proofsimple.root' PutPoint(); { SwitchProgressGuard spg; gTimer.Start(); gProof->Process(gSimpleSel.Data(), nevt, testopt[i]); gTimer.Stop(); } if (PT_CheckSimple(gProof->GetQueryResult(), nevt, nhist) != 0) { printf("\n >>> Test failure: output handling via file: option '%s'\n", testopt[i]); return -1; } // Count gSimpleCnt++; gSimpleTime += gTimer.RealTime(); // Remove file gSystem->Unlink("proofsimple.root"); } // Test dataset creationg with a ntuple const char *dsname = "PT_ds_proofsimple"; if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); if (gProof->ExistsDataSet(dsname)) gProof->RemoveDataSet(dsname); // We want the ntuple gProof->SetParameter("ProofSimple_Ntuple", ""); // Save results to file 'proofsimple.root' PutPoint(); { SwitchProgressGuard spg; gTimer.Start(); gProof->Process(gSimpleSel.Data(), nevt, TString::Format("ds=%s|V", dsname)); gTimer.Stop(); } if (!gProof->ExistsDataSet(dsname)) { printf("\n >>> Test failure: output handling via file: dataset '%s' not created\n", dsname); return -1; } // Remove any setting related to submergers gProof->DeleteParameters("PROOF_UseMergers"); // The runtimes PT_GetLastProofTimes(tt); // Check the results PutPoint(); return PT_CheckSimpleNtuple(gProof->GetQueryResult(), nevt, dsname); } //_____________________________________________________________________________ Int_t PT_H1Http(void *, RunTimes &tt) { // Test run for the H1 analysis as a chain reading the data from HTTP // Checking arguments PutPoint(); if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } // Set/unset the parallel unzip flag AssertParallelUnzip(); // Create the chain PutPoint(); TChain *chain = new TChain("h42"); // Assert the files, if needed if (!gh1ok) { if (PT_H1AssertFiles(gh1src.Data()) != 0) { gProof->SetPrintProgress(0); printf("\n >>> Test failure: could not assert the H1 files\n"); return -1; } } Int_t i = 0; for (i = 0; i < 4; i++) { chain->Add(TString::Format("%s%c%s", gh1src.Data(), gh1sep, gh1file[i])); } // Clear associated memory cache if (gClearCache && PT_H1ReleaseCache(gh1src.Data()) != 0) { gProof->SetPrintProgress(0); printf("\n >>> Test failure: could not clear memory cache for the H1 files\n"); return -1; } // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Process PutPoint(); chain->SetProof(); PutPoint(); { SwitchProgressGuard spg; gTimer.Start(); chain->Process(gH1Sel.Data()); gTimer.Stop(); } gProof->RemoveChain(chain); // Count gH1Cnt++; gH1Time += gTimer.RealTime(); // The runtimes PT_GetLastProofTimes(tt); // Check the results PutPoint(); return PT_CheckH1(gProof->GetQueryResult()); } //_____________________________________________________________________________ Int_t PT_H1FileCollection(void *arg, RunTimes &tt) { // Test run for the H1 analysis as a file collection reading the data from HTTP // Checking arguments PutPoint(); if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } // Set/unset the parallel unzip flag AssertParallelUnzip(); // Are we asked to change the packetizer strategy? if (arg) { PT_Packetizer_t *strategy = (PT_Packetizer_t *)arg; if (strcmp(strategy->fName, "TPacketizerAdaptive")) { gProof->SetParameter("PROOF_Packetizer", strategy->fName); } else { if (strategy->fType != 1) gProof->SetParameter("PROOF_PacketizerStrategy", strategy->fType); } } // Create the file collection PutPoint(); TFileCollection *fc = new TFileCollection("h42"); // Assert the files, if needed if (!gh1ok) { if (PT_H1AssertFiles(gh1src.Data()) != 0) { printf("\n >>> Test failure: could not assert the H1 files\n"); return -1; } } Int_t i = 0; for (i = 0; i < 4; i++) { fc->Add(new TFileInfo(TString::Format("%s%c%s", gh1src.Data(), gh1sep, gh1file[i]))); } // Clear associated memory cache if (gClearCache && PT_H1ReleaseCache(gh1src.Data()) != 0) { gProof->SetPrintProgress(0); printf("\n >>> Test failure: could not clear memory cache for the H1 files\n"); return -1; } // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Process PutPoint(); { SwitchProgressGuard spg; gTimer.Start(); gProof->Process(fc, gH1Sel.Data()); gTimer.Stop(); } // Restore settings gProof->DeleteParameters("PROOF_Packetizer"); gProof->DeleteParameters("PROOF_PacketizerStrategy"); // Count gH1Cnt++; gH1Time += gTimer.RealTime(); // The runtimes PT_GetLastProofTimes(tt); // Check the results PutPoint(); return PT_CheckH1(gProof->GetQueryResult()); } //_____________________________________________________________________________ Int_t PT_H1DataSet(void *, RunTimes &tt) { // Test run for the H1 analysis as a named dataset reading the data from HTTP // Checking arguments if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } // Not yet supported for PROOF-Lite if (gSkipDataSetTest) { return 1; } PutPoint(); // Set/unset the parallel unzip flag AssertParallelUnzip(); // Name for the target dataset const char *dsname = "h1dset"; // Clear associated memory cache if (gClearCache && PT_H1ReleaseCache(gh1src.Data()) != 0) { gProof->SetPrintProgress(0); printf("\n >>> Test failure: could not clear memory cache for the H1 files\n"); return -1; } // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Process the dataset by name PutPoint(); { SwitchProgressGuard spg; gTimer.Start(); gProof->Process(dsname, gH1Sel.Data()); gTimer.Stop(); } // Count gH1Cnt++; gH1Time += gTimer.RealTime(); // The runtimes PT_GetLastProofTimes(tt); // Check the results PutPoint(); return PT_CheckH1(gProof->GetQueryResult()); } //_____________________________________________________________________________ Int_t PT_H1MultiDataSet(void *, RunTimes &tt) { // Test run for the H1 analysis as a named dataset reading the data from HTTP // Checking arguments if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } // Not yet supported for PROOF-Lite if (gSkipDataSetTest) { return 1; } PutPoint(); // Set/unset the parallel unzip flag AssertParallelUnzip(); // Name for the target dataset const char *dsname = "h1dseta h1dsetb"; // Clear associated memory cache if (gClearCache && PT_H1ReleaseCache(gh1src.Data()) != 0) { gProof->SetPrintProgress(0); printf("\n >>> Test failure: could not clear memory cache for the H1 files\n"); return -1; } // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Process the dataset by name PutPoint(); { SwitchProgressGuard spg; gTimer.Start(); gProof->Process(dsname, gH1Sel.Data()); gTimer.Stop(); } // Count gH1Cnt++; gH1Time += gTimer.RealTime(); // The runtimes PT_GetLastProofTimes(tt); // Check the results PutPoint(); return PT_CheckH1(gProof->GetQueryResult()); } //_____________________________________________________________________________ Int_t PT_H1MultiDSetEntryList(void *, RunTimes &tt) { // Test run using the H1 analysis for the multi-dataset functionality and // entry-lists // Checking arguments if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } // Not yet supported for PROOF-Lite if (gSkipDataSetTest) { return 1; } PutPoint(); // Set/unset the parallel unzip flag AssertParallelUnzip(); // Multiple dataset used to create the entry list TString dsname("h1dseta|h1dsetb"); // Clear associated memory cache if (gClearCache && PT_H1ReleaseCache(gh1src.Data()) != 0) { gProof->SetPrintProgress(0); printf("\n >>> Test failure: could not clear memory cache for the H1 files\n"); return -1; } // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Entry-list creation run PutPoint(); { SwitchProgressGuard spg; gTimer.Start(); gProof->Process(dsname, gH1Sel.Data(), "fillList=elist.root"); gTimer.Stop(); } // Cleanup entry-list from the input list TIter nxi(gProof->GetInputList()); TObject *o = 0; while ((o = nxi())) { if (!strncmp(o->GetName(), "elist", 6) || !strcmp(o->GetName(), "fillList")) { gProof->GetInputList()->Remove(o); delete o; } } // Count gH1Cnt++; gH1Time += gTimer.RealTime(); // Clear associated memory cache if (gClearCache && PT_H1ReleaseCache(gh1src.Data()) != 0) { gProof->SetPrintProgress(0); printf("\n >>> Test failure: could not clear memory cache for the H1 files\n"); return -1; } // Run using the entrylist dsname = "h1dseta<Process(dsname, gH1Sel.Data()); gTimer.Stop(); } // Unlink the entry list file gSystem->Unlink("elist.root"); // Cleanup entry-list from the input list nxi.Reset(); while ((o = nxi())) { if (!strncmp(o->GetName(), "elist", 6)) { gProof->GetInputList()->Remove(o); delete o; } } // The runtimes PT_GetLastProofTimes(tt); // Check the results PutPoint(); return PT_CheckH1(gProof->GetQueryResult(), 1); } //_____________________________________________________________________________ Int_t PT_DataSets(void *, RunTimes &tt) { // Test dataset registration, verification, usage, removal. // Use H1 analysis files on HTTP as example // Checking arguments if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } // Not yet supported for PROOF-Lite if (gSkipDataSetTest) { return 1; } PutPoint(); // Cleanup the area PutPoint(); TMap *dsm = gProof->GetDataSets(); if (!dsm) { printf("\n >>> Test failure: could not retrieve map of datasets (even empty)!\n"); return -1; } if (dsm->GetSize() > 0) { // Remove the datasets already registered TIter nxd(dsm); TObjString *os = 0; while ((os = (TObjString *)nxd())) { gProof->RemoveDataSet(os->GetName()); } // Check the result delete dsm; dsm = gProof->GetDataSets(); if (!dsm || dsm->GetSize() > 0) { printf("\n >>> Test failure: could not cleanup the dataset area! (%p)\n", dsm); delete dsm; return -1; } } delete dsm; // Create the file collection PutPoint(); TFileCollection *fc = new TFileCollection(); TFileCollection *fca = new TFileCollection(); TFileCollection *fcb = new TFileCollection(); // Assert the files, if needed if (!gh1ok) { if (PT_H1AssertFiles(gh1src.Data()) != 0) { printf("\n >>> Test failure: could not assert the H1 files\n"); return -1; } } Int_t i = 0; for (i = 0; i < 4; i++) { fc->Add(new TFileInfo(TString::Format("%s%c%s", gh1src.Data(), gh1sep, gh1file[i]))); if (i < 2) { fca->Add(new TFileInfo(TString::Format("%s%c%s", gh1src.Data(), gh1sep, gh1file[i]))); } else { fcb->Add(new TFileInfo(TString::Format("%s%c%s", gh1src.Data(), gh1sep, gh1file[i]))); } } fc->Update(); fca->Update(); fcb->Update(); // Name for this dataset const char *dsname = "h1dset"; const char *dsnamea = "h1dseta"; const char *dsnameb = "h1dsetb"; // Register the dataset PutPoint(); gProof->RegisterDataSet(dsname, fc); gProof->RegisterDataSet(dsnamea, fca); gProof->RegisterDataSet(dsnameb, fcb); // Check the result dsm = gProof->GetDataSets(); if (!dsm || dsm->GetSize() != 3) { printf("\n >>> Test failure: could not register '%s,%s,%s' (%p)\n", dsname, dsnamea, dsnameb, dsm); delete dsm; return -1; } delete dsm; // Test removal PutPoint(); gProof->RemoveDataSet(dsname); gProof->RemoveDataSet(dsnamea); gProof->RemoveDataSet(dsnameb); // Check the result dsm = gProof->GetDataSets(); if (!dsm || dsm->GetSize() != 0) { printf("\n >>> Test failure: could not cleanup '%s,%s,%s' (%p)\n", dsname, dsnamea, dsnameb, dsm); delete dsm; return -1; } delete dsm; // Re-register the dataset PutPoint(); gProof->RegisterDataSet(dsname, fc); gProof->RegisterDataSet(dsnamea, fca); gProof->RegisterDataSet(dsnameb, fcb); // Check the result dsm = gProof->GetDataSets(); if (!dsm || dsm->GetSize() != 3) { printf("\n >>> Test failure: could not re-register '%s,%s,%s' (%p)\n", dsname, dsnamea, dsnameb, dsm); delete dsm; return -1; } delete dsm; // Verify the dataset PutPoint(); if (gProof->VerifyDataSet(dsname) != 0) { printf("\n >>> Test failure: could not verify '%s'!\n", dsname); return -1; } if (gProof->VerifyDataSet(dsnamea) != 0) { printf("\n >>> Test failure: could not verify '%s'!\n", dsnamea); return -1; } if (gProof->VerifyDataSet(dsnameb) != 0) { printf("\n >>> Test failure: could not verify '%s'!\n", dsnameb); return -1; } gProof->ShowDataSets(); // Remove the file collection delete fc; delete fca; delete fcb; // The runtimes PT_GetLastProofTimes(tt); // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_Packages(void *, RunTimes &tt) { // Test package clearing, uploading, enabling, removal. // Use event.par as example. // Checking arguments PutPoint(); if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } // Cleanup the area PutPoint(); TList *packs = gProof->GetListOfPackages(); if (!packs) { printf("\n >>> Test failure: could not retrieve list of packages (even empty)!\n"); return -1; } if (packs->GetSize() > 0) { // Remove the packages already available gProof->ClearPackages(); // Check the result packs = gProof->GetListOfPackages(); if (!packs || packs->GetSize() > 0) { printf("\n >>> Test failure: could not cleanup the package area!\n"); return -1; } } // Name and location for this package const char *pack = "event"; // Upload the package PutPoint(); gProof->UploadPackage(gPackEvent); // Check the result packs = gProof->GetListOfPackages(); if (!packs || packs->GetSize() != 1) { printf("\n >>> Test failure: could not upload '%s'!\n", gPackEvent.Data()); return -1; } // Test cleanup PutPoint(); gProof->ClearPackage(pack); // Check the result packs = gProof->GetListOfPackages(); if (!packs || packs->GetSize() != 0) { printf("\n >>> Test failure: could not cleanup '%s'!\n", pack); return -1; } // Re-upload the package PutPoint(); gProof->UploadPackage(gPackEvent); // Check the result packs = gProof->GetListOfPackages(); if (!packs || packs->GetSize() != 1) { printf("\n >>> Test failure: could not re-upload '%s'!\n", gPackEvent.Data()); return -1; } // Enable the package PutPoint(); gProof->EnablePackage(pack); // Check the result packs = gProof->GetListOfEnabledPackages(); if (!packs || packs->GetSize() != 1) { printf("\n >>> Test failure: could not enable '%s'!\n", pack); return -1; } // Fill times PT_GetLastTimes(tt); // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_Event(void *, RunTimes &tt) { // Test run for the ProofEvent analysis (see tutorials) // Checking arguments PutPoint(); if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } // Define the number of events Long64_t nevt = 100000; // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Process PutPoint(); { SwitchProgressGuard spg; gProof->Process(gEventSel.Data(), nevt); } // Make sure the query result is there PutPoint(); TQueryResult *qr = 0; if (!(qr = gProof->GetQueryResult())) { printf("\n >>> Test failure: query result not found\n"); return -1; } // Make sure the number of processed entries is the one expected PutPoint(); if (qr->GetEntries() != nevt) { printf("\n >>> Test failure: wrong number of entries processed: %lld (expected %lld)\n", qr->GetEntries(), nevt); return -1; } // Make sure the output list is there PutPoint(); if (!(gProof->GetOutputList())) { printf("\n >>> Test failure: output list not found\n"); return -1; } // Check the 'histo' PutPoint(); TH1F *histo = dynamic_cast(gProof->GetOutputList()->FindObject("histo")); if (!histo) { printf("\n >>> Test failure: 'histo' not found\n"); return -1; } // Check the mean values Double_t ave = histo->GetMean(); Double_t rms = histo->GetRMS(); if (TMath::Abs(ave - 50) > 10 * rms / TMath::Sqrt(histo->GetEntries())) { printf("\n >>> Test failure: 'histo': mean > 5 * RMS/Sqrt(N)\n"); return -1; } // The runtimes PT_GetLastProofTimes(tt); // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_InputData(void *, RunTimes &tt) { // Test input data functionality // Checking arguments if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } PutPoint(); // Create the test information to be send via input and retrieved TH1F *h1 = new TH1F("h1data","Input data from file",100,-5.,5.); h1->FillRandom("gaus", 1000); TList *h1list = new TList; h1list->SetName("h1list"); h1list->SetOwner(kTRUE); h1list->Add(h1); h1list->Add(new TParameter("h1avg", h1->GetMean())); h1list->Add(new TParameter("h1rms", h1->GetRMS())); TString datafile = glogfile; datafile += ("_h1data.root"); TFile *f = TFile::Open(datafile, "RECREATE"); if (!f) { printf("\n >>> Test failure: could not open file for input data\n"); return -1; } f->cd(); h1list->Write(0, TObject::kSingleKey, 0); f->Close(); gProof->SetInputDataFile(datafile.Data()); // Histo to be sent from memory TH1F *h2 = new TH1F("h2data","Input data from memory",100,-5.,5.); h2->FillRandom("gaus", 1000); TList *h2list = new TList; h2list->SetName("h2list"); h2list->SetOwner(kTRUE); h2list->Add(h2); h2list->Add(new TParameter("h2avg", h2->GetMean())); h2list->Add(new TParameter("h2rms", h2->GetRMS())); gProof->AddInputData(h2list); // Normal input parameter gProof->AddInput(new TNamed("InputObject", glogfile.Data())); // Type of test gProof->AddInput(new TNamed("ProofTests_Type", "InputData")); // Define the number of events Long64_t nevt = 1; // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Process PutPoint(); { SwitchProgressGuard spg; gProof->Process(gTestsSel.Data(), nevt); } // Cleanup gSystem->Unlink(datafile.Data()); gProof->ClearInputData(h1list); gProof->ClearInputData(h2list); delete h1list; delete h2list; // Make sure the query result is there PutPoint(); TQueryResult *qr = 0; if (!(qr = gProof->GetQueryResult())) { printf("\n >>> Test failure: query result not found\n"); return -1; } // Make sure the output list is there PutPoint(); if (!(gProof->GetOutputList())) { printf("\n >>> Test failure: output list not found\n"); return -1; } // Check the 'histo's PutPoint(); TH1I *stat = dynamic_cast(gProof->GetOutputList()->FindObject("TestStat")); if (!stat) { printf("\n >>> Test failure: 'TestStat' histo not found\n"); return -1; } // Test how many workers got everything successfully Int_t nw = (Int_t) stat->GetBinContent(1); PutPoint(); if (TMath::Abs(stat->GetBinContent(2) - nw) > .1) { printf("\n >>> Test failure: histo 'h1' not correctly received on all workers (%.0f/%d)\n", stat->GetBinContent(2), nw); return -1; } if (TMath::Abs(stat->GetBinContent(3) - nw) > .1) { printf("\n >>> Test failure: histo 'h2' not correctly received on all workers (%.0f/%d)\n", stat->GetBinContent(3), nw); return -1; } if (TMath::Abs(stat->GetBinContent(4) - nw) > .1) { printf("\n >>> Test failure: test input object not correctly received on all workers (%.0f/%d)\n", stat->GetBinContent(4), nw); return -1; } // Fill times PT_GetLastTimes(tt); // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_PackageArguments(void *, RunTimes &tt) { // Testing passing arguments to packages // Checking arguments if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } PutPoint(); // Passing a 'const char *': upload packtest1 const char *pack1 = "packtest1"; PutPoint(); gProof->UploadPackage(gPack1); // Check the result TList *packs = gProof->GetListOfPackages(); if (!packs || !packs->FindObject(pack1)) { printf("\n >>> Test failure: could not upload '%s'!\n", gPack1.Data()); return -1; } // Enable the package now passing a 'const char *' argument TString arg("ProofTest.ConstChar"); if (gProof->EnablePackage(pack1, arg) != 0) { printf("\n >>> Test failure: could not enable '%s' with argument: '%s'!\n", gPack1.Data(), arg.Data()); return -1; } // Type of test gProof->SetParameter("ProofTests_Type", "PackTest1"); // Define the number of events Long64_t nevt = 1; // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Variable to check gProof->SetParameter("testenv", arg.Data()); // Process PutPoint(); { SwitchProgressGuard spg; gProof->Process(gTestsSel.Data(), nevt); } // Some cleanup gProof->ClearPackage(pack1); gProof->DeleteParameters("ProofTests_Type"); gProof->DeleteParameters("testenv"); // Make sure the query result is there PutPoint(); TQueryResult *qr = 0; if (!(qr = gProof->GetQueryResult())) { printf("\n >>> Test failure: query result not found\n"); return -1; } // Make sure the output list is there PutPoint(); if (!(gProof->GetOutputList())) { printf("\n >>> Test failure: output list not found\n"); return -1; } // Check the 'histo's PutPoint(); TH1I *stat = dynamic_cast(gProof->GetOutputList()->FindObject("TestStat")); if (!stat) { printf("\n >>> Test failure: 'TestStat' histo not found\n"); return -1; } // Test how many workers got everything successfully Int_t nw = (Int_t) stat->GetBinContent(1); PutPoint(); if (TMath::Abs(stat->GetBinContent(2) - nw) > .1) { printf("\n >>> Test failure: var '%s' not correctly set on all workers (%.0f/%d)\n", arg.Data(), stat->GetBinContent(2), nw); return -1; } // Passing a 'TList *': upload packtest2 const char *pack2 = "packtest2"; PutPoint(); gProof->UploadPackage(gPack2); // Check the result packs = gProof->GetListOfPackages(); if (!packs || !packs->FindObject(pack2)) { printf("\n >>> Test failure: could not upload '%s'!\n", gPack2.Data()); return -1; } // Create the argument list TList *argls = new TList; argls->Add(new TNamed("ProofTest.ArgOne", "2.")); argls->Add(new TNamed("ProofTest.ArgTwo", "3.")); argls->Add(new TNamed("ProofTest.ArgThree", "4.")); // Enable the package now passing the 'TList *' argument if (gProof->EnablePackage(pack2, argls) != 0) { printf("\n >>> Test failure: could not enable '%s' with argument: '%s'!\n", gPack2.Data(), arg.Data()); return -1; } // Type of test gProof->SetParameter("ProofTests_Type", "PackTest2"); // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Variable to check TString envs("ProofTest.ArgOne,ProofTest.ArgTwo,ProofTest.ArgThree"); gProof->SetParameter("testenv", envs.Data()); // Process PutPoint(); { SwitchProgressGuard spg; gProof->Process(gTestsSel.Data(), nevt); } // Some cleanup gProof->ClearPackage(pack2); gProof->DeleteParameters("ProofTests_Type"); gProof->DeleteParameters("testenv"); // Make sure the query result is there PutPoint(); qr = 0; if (!(qr = gProof->GetQueryResult())) { printf("\n >>> Test failure: query result not found\n"); return -1; } // Make sure the output list is there PutPoint(); if (!(gProof->GetOutputList())) { printf("\n >>> Test failure: output list not found\n"); return -1; } // Check the 'histo's PutPoint(); if (!(stat = dynamic_cast(gProof->GetOutputList()->FindObject("TestStat")))) { printf("\n >>> Test failure: 'TestStat' histo not found\n"); return -1; } // Test how many workers got everything successfully nw = (Int_t) stat->GetBinContent(1); PutPoint(); if (TMath::Abs(stat->GetBinContent(2) - nw) > .1) { printf("\n >>> Test failure: var 'ProofTest.ArgOne' not correctly set on all workers (%.0f/%d)\n", stat->GetBinContent(2), nw); return -1; } if (TMath::Abs(stat->GetBinContent(3) - nw) > .1) { printf("\n >>> Test failure: var 'ProofTest.ArgTwo' not correctly set on all workers (%.0f/%d)\n", stat->GetBinContent(3), nw); return -1; } if (TMath::Abs(stat->GetBinContent(4) - nw) > .1) { printf("\n >>> Test failure: var 'ProofTest.ArgThree' not correctly set on all workers (%.0f/%d)\n", stat->GetBinContent(4), nw); return -1; } // Fill times PT_GetLastTimes(tt); // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_H1SimpleAsync(void *arg, RunTimes &tt) { // Test run for the H1 and Simple analysis in asynchronous mode // Checking arguments if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } // Not yet supported for PROOF-Lite if (gProof->IsLite()) { return 1; } // Not supported in dynamic mode if (gDynamicStartup) { return 1; } PutPoint(); // Set/unset the parallel unzip flag AssertParallelUnzip(); // Are we asked to change the packetizer strategy? if (arg) { PT_Packetizer_t *strategy = (PT_Packetizer_t *)arg; if (strcmp(strategy->fName, "TPacketizerAdaptive")) { gProof->SetParameter("PROOF_Packetizer", strategy->fName); } else { if (strategy->fType != 1) gProof->SetParameter("PROOF_PacketizerStrategy", strategy->fType); } } // Create the file collection PutPoint(); TFileCollection *fc = new TFileCollection("h42"); // Assert the files, if needed if (!gh1ok) { if (PT_H1AssertFiles(gh1src.Data()) != 0) { printf("\n >>> Test failure: could not assert the H1 files\n"); return -1; } } Int_t i = 0; for (i = 0; i < 4; i++) { fc->Add(new TFileInfo(TString::Format("%s%c%s", gh1src.Data(), gh1sep, gh1file[i]))); } // Clear associated memory cache if (gClearCache && PT_H1ReleaseCache(gh1src.Data()) != 0) { gProof->SetPrintProgress(0); printf("\n >>> Test failure: could not clear memory cache for the H1 files\n"); return -1; } // Clear the list of query results PutPoint(); if (gProof->GetQueryResults()) { gProof->GetQueryResults()->Clear(); gProof->Remove("cleanupdir"); } // Define the number of events and histos Long64_t nevt = 1000000; Int_t nhist = 16; // Submit the processing requests PutPoint(); { SwitchProgressGuard spg; gProof->Process(fc, gH1Sel.Data(), "ASYN"); // The number of histograms is added as parameter in the input list gProof->SetParameter("ProofSimple_NHist", (Long_t)nhist); gProof->Process(gSimpleSel.Data(), nevt, "ASYN"); // Wait a bit as a function of previous runnings Double_t dtw = 10; if (gH1Cnt > 0 && gSimpleTime > 0) { dtw = gH1Time / gH1Cnt + gSimpleTime / gSimpleCnt + 1; if (dtw < 10) dtw = 10; } Int_t tw = (Int_t) (5 * dtw); gTimedOut = kFALSE; TTimeOutTimer t(tw*1000); // Wait for the processing while (!gProof->IsIdle() && !gTimedOut) gSystem->InnerLoop(); } PutPoint(); // Restore settings gProof->DeleteParameters("PROOF_Packetizer"); gProof->DeleteParameters("PROOF_PacketizerStrategy"); // Retrieve the list of available query results TList *ql = gProof->GetQueryResults(); if (ql && ql->GetSize() > 0) { ql->Print(); } TString ref; TIter nxq(ql, kIterBackward); Int_t nd = 2; TQueryResult *qr = 0; while ((qr = (TQueryResult *)nxq()) && nd > 0) { ref.Form("%s:%s", qr->GetTitle(), qr->GetName()); gProof->Retrieve(ref); qr = gProof->GetQueryResult(ref); if (qr && qr->GetSelecImp()) { if (!strcmp(qr->GetSelecImp()->GetTitle(), "h1analysis")) { PutPoint(); if (PT_CheckH1(qr) != 0) return -1; nd--; } else if (!strcmp(qr->GetSelecImp()->GetTitle(), "ProofSimple")) { PutPoint(); if (PT_CheckSimple(qr, nevt, nhist) != 0) return -1; nd--; } else { printf("\n >>> Test failure: query with unexpected selector '%s'\n", qr->GetSelecImp()->GetTitle()); return -1; } } else { printf("\n >>> Test failure: query undefined (%p) or with empty selector macro ('%s')\n", qr, ref.Data()); return -1; } } // The runtimes PT_GetLastProofTimes(tt); // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_AdminFunc(void *, RunTimes &tt) { // Test run for the admin functionality // Checking arguments if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } // Not yet supported for PROOF-Lite if (gProof->IsLite()) { return 1; } PutPoint(); // Attach to the manager TProofMgr *mgr = gProof->GetManager(); if (!mgr) { printf("\n >>> Test failure: no PROOF manager found\n"); return -1; } PutPoint(); // Directory for this test TString testDir(TString::Format("%s/stressProof-Admin", gtutdir.Data())); if (gSystem->AccessPathName(testDir)) { // Create the directory if (gSystem->MakeDirectory(testDir)) { printf("\n >>> Test failure: cannot create %s\n", testDir.Data()); return -1; } } // Create a small test file TMacro testMacro; testMacro.AddLine("// Test macro"); testMacro.AddLine("#include \"TSystem.h\""); testMacro.AddLine("void testMacro(Int_t opt = 1)"); testMacro.AddLine("{"); testMacro.AddLine(" if (opt == 1) {"); testMacro.AddLine(" Printf(\"Pid: \", gSystem->GetPid());"); testMacro.AddLine(" }"); testMacro.AddLine("}"); // Save the file in the temporary area TString testFile(TString::Format("%s/testMacro.C", testDir.Data())); if (!gSystem->AccessPathName(testFile)) { // The file exists: remove it first if (gSystem->Unlink(testFile)) { printf("\n >>> Test failure: cannot unlink %s\n", testFile.Data()); return -1; } } testMacro.SaveSource(testFile); FileStat_t stloc; if (gSystem->GetPathInfo(testFile, stloc) != 0) { // The file was not created printf("\n >>> Test failure: file %s was not created\n", testFile.Data()); return -1; } // Reference checksum TMD5 *testMacroMd5 = testMacro.Checksum(); if (!testMacroMd5) { // MD5 sum not calculated printf("\n >>> Test failure: could not calculate the md5 sum of the test macro\n"); return -1; } PutPoint(); // Send the file to the sandbox if (mgr->PutFile(testFile, "~/", "force") != 0) { // The file was not sent over correctly printf("\n >>> Test failure: problems sending file to master sandbox\n"); return -1; } PutPoint(); // Retrieve the file TString testFile1(TString::Format("%s/testMacro.cxx", testDir.Data())); if (mgr->GetFile("~/testMacro.C", testFile1, "force") != 0) { // The file was not retrieved correctly printf("\n >>> Test failure: problems retrieving file from the master sandbox\n"); return -1; } PutPoint(); // Test 'ls' gSystem->RedirectOutput(0, 0, &gRH); TString testLs(TString::Format("%s/testLs.log", testDir.Data())); gSystem->RedirectOutput(testLs, "w", &gRHAdmin); mgr->Ls("~/testMacro.C"); gSystem->RedirectOutput(0, 0, &gRHAdmin); gSystem->RedirectOutput(glogfile, "a", &gRH); TMacro macroLs(testLs); TString testLsLine = TString::Format("%s/testMacro.C", gsandbox.Data()); // The first part of maybe sligthly different #if defined(R__MACOSX) if (testLsLine.Index(".proof") != kNPOS) testLsLine.Remove(0, testLsLine.Index(".proof")); #else if (testLsLine.Index(".proof-tutorial") != kNPOS) testLsLine.Remove(0, testLsLine.Index(".proof-tutorial")); #endif if (!macroLs.GetLineWith(testLsLine)) { printf("\n >>> Test failure: Ls: output not consistent (line: '%s')\n", testLsLine.Data()); printf(" >>> Log file: '%s'\n", testLs.Data()); printf("+++ BOF +++\n"); macroLs.Print(); printf("+++ EOF +++\n"); return -1; } PutPoint(); // Test 'more' gSystem->RedirectOutput(0, 0, &gRH); TString testMore(TString::Format("%s/testMore.log", testDir.Data())); gSystem->RedirectOutput(testMore, "w", &gRHAdmin); mgr->More("~/testMacro.C"); gSystem->RedirectOutput(0, 0, &gRHAdmin); gSystem->RedirectOutput(glogfile, "a", &gRH); TMacro macroMore(testMore); if (macroMore.GetListOfLines()->GetSize() < 2) { printf("\n >>> Test failure: More output not too short: %d lines\n", macroMore.GetListOfLines()->GetSize()); return -1; } TObjString *os = (TObjString *) macroMore.GetListOfLines()->First(); while (!os->GetString().BeginsWith("// Test macro")) { macroMore.GetListOfLines()->Remove(macroMore.GetListOfLines()->First()); os = (TObjString *) macroMore.GetListOfLines()->First(); } TMD5 *testMoreMd5 = macroMore.Checksum(); if (!testMoreMd5) { // MD5 sum not calculated printf("\n >>> Test failure: could not calculate the md5 sum of the 'more' result\n"); return -1; } if (strcmp(testMacroMd5->AsString(), testMoreMd5->AsString())) { printf("\n >>> Test failure: More: result not consistent with reference: {%s, %s}\n", testMacroMd5->AsString(), testMoreMd5->AsString()); return -1; } PutPoint(); // Test 'stat' FileStat_t strem; if (mgr->Stat("~/testMacro.C", strem) != 0) { // Stat failure printf("\n >>> Test failure: could not stat remotely the test file\n"); return -1; } if (strem.fSize != stloc.fSize) { // Stat failure printf("\n >>> Test failure: stat sizes inconsistent: %lld vs %lld (bytes)\n", strem.fSize, stloc.fSize); return -1; } PutPoint(); // Test 'cp' and 'md5sum; if (mgr->Cp("http://root.cern.ch/files/h1/dstarmb.root", "~/") != 0) { // Cp failure printf("\n >>> Test failure: could not retrieve remotely dstarmb.root from the Root Web server\n"); return -1; } TString sum; if (mgr->Md5sum("~/dstarmb.root", sum) != 0) { // MD5 printf("\n >>> Test failure: calculating the md5sum of dstarmb.root\n"); return -1; } if (sum != "0a60055370e16d954f90fb50c2d1a801") { // MD5 wrong printf("\n >>> Test failure: wrong value for md5sum of dstarmb.root: %s\n", sum.Data()); return -1; } PutPoint(); // Clean up sums SafeDelete(testMoreMd5); SafeDelete(testMacroMd5); // Fill times PT_GetLastTimes(tt); // Done PutPoint(); return 0; } //_____________________________________________________________________________ Int_t PT_EventRange(void *arg, RunTimes &tt) { // Test processing of sub-samples (entries-from-first) from files with the // 'event' structures // Checking arguments PutPoint(); if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } // Set/unset the parallel unzip flag AssertParallelUnzip(); // Are we asked to change the packetizer strategy? const char *pack = "TPacketizerAdaptive"; if (arg) { PT_Packetizer_t *strategy = (PT_Packetizer_t *)arg; if (strcmp(strategy->fName, "TPacketizerAdaptive")) { gProof->SetParameter("PROOF_Packetizer", strategy->fName); pack = strategy->fName; } else { if (strategy->fType != 1) gProof->SetParameter("PROOF_PacketizerStrategy", strategy->fType); } } // Test first with a chain PutPoint(); TChain *chain = new TChain("EventTree"); // Assert the files, if needed if (!geventok) { if (PT_EventAssertFiles(geventsrc.Data(), geventnf) != 0) { gProof->SetPrintProgress(0); printf("\n >>> Test failure: could not assert the event files\n"); return -1; } } Int_t i = 0; for (i = 0; i < geventnf; i++) { chain->AddFile(TString::Format("%s/event_%d.root", geventsrc.Data(), i+1)); } // Clear associated memory cache if (gClearCache && PT_EventReleaseCache(geventsrc.Data(), geventnf) != 0) { gProof->SetPrintProgress(0); printf("\n >>> Test failure: could not clear memory cache for the event files\n"); return -1; } // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Load special class for event ranges checks if (gProof->Load(TString::Format("%s,%s", gProcFileElem.Data(), gEmptyInclude.Data())) != 0) { gProof->SetPrintProgress(0); printf("\n >>> Test failure: could not load auxilliary files %s and %s\n", gProcFileElem.Data(), gEmptyInclude.Data()); return -1; } // Add some parameters for later checking in Terminate Int_t ifst = gEventFst / gEventSiz + 1; Long64_t efst = gEventFst - (ifst - 1) * gEventSiz; TString ffst = TString::Format("%s/event_%d.root?fst=%lld", geventsrc.Data(), ifst, efst); gProof->SetParameter("Range_First_File", ffst.Data()); Int_t ilst = (gEventFst + gEventNum) / gEventSiz + 1; Long64_t elst = (gEventFst + gEventNum) - (ilst - 1) * gEventSiz - 1; TString flst = TString::Format("%s/event_%d.root?lst=%lld", geventsrc.Data(), ilst, elst); gProof->SetParameter("Range_Last_File", flst.Data()); gProof->SetParameter("Range_Num_Files", (Int_t) (ilst - ifst + 1)); // Process PutPoint(); chain->SetProof(); PutPoint(); { SwitchProgressGuard spg; gTimer.Start(); chain->Process(gEventProcSel.Data(), "", gEventNum, gEventFst); gTimer.Stop(); } gProof->RemoveChain(chain); // Count gEventCnt++; gEventTime += gTimer.RealTime(); // Check the result Int_t rcch = PT_CheckEvent(gProof->GetQueryResult(), pack); // We are done if not dataset test possible if (gSkipDataSetTest) { // Restore settings gProof->DeleteParameters("PROOF_Packetizer"); gProof->DeleteParameters("PROOF_PacketizerStrategy"); return rcch; } // Create the dataset TFileCollection *fc = new TFileCollection("dsevent", "", ""); for (i = 0; i < geventnf; i++) { fc->Add(new TFileInfo(TString::Format("%s/event_%d.root", geventsrc.Data(), i+1))); } // Register the dataset PutPoint(); gProof->RegisterDataSet("dsevent", fc); // Check the result if (!gProof->ExistsDataSet("dsevent")) { printf("\n >>> Test failure: could not register 'dsevent'\n"); return -1; } // Verify the dataset PutPoint(); if (gProof->VerifyDataSet("dsevent") < 0) { printf("\n >>> Test failure: could not verify 'dsevent'!\n"); return -1; } // Clear associated memory cache if (gClearCache && PT_EventReleaseCache(geventsrc.Data(), geventnf) != 0) { gProof->SetPrintProgress(0); printf("\n >>> Test failure: could not clear memory cache for the event files\n"); return -1; } // Process PutPoint(); { SwitchProgressGuard spg; gTimer.Start(); gProof->Process("dsevent", gEventProcSel.Data(), "", gEventNum, gEventFst); gTimer.Stop(); } gProof->RemoveDataSet("dsevent"); // Restore settings gProof->DeleteParameters("PROOF_Packetizer"); gProof->DeleteParameters("PROOF_PacketizerStrategy"); // Count gEventCnt++; gEventTime += gTimer.RealTime(); // The runtimes PT_GetLastProofTimes(tt); // Check the results PutPoint(); return PT_CheckEvent(gProof->GetQueryResult(), pack); } //_____________________________________________________________________________ Int_t PT_POFNtuple(void *opts, RunTimes &tt) { // Test TProofOutputFile technology to create a ntuple, with or without // submergers // Checking arguments PutPoint(); if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } PT_Option_t *ptopt = (PT_Option_t *) opts; // Setup submergers if required if (ptopt && ptopt->fTwo > 0) { gProof->SetParameter("PROOF_UseMergers", 0); } // Output file TString fout("/ProofNtuple.root"); gProof->AddInput(new TNamed("PROOF_OUTPUTFILE", fout.Data())); // We use the 'NtpRndm' for a fixed values of randoms; we need to send over the file gProof->SetInputDataFile(gNtpRndm); // Set the related parameter gProof->SetParameter("PROOF_USE_NTP_RNDM","yes"); // Define the number of events and histos Long64_t nevt = 1000; // We do not plot the ntuple (we are in batch mode) gProof->SetParameter("PROOF_NTUPLE_DONT_PLOT", "yes"); // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Process PutPoint(); { SwitchProgressGuard spg; gTimer.Start(); gProof->Process(gNtupleSel.Data(), nevt); gTimer.Stop(); } // Remove any setting related to submergers gProof->DeleteParameters("PROOF_UseMergers"); gProof->DeleteParameters("PROOF_NTUPLE_DONT_PLOT"); gProof->DeleteParameters("PROOF_USE_NTP_RNDM"); gProof->SetInputDataFile(0); // The runtimes PT_GetLastProofTimes(tt); // Check the results PutPoint(); return PT_CheckNtuple(gProof->GetQueryResult(), nevt); } //_____________________________________________________________________________ Int_t PT_POFDataset(void *, RunTimes &tt) { // Test TProofOutputFile technology to create a dataset // Checking arguments PutPoint(); if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } const char *dsname = "testNtuple"; // Clean-up any existing dataset with that name if (gProof->ExistsDataSet(dsname)) gProof->RemoveDataSet(dsname); // Ask for registration of the dataset (the default is the the TFileCollection is return // without registration; the name of the TFileCollection is the name of the dataset gProof->SetParameter("SimpleNtuple.root", dsname); // We use the 'NtpRndm' for a fixed values of randoms; we need to send over the file gProof->SetInputDataFile(gNtpRndm); // Set the related parameter gProof->SetParameter("PROOF_USE_NTP_RNDM","yes"); // Define the number of events and histos Long64_t nevt = 1000000; // We do not plot the ntuple (we are in batch mode) gProof->SetParameter("PROOF_NTUPLE_DONT_PLOT", "yes"); // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Process PutPoint(); { SwitchProgressGuard spg; gTimer.Start(); gProof->Process(gNtupleSel.Data(), nevt); gTimer.Stop(); } // Remove any setting related to submergers gProof->DeleteParameters("PROOF_NTUPLE_DONT_PLOT"); gProof->DeleteParameters("SimpleNtuple.root"); gProof->DeleteParameters("PROOF_USE_NTP_RNDM"); gProof->SetInputDataFile(0); // The runtimes PT_GetLastProofTimes(tt); // Check the results PutPoint(); return PT_CheckDataset(gProof->GetQueryResult(), nevt); } //_____________________________________________________________________________ Int_t PT_MultiTrees(void *, RunTimes &tt) { // Test processing of multiple trees in the same files // Checking arguments PutPoint(); if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } const char *dsname = "testNtuple"; // There must be a dataset 'testNtuple' already registered and validated if (!gProof->ExistsDataSet(dsname)) { printf("\n >>> Test failure: dataset '%s' does not exist\n", dsname); return -1; } // Get the associated TFileCollection TFileCollection *fc = gProof->GetDataSet(dsname); if (!fc) { printf("\n >>> Test failure: unable to get TFileCollection for dataset '%s'\n", dsname); return -1; } // Now create a TDSet out of the TFileCollection TDSet *dset = new TDSet("testntps", "ntuple", "/", "TTree"); TChain *ch1 = new TChain("ntuple"); TChain *ch2 = new TChain("ntuple2"); TIter nxf(fc->GetList()); TFileInfo *fi = 0; while ((fi = (TFileInfo *) nxf())) { dset->Add(fi->GetCurrentUrl()->GetUrl()); ch1->Add(fi->GetCurrentUrl()->GetUrl()); ch2->Add(fi->GetCurrentUrl()->GetUrl()); } // Check the ntuple content by filling some histos TH1F *h1s[2] = {0}; h1s[0] = new TH1F("h1_1", "3*px+2 with px**2+py**2>1", 50, -15., 15.); h1s[1] = new TH1F("h1_2", "vx**2+vy**2 with abs(vz)<.1", 50, 0., 10.); Int_t rch1s = 0; TString emsg; const char *type[3] = { "dsname", "TDSet", "TChain" }; for (Int_t j = 0; j < 3; j++) { PutPoint(); if (j == 0) { // Fill the first histo from the first ntuple gProof->SetDataSetTreeName(dsname, "ntuple"); { SwitchProgressGuard spg; gProof->DrawSelect(dsname, "3*px+2>>h1_1", "px*px+py*py>1"); } // Fill the second histo from the second ntuple gProof->SetDataSetTreeName(dsname, "ntuple2"); { SwitchProgressGuard spg; gProof->DrawSelect(dsname, "vx*vx+vy*vy>>h1_2", "vz>-0.1&&vz<0.1"); } } else if (j == 1) { // Fill the first histo from the first ntuple { SwitchProgressGuard spg; gProof->DrawSelect(dset, "3*px+2>>h1_1", "px*px+py*py>1"); } // Fill the second histo from the second ntuple dset->SetObjName("ntuple2"); { SwitchProgressGuard spg; gProof->DrawSelect(dset, "vx*vx+vy*vy>>h1_2", "vz>-0.1&&vz<0.1"); } } else { // Fill the first histo from the first ntuple { SwitchProgressGuard spg; ch1->Draw("3*px+2>>h1_1", "px*px+py*py>1"); } // Fill the second histo from the second ntuple { SwitchProgressGuard spg; ch2->Draw("vx*vx+vy*vy>>h1_2", "vz>-0.1&&vz<0.1"); } } rch1s = 0; // Check the histogram entries and mean values Int_t hent[2] = { 607700, 96100}; Double_t hmea[2] = { 2.022, 1.859}; for (Int_t i = 0; i < 2; i++) { if ((Int_t)(h1s[i]->GetEntries()) != hent[i]) { emsg.Form("%s: '%s' histo: wrong number of entries (%d: expected %d)", type[j], h1s[i]->GetName(), (Int_t)(h1s[i]->GetEntries()), hent[i]); rch1s = -1; break; } if (TMath::Abs((h1s[i]->GetMean() - hmea[i]) / hmea[i]) > 0.001) { emsg.Form("%s: '%s' histo: wrong mean (%f: expected %f)", type[j], h1s[i]->GetName(), h1s[i]->GetMean(), hmea[i]); rch1s = -1; break; } } } // Cleanup for (Int_t i = 0; i < 2; i++) delete h1s[i]; // Check the result if (rch1s != 0) { printf("\n >>> Test failure: %s\n", emsg.Data()); return -1; } // Clean-up gProof->RemoveDataSet(dsname); // The runtimes PT_GetLastProofTimes(tt); // Check the results PutPoint(); return rch1s; } //_____________________________________________________________________________ Int_t PT_Friends(void *sf, RunTimes &tt) { // Test processing of TTree friends in PROOF // Checking arguments PutPoint(); if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } // Not supported in dynamic mode if (gDynamicStartup) { return 1; } PutPoint(); // Separate or same file ? Bool_t sameFile = (sf) ? kTRUE : kFALSE; // File generation: we use TPacketizerFile in here to create two files per node TList *wrks = gProof->GetListOfSlaveInfos(); if (!wrks) { printf("\n >>> Test failure: could not get the list of information about the workers\n"); return -1; } // Create the map TString fntree; TMap *files = new TMap; files->SetName("PROOF_FilesToProcess"); TIter nxwi(wrks); TSlaveInfo *wi = 0; while ((wi = (TSlaveInfo *) nxwi())) { fntree.Form("tree_%s.root", wi->GetOrdinal()); THashList *wrklist = (THashList *) files->GetValue(wi->GetName()); if (!wrklist) { wrklist = new THashList; wrklist->SetName(wi->GetName()); files->Add(new TObjString(wi->GetName()), wrklist); } wrklist->Add(new TObjString(fntree)); } Int_t nwrk = wrks->GetSize(); // Generate the files gProof->AddInput(files); if (sameFile) { Printf("runProof: friend tree stored in the same file as the main tree"); gProof->SetParameter("ProofAux_Action", "GenerateTreesSameFile"); } else { gProof->SetParameter("ProofAux_Action", "GenerateTrees"); } // File generation: define the number of events per worker Long64_t nevt = 1000; gProof->SetParameter("ProofAux_NEvents", (Long64_t)nevt); // Special Packetizer gProof->SetParameter("PROOF_Packetizer", "TPacketizerFile"); // Now process gProof->Process(gAuxSel.Data(), 1); // Remove the packetizer specifications gProof->DeleteParameters("PROOF_Packetizer"); // Check that we got some output if (!gProof->GetOutputList()) { printf("\n >>> Test failure: output list not found!\n"); return -1; } // Create the TDSet objects TDSet *dset = new TDSet("Tmain", "Tmain"); TDSet *dsetf = new TDSet("Tfrnd", "Tfrnd"); // Fill them with the information found in the output list Bool_t foundMain = kFALSE, foundFriend = kFALSE; TIter nxo(gProof->GetOutputList()); TObject *o = 0; TObjString *os = 0; while ((o = nxo())) { TList *l = dynamic_cast (o); if (l && !strncmp(l->GetName(), "MainList-", 9)) { foundMain = kTRUE; TIter nxf(l); while ((os = (TObjString *) nxf())) dset->Add(os->GetName()); } } nxo.Reset(); while ((o = nxo())) { TList *l = dynamic_cast (o); if (l && !strncmp(l->GetName(), "FriendList-", 11)) { foundFriend = kTRUE; TIter nxf(l); while ((os = (TObjString *) nxf())) dsetf->Add(os->GetName()); } } // If we did not found the main or the friend meta info we fail if (!foundMain || !foundFriend) { printf("\n >>> Test failure: 'main' or 'friend' meta info missing!\n"); return -1; } // Connect the two datasets for processing dset->AddFriend(dsetf, "friend"); // We do not plot the ntuple (we are in batch mode) gProof->SetParameter("PROOF_DONT_PLOT", "yes"); // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Process PutPoint(); { SwitchProgressGuard spg; gTimer.Start(); dset->Process(gFriendsSel.Data()); gTimer.Stop(); } // Remove any setting gProof->DeleteParameters("PROOF_DONT_PLOT"); gProof->GetInputList()->Remove(files); files->SetOwner(kTRUE); SafeDelete(files); // Clear the files created by this run gProof->ClearData(TProof::kUnregistered | TProof::kForceClear); // The runtimes PT_GetLastProofTimes(tt); // Check the results PutPoint(); return PT_CheckFriends(gProof->GetQueryResult(), nevt * nwrk); } //_____________________________________________________________________________ Int_t PT_SimpleByObj(void *submergers, RunTimes &tt) { // Test run for the ProofSimple analysis (see tutorials) passing the // selector by object // Checking arguments PutPoint(); if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } // Setup submergers if required if (submergers) { gProof->SetParameter("PROOF_UseMergers", 0); } // Define the number of events and histos Long64_t nevt = 1000000; Int_t nhist = 16; // The number of histograms is set inside the selector object; make sure // that it is not passed in the input list gProof->DeleteParameters("ProofSimple_NHist"); // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Define TSelector object. We use reflection to avoid including the header, // so being able to change the tutorial directory TString emsg; gProof->Load(gSimpleSel); TSelector *sel = TSelector::GetSelector(gSimpleSel); if (sel) { TClass *cl = sel->IsA(); if (cl) { TDataMember *dm = cl->GetDataMember("fNhist"); if (dm) { TMethodCall *setter = dm->SetterMethod(cl); if (setter) { setter->Execute(sel, TString::Format("%d", nhist).Data()); } else { emsg = "no SetterMethod for fNhist: check version of ProofSimple"; } } else { emsg = "fNhist not found"; } } else { emsg = "IsA() failed"; } } else { emsg = "GetSelector failed"; } if (!emsg.IsNull()) { printf("\n >>> Test failure: initializing ProofSimple selector: %s\n", emsg.Data()); return -1; } // Process PutPoint(); { SwitchProgressGuard spg; gTimer.Start(); gProof->Process(sel, nevt); gTimer.Stop(); } // Count gSimpleCnt++; gSimpleTime += gTimer.RealTime(); // Remove any setting related to submergers gProof->DeleteParameters("PROOF_UseMergers"); // The runtimes PT_GetLastProofTimes(tt); // Check the results PutPoint(); return PT_CheckSimple(gProof->GetQueryResult(), nevt, nhist); } //_____________________________________________________________________________ Int_t PT_H1ChainByObj(void *, RunTimes &tt) { // Test run for the H1 analysis as a chain reading the data from HTTP and // passing the selector by object // Checking arguments if (!gProof) { printf("\n >>> Test failure: no PROOF session found\n"); return -1; } // Not yet supported for PROOF-Lite if (gSkipDataSetTest) { return 1; } PutPoint(); // Set/unset the parallel unzip flag AssertParallelUnzip(); // Create the chain PutPoint(); TChain *chain = new TChain("h42"); // Assert the files, if needed if (!gh1ok) { if (PT_H1AssertFiles(gh1src.Data()) != 0) { gProof->SetPrintProgress(0); printf("\n >>> Test failure: could not assert the H1 files\n"); return -1; } } Int_t i = 0; for (i = 0; i < 4; i++) { chain->Add(TString::Format("%s%c%s", gh1src.Data(), gh1sep, gh1file[i])); } // Clear associated memory cache if (gClearCache && PT_H1ReleaseCache(gh1src.Data()) != 0) { gProof->SetPrintProgress(0); printf("\n >>> Test failure: could not clear memory cache for the H1 files\n"); return -1; } // Clear the list of query results if (gProof->GetQueryResults()) gProof->GetQueryResults()->Clear(); // Load TSelector gProof->Load(gH1Sel); TSelector *sel = TSelector::GetSelector(gH1Sel); // Process PutPoint(); chain->SetProof(); PutPoint(); { SwitchProgressGuard spg; gTimer.Start(); chain->Process(sel); gTimer.Stop(); } gProof->RemoveChain(chain); // Count gH1Cnt++; gH1Time += gTimer.RealTime(); // The runtimes PT_GetLastProofTimes(tt); // Check the results PutPoint(); return PT_CheckH1(gProof->GetQueryResult()); }