source: branches/testScripts/nightlyBuild.py @ 624

Last change on this file since 624 was 624, checked in by jpfasano, 12 years ago

fixed problem in how cbc and clp's output checked for successful run

  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 11.6 KB
Line 
1#! /usr/bin/env python
2
3import os
4import sys
5import commands
6import smtplib
7import re 
8
9import NBuserConfig
10import NBprojectConfig
11import NBlogMessages
12import NBemail
13
14# TODO:
15#   -After "svn co" then get all 3rd party packages.
16#   -Get some information about the platform and put this in email failure message.
17#   -Implement Kipp's vpath (delete vpath instead of 'make distclean').
18#   Break this file up into multiple files so it is manageable.
19#   Don't do build if 'svn update' doesn't change anything and prior test was OK.
20#     (no need to re-run if nothing has changed since prior run)
21#   Build both trunk and latest stable
22#   Build both optimized and debug (or have a set of config-site scripts to test?)
23#   Check the testing of the success criteria of each projects "make test"
24#   Implement "cbc -miplib" test for successful run.  JohnF sent JP the criteria
25#     to test on in an email dated 10/12/2007 12:01pm
26
27
28#------------------------------------------------------------------------
29# Run command in another process.
30# Return: command's return code, stdout messages, & stderr messages
31#------------------------------------------------------------------------
32def runCommand(cmd) :
33  p=subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
34  p.wait
35  cmdRc=p.returncode
36  cmdStdout=p.stdout.read()
37  cmdStderr=p.stderr.read() 
38
39#------------------------------------------------------------------------
40# Function to Check Return Code from unitTest
41#------------------------------------------------------------------------
42def didTestFail( rc, project, buildStep ) :
43  retVal = 0
44
45  # If the return code is not 0, then failure
46  if rc[0] != 0 :
47    retVal = 1
48
49  # Many tests write a "Success" message.
50  # For test that do this, check for the success message
51  if NBprojectConfig.ALL_TESTS_COMPLETED_SUCCESSFULLY_CMDS.has_key(project) : 
52    if buildStep in NBprojectConfig.ALL_TESTS_COMPLETED_SUCCESSFULLY_CMDS[project] :
53      # Is the success message contained in the output?
54      if rc[1].rfind("All tests completed successfully") == -1 :
55        # Success message not found, assume test failed
56        retVal = 1
57
58  #---------------------------------------------------------------------
59  # Some (project,buildStep) pairs require further checking
60  # to determine if they were successful
61  #---------------------------------------------------------------------
62  # Clp's "./clp -unitTest dirNetlib=_NETLIBDIR_ -netlib"
63  if project=='Clp' and buildStep==NBprojectConfig.UNITTEST_CMD['Clp'] :
64    # Check that last netlib test case ran by looking for message of form
65    # '../../Data/Netlib/woodw took 0.47 seconds using algorithm either'
66    reexp = r"(.|\n)*\.\.(\\|/)\.\.(\\|/)Data(\\|/)Netlib(\\|/)woodw took (\d*\.\d*) seconds using algorithm either(.|\n)*"
67    msgTail = rc[1][-200:]
68    if not re.compile(reexp).match(msgTail,1) :
69      # message not found, assume test failed
70      retVal = 1
71     
72  # Cbc's "make test"
73  elif project=='Cbc' and buildStep=='make test' :
74    # Check that last the last few lines are of the form
75    # 'cbc_clp solved 2 out of 2 and took XX.XX seconds.'
76    reexp=r"(.|\n)*cbc_clp solved 2 out of 2 and took (\d*\.\d*) seconds."
77    msgTail = rc[1][-300:]
78    if not re.compile(reexp).match(msgTail,1) :
79      # message not found, assume test failed
80      retVal = 1
81
82  # Cbc's "./cbc -unitTest dirNetlib=_MIPLIB3DIR_ -miplib"
83  elif project=='Cbc' and buildStep==NBprojectConfig.UNITTEST_CMD['Cbc'] :
84    if rc[0]>=0 and rc[0]<=2 :
85      # return code is between 0 and 2.
86      # Return code between 1 and 44 is the number of test cases that
87      # ended because maxnodes limit reached.  John Forrest says if this
88      # is less than 3, the OK.
89      retVal=0
90    else :
91      retVal=1
92
93  return retVal
94
95#------------------------------------------------------------------------
96# Function for executing svn commands
97#------------------------------------------------------------------------
98def issueSvnCmd(svnCmd,dir,project) :
99  retVal='OK'
100  os.chdir(dir)
101  NBlogMessages.writeMessage('  '+svnCmd)
102  rc=commands.getstatusoutput(svnCmd)
103  if rc[0] != 0 :
104    NBemail.sendCmdMsgs(project,rc[1],svnCmd)
105    retVal='Error'
106  return retVal
107
108#------------------------------------------------------------------------
109#  Main Program Starts Here 
110#------------------------------------------------------------------------
111
112#------------------------------------------------------------------------
113#  If needed create the top level directory
114#------------------------------------------------------------------------
115# rc=commands.getstatusoutput(NBuserConfig.NIGHTLY_BUILD_ROOT_DIR)
116if not os.path.isdir(NBuserConfig.NIGHTLY_BUILD_ROOT_DIR) :
117  os.makedirs(NBuserConfig.NIGHTLY_BUILD_ROOT_DIR)
118os.chdir(NBuserConfig.NIGHTLY_BUILD_ROOT_DIR)
119
120#------------------------------------------------------------------------
121#  Get the data directories if they don't already exist
122#------------------------------------------------------------------------
123dataBaseDir=os.path.join(NBuserConfig.NIGHTLY_BUILD_ROOT_DIR,'Data')
124if not os.path.isdir(dataBaseDir) :
125  os.makedirs(dataBaseDir)
126dataDirs=['Netlib','miplib3']
127for d in dataDirs :
128  dataDir=os.path.join(dataBaseDir,d)
129  if not os.path.isdir(dataDir) :
130    svnCmd='svn checkout https://projects.coin-or.org/svn/Data/releases/1.0.0/'+d+' '+d
131    if issueSvnCmd(svnCmd,dataBaseDir,'Data')!='OK' :
132      sys.exit(1)
133    rc=commands.getstatusoutput('find '+d+' -name \*.gz -print | xargs gzip -d')
134netlibDir=os.path.join(dataBaseDir,'Netlib')
135miplib3Dir=os.path.join(dataBaseDir,'miplib3')
136
137#------------------------------------------------------------------------
138# Loop once for each project
139#------------------------------------------------------------------------
140for p in NBuserConfig.PROJECTS:
141  NBlogMessages.writeMessage( p )
142  rc = [0]
143
144  #---------------------------------------------------------------------
145  # svn checkout or update the project
146  #---------------------------------------------------------------------
147  projectBaseDir=os.path.join(NBuserConfig.NIGHTLY_BUILD_ROOT_DIR,p)
148  projectCheckOutDir=os.path.join(projectBaseDir,'trunk')
149  if not os.path.isdir(projectBaseDir) :
150    os.makedirs(projectBaseDir)
151  if not os.path.isdir(projectCheckOutDir) :
152    svnCmd='svn checkout https://projects.coin-or.org/svn/'+p+'/trunk trunk'
153    if issueSvnCmd(svnCmd,projectBaseDir,p)!='OK' :
154      continue
155  else :
156    svnCmd='svn update'
157    if issueSvnCmd(svnCmd,projectCheckOutDir,p)!='OK' :
158      continue
159
160  #---------------------------------------------------------------------
161  # Should probably run make 'distclean' to do a build from scrath
162  # or delete the VPATH directory when there is one
163  #---------------------------------------------------------------------
164
165
166  #---------------------------------------------------------------------
167  # Run configure part of buid
168  #---------------------------------------------------------------------
169  os.chdir(projectCheckOutDir)
170  configCmd = os.path.join('.','configure -C')
171  NBlogMessages.writeMessage('  '+configCmd)
172  rc=commands.getstatusoutput(configCmd)
173 
174  # Check if configure worked
175  if rc[0] != 0 :
176    error_msg = rc[1] + '\n\n'
177    # Add contents of log file to message
178    logFileName = 'config.log'
179    if os.path.isfile(logFileName) :
180      logFilePtr = open(logFileName,'r')
181      error_msg += "config.log contains: \n" 
182      error_msg += logFilePtr.read()
183      logFilePtr.close()
184    NBemail.sendCmdMsgs(p,error_msg,configCmd)
185    continue
186
187  #---------------------------------------------------------------------
188  # Run make part of buid
189  #---------------------------------------------------------------------
190  NBlogMessages.writeMessage( '  make' )
191  rc=commands.getstatusoutput('make')
192 
193  # Check if make worked
194  if rc[0] != 0 :
195    NBemail.sendCmdMsgs(p,rc[1],'make')
196    continue
197
198  #---------------------------------------------------------------------
199  # Run 'make test' part of buid
200  #---------------------------------------------------------------------
201  NBlogMessages.writeMessage( '  make test' )
202  rc=commands.getstatusoutput('make test')
203 
204  # Check if 'make test' worked
205  if didTestFail(rc,p,"make test") :
206    NBemail.sendCmdMsgs(p,rc[1],"make test")
207    continue
208
209  #---------------------------------------------------------------------
210  # Run unitTest if available and different from 'make test'
211  #---------------------------------------------------------------------
212  if NBprojectConfig.UNITTEST_CMD.has_key(p) :
213    unitTestPath = os.path.join(projectCheckOutDir,NBprojectConfig.UNITTEST_DIR[p])
214    os.chdir(unitTestPath)
215
216    unitTestCmdTemplate=NBprojectConfig.UNITTEST_CMD[p]
217    unitTestCmd=unitTestCmdTemplate.replace('_NETLIBDIR_',netlibDir)
218    unitTestCmd=unitTestCmd.replace('_MIPLIB3DIR_',miplib3Dir)
219
220    NBlogMessages.writeMessage( '  '+unitTestCmd )
221    rc=commands.getstatusoutput(unitTestCmd)
222 
223    if didTestFail(rc,p,unitTestCmdTemplate) :
224      NBemail.sendCmdMsgs(p,rc[1],unitTestCmd)
225      continue
226
227  # For testing purposes only do first successful project
228  #break
229
230
231NBlogMessages.writeMessage( "nightlyBuild.py Finished" )
232
233sys.exit(0)
234
235
236# START KIPP
237#----------------------------------------------------------------------
238# CONFIG FILE PATH:
239#   path to the config file for the build
240#   done. If the directory does not exist, it will be created.
241#   this should have all of the user specific data
242#   it should have values for
243#   NIGHTLY_BUILD_ROOT
244#   NBuserConfig.SMTP_SERVER_NAME
245#   NBuserConfig.SMTP_SERVER_PORT
246#   NBuserConfig.SMTP_SSL_SERVER
247#   NBuserConfig.SMTP_USER_NAME
248#   NBuserConfig.SMTP_PASSWORD_FILENAME = '/home/jp/bin/smtpPwFile'
249#   NBuserConfig.SENDER_EMAIL_ADDR='jpfasano _AT_ verizon _DOT_ net'
250#   NBuserConfig.MY_EMAIL_ADDR='jpfasano _AT_ us _DOT_ ibm _DOT_ com'
251#   
252#----------------------------------------------------------------------
253
254CONFIG_FILE_PATH = '/Users/kmartin/Documents/files/configDir/'
255CONFIG_FILENAME = 'config.txt'
256
257
258# Get configFile data
259
260configFile = os.path.join(os.path.dirname( CONFIG_FILE_PATH),
261                                 os.path.basename(CONFIG_FILENAME ))
262if os.path.isfile(  configFile) :
263  pwFilePtr = open(configFile ,'r')
264  d = pwFilePtr.readlines()
265  # do pwFilePtr.read() to get a string object
266  # we have a list object
267  print d[0]
268  print d[1]
269  # make a dictionary
270  config_dic = {}
271
272  #smtppass  = pwFilePtr.read().strip()
273  pwFilePtr.close()
274else :
275  #NBlogMessages.writeMessage( "Failure reading pwFileName=" + CONFIG_FILENAME )
276  #print cmdMsgs
277  sys.exit( 1)
278sys.exit( 0)
279
280
281
282# START KIPP
283#----------------------------------------------------------------------
284#   path to the config file for the build
285#   get the user dependent variables
286# CONFIG FILE PATH:
287#   it should have values for
288#   NIGHTLY_BUILD_ROOT
289#   NBuserConfig.SMTP_SERVER_NAME
290#   NBuserConfig.SMTP_SERVER_PORT
291#   NBuserConfig.SMTP_SSL_SERVER
292#   NBuserConfig.SMTP_USER_NAME
293#   NBuserConfig.SMTP_PASSWORD_FILENAME
294#   NBuserConfig.SENDER_EMAIL_ADDR
295#   NBuserConfig.MY_EMAIL_ADDR
296#   
297#----------------------------------------------------------------------
298
299CONFIG_FILE_PATH = '/Users/kmartin/Documents/files/configDir/'
300CONFIG_FILENAME = 'config.txt'
301
302
303# Get configFile data
304
305configFile = os.path.join(os.path.dirname( CONFIG_FILE_PATH),
306                                 os.path.basename(CONFIG_FILENAME ))
307if os.path.isfile(  configFile) :
308  pwFilePtr = open(configFile ,'r')
309  d = pwFilePtr.readlines()
310  # do pwFilePtr.read() to get a string object
311  # we have a list object
312  print d[0]
313  print d[1]
314  # make a dictionary
315  config_dic = {}
316
317  #smtppass  = pwFilePtr.read().strip()
318  pwFilePtr.close()
319else :
320  #NBlogMessages.writeMessage( "Failure reading pwFileName=" + CONFIG_FILENAME )
321  #print cmdMsgs
322  sys.exit( 1)
323sys.exit( 0)
324
325# END KIPP
Note: See TracBrowser for help on using the repository browser.