How to find path to executable in Ant - mysql

In my Ant build file I want to test whether the mysql command is found on the environment path. This should be system independent.
What I did until now was the following:
<trycatch property="mysql.error">
<try>
<echo message="Testing mysql..." />
<exec executable="mysql" outputproperty="null" append="true" />
<echo message="MySQL executable found in path." />
<property name="mysql.command" value="mysql"/>
</try>
<catch>
<echo message="MySQL executable not found in path, trying to locate default folder." />
<if>
<istrue value="${isWindows}"/>
<then>
<antcallback target="search-file-windows" return="search.result">
<param name="search.target" value="mysql.exe"/>
</antcallback>
<property name="mysql.command" value="${search.result}"/>
</then>
<else>
<property name="mysql.command" value="/usr/local/mysql/bin/mysql"/>
</else>
</if>
<echo message="MySQL executable found at location: ${mysql.command}." />
<trycatch property="mysql.error">
<try>
<echo message="Possible path found, testing again..." />
<exec executable="${mysql.command}" outputproperty="null" append="true" />
<echo message="MySQL executable found at location: ${mysql.command}." />
</try>
<catch>
<fail message="Unable to locate MySQL executable. Please add your local MySQL installation to the PATH environment variable."/>
</catch>
</trycatch>
</catch>
</trycatch>
So I just execute the mysql command and if that fails, I will run a batch file which does some magic to efficiently search for mysql. However the check fails if there is any error in calling mysql, even if it is found in the path. On my Windows machine this happens, because just starting mysql gives the following error: ERROR 1045 (28000): Access denied for user 'ODBC'#'localhost'
This error is fixable of course, but I am really looking for a generic solution. Now the PATH variable contains "C:\Program Files\MySQL\MySQL Server 5.6\bin" so the solutions in this question will not work: Check if executable command exists using ant
Any ideas?

available can do the trick for you, you "only" need to deal with the differences between Windows and Unix-likes.
Something like this
<!-- load environment variables into properties -->
<property environment="env"/>
<!-- On Windows the Environment-Variable is not all uppercase -->
<path id="combined-PATH">
<pathelement path="${env.PATH}"/>
<pathelement path="${env.Path}"/>
</path>
<!-- toString() -->
<property name="PATH" refid="combined-PATH"/>
<condition property="mysql.found">
<or>
<available file="mysql.exe" filepath="${PATH}"/>
<available file="mysql" filepath="${PATH}"/>
</or>
</condition>
will set the property mysql.found if and only if mysql is on the PATH.

The following Ant script uses the third-party Ant-Contrib library's <for> task:
<project name="ant-first-match-on-path" default="run">
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<target name="run">
<property name="executable-name" value="mysql"/>
<condition property="executable-filename"
value="${executable-name}.exe"
else="${executable-name}"
>
<os family="windows"/>
</condition>
<property environment="env" />
<for param="dir">
<path>
<pathelement path="${env.PATH}"/>
<pathelement path="${env.Path}"/>
</path>
<sequential>
<if>
<not>
<isset property="first-match"/>
</not>
<then>
<local name="executable-absolute-path"/>
<property
name="executable-absolute-path"
location="#{dir}/${executable-filename}"
/>
<available
file="${executable-absolute-path}"
property="first-match"
value="${executable-absolute-path}"
/>
</then>
</if>
</sequential>
</for>
<condition property="echo-message"
value="First [${executable-filename}] found at [${first-match}]."
else="[${executable-filename}] not found on PATH."
>
<isset property="first-match"/>
</condition>
<echo message="${echo-message}"/>
</target>
</project>

Related

How to use junit configuration parameters in an ant script

