How to put condition in exec in a build.xml file? - ant

How to put a condition in exec in a build.xml file invoked from Hudson?
I need to use arg only if something happened (I send some parameters) and I need an if task or a condition for can solve the problem.

The Ant Contrib library has an if task which looks like:
<if>
<my condition goes here>
<then>
</then>
</if>
In raw Ant, you use the condition task which looks like:
<condition property="condition.to.set">
<my condition goes here>
</condition>
and then a conditional target:
<target name="mine" if="condition.to.set">
I prefer Ant Contrib as it is easier to read.

Related

What is the env value in if condition of ant script

Can someone tell from where the build script is taking $env variable value?. Dont find anything in the ant build script.
<if>
<or>
<equals arg1="${env}" arg2="test"/>
<equals arg1="${env}" arg2="dev"/>
</or>
<then>
Probably the script is designed to run with additional properties. From the command line for example, like:
ant -Denv=test

Tags between <echo> and </echo> in ant

I have an Ant script like this:
<target name="create_report_file">
<echo file="${testResultsDir}/test_report.xml">
<testsuite name="${platformTask}">
</testsuite>
</echo>
</target>
What do the tags between <echo> and </echo> mean? Will Ant run them or output? Or both?
file is an echo parameter. It's the file to write the message to.
testsuite is possibly a JUnit task.
The Ant target runs the test suite and outputs the results to the test_report.xml file.
Does your Ant script work? What about if it attempts to execute the create_report_file target?
Usually, echo tasks simply echo the contents to either the console or to a file if the file parameter is specified.
However, as written, it makes <testsuite> is a sub-entity of the <echo/> task, and it's not. In fact, there's no documented sub-entities in the <echo/> task. In fact, <echo> doesn't even take <condition/> sub-entity tasks like <fail/> would.
This is why I'm asking whether or not your build file is even working.
It appears they might want to log the testsuite being executed. There are two ways to do this to make this work:
Change all < and > to character entities:
<target name="create_report_file">
<echo file="${testResultsDir}/test_report.xml">
<testsuite name="${platformTask}">
</testsuite>
</echo>
</target>
Use <echoxml> instead of <echo>:
<target name="create_report_file">
<echoxml file="${testResultsDir}/test_report.xml">
<testsuite name="${platformTask}">
</testsuite>
</echoxml>
</target>
Another possibility
It is possible that you're using some Ant plugin that has a <testsuite> task. I don't know what this would be. The <testsuite> task isn't part of JUnit or TestNG. However, if there is an Ant plugin being used that defines a <testsuite> task, it might redefine the <echo> task which it's at it. Does your build script have a <taskdef> in it? If so, what's the class reference?
It could be that the user defines their own <testsuite> macro in your build script. However, that wouldn't redefine the <echo> task and it still wouldn't work.

How can I apply a timeout to an Ant task?

Without writing a custom Ant task, is there a way to use a timeout on a regular ant target?
To give some background info: we are using the 'delete' task to remove the contents of a given directory.
Sometimes this directory is massive, with lots of generated folders and files.
We wanted to have that task timeout after, say, 5 minutes.
You might use the parallel task, which has a timeout, with a parallel degree of one:
<target name="timed_del">
<parallel threadCount="1" timeout="300000">
<sequential>
... your tasks here ...
</sequential>
</parallel>
</target>
You can also use the limit task.
<target name="my-target">
<limit seconds="2" failonerror="true">
<sshexec ... />
</limit>
</target>

Ant for other ant's

I have several projects, most of them has "test" target, which run tests and store results in property 'test.faulire'.
All projects located in same directory:
big_project / someproject1
big_project / someproject1 / build.xml
big_project / someproject2
big_project / someproject2 / build.xml
So, in root of 'big_project' i want to create one build.xml for:
Running test on all projects
If all test ok, run "deploy" task on each project. It'll be very well
if I could pass some deployment
parameters to each project.
How would you realize this scenario ?
You might have a look at the for task in ant-contrib. With it you could iterate over all directories like that:
<for param="dir">
<path>
<dirset dir="." includes="*"/>
</path>
<sequential>
<ant dir="${dir}" antfile="${dir}/build.xml" target="aTarget" />
</sequential>
</for>
Have a look at the Ant manual page on the 'subant' task. The page contains examples on how to use the task the way you want to.

