try finally in ant - ant

In my ant script, which runs the end-to-end integration tests, I first start a process, then do some other stuff, then run the tests, and then I need to make sure I kill the process. However, I need to make sure I kill the process even if something fails (so I need an equivalent to try finally). What is the recommended way of doing it?

You could use Trycatch task from Antcontrib
<trycatch property="error.message">
<try>
<echo message="Run integration test..."/>
<echo message="Start process"/>
<antcall target="launchTests"/>
</try>
<catch>
<echo message="Integration test failed"/>
</catch>
<finally>
<echo message="Kill the process"/>
<exec executable="kill -9 ..."/>
</finally>
</trycatch>

Related

what's meaning of Ant exec Result:128

my ant was stoped when execute "<exec excultable="c:\myExe.exe"/>",the result code is just "<message priority="error"><![CDATA[Result: 128]]></message>".I don't know what's meaning of that.
I've tried to search some info like: error code 128---no such exe file,but I havn't.
some one could help me to explain what's the meaning?
Thanks
Oh sorry.
More info:
<macrodef name="gtest-layer-macro">
<attribute name="execfile"/>
<attribute name="layerpath" default=""/>
<attribute name="outputDir" default="${basedir}/${reports}/gtest"/>
<attribute name="reportfile" default="#{outputDir}/gtest_report.xml"/>
<sequential>
<check-layer-path layerpath="#{layerpath}"/>
<if>
<and>
<length string="#{execfile}" when="gt" length="0" trim="true"/>
<available file="#{execfile}"/>
</and>
<then>
<var name="##report.dir##" unset="true"/>
<dirname property="##report.dir##" file="#{reportfile}"/>
<mkdir dir="${##report.dir##}"/>
<exec executable="#{execfile}">
<arg value="--gtest_output="xml:#{reportfile}""/>
</exec>
</then>
</if>
</sequential>
</macrodef>
When I run the <exec>, there’s "error Result:128".
The “#{execfile}” is a gtest.exe file(a exe file to test a module),it could run correctly when I double-click it,it could print the unit test result in the console;Run in the CMD with “--gtest_output="xml:#{reportfile}"” is also could print the unit test result in the console,and output a unit test report(a .xml file).And I have changed another .exe instead of the “gtest.exe”,it’s right too.
So,I don’t know where I’m wrong.
An [exec] Result:128 is a process that can't be found/doesn't exist. At least this is what I've found out from my Ant target to kill any remaining processes at the end of certain tests. I get that result when the process I want to kill isn't running. My build log output looks like this;
[shutdown.server] exec
[13:45:33][exec] ERROR: The process "firefox.exe" not found.
[13:45:34][exec] Result: 128
So if that result is from the execution of your .exe then I'd check the path to ensure the exe is available.

Is it possible to launch Gradle tasks from Ant?

I am researching replacements for Ant. I've looked at Gant and Gradle.
Is it possible to kick off a Gradle task from Ant? This is possible in Gant with a taskdef.
<taskdef
name = "gant"
classname = "org.codehaus.gant.ant.Gant"
classpathref = "classpath"
/>
<gant />
Is there something similar Gradle? I'm eager to start migrating from Ant to Gradle, but we have a large Ant infrastructure and any Gradle build scripts I create need to be callable from Ant.
Thanks!
Create a macrodef for gradle, call it just like any other task. Here is the setup and an example...
<!-- Gradle path stuff -->
<property environment="env" />
<condition property="gradle.executable" value="${env.GRADLE_HOME}/bin/gradle.bat" else="${env.GRADLE_HOME}/bin/gradle">
<os family="windows" />
</condition>
<!-- Macro def, gives us an ant 'gradle' task-->
<macrodef name="gradle">
<attribute name="task" />
<sequential>
<exec executable="${gradle.executable}" dir="." failonerror="true">
<arg value="#{task}" />
</exec>
</sequential>
</macrodef>
Example of using the macro def
<!-- Example, call grade with new macro -->
<target name="example">
<gradle task="build" />
</target>
Instead of switching build technology, why not use a combination of ivy and groovy to extend the capabilities of your existing ant builds?
An example is the following posting:
Parse HTML using with an Ant Script
BTW I'm a big fan of Gradle, however, like you I have to live with and support a large ANT legacy :-)
Actually I want to do the same thing and where implemented by calling a sh file and then the sh was calling the gradle but it was too much around the bush and finally the following code made it to work cool..
Hope this will help you..
<property environment="env" />
<property name="gradle.wrapper.executable" location="${env.GRADLE_HOME}/bin/gradle" />
<target name="dependencies-report" description="Creates a text file report of the depdency tree">
<exec executable="${gradle.wrapper.executable}" dir=".">
<arg value="dependencyReport" />
</exec>
</target>
Gradle doesn't offer an Ant task to run a Gradle build from Ant. What you could do is to invoke a Gradle command (like gradle build) from Ant.
In terms of Ant integration, Gradle offers two features: Importing Ant builds, and reusing Ant tasks.
Gradle is very different from Gant. Gradle is an entire new build system; Gant is a thin layer above Ant.

Deploy a app in weblogic only if it is not already present in it using ant wldeploy task

how can i deploy a app in weblogic only if it is not present in it using wldeploy ant task
when i run ant testapp it deploys fresh everytime over existing app as far as i could see in console messages (ie in sysout).
i call this ant target as dependency in some other target, and i want this to run only if app is not already present in weblogic server (to be more efficient)
<target name="testapp" depends="init-wls">
<wldeploy action="deploy" verbose="true" debug="true"
name="testapp" failonerror="false"
...
source="testapp.war"/>
</target>
an interesting question. I'm not sure if wldeploy can do what you want. One approach that might work would be to use the wlconfig ant task. You could use it to get the ApplicationRuntimeMBeans and then query their ApplicationName attributes (again, with wlconfig task) to see if the application is deployed. Not super straightforward but at least you would avoid the application redeployment.
This is just a quick idea off the top of my head so not sure if it is feasible in practice, sorry.... :)
--edit: tried it out, something like this should work, the assumption here is that if we can find the MBean then it is already deployed which should be a valid assumption since these beans live under AppDeployments:
<project name="test" default="deploy">
<property name="domainName" value="ejbTestDomain"/>
<property name="serverName" value="AdminServer"/>
<property name="appName" value="ejbWebEAR"/>
<target name="findApp">
<wlconfig url="t3://localhost:7001" username="weblogic" password="password_for_weblogic">
<query pattern="${domainName}:ServerRuntime=${serverName},Name=${appName},*,Type=ApplicationRuntime" property="app.is.deployed"/>
</wlconfig>
</target>
<target name="deploy" unless="app.is.deployed" depends="findApp">
<echo message="Deploying..."/>
<!-- deploy using wldeploy task -->
</target>
</project>

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>

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