source: scripts/doug/execution.py @ de5eecc

Revision de5eecc, 8.2 KB checked in by Oleg Batrashev <ogbash@…>, 2 years ago (diff)

Test script: always add prof.00 to tar.

  • Property mode set to 100644
Line 
1import subprocess
2import re
3import copy
4from StringIO import StringIO
5import os
6
7import doug
8from doug.config import DOUGConfigParser, ControlFile
9
10from scripts import ScriptException
11
12import logging
13LOG = logging.getLogger('doug')
14
15_defaultConfig = None
16def getDefaultConfig():
17    global _defaultConfig
18    if _defaultConfig is None:
19        _defaultConfig = DOUGConfigParser(name="DOUG default config")
20        _defaultConfig.addConfigContents(doug.execution_conf_tmpl)
21    return _defaultConfig
22
23def getDefaultControlFile(basedir):
24    cf = ControlFile(contents=doug.DOUG_ctl_tmpl, basedir=basedir)
25    cf.name = '<doug.DOUG_ctl_tmpl>'
26    return cf
27
28class DOUGExecution:
29
30    def __init__(self, config, dougControls=None):
31        self.workdir = os.path.abspath(config.get('doug', 'workdir'))
32        self.config = DOUGConfigParser(name='DOUG execution', basedir=self.workdir)
33        # default config
34        self.config.addConfig(getDefaultConfig())
35        self.config.addControlFile(getDefaultControlFile(self.workdir))
36       
37        # copy controls from control file
38        if dougControls is not None:
39            self.config.addControlFile(dougControls)
40        # copy config
41        self.config.addConfig(config)
42
43        # output or other files, exception grabs it on exit
44        self.files = []
45
46        # how many test results are using this test, files are deleted only after last free() call
47        self._inUse = 0
48
49    def setUp(self):
50        LOG.debug("Preparing testing environment")
51        self.workdir = self.workdir
52        if os.path.isdir(self.workdir):
53            self.workdirExisted = True
54        else:
55            self.workdirExisted = False
56            os.mkdir(self.workdir)
57            LOG.debug("Working directory %s created" % self.workdir)
58        self.preserveOutput = self.config.getboolean("doug", "preserveOutput")
59        try:
60            # create control file
61            self.testctrlfname = os.path.abspath(os.path.join(self.workdir, 'DOUG-exec.ctl'))
62            controlFile = self.config.getControlFile(self.testctrlfname)
63            controlFile.save(self.testctrlfname)
64            self.files.append((self.testctrlfname, "Control file"))
65
66            # run mpiboot
67            mpibootname = self.config.get("doug", "mpiboot")
68            outfilename = self.config.get("doug", "mpiboot-outfilename")
69            errfilename = self.config.get("doug", "mpiboot-errfilename")
70
71            if mpibootname:
72                LOG.debug("Setting up mpi")
73                mpiboot = subprocess.Popen("%s > %s 2> %s" % (mpibootname, outfilename, errfilename), shell=True)
74                res = mpiboot.wait()
75                if res:
76                    raise ScriptException("Error running %s (%d)"
77                                          "inspect output files (%s, %s) for error description."
78                                          % (mpibootname, res, outfilename, errfilename))
79        except:
80            self._clean()
81            raise
82       
83           
84    def tearDown(self):
85        try:
86            mpihaltname = self.config.get("doug", "mpihalt")
87            if mpihaltname:
88                outfilename = self.config.get("doug", "mpihalt-outfilename")
89                errfilename = self.config.get("doug", "mpihalt-errfilename")         
90                LOG.debug("Shutting down mpi")
91                mpihalt = subprocess.Popen("%s > %s 2> %s" % (mpihaltname, outfilename, errfilename), shell=True)
92                import time
93                time.sleep(4) # lamhalt <=7.1.1 does not wait until whole universe is shut down
94                res = mpihalt.wait()
95                if res:
96                    LOG.warn("Error running %s (%d)"
97                         "inspect output files (%s, %s) for error description."
98                         % (mpihaltname, res, outfilename, errfilename))
99        except Exception, e:
100            LOG.warn("Exception running mpihalt: %s" % e)
101
102    def _clean(self):
103        if not self.preserveOutput and not self.workdirExisted:
104            os.system('rm -rf %s' % self.workdir)
105            LOG.debug("Temporary directory %s deleted" % self.workdir)
106
107    def acquire(self):
108        self._inUse += 1
109
110    def free(self):
111        self._inUse -= 1
112        if self._inUse == 0:
113            self._clean()
114
115    def run(self):
116        return self.runDOUG()
117
118    def runDOUG(self):
119        LOG.debug("Running DOUG")
120        nproc = self.config.getint('doug', 'nproc')
121        solver = self.config.getint('doug-controls', 'solver')
122        levels = self.config.getint('doug-controls', 'levels')
123        method = self.config.getint('doug-controls', 'method')
124        LOG.info("solver=%d, method=%d, levels=%d, nproc=%d" % (solver, method, levels, nproc))
125        mpirun = self.config.get("doug", "mpirun")
126        main = self.config.getpath("doug", "executable")
127        errfname = self.config.getpath("doug", "errfilename")
128        outfname = self.config.getpath("doug", "outfilename")
129        solutionfname = self.config.getpath('doug-controls', 'solution_file')
130
131        curdir = os.getcwd()
132
133        self.result = result = DOUGConfigParser(self.config.defaults(), basedir=self.workdir)
134        result.add_section('doug-result')
135        try:
136            LOG.debug("Changing directory to %s" % self.workdir)
137            os.chdir(self.workdir)
138            outf = open(outfname, "w")
139            errf = open(errfname, "w")
140            try:
141                args = [mpirun, "-np", "%d"%nproc, main, "-f", self.testctrlfname, "-p"]
142                LOG.debug("Running %s" % " ".join(args))
143                doug = subprocess.Popen(args, stdout=outf, stderr=errf)
144                   
145                import time
146                maxtime = self.config.getint('doug', 'max-time')
147                for i in xrange(maxtime): # ~1 minute
148                    time.sleep(1)
149                    doug.poll()
150                    if doug.returncode != None:
151                        break
152                else:
153                    LOG.info("Terminating DOUG")
154                    doug.terminate()
155                    doug.wait()
156                   
157                value = doug.returncode
158                LOG.debug("Finished %s with code %d" % (mpirun, value))
159                self.files.append((outfname, "%s standard output" % mpirun))
160                self.files.append((errfname, "%s standard error" % mpirun))
161                result.setpath('doug-result', 'returnvalue', str(value))
162                result.setpath('doug-result', 'outputfile', outfname)
163                result.setpath('doug-result', 'errorfile', errfname)
164               
165                if value != 0:
166                    se = ScriptException("Error occured while running doug (value=%d), "
167                                             "inspect output files (%s, %s) for error description." %
168                                             (value, outfname, errfname))
169                    raise se
170
171                if solutionfname and os.path.isfile(solutionfname):
172                    result.setpath('doug-result', 'solutionfile', solutionfname)
173                if solutionfname and os.path.isfile('aggr1.txt'):
174                    result.setpath('doug-result', 'fineaggrsfile', 'aggr1.txt')
175                    #self.files.append(("aggr1.txt", "Fine aggregates"))
176                if solutionfname and os.path.isfile('aggr2.txt'):
177                    result.setpath('doug-result', 'coarseaggrsfile', 'aggr2.txt')
178                    #self.files.append(("aggr2.txt", "Coarse aggregates"))
179                   
180                files = os.listdir(self.workdir)
181                files = filter(lambda name: name.startswith('prof.00'), files)
182                if files:
183                    result.setpath('doug-result', 'profilefile', files[0])
184                    self.files.append((os.path.join(self.workdir, files[0]), "Profile info"))
185               
186                # compare answers
187               
188            finally:
189                outf.close()
190                errf.close()
191                LOG.debug("Changing directory to %s" % curdir)
192                os.chdir(curdir)
193        except ScriptException, e:
194            for fn in self.files:
195                e.addFile(*fn)
196            raise
197
198        return result
199
200    def __str__(self):
201        return "%s: solver=%d, method=%d, processors=%d" % \
202               (self.testname, self.solver, self.method, self.nproc)
Note: See TracBrowser for help on using the repository browser.