How do I pass an argument to an Ant task?

I'm not very good with Ant, but we're using it as a build tool. Right now, we can run "ant test" and it'll run through all the unit tests.
However, I'd love to be able to do something like ant test some_module and have it accept some_module as a parameter, and only test that.
I haven't been able to find how to pass command line args to Ant - any ideas?
One solution might be as follows. (I have a project that does this.)
Have a separate target similar to test with a fileset that restricts the test to one class only. Then pass the name of that class using -D at the ant command line:
ant -Dtest.module=MyClassUnderTest single_test
In the build.xml (highly reduced):
<target name="single_test" depends="compile" description="Run one unit test">
<junit>
<batchtest>
<fileset dir="${test.dir}" includes="**/${test.module}.class" />
</batchtest>
</junit>
</target>
You can also define a property with an optional default value that can be replaced via command line, e.g.
<target name="test">
<property name="moduleName" value="default-module" />
<echo message="Testing Module: ${moduleName}"/>
....
</target>
and run it as:
ant test -DmoduleName=ModuleX
What about using some conditional in your test target and the specifying -Dcondition=true?
<target name="test" depends="_test, _test_if_true>
...
</target>
<target name="_test_if_true" if="condition">
...
</target>
<target name="_test" unless="condition">
...
</target>
Adapted a bit from the ant faq.
You can define a property on commandline when invoking ant:
ant -Dtest.module=mymodulename
Then you can use it as any other ant property:
...
<fileset dir="${test.dir}" includes="**/${test.module}.class" />
...
Have a look at Ant's manual.
I tried the solutions posted here for the very same original question. Yes just use ant -D<arg_name>. THe -D is a "keyword" I guess. I'm no ant expert and have not read the manuals in detail. Then inside the ant XML files can be accessed like: ${arg_name}
For instance you can have an argument name like: arg.myarg, so in XML ${arg.myarg}.
Ant really doesn't have parameters_ for the build file. I can think of a few ways to do this:
Use a special target to specify the tests. You can use the <for/> task from AntContrib to allow you to specify multiple tests. You'll need to download the Ant-Contrib jar file. I recommend placing it inside your project under the `${basedir}/antlib/antcontrib" directory. That way, when others checkout your project, they get the needed Ant-Contrib jar file.
<property name="antlib.dir" value="${basedir}/antlib"/>
<property name="antcontrib.dir" value="${antlib}/antcontrib"/>
<!-- Set up the ant contrib tasks for your use -->
<taskdef resource="net/sf/antcontrib/antlib.xml">
<classpath>
<fileset dir="${antcontrib.dir}"/>
</classpath>
</taskdef>
<target name="select-test"
description="Select the tests to run"
depends="test-compile"
if="junit-tests">
<for parameter="module"
list="${junit-tests}"
delimiter=" ">
<sequential>
<junit
fork="true"
...>
<batchtest todir="$target/unit-tests">
<fileset dir="${test.destdir}">
<include name="**/#{module}.class"/>
</fileset>
</junit>
</sequential>
</for>
</target>
You cab now run multiple tests like this:
$ ant -D"test-one test-two test-three" select-test
You could try this to access one target at a time. Add these lines to your build.xml file :
<project name="whatever" default="default">
<input message="Please select module:" addproperty="mod" />
<target name="default" depends="${mod}/>
...
</project>
This allows you to enter the module you want to execute and execute that itself instead of running the whole build.xml
You might need to make a few more changes to your build.xml for this to work perfectly.
For the arguments , there is Facility called property. You need to set the property. As in ANT plain arguments is taken as target name.
Lest say you have two modules in your project ModuleX and ModuleY where ModuleX has 2 testcases to run and ModuleY with 10 testcases.
You could do something like this :
ant runTestsOnModule -Dtestmodule="ModuleX"
OR to test all modules by calling
ant tests
<target name="runTestsOnModule">
<antCall target="testcase${testmodule}"/>
</target>'
<! -- run single module -->
<target name="runTestsOnModule">
<antCall target="testcase${testmodule}"/>
</target>
<!--run all tests-->
<target name="tests">
<antcall target="testcaseModuleX">
<antcall target="testCaseModuleY">
</target>
<target name="testcaseModuleX">
..run junit task to call 2 testcase
</target>
<target name="testcaseModuleY">
....run junit task to call 10 testcase
</target>

Resources