Conditionally load properties files in Ant - ant

My Ant script should download a ZIP file which contains a set-up file to be installed in a database (Oracle or PostgreSQL) and generate dumps. Different dumps are generated depending on the properties data provided in the set up file.
I have 3 properties files:
user.properties : this contains various details provided from Jenkins and apart from that a value: prepare.MTdump.generate=true
nonMT.properties
MT.properties
Is it possible in Ant to load the first properties file user.properties and depending upon the condition (e.g. if prepare.MTdump.generate=true) load MT.properties or if it's false load nonMT.properties?
I have been unable to add an IF condition to load the properties file. I even tried with the unless condition of <target> but have been unable to achieve the requirement.

If you are using ant-contrib, this should work:
<property file="user.properties"/>
<if>
<equals arg1="${prepare.MTdump.generate}" arg2="true"/>
<then>
<property file="MT.properties"/>
</then>
<else>
<property file="nonMT.properties"/>
</else>
</if>
Otherwise, you can just use conditions. Just run the loadProperties target below.
<property file="user.properties"/>
<target name="test.if.use.MT">
<condition property="useMT">
<equals arg1="${prepare.MTdump.generate}" arg2="true"/>
</condition>
<condition property="useNonMT">
<not>
<equals arg1="${prepare.MTdump.generate}" arg2="true"/>
</not>
</condition>
</target>
<target name="loadMTProperties" if="${useMT}" depends="test.if.use.MT">
<property file="MT.properties"/>
</target>
<target name="loadNonMTProperties" if="${useNonMT}" depends="test.if.use.MT">
<property file="nonMT.properties"/>
</target>
<target name="loadProperties" depends="loadMTProperties, loadNonMTProperties"/>

Related

Getting condition doesn't support the nested "then" element in <condition>

I'm new to Ant/Apache. When I tried to use <condition> tag in XML it's throwing an error. condition doesn't support the nested "then" element. Here is my code
<target name="determine-ae-build">
<condition property="ApplicationName">
<equals arg1="${ApplicationName}" arg2="new"/>
<then>
<echo>3.9 Robots Config Copied</echo>
</then>
<else>
<condition property="ApplicationName">
<equals arg1="${ApplicationName}" arg2="old"/>
<then>
<echo>3.8 Robots Config Copied</echo>
</then>
<else>
<echo>3.9 Robots Config Copied</echo>
</else>
</condition>
</else>
</condition>
</target>
I've tried with IF also but since my Ant version is not supporting to do this. Can someone help to resolve this issue. Thanks! in advance
The condition task simply sets a property; it doesn't contain nested build logic. The property that it sets can later be used to control which targets are executed.
While you can use antcontrib's extra if, then, and else tasks to accomplish something like what you showed in your example, I'd recommend sticking to the native Ant approach, which relies on target dependencies and uses separate targets to control build logic:
<project name="build" basedir="." default="build">
<target name="build" depends="copy-3.8,copy-3.9" />
<target name="copy-3.8" depends="determine-ae-build" if="copy.old">
<echo>3.8 Robots Config Copied</echo>
</target>
<target name="copy-3.9" depends="determine-ae-build" unless="copy.old">
<echo>3.9 Robots Config Copied</echo>
</target>
<target name="determine-ae-build">
<condition property="copy.old">
<equals arg1="${ApplicationName}" arg2="old"/>
</condition>
</target>
</project>
With the above script, you would run ant build (possibly with -DApplicationName=old). The build target depends on both copy targets, both of which depend on determine-ae-build. The determine-ae-build target will therefore run first. If ApplicationName is set to "old" (either from a properties file that has been loaded, or from being provided in command line with -DApplicationName=old) then the property copy.old will be set to true. Otherwise it will remain unset.
Then copy-3.8 and copy-3.9 will be called. If copy.old is is true, copy-3.8 will run. Otherwise, it will be skipped. copy-3.9 has no condition so it will run no matter what.
Lastly, the build target will execute because it was the original target called from the command line, but it contains no actual steps so the build will finish.
<target name="prepare-copy" description="copy file based on condition" depends="determine-ae-build, prepare-copy-old, prepare-copy-new, prepare-copy-default">
<sleep seconds="10"/> --To read the results
</target>
<target name="prepare-copy-old" description="copy file based on condition" if="copy.old">
<echo>Old File Copied </echo>
</target>
<target name="prepare-copy-new" description="copy file based on condition" if="copy.new">
<echo>New File Copied</echo>
</target>
<target name="prepare-copy-default" description="copy file based on false condition" if="copy.default">
<echo>Default File Coping</echo>
</target>
<target name="determine-ae-build">
<condition property="copy.old">
<equals arg1="${ApplicationName}" arg2="old"/>
</condition>
<condition property="copy.new">
<equals arg1="${ApplicationName}" arg2="new"/>
</condition>
<condition property="copy.default">
<not>
<or>
<equals arg1="${ApplicationName}" arg2="new"/>
<equals arg1="${ApplicationName}" arg2="old"/>
</or>
</not>
</condition>
</target>
Explanation: Calling way "ant -Dcopy.old = true prepare-copy". Here we are passing to copy old file hence, "Old File Copied" will copied. If you call it like "ant prepare-copy" it'll call "Default File Coping".
Kindly Accept my answer if it is answered your question.Thankyou!

