Jmeter Xslt Test Report "Fatal Error! Content is not allowed in prolog." - xslt

I have been update my jmeter from 2.9 to 2.13. I usually use ant build and xslt to generate html report. Here is my ant xml script :
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="ballot.xsl"?>
<project default="all">
<!-- Define an environment variable pointing to JMETER folder or change this -->
<property environment="env"/>
<!-- <property name="jmeter-home" location="${env.JMETER_DIR}"/>-->
<property name="jmeter-home" location="C:\apache-jmeter-2.13"/>
<!-- ant-jmeter.jar comes with jmeter, be sure this is the release you have -->
<path id="ant.jmeter.classpath">
<pathelement
location="${jmeter-home}/extras/ant-jmeter-1.1.1.jar" />
</path>
<taskdef
name="jmeter"
classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask"
classpathref="ant.jmeter.classpath" />
<target name="clean">
<delete dir="results2"/>
<delete file="jmeter.log"/>
<mkdir dir="results2/jtl"/>
<mkdir dir="results2/html"/>
</target>
<target name="test" depends="clean">
<jmeter
jmeterhome="${jmeter-home}"
resultlogdir="results2/jtl">
<testplans dir="IAM_jmeter" includes="*.jmx"/>
</jmeter>
</target>
<!-- This is not needed for the plugin, but it produces a nice html report
which can be saved usin hudson's archive artifact feature -->
<target name="report" depends="test">
<xslt
basedir="results2/jtl"
destdir="results2/html"
includes="*.jtl"
style="${jmeter-home}/extras/jmeter-results-detail-report_21.xsl"/>
</target>
<target name="all" depends="test, report"/>
</project>
It worked with jmeter 2.9. But when I update to jmeter 2.13, it genereate an error. Here is the error message :
[xslt] Transforming into C:\Users\Administrator\Downloads\workspace\IAM-JmeterTest-Rest\results2\html
[xslt] Processing C:\Users\Administrator\Downloads\workspace\IAM-JmeterTest-Rest\results2\jtl\IAM_Jmeter.jtl to C:\Users\Administrator\Downloads\workspace\IAM-JmeterTest-Rest\results2\html\IAM_Jmeter.html
[xslt] Loading stylesheet C:\apache-jmeter-2.13\extras\jmeter-results-detail-report_21.xsl
[xslt] C:\Users\Administrator\Downloads\workspace\IAM-JmeterTest-Rest\results2\jtl\IAM_Jmeter.jtl:1:1: Fatal Error! Content is not allowed in prolog.
[xslt] Failed to process null
Any idea why?
Thanks for the attention.