I have multiple projects and I am currently trying to set some configuration parameters for junit in ant. However I have trouble doing so.
Is there a way to set junit configuration parameters in ant? For example I try to set junit.jupiter.execution.parallel.enabled=true but I am not sure which tag to use.
<project>
<property name="output.dir" value="${basedir}/build"/>
<property name="src.test.dir" value="${basedir}/src/test"/>
<property name="build.classes.dir" value="${output.dir}/classes"/>
<target name="init">
<mkdir dir="${output.dir}"/>
</target>
<path id="junit.platform.libs.classpath">
<fileset dir="${basedir}/src/lib/junit-platform/"/>
</path>
<path id="junit.engine.jupiter.classpath">
<fileset dir="${basedir}/src/lib/jupiter/"/>
</path>
<target name="compile-test" depends="init">
<mkdir dir="${build.classes.dir}"/>
<javac srcdir="${src.test.dir}"
destdir="${build.classes.dir}">
<!-- our tests only need JUnit Jupiter engine
libraries in our compile classpath for the tests -->
<classpath refid="junit.engine.jupiter.classpath"/>
</javac>
</target>
<target name="test" depends="compile-test">
<junitlauncher>
<!-- include the JUnit platform related libraries
required to run the tests -->
<classpath refid="junit.platform.libs.classpath"/>
<!-- include the JUnit Jupiter engine libraries -->
<classpath refid="junit.engine.jupiter.classpath"/>
<classpath>
<!-- the test classes themselves -->
<pathelement location="${build.classes.dir}"/>
</classpath>
<testclasses outputdir="${output.dir}">
<fileset dir="${build.classes.dir}"/>
<listener type="legacy-brief" sendSysOut="true"/>
<listener type="legacy-xml" sendSysErr="true" sendSysOut="true"/>
</testclasses>
</junitlauncher>
</target>
It's been a long long time, but pretty sure you don't do this in ant. Put
junit.jupiter.execution.parallel.enabled=true in src/test/resources/junit-platform.properties and commit it.

Use a different JAVA_HOME when running JUnit through Ant

Currently, I am running Junit from Ant.
My environment variable JAVA_HOME is set to /path-to-jdk6 but I want the JUnit tests to run with /path-to-jdk8.
How do I set that?
This is my Ant target:
<target name="junit" depends="compile">
<junit printsummary="yes"
haltonfailure="no">
<classpath> <path refid="sample-classpath" /> </classpath>
<formatter type="plain" usefile="false" />
<batchtest todir="${junit.report.dir}">
<fileset dir="${build.classes.dir}">
<include name="**/*Test.class" />
</fileset>
</batchtest>
</junit>
</target>
You could wrap your JUnit task in a separate Ant exec task like so:
<macrodef name="exec-junit">
<attribute name="antfile" default="${ant.file}" />
<sequential>
<exec executable="ant">
<env key="JAVACMD" value="/path/to/jvm/1.8/bin/java" />
<arg line='-f "#{antfile}"' />
<arg line="junit" />
</exec>
</sequential>
</macrodef>
This uses the JAVACMD environment variable ...
JAVACMD - full path of the Java executable. Use this to invoke a different JVM than JAVA_HOME/bin/java(.exe).
The above target can then be invoked like so:
<target name="test">
<exec-junit/>
</target>

Empty Ant <junitreport> report for SoapUI testrunner XML results

I am running a SoapUI project using Ant to get a JUnit report.
Here is my build.xml:
<project basedir="." default="testreport" name="APIAutomation">
<target name="SoapUI">
<exec dir="." executable="C:\Program Files (x86)\SmartBear\SoapUI-5.0.0\bin\testrunner.bat">
<arg line="-r -j -a -f 'C:\Users\F3020722\Desktop\Notification\New folder' -sFirstLoginTest 'C:\Users\F3020722\Desktop\Notification\New folder\APIRegression.xml'"></arg>
</exec>
</target>
<target name="testreport" depends="SoapUI">
<junitreport todir="C:\Users\F3020722\Desktop\Notification\New folder\API">
<fileset dir="C:\Users\F3020722\Desktop\Notification\New folder\API">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames"
todir="C:\Users\F3020722\Desktop\Notification\New folder\reports\html">
</report>
</junitreport>
</target>
</project>
I am getting an XML report properly. However, the JUnit report is empty. all contains 0 and successrate is Nan.
Can anyone check the build.xml is correct?
Looks build script seems ok
Avoid spaces in the directory names
Use forward slashes like unix style even on windows
Use property file or properties in build script so that other members do not have it edit the build scripts as paths might change machine to machine.
For now, added properties in the below script, you may externalize to a property file too.
build.xml
<project basedir="." default="testreport" name="APIAutomation">
<property name="test.suite" value="FirstLoginTest"/>
<property name="soapui.project" value="C:/Users/F3020722/Desktop/Notification/New folder/APIRegression.xml"/>
<property name="soapui.home" value="C:/Program Files (x86)/SmartBear/SoapUI-5.0.0"/>
<property name="results.dir" value="C:/Users/F3020722/Desktop/Notification/API/Results"/>
<property name="reports.dir" value="${results.dir}/Reports"/>
<property name="html.dir" value="${reports.dir}/html"/>
<target name="execute.project">
<exec dir="${soapui.home}/bin" executable="testrunner.bat">
<arg line="-raj -f ${results.dir} -s ${test.suite} ${soapui.project}" />
</exec>
</target>
<target name="testreport" depends="execute.project">
<mkdir dir="${reports.dir}"/>
<junitreport todir="${reports.dir}">
<fileset dir="${results.dir}">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${html.dir}" />
</junitreport>
</target>
</project>
You can also find a docker image for soapui and run tests & generate junit style html report as well. Refer soapui repository # hub.docker.com
Note: that build script used docker images is exactly the same as above except the machine path.