Generating HTML report with Ant 1.9.7 from Jmeter 3.0 file - "Start and end within the same entity" Error

Here is basically the build.xml that Jmeter 3.0 generated itself. When I try to run the tests with 40 000 users within an hour I get the error after 17 minutes - "${path}/build.xml: Fatal error during transformation using ${path}/jmeter-results-detail-report_21.xsl: XML document structures must start and end within the same entity.; SystemID: file:${path}/Test.jtl;"
<?xml version="1.0"?>
<project name="ant-jmeter" default="all">
<property name="testpath" value="${user.dir}"/>
<property name="jmeter.home" value="${basedir}/.."/>
<property name="report.title" value="Load Test Results"/>
<property name="target.report.dir" location="Asjad/apache-jmeter-3.0/extras/report"/>
<property name="test" value="Test"/>
<property name="show-data" value="n"/>
<property name="format" value="2.1"/>
<condition property="style_version" value="">
<equals arg1="${format}" arg2="2.0"/>
</condition>
<condition property="style_version" value="_21">
<equals arg1="${format}" arg2="2.1"/>
</condition>
<condition property="funcMode">
<equals arg1="${show-data}" arg2="y"/>
</condition>
<condition property="funcMode" value="false">
<not>
<equals arg1="${show-data}" arg2="y"/>
</not>
</condition>
<path id="jmeter.classpath">
<fileset dir="${basedir}">
<include name="ant-jmeter*.jar"/>
</fileset>
</path>
<taskdef
name="jmeter"
classpathref="jmeter.classpath"
classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"/>
<target name="all" depends="run,report"/>
<target name="run">
<echo>funcMode = ${funcMode}</echo>
<delete file="${testpath}/${test}.html"/>
<delete file="${testpath}/${test}.jtl"/>
<jmeter
jmeterhome="${jmeter.home}"
testplan ="${testpath}/${test}.jmx"
resultlog="${testpath}/${test}.jtl">
<property name="jmeter.save.saveservice.output_format" value="xml"/>
<property name="jmeter.save.saveservice.assertion_results" value="all"/>
<property name="jmeter.save.saveservice.bytes" value="true"/>
<property name="file_format.testlog" value="${format}"/>
<property name="jmeter.save.saveservice.response_data.on_error" value="${funcMode}"/>
</jmeter>
</target>
<property name="lib.dir" value="${jmeter.home}/lib"/>
<path id="xslt.classpath">
<fileset dir="${lib.dir}" includes="xalan*.jar"/>
<fileset dir="${lib.dir}" includes="serializer*.jar"/>
</path>
<target name="report" depends="xslt-report">
<echo>Report generated at ${report.datestamp}</echo>
</target>
<target name="xslt-report" depends="_message_xalan">
<tstamp><format property="report.datestamp" pattern="yyyy/MM/dd HH:mm"/></tstamp>
<xslt
classpathref="xslt.classpath"
force="true"
in="${testpath}/${test}.jtl"
out="${testpath}/${test}.html"
style="${basedir}/jmeter-results-detail-report_21.xsl">
<param name="showData" expression="${show-data}"/>
<param name="titleReport" expression="${report.title}"/>
<param name="dateReport" expression="${report.datestamp}"/>
</xslt>
</target>
<condition property="xalan.present">
<and>
<available classpathref="xslt.classpath" classname="org.apache.xalan.processor.TransformerFactoryImpl"/>
<available classpathref="xslt.classpath" classname="org.apache.xml.serializer.ExtendedContentHandler"/>
</and>
</condition>
<target name="_message_xalan" unless="xalan.present">
<echo>Cannot find all xalan and/or serialiser jars</echo>
<echo>The XSLT formatting may not work correctly.</echo>
<echo>Check you have xalan and serializer jars in ${lib.dir}</echo>
</target>
</project>
It is a simple test that just makes requests to the webpage.
I am using Ant build 1.9.7 and Jmeter 3.0.
I can think of 2 possible reasons:
Ant might be trying to convert .jtl to HTML when the .jtl is incomplete. In order to work that around:
Add the next line to <jmeter> section:
<property name="jmeter.save.saveservice.autoflush" value="true"/>
Or alternatively put add the following line to user.properties file (lives in JMeter's "bin" folder)
jmeter.save.saveservice.autoflush=true
It will "tell" JMeter to store the results as soon as they arrive.
40 000 users is quite a "heavy" load and JMeter default configuration might not be suitable for this. I believe you need to add at least some Java Heap space. In case of Ant it would be adding the next lines to <jmeter> section:
<jvmarg value="-Xmx8G"/>
Change that 8G reference value to be around 80% of your available physical RAM. See 9 Easy Solutions for a JMeter Load Test “Out of Memory” Failure guide for more recommendations on JMeter tuning for maximum performance
Showing your jmeter.log file (jmeter 3.0 will tell you where it is generated) will help.
But you may be facing this bug if using ANT + XSL to generated report:
https://bz.apache.org/bugzilla/show_bug.cgi?id=59918
See this :
Generating a faulty report when running JMeter 3.0 test with Ant

Check the existence file in ant [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Ant task to check if a file exists?
How can one check if a file exist in a directory, if not use another file in different location. I tried the follow but does not help me with what I want. Could someone help?
<condition property="somefile.available">
<or>
<available file="/home/doc/somefile"/>
<and>
<available file="/usr/local/somefile" />
</and>
</or>
</condition>
Use condition tests to establish if files are present. Then have a target for each true condition
<target name="go" depends="file-checks, do-something-with-first-file, do-something-with-second-file"/>
<target name="file-checks">
<available file="/home/doc/somefile" property="first.file.found"/>
<available file="/usr/local/somefile" property="second.file.found"/>
</target>
<target name="do-something-with-first-file" if="first.file.found">
???
</target>
<target name="do-something-with-second-file" if="second.file.found">
???
</target>
If you don't mind using ant-contrib you can take the procedural approach like this:
<if>
<available file="file1"/>
<then>
<property name="file.exists" value="true"/>
</then>
<else>
<if>
<available file="file2"/>
<then>
<copy file="file2" tofile="file1"/>
<property name="file.exists" value="true"/>
</then>
</if>
</else>
</if>
Otherwise you can probably use a target that is conditional on a property being set to indicate whether the file already exists in the preferred location, like Ant task to run an Ant target only if a file exists? but using unless instead of if.

ant: how to compare contents of two files

I want to compare the contents of two files (say file1.txt,file2.txt) using ANT.
if files content are same then it should set some 'property' to true, if contents are not same then it should set the 'property' as false.
Can anyone suggest me any ANT task that can do this.
Thanks in advance.
You can use something like:
<condition property="property" value="true">
<filesmatch file1="file1"
file2="file2"/>
</condition>
This will set the property only if the files are the same.
You can then check for the property, using
<target name="foo" if="property">
...
</target>
This is available in ant, with no added dependency, see here for other conditions.
I am in the same situation to compare two files and switch into different targets depending on files match or files mismatch...
Heres the code:
<project name="prospector" basedir="../" default="main">
<!-- set global properties for this build -->
<property name="oldVersion" value="/code/temp/project/application/configs/version.ini"></property>
<property name="newVersion" value="/var/www/html/prospector/application/configs/version.ini"></property>
<target name="main" depends="prepare, runWithoutDeployment, startDeployment">
<echo message="version match ${matchingVersions}"></echo>
<echo message="version mismatch ${nonMatchingVersion}"></echo>
</target>
<target name="prepare">
<!-- gets true, if files are matching -->
<condition property="matchingVersions" value="true" else="false">
<filesmatch file1="${oldVersion}" file2="${newVersion}" textfile="true"/>
</condition>
<!-- gets true, if files are mismatching -->
<condition property="nonMatchingVersion" value="true" else="false">
<not>
<filesmatch file1="${oldVersion}" file2="${newVersion}" textfile="true"/>
</not>
</condition>
</target>
<!-- does not get into it.... -->
<target name="startDeployment" if="nonMatchingVersions">
<echo message="Version has changed, update gets started..."></echo>
</target>
<target name="runWithoutDeployment" if="matchingVersions">
<echo message="Version equals, no need for an update..."></echo>
</target>
The properties are correct and change on changing file contents.
the task for nonMatchingVersions never gets started.

Ant check existence for a set of files

In ant, how can i check if a set of files (comma-separated list of paths) exist or not?
For example I need to check if all paths listed in myprop exist and if so i want to set a property pathExist:
<property name="myprop" value="path1,path2,path3"/>
So in the example all of path1 path2 path3 must exist to set pathExist to true, otherwise false.
I discovered that for a single resource I can use the resourceexist task, but i can't figure out how to use that with a comma-separated list of paths.
How can I check the existence for a set of paths? Thanks!
You can use a combination of a filelist, restrict and condition task for this.
In the below example a filelist is created from the property with the comma-separated list of files. Using restrict a list of the files that don't exist is found. This is placed in a property which will be empty if all the files are found.
<property name="myprop" value="path1,path2,path3"/>
<filelist id="my.files" dir="." files="${myprop}" />
<restrict id="missing.files">
<filelist refid="my.files"/>
<not>
<exists/>
</not>
</restrict>
<property name="missing.files" refid="missing.files" />
<condition property="pathExist" value="true" else="false">
<length string="${missing.files}" length="0" />
</condition>
<echo message="Files all found: ${pathExist}" />
You could use something like this to generate a failure message listing the missing files:
<fail message="Missing files: ${missing.files}">
<condition>
<length string="${missing.files}" when="greater" length="0" />
</condition>
</fail>
Bundled conditions are the shortest solution to check for existence of multiple dirs or files :
<condition property="pathExist">
<and>
<available file="/foo/bar" type="dir"/>
<available file="/foo/baz" type="dir"/>
<available file="path/to/foobar.txt"/>
...
</and>
</condition>
To check for a commaseparated list of path use Ant addon Flaka , f.e. :
<project xmlns:fl="antlib:it.haefelinger.flaka">
<!-- when you have a cvs property use split function
to get your list to iterate over -->
<property name="checkpath" value="/foo/bar,/foo/baz,/foo/bazz"/>
<fl:for var="file" in="split('${checkpath}', ',')">
<fl:fail message="#{file} does not exist !!" test="!file.tofile.exists"/>
</fl:for>
</project>
Another possibility is the use of scriptcondition task with a jvm scripting language like groovy,beanshell .. etc.
This can be solved with the set operations of Ant´s resource collections. If you calculate the intersection of the list of required files with the list of existing files it must not differ from the list of required files. This shows how to do it:
<property name="files" value="a.jar,b.jar,c.jar"/>
<target name="missing">
<condition property="missing">
<resourcecount when="ne" count="0">
<difference id="missing">
<intersect>
<filelist id="required" dir="." files="${files}"/>
<fileset id="existing" dir="." includes="*.jar"/>
</intersect>
<filelist refid="required"/>
</difference>
</resourcecount>
</condition>
</target>
<target name="check" depends="missing" if="missing">
<echo message="missing: ${toString:missing}"/>
</target>
The check target reports the list of missing files only if a file is missing.

Resources