My expectation is that this is due to CSV format of your .jtl file, and for successful XSLT transformation it needs to be XML.
You need to "tell" JMeter to store its results in XML format. To do so add the following line to "test" target:
<property name="jmeter.save.saveservice.output_format" value="xml"/>
So the whole target would look as:
<target name="test" depends="clean">
<jmeter
jmeterhome="${jmeter-home}"
resultlogdir="results2/jtl">
<property name="jmeter.save.saveservice.output_format" value="xml"/>
<testplans dir="IAM_jmeter" includes="*.jmx"/>
</jmeter>
</target>
Another option is adding the following line to user.properties file (lives under /bin folder of your ${jmeter-home}
jmeter.save.saveservice.output_format=xml
See Apache JMeter Properties Customization Guide for more information on JMeter Properties and ways of setting and overriding them.

Related

Copy the value from a property in an Ant propertyfile to another property

I need to copy the value of one property in a propertyfile to a second property, and add that to the propertyfile.
For example, if I have a property file Test.properties containing
2018=jan;feb;mar
2019=jan;feb;mar
2020=jan;feb;mar
********************************
name=john,math,sudha
my input property is "2020" and output is "2021", after running Ant Test.properties should contain
2018=jan;feb;mar
2019=jan;feb;mar
2020=jan;feb;mar
2021=jan;feb;mar
********************************
name=john,math,sudha
with out changing the order How could I do that?
You might be able to use something based on the following:
The idea is to read the propertyfile, then use two <propertyset> instances with the <echoproperties> task to update the file.
<property name="prop.file" value="Test.properties" />
<property name="input" value="2020" />
<property name="output" value="2021" />
<property name="pf" value="prefix" />
<property name="input.prop" value="${pf}.${input}" />
<loadproperties srcfile="${prop.file}" prefix="${pf}" />
<echoproperties destfile="${prop.file}">
<propertyset>
<propertyref prefix="${pf}" />
<mapper type="glob" from="${pf}.*" to="*" />
</propertyset>
<propertyset>
<propertyref name="${input.prop}" />
<mapper type="glob" from="${input.prop}*" to="${output}*" />
</propertyset>
</echoproperties>
There's more code there than you might expect: the "prefix" is being used to ensure that the properties loaded from the file don't clash with any in your Ant buildfile as properties are imutable.
The order of the propertysets in the echoproperties task is important, especially if there is already a value for property "2021" in the file that you are updating. Where properties appear in both sets, the value in the last propertyset seen "wins" and is echoed to the output file.
<property name="prop.file" value="test.properties" />
<property name="input" value="2020" />
<property name="output" value="2021" />
<replaceregexp file="${prop.file}"
match="${input}(=)(.*)"
replace="${input}=\2${line.separator}${output}=\2"
flags="gi"
byline="true" />

SAS Parameter logconfigloc and conventional log output

I got the task to log user access to datasets in certain libraries.
To solve this I use the SAS Audit logger, which already provides the desired output.
To get this desired output, i use the start parameter logconfigloc with the following XML-file:
<?xml version="1.0" encoding="UTF-8"?>
<logging:configuration xmlns:logging="http://www.sas.com/xml/logging/1.0/">
<!-- Log file appender with immediate flush set to true -->
<appender name="AuditLog" class="FileAppender">
<param name="File" value="logconfig.xml.win.audit.file.xml.log"/>
<param name="ImmediateFlush" value="true" />
<filter class="StringMatchFilter">
<param name="StringToMatch" value="WORK"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
<filter class="StringMatchFilter">
<param name="StringToMatch" value="Libref"/>
<param name="AcceptOnMatch" value="true"/>
</filter>
<!-- The DenyAllFilter filters all events not fullfilling the criteria of at least one filters before -->
<filter class="DenyAllFilter">
</filter>
<layout>
<param name="ConversionPattern"
value="%d - %u - %m"/>
</layout>
</appender>
<!-- Audit message logger -->
<logger name="Audit" additivity="false">
<appender-ref ref="AuditLog"/>
<level value="trace"/>
</logger>
<!-- root logger events not enabled -->
<root>
</root>
</logging:configuration>
My Problem is, that by using the logconfigloc parameter, the log parameter is not working any more hence I get no "conventional" SAS log.
I allready tried to enable the root logger, but it´s output only looks similar to the original logfiles but has some diffrences.
Is there an (easy) way to get the "conventional" SAS log in addition the to the afforementioned special access logging output?
Kind Regards,
MiKe
I found the answer to the question how to obtain the conventional log.
For this purpose the SAS logger named "App" with message level "info" can be used.
So the following XML does the trick:
<?xml version="1.0" encoding="UTF-8"?>
<logging:configuration xmlns:logging="http://www.sas.com/xml/logging/1.0/">
<appender name="AppLog" class="FileAppender">
<param name="File" value="D:\Jobs_MK\SAS_Logging_Facility\Advanced_Logging_Test_with_XML\logconfig_standard_log.log"/>
<param name="ImmediateFlush" value="true" />
<layout>
<param name="ConversionPattern"
value="%m"/>
</layout>
</appender>
<!-- Application message logger -->
<logger name="App" additivity="false">
<appender-ref ref="AppLog"/>
<level value="info"/>
</logger>
<!-- root logger events not enabled -->
<root>
</root>
</logging:configuration>

Execute selected ant tasks for a selected set of projects

I have defined targets in ant for our games, e.g. clean, build-ios, build-android, deploy-ios, deploy-android, etc. Now I would like to define a new set of targets that represent our games, say game1, game2, game3.
My goal is to be able to launch ant with a set of target games and a set of target tasks so that for each selected game, each selected task is executed.
Example pseudo code: Foreach [game1, game3]: clean, build-ios, deploy-ios
How can I achieve this with ant? A requirement would be to define which games and which tasks are selected through targets, not to write them in a file that is altered manually.
The subant task is useful for situations where you have multiple subprojects that share similar structures.
In your main build.xml, define a target that rubs the desired build target on your game subdirectories, along with all of the generalized build targets.
<target name="deploy-all">
<subant target="deploy">
<dirset dir="." includes="game-*" />
</subant>
<echo message="All games deployed." />
</target>
<target name="deploy" depends="deploy-ios,deploy-android">
<echo message="${ant.project.name} build complete." />
</target>
<target name="clean">
<echo message="Cleaning ${ant.project.name}" />
</target>
<target name="build-ios" depends="clean">
<echo message="Building iOS ${ant.project.name}" />
</target>
<target name="build-android" depends="clean">
<echo message="Building Android ${ant.project.name}" />
</target>
<target name="deploy-ios" depends="build-ios">
<echo message="Deploying iOS ${ant.project.name}" />
</target>
<target name="deploy-android" depends="build-android">
<echo message="Deploying Android ${ant.project.name}" />
</target>
Then, in the game-* subdirectories, create a simple build.xml that links back to the common one.
game-1/build.xml:
<project name="game-1" default="build">
<import file="../build.xml" />
<echo message="=== Building Game 1 ===" />
</project>
game-2/build.xml:
<project name="game-2" default="build">
<import file="../build.xml" />
<echo message="=== Building Game 2 ===" />
</project>
Edit: If your build needs to include/exclude certain subprojects based on the user's input or a pre-defined property, you can modify the subant task's nested resource collection to accommodate for this.
<property name="game.includes" value="game-*" />
<property name="game.excludes" value="" />
<subant target="deploy">
<dirset dir="." includes="${game.includes}" excludes="${game.excludes}" />
</subant>
The user can then run a command that optionally passes values for game.includes and/or game.excludes. If these properties are not specified, the values defined above by the property task will be used as defaults.

How can I execute an ant target depending on the value of an environment variable?

I want to execute an ant script on two different computers. Depending on the name of the computer either one of the two targets should be executed. Following doesn't work:
<project name="import" default="all">
<property environment="env"/>
<target name="staging" if="${env.COMPUTERNAME}='STG'">
<echo>executed on staging</echo>
</target>
<target name="production" if="${env.COMPUTERNAME}='PRD'">
<echo>executed on production</echo>
</target>
<target name="all" depends="staging,production" description="STG or PRD"/>
</project>
As I understood, "if" can only be used with property and it checks whether a property is set or not. But is there a way to to make a condition depending on the value of a property?
I would suggest writing an "init" target that sets any conditions you need for later build steps, and also fails the build if certain required properties don't evaluate to what's expected.
For example:
<target name="all" depends="staging,production,init" />
<target name="staging" if="staging.environment" depends="init">
<echo message="executed on staging" />
</target>
<target name="production" if="production.environment" depends="init">
<echo message="executed on production" />
</target>
<target name="init">
<condition property="staging.environment">
<equals arg1="${env.COMPUTERNAME}" arg2="STG" />
</condition>
<condition property="production.environment">
<equals arg1="${env.COMPUTERNAME}" arg2="PRD" />
</condition>
<fail message="Neither staging nor production environment detected">
<condition>
<not>
<or>
<isset property="staging.environment" />
<isset property="production.environment" />
</or>
</not>
</condition>
</fail>
</target>

MSBuild: Do I need Target Rebuild?

I use a build file to build and test my project.
I have a Compile-Target which has this line "Targets = "Rebuild". Do I really need this line? Using Visual Studio I know that I can clean a Solution and build it again, or I can just rebuild the solution.
In my msbuild-file I delete my main folder BuildArtifacts before creating him again. I used this Tutorial and I don't know why he uses Target=Rebuild?
This is my build file:
<Project ToolsVersion="4.0" DefaultTargets="RunUnitTests" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Falls Eigenschaften nicht gesetzt -> Release & Any CPU als default-->
<PropertyGroup>
<!-- ... -->
</PropertyGroup>
<ItemGroup>
<!-- ... -->
</ItemGroup>
<!-- All the stuff go into my main folder -->
<Target Name="Init" DependsOnTargets="Clean">
<MakeDir Directories="#(BuildArtifacts)" />
</Target>
<!-- delete my main folder -->
<Target Name="Clean">
<RemoveDir Directories="#(BuildArtifactsDir)" />
</Target>
<!-- delete NUnit-Files -->
<Target Name="CleanAfter">
<RemoveDir Directories="#(NunitDir)" />
</Target>
<Target Name="Compile" DependsOnTargets="Init">
<MSBuild Projects="#(SolutionFile)"
Targets="Rebuild"
Properties="OutDir=%(BuildArtifactsDir.FullPath);
Configuration=$(Configuration);
Platform=$(BuildPlatform)" />
</Target>
<Target Name="RunUnitTests" DependsOnTargets="Compile">
<Exec Command='"#(NUnitConsole)" "#(UnitTestsDLL)" --result=console-test.xml --work=BuildArtifacts' />
<CallTarget Targets="CleanAfter" />
</Target>
</Project>
This depends on your own needs: do you need the whole solution to be rebuilt or not? Arguably, on a build server, you want to do a complete clean/rebuild after every commit to make sure the codebase is sane. Removing just the output directory (I assume that is what the Clean starget does) doesn't necessarily remove all object files as well since they typically go into the intermediate directory which might not be the same as the output directory.