Cobertura with Ant Script Junit test case failure

I have got the below build.xml
<?xml version="1.0" encoding="UTF-8"?
<project name="Sample" default="coverage" basedir=".">
<property file="build.properties" />
<path id="cobertura.classpath">
<fileset dir="lib">
<include name="**/*.jar" />
</fileset>
</path>
<taskdef classpathref="cobertura.classpath" resource="tasks.properties"/>
<target name="init">
<mkdir dir="${classes.dir}" />
<mkdir dir="${instrumented.dir}" />
<mkdir dir="${reports.xml.dir}" />
<mkdir dir="${reports.html.dir}" />
<mkdir dir="${coverage.xml.dir}" />
<mkdir dir="${coverage.summaryxml.dir}" />
<mkdir dir="${coverage.html.dir}" />
</target>
<target name="compile" depends="init">
<javac srcdir="${src.dir}" destdir="${classes.dir}" debug="yes" includeantruntime="false">
<classpath refid="cobertura.classpath" />
</javac>
</target>
<target name="instrument" depends="init,compile">
<!--
Remove the coverage data file and any old instrumentation.
-->
<delete file="cobertura.ser" />
<delete dir="${instrumented.dir}" />
<!--
Instrument the application classes, writing the
instrumented classes into ${build.instrumented.dir}.
-->
<cobertura-instrument todir="${instrumented.dir}" datafile="cobertura.ser">
<!--
The following line causes instrument to ignore any
source line containing a reference to log4j, for the
purposes of coverage reporting.
-->
<ignore regex="org.apache.log4j.*" />
<fileset dir="${classes.dir}">
<!--
Instrument all the application classes, but
don't instrument the test classes.
-->
<include name="**/*.class" />
<exclude name="**/*Test.class" />
</fileset>
</cobertura-instrument>
</target>
<target name="test" depends="init,compile">
<echo>${basedir}\cobertura.ser</echo>
<junit fork="yes" dir="test" showoutput="yes" printsummary="yes" reloading="false">
<sysproperty key="net.sourceforge.cobertura.datafile"
file="${basedir}\cobertura.ser" />
<!--
Note the classpath order: instrumented classes are before the
original (uninstrumented) classes. This is important.
-->
<classpath location="${instrumented.dir}" />
<classpath location="${classes.dir}" />
<!--
The instrumented classes reference classes used by the
Cobertura runtime, so Cobertura and its dependencies
must be on your classpath.
-->
<classpath refid="cobertura.classpath" />
<formatter type="xml" />
<test name="${testcase}" todir="${reports.xml.dir}" if="testcase" />
<batchtest todir="${reports.xml.dir}" unless="testcase">
<fileset dir="test">
<include name="**/*Test.java" />
</fileset>
</batchtest>
</junit>
<!-- JUnit Report in HTML -->
<junitreport todir="${reports.xml.dir}">
<fileset dir="${reports.xml.dir}">
<include name="TEST-*.xml" />
</fileset>
<report format="frames" todir="${reports.html.dir}" />
</junitreport>
</target>
<target name="coverage-check">
<cobertura-check branchrate="34" totallinerate="100" />
</target>
<target name="coverage-report">
<!--
Generate an XML file containing the coverage data using
the "srcdir" attribute.
-->
<cobertura-report srcdir="${src.dir}" destdir="${coverage.xml.dir}" format="xml" />
</target>
<target name="summary-coverage-report">
<!--
Generate an summary XML file containing the coverage data using
the "srcdir" attribute.
-->
<cobertura-report srcdir="${src.dir}" destdir="${coverage.summaryxml.dir}" format="summaryXml" />
</target>
<target name="alternate-coverage-report">
<!--
Generate a series of HTML files containing the coverage
data in a user-readable form using nested source filesets.
-->
<cobertura-report destdir="${coverage.html.dir}">
<fileset dir="${src.dir}">
<include name="**/*.java"/>
</fileset>
</cobertura-report>
</target>
<target name="clean" description="Remove all files created by the build/test process.">
<delete dir="${classes.dir}" />
<delete dir="${instrumented.dir}" />
<delete dir="${reports.dir}" />
<delete file="cobertura.log" />
<delete file="cobertura.ser" />
</target>
<target name="coverage" depends="compile,instrument,test,coverage-report,summary-coverage-report,alternate-coverage-report" description="Compile, instrument ourself, run the tests and generate JUnit and coverage reports."/>
</project>
But i am when i run the build, i am getting 0% coverage.
Till instrument target i believe everything looks fine. But when build runs the Test target the tests are failing. Not sure why this is happening. If i run the Tests outside the ant its succeed.
Any suggestions where i can look to troubleshoot this issue?
I get below error when i run the test target
test:
[junit] Running org.jtaddeus.playground.LogicTest
[junit] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.141 sec
[junit] Test org.jtaddeus.playground.LogicTest FAILED
[junit] Running org.jtaddeus.playground.ValidatorTest
[junit] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.14 sec
[junit] Test org.jtaddeus.playground.ValidatorTest FAILED
Finally i found an solution (not answer)
After tracing the Junit report i found its something to do with Junit dependency.
I just removed the Junit-4 Library from the build path and added Junit-4.7.jar to Build path And you know what it worked..
If any one explain me why this happen i would be very thankful.
If i use Junit-4.11.jar again same failure. The Junit error in the report says error message="org/hamcrest/SelfDescribing" type="java.lang.NoClassDefFoundError">java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing

