/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ // // $Id: Controller.groovy 1070028 2011-02-12 05:22:30Z genspring $ // package gbuild.config.projects.Geronimo_CTS import gbuild.system.library.LibraryManager import gbuild.system.commands.MavenCommand import gbuild.system.commands.ExecCommand import gbuild.system.util.BastardChildReaper import gbuild.system.util.IterationConfigurator import gbuild.system.util.Sorting import gbuild.system.util.ShellExecutor import gbuild.config.projects.Geronimo_CTS.report.ReportGenerator import org.apache.commons.lang.time.StopWatch /** * ??? */ class Controller extends gbuild.system.ProjectController { // // TODO: Need to add a way to provide custom initalization for controllers // so we can easily setup commonly used variables. // // Might simply override init() ? // def getBaseVersion() { def version = params.require('version') def matcher = version =~ /([^-]*)-(.*)/ return matcher[0][1] } def build = { def maven = new MavenCommand(context) switch (baseVersion) { case '1.2': maven.javaVersion = 1.4 break case '2.0': maven.javaVersion = 1.5 break } maven.execute() } // // TODO: May want to collect the harness too, so that report generation can work // until AH supports picking up a specific dependency from a workflow // def collectRuntime = { def sourceDir = new File('.').canonicalFile log.info "Source dir: $sourceDir" def targetDir = new File('target/runtime').canonicalFile log.info "Target dir: $targetDir" separator() // Collect the harness ant.mkdir(dir: targetDir) ant.copy(todir: targetDir, verbose: true) { fileset(dir: sourceDir) { include(name: 'harness.xml') include(name: 'lib/**') include(name: 'tools/**') // Do not include libraries/** setup will still check out the right version } } // Collect the repository ant.mkdir(dir: "$targetDir/repository") // Determine the set of artifacts based on the workflow since this will // differ from version to version :-( switch (baseVersion) { case '1.2': Geronimo12Collector.collect(ant, sourceDir, targetDir) break case '2.0': Geronimo20Collector.collect(ant, sourceDir, targetDir) break } // Collect the project ant.mkdir(dir: "$targetDir/project") ant.copy(todir: "$targetDir/project", verbose: true) { fileset(dir: "$sourceDir/project") { include(name: '*') include(name: 'tck-testsuite/**') // Make sure we don't get any target muck exclude(name: '**/target/**') } } separator() } def showEnv() { def shell = new ShellExecutor() shell << """ echo "Environment:" set """ shell.execute() } def showProcessesAndTemp() { def shell = new ShellExecutor() shell << """ ps -ef | grep anthill | grep -v com.urbancode.anthill3.main | grep -v grep | grep -v \$0 echo "" echo "Tmp files:" ls -lh /tmp | grep -v `basename \$0` """ shell.execute() } def runtests = { showEnv() cleanEnvironment() showProcessesAndTemp() def exec = new ExecCommand(context) exec.executable = 'project/tck-testsuite/runtests' exec.environment['M2_HOME'] = new File('tools/maven').canonicalFile def args = [] args << '--nocolor' // Run in offline mode for the moment until we resolve the maven-jar-plugin issue args << '--offline' // Setup a tmp dir within our workspace def tmpDir = new File('tmp').canonicalFile // Must be canonical tmpDir.mkdirs() args << "-Djava.io.tmpdir=$tmpDir" args << '--web' args << params.require('webcontainer') // // HACK: Handle retry // if (params.retry) { args << '--retry' args << 'fail,error' // Refresh the server installation for sanity args << '--refresh' } if (params.get('javaee5.cts.home') != null) { def javaeeCtsHome = params.get('javaee5.cts.home') args << "-Djavaee5.cts.home=$javaeeCtsHome" } if (params.get('javaee5.ri.home') != null) { def javaeeRiHome = params.get('javaee5.ri.home') args << "-Djavaee5.ri.home=$javaeeRiHome" } if (params.get('javaee6.cts.home') != null) { def javaeeCtsHome = params.get('javaee6.cts.home') args << "-Djavaee6.cts.home=$javaeeCtsHome" } if (params.get('javaee6.ri.home') != null) { def javaeeRiHome = params.get('javaee6.ri.home') args << "-Djavaee6.ri.home=$javaeeRiHome" } if (params.get('javaee.level') != null) { def javaeeLevel = params.get('javaee.level') args << "-Djavaee.level=$javaeeLevel" } def localRepo = params.require('maven.repo.local') args << "-Dmaven.repo.local=$localRepo" if (params.get('options') != null) { args << '-o' args << params.get('options') } if (params.get('refresh').equals("true")) { args << '-Drefresh=true' } if (params.get('jaxrs').equals("true")) { args << '-Djaxrs=true' } if (params.get('interop').equals("true")) { args << '-Dinterop=true' } if (params.get('reverse').equals("true")) { args << '-Dreverse=true' } if (params.get('rmiiiop').equals("true")) { args << '-Drmiiiop=true' } if (params.get('connector').equals("true")) { args << '--connector' } if (params.get('keywords') != null) { def keywords = params.get('keywords') args << "-Dkeywords=$keywords" } // The AHP server secure port conflicts with the geronimo server secure port // args << '-Dorg.apache.geronimo.config.substitution.PortOffset=1000' args << params.require('tests') // Before we execute, save the parameters used to execute runtests def targetDir = new File('target').canonicalFile targetDir.mkdirs() params.store("$targetDir/runtests.properties") def tckDir if (params.get('javaee5.cts.home') != null) { tckDir = params.get('javaee5.cts.home') } if (params.get('javaee6.cts.home') != null) { tckDir = params.get('javaee6.cts.home') } // Execute runtests try { exec.execute(args) } finally { // Save the testsuite ts.jte ant.copy(todir: 'target') { fileset(dir: tckDir) { include(name: 'ts.jte') } } // // HACK: Show what processes and tmp are left around afterwards // showProcessesAndTemp() cleanEnvironment() showProcessesAndTemp() } } def runtestsRetryNonPassing = { // // TODO: May want to pass in a property to trigger retry, perhaps with the max // so the AH UI can be used to optionally enable this feature. // def summaryFile = new File('project/tck-testsuite/target/summary.properties') if (!summaryFile.exists()) { log.warn "Missing runtests summary file: $summaryFile" return } def summaryProps = new Properties() summaryProps.load(summaryFile.newInputStream()) // Only attempt retries if there were non-passing tests if (summaryProps.passed == 'true') { log.info 'No failed tests detected; skipping retry' return } def failureCount = summaryProps.failureCount.toInteger() def errorCount = summaryProps.errorCount.toInteger() def total = failureCount + errorCount // For now only retry if one errors/failures was detected def maxFailures = 1 // Retry failed tests if there are only a few, else something big might be broke if (total > maxFailures) { log.info "Too many test errors/failures to retry: $total (max to retry: $maxFailures)" return } log.info "Some tests ($total) did not pass; attempting to retry" // // HACK: Flag for retry... // params.retry = true // // HACK: Need to handle iterataions and non-iterations... // def iteration = params.require('iteration').toInteger() if (iteration == 0) { runtests() } else { runtestsIteration() } } def runtestsIteration = { params.tests = '%' def cfg = new IterationConfigurator() def javaeeLevel = params.require('javaee.level') def iterationName =params.get('iteration.name') if (javaeeLevel.equals('web')) { if(iterationName==null||iterationName.equals('all')) { cfg.configFile = "project/tck-testsuite/iterations/iterations-web.xml" } else { cfg.configFile = "project/tck-testsuite/iterations/iterations-web-${iterationName}.xml" } } if (javaeeLevel.equals('full')) { if(iterationName==null||iterationName.equals('all')) { cfg.configFile = "project/tck-testsuite/iterations/iterations-full.xml" } else { cfg.configFile = "project/tck-testsuite/iterations/iterations-full-${iterationName}.xml" } } cfg.iteration = params.iteration cfg.applyTo = [ 'tests' ] cfg.apply(params) runtests() } def collectResults = { def tests = params.require('tests') def webcontainer = params.require('webcontainer') def sourceDir = new File('project/tck-testsuite/target').canonicalFile log.info "Source dir: $sourceDir" def targetDir = new File("target/results/$webcontainer").canonicalFile log.info "Target dir: $targetDir" separator() ant.mkdir(dir: targetDir) // // FIXME: Need to handle logs for retries.... // ant.zip(destfile: "$targetDir/runtests-results-${tests}-${webcontainer}.zip") { zipfileset(dir: 'target') { include(name: 'runtests.properties') include(name: 'ts.jte') } zipfileset(dir: "$sourceDir") { include(name: 'logs/**') include(name: 'javatest/**') } // If there are any RI logs, then include them too def dir = new File('target/ri/domains/domain1/logs') if (dir.exists()) { zipfileset(dir: dir, prefix: 'rilogs') { include(name: '**') exclude(name: 'tx/**') } } } separator() } def generateReport = { def webcontainer = params.require('webcontainer') def javaeeLevel = params.require('javaee.level') def iterationName =params.get('iteration.name') def sourceDir = new File("target/results").canonicalFile log.info "Source dir: $sourceDir" assert sourceDir.exists() : sourceDir def targetDir = new File('target/report').canonicalFile log.info "Target dir: $targetDir" // Find all of the result archives def files files = ant.fileScanner { fileset(dir: sourceDir) { include(name: "${webcontainer}/runtests-results-*.zip") } } def archives = [] files.each { file -> archives << file } log.info 'Result archives:' archives = archives.sort() archives.each { file -> log.info " $file" } separator() new ReportGenerator(archives, targetDir, javaeeLevel, iterationName).generate() separator() } def cleanEnvironment = { // This isn't working properly. Comment it out for now. // Nuke any bastard children //new BastardChildReaper().reap() // Still need to make sure that the server isn't left around after the test finishes ant.delete() { fileset(dir: '/tmp') { include(name: 'anthill-cts-props.txt') include(name: 'geronimo*.*') include(name: 'test-*.jar') include(name: 'Axis*.att') include(name: 'axis2*.tmp') include(name: '*wscompile*') include(name: 'accessedFile*tmp') include(name: 'deniedFile*tmp') include(name: 'runtimedepplan*') include(name: 'deniedFile*tmp') include(name: 'fSimpleTabularData*ser') include(name: '*.tmpdir') } } ShellExecutor.execute('pkill -9 -f server.jar') ShellExecutor.execute('pkill -9 -f geronimo-main.jar') ShellExecutor.execute('pkill -9 -f dbprocedures.jar') ShellExecutor.execute('pkill -9 -f admin-cli.jar') } }