weaving .aj files into existing javac compiled sources

I am trying to use javac to compile a set of java files to .class files and then subsequently use iajc to compile and weave all the aspects. My ant build.xml looks like this.
The compile part:
<target name="compile" depends="init" description="compile the source ">
<!-- Compile the java code from ${src} into ${target} -->
<javac srcdir="${src}" destdir="${target}" debug="true">
<classpath refid="project.class.path" />
</javac>
</target>
The iajc part:
<target name="aspects">
<mkdir dir="dist"/>
<iajc source="1.6" target="${asptarget}">
<inpath>
<pathelement location="${target}"/>
</inpath>
<sourceroots>
<fileset dir="${src}">
<include name="**/*.aj"/>
</fileset>
</sourceroots>
<classpath>
<pathelement location="${aspectj.home}/lib/aspectjrt.jar"/>
</classpath>
</iajc>
</target>
Judging by the error message, I am not getting this correct. The sourceroots are wrong!
How can I compile just the .aj files with aspectj and then binary weave the class files and compiled .aj files? Is that possible without recompiling all the original java sources too?
If you want to use the regular compiler for building .java files and iajc to build .aj files you do this:
<target name="aspects" depends="compile" description="build binary aspects">
<fileset id="ajFileSet" dir="${src}" includes="**/*.aj"/>
<pathconvert pathsep="${line.separator}" property="ajFiles" refid="ajFileSet"/>
<echo file="${src}/aj-files.txt">${ajFiles}</echo>
<iajc source="1.6" target="${asptarget}">
<argfiles>
<pathelement location="${src}/aj-files.txt"/>
</argfiles>
<classpath>
<pathelement path="${target}"/>
<fileset dir="lib" includes="**/*.jar"/>
</classpath>
<classpath>
<pathelement location="${aspectj.home}/lib/aspectjrt.jar"/>
</classpath>
</iajc>
</target>
Works perfectly by building a file containing a list of the .aj files and compiling them. You can then use runtime OR binary weaving to finish the process.