How to encode an attachment to Base64 in Jmeter? - web-services

I'm trying to encode a file to Base64 in Jmeter to test a web service using the following script:
String file = FileUtils.readFileToString(new File("${filepath}"), "UTF-8");
vars.put("file", new String(Base64.encodeBase64(file.getBytes("UTF-8"))));
This works fine for plain/text files and does not work for other file types correctly.
How could I make it work for other file types?

Jmeter has many potions to convert a variable to "Base64", below are a few options
Bean shell pre processor
BeanShell PostProcessor
BeanShell Sampler.
Below is the "bean shell" code, which used in "Bean shell pre processor" to convert variable to Base64
import org.apache.commons.codec.binary.Base64;
String emailIs= vars.get("session");
byte[] encryptedUid = Base64.encodeBase64(emailIs.getBytes());
vars.put("genStringValue",new String(encryptedUid));
Example :
Before Base64 :jdwqoeendwqqm12sdw
After Base64 :amR3cW9lZW5kd3FxbTEyc2R3
Converted using Jmeter :
Converted Using base64 site:

As Groovy is now the preferred JSR223 script language in each JMeter Sampler, Pre- & PostProcessor, Listener, Assertion, etc. this task is pretty easy.
def fileAsBase64 = new File("${filepath}").bytes.encodeBase64().toString()
vars.put("file", fileAsBase64)
Or as one liner:
vars.put("file", new File("${filepath}").bytes.encodeBase64().toString())
That's it.

Use the function ${__base64Encode(nameofthestring)} to encode the string value and ${__base64Decode(nameofthestring)} to decode the string value.

Your issue comes from the fact that you're considering binary files as text when reading them which is wrong.
Use this for reading the file:
https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/FileUtils.html#readFileToByteArray(java.io.File)
Then encode the byte array in Base64

Try this
import org.apache.commons.codec.binary.Base64;
String forEncoding = vars.get("userName") + ":" + vars.get("passWord");
byte[] token = Base64.encodeBase64(forEncoding.getBytes());
vars.put("token", new String(token));

Alternative for this is to directly create a groovy function in User Defined Variable as
${__groovy(new File(vars.get("filepath")).bytes.encodeBase64().toString(),)}

Related

Unable to read value from location URL using RegEx inside BeanShell Post Processor

I am using JMeter to automate performance test cases. After HTTP request, I have used RegEx Post Extractor to read the response header. This response header return location. Location is project-specific URL. I want to read the value of the state variable from this URL. For this, I have used BeanShell PostProcessor. For example,
location: "http://www.google.com/state=asdas123123123123&query=asdasdas!##"
I am able to read value of response header as http://www.google.com/state=asdas123123123123&query=asdasdas!##" using regular expression extractor
Then, I have added BeanShell PostProcesssor to read state and query.
import java.util.regex.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
try{
//location = "http://www.google.com/state=asdas123123123123&query=asdasdas!##"
String location = vars.get("location");
String pStr = "/state=(\\S+?)&/"";
Pattern patternN = Pattern.compile(pStr);
Matcher matcher = patternN.matcher(pStr);
if (matcher.find()) {
vars.put("variablename_1",matcher.group(0));
}
vars.put("variablename_2",location);
}catch (Exception ex) {
vars.put("variablename_ex",ex);
throw ex;
}
This code is not working. It seems double slash is creating problems.
Since JMeter 3.1 you should be using JDR223 Test Elements and Groovy language for scripting
Groovy provides Find operator which looks like =~
Assuming above 2 points you can refactor your "code" to this one-liner:
vars.put('variablename_1', (vars.get('location') =~ /state=(\w+)&/)[0][1])
Demo:
More information:
Pattern Matching in Strings in Groovy
Apache Groovy - Why and How You Should Use It

string in webclient class c# changed to uncorrect format

I call my service in wcf as you can see :
ClientRequest.Headers["Content-type"] = "application/json";
string result = ClientRequest.DownloadString(ServiceHostName + "/NajaService.svc/GetCarData/" + plaque);
var javascriptserializer = new JavaScriptSerializer();
return javascriptserializer.Deserialize<NajaResult>(result);
But the returned data is like this :
{"CarColor":"آبي سير","CarModel":"1383","CarTip":"ال ايکس","CarType":"سواري","Chassis":"83844131","Family":"####","FuelType":1,"MotorNum":"12483068683","Name":"####","NationalCode":"0000000000","Plaque":"11-426د61","PlaqueCoded":110561426,"PlaqueType":"","SystemType":"سمند","VinNo":"IRFC831V3GJ844131"}
I converted it to UTF8 byte and again convert it to utf8 string but not solved.
The encoded data is in Persian language .
I traced the request in fiddler and i found that the data is come with the correct format as you can see ,But in my code is changed
The WebRequest contains the Encoding property you can set up before downloading the service reply. Details are here: https://msdn.microsoft.com/en-us/library/system.net.webclient.encoding(v=vs.110).aspx

Jmter complicated regular expression solution? [duplicate]

I have following JSON format in response body
[
{
"Name" : "Prashant",
"City" : "Sydney"
},
{
"Name" : "Yogi",
"City" : "London"
}
]
What is the better way for checking if this array has any records and if yes give me "Name" for first array index. I am using jp#gc JSON extractor plugin for jMeter.
Is it possible to parse this using a plugin or do I need to do it using regular expressions?
Using Ubik Load Pack JSON plugin for JMeter which is part of JMeter since version 3.0 (donated plugin) and called JSON Extractor, you can do it:
Test Plan overview:
ULP_JSON PostProcessor:
If Controller:
And here is the run result:
So as you can see it is possible with plain JMeter
If you're looking to learn JMeter, this book by 3 developers of the project will help you.
I am not sure about your plugin but if it supports JSON path expressions it should be possible.
Try with this expression: $.[0].Name.
This is the plugin I use: http://jmeter-plugins.org/wiki/JSONPathExtractor/ and given expression works with it.
You can find more about JSON Path expressions here: http://goessner.net/articles/JsonPath/index.html#e2.
Working with JSON in JMeter is not quite easy as JMeter was designed long ago before JSON was invented.
There are some extensions however that make life easier:
http://www.ubik-ingenierie.com/blog/extract-json-content-efficiently-with-jmeter-using-json-path-syntax-with-ubik-load-pack/
We can add a regular expression extractor for fetching the value from the response.
Like This:
If possible, always use Regular Expression Extractor. Try to avoid JSON / XPATH / Other extractors. They might look easy to use. But they consume more memory and time. It will affect the performance of your test plan.
source: http://www.testautomationguru.com/jmeter-response-data-extractors-comparison/
Rest Get service sample:
{
"ObjectIdentifiers": {
"internal": 1,
"External1": "221212-12121",
"External3": "",
"Name": "koh"
},
"PartyType": "naturalPerson",
"NaturalPerson": {
"idNo": "221212-12121",
"Title": "Mr",
"Name": "koh",
"FirstName": "",
We had a similar requirement in our project for parsing json responses using jmeter. The requirement was to validate all the fields in the json response and the expected values of field would be provided from external data source.
I found the JSR223 PostProcessor quite usefule in this case as we are able to implement Groovy scripts with this. it comes as a default plugin with the recent Jmeter version
Edit:
Below is the code snippet:
//get the JSON response from prev sampler
String getResponse = prev.getResponseDataAsString();
//parse the response and convert to string
JSONParser parser = new JSONParser(JSONParser.MODE_JSON_SIMPLE);
String parResponse = parser.parse(getResponse);
String preResponse = parResponse.toString();
JsonObject NaturalPerson = JsonObject.readFrom(preResponse);
//replace all commas with a semi-colon
String csvResponse = preResponse.replaceAll(",", ";");
//log response to file
logFileName = "C:/apache-jmeter-5.1.1/Web_Service_Output.csv";
BufferedWriter outLog = new BufferedWriter(new FileWriter(logFileName, true));
outLog.write(csvResponse + "\n");
outLog.close();

Parametrising encoded web service requests

I am trying to parametrise web service requests in a web performance test. Using Fiddler2 I have recorded a sequence of over 60 web service requests for a transaction performed by my desktop application and saved them as a .webtest file. This web test runs without any errors and the responses that I have checked look correct.
When the web service requests are viewed in Visual Studio 2012 they appear in plain text and so I should be able to edit them to parametrise the values in the SOAP requests. For example, most of the requests contain the text <Database>db1a</Database> (actually it has <Database>db1a</Database>) and I want to change them to get the database name from a context parameter. There are several other items to replace with parameters. For this one transaction there are over 60 web service requests and I have other transactions to record. The .webtest file contains XML and the requests looks like:
<Request Method="POST" Version="1.1" Url="http://example.com/somewhere.asmx" ThinkTime="83" Timeout="60" ParseDependentRequests="True" FollowRedirects="True" RecordResult="True" Cache="False" ResponseTimeGoal="0" Encoding="utf-8">
<Headers>
<Header Name="Content-Type" Value="text/xml; charset=utf-8" />
<Header Name="SOAPAction" Value=""http://example.com/webservices/VariousActionNamesHere"" />
</Headers>
<StringHttpBody ContentType="text/xml; charset=utf-8">PAA/AHgAbQBsACAAdg
... lots more characters not shown
+AA==</StringHttpBody>
</Request>
The StringHttpBody field contains an encoded version of the SOAP request. Visual Studio shows it as plain text. What is the encoding of this field and how can I decode and encode it?
I have installed Release 3.0 of the “Web and Load Test Plugins for Visual Studio Team Test” from http://teamtestplugins.codeplex.com/ . They provide a slightly better interface for editing the SOAP requests one at a time. But they do not allow mass changes.
Converting the web test to a coded web test (ie into C#) shows the SOAP requests as simple text and they could be edited there but I would prefer to keep the flexibility of a .webtest file.
Update: I have posted a partial answer to the question. Whilst it works, it feels the wrong way to do the work because it feels too complicated. So I am looking for a better overall approach.
StringHttpBody is base64 encoded. The raw body of the request is converted to a UTF-16 byte array and then base64 encoded, like so:
Convert.ToBase64String(Encoding.Unicode.GetBytes(oSession.GetRequestBodyAsString()));
For a quick view, you can copy/paste this string into Fiddler's Tools > TextWizard screen then use the From Base64 option to decode.
Here is part of an answer to working with the StringHttpBody fields. This is about decoding and encoding the fields to allow easier understanding and modification.
Read the input XML and find the contents of the StringHttpBody fields. Replace each field contents with the result of calling the following routine on the original contents. Write the all the lines to a new intermediate file. The byte array contains UTF-16 characters as high and low bytes. (All the characters I have seen so far have high byte zero.)
private string DecodeBody(string source) {
byte[] outBytes = Convert.FromBase64String(source);
StringBuilder sb = new StringBuilder();
Assert( (outBytes.Length % 2) != 0 );
for (int ix = 0; ix < outBytes.Length; ix += 2) {
Assert(outBytes[ix] != 0);
sb.Append((char)outBytes[ix + 1]);
}
return sb.ToString();
}
Now have a file containing a simple text version of the .webtest file. This file can easily be edited to parameterise fields of the requests. Have an routine used similar to the one above and writing to another intermediate file. The routine has statements such as:
source = source.Replace("<Database>db1a</Database>", "<Database>{{DatabaseName}}</Database>");
The final intermediate file is then reencoded to create a new .webtest file. Just as before the contents of the StringHttpBody fields are found and replaced with the result of calling a routine. The encoding routine is:
private string EncodeBody(string source) {
StringBuilder sb = new StringBuilder();
byte[] outBytes = new byte[2 * source.Length];
for (int ix = 0; ix < source.Length; ix++) {
char ch = source[ix];
outBytes[2 * ix] = (byte)(((int)ch) & 0xFF);
outBytes[2 * ix + 1] = (byte)((((int)ch) / 256) & 0xFF);
}
sb.Append(Convert.ToBase64String(outBytes));
return sb.ToString();
}
The flow of files is thus:
decode original.webtest > intermediate1
parameterise intermediate1 > intermediate2
encode intermediate2 > final.webtest
On the small number of .webtest files I have tried the encode operation is the inverse of the decode operation, the original file from before decoding is identical to the file after encoding. Having the two intermediate files allows easy checking and searching of the contents of the unencoded file and the effect of the parameterise step.
For
[StringHttpBody ContentType="application/json"]
To Decode the body:
var encodedString = childNode.InnerText;
var encodedStringBytes = Convert.FromBase64String(encodedString);
var decodedString = Encoding.Unicode.GetString(encodedStringBytes);
JObject jsonString =JsonConvert.DeserializeObject(decodedString);
To Encode the body:
childNode.InnerText =
Convert.ToBase64String(Encoding.Unicode.GetBytes(JsonConvert.SerializeObject(jsonString)));
I think this might help.

Return part of string using Regex

I'm looking for some regex to retrieve the GUID from the following URL
GetUploadedUserAudioIdfriendlyName=eb0c5663-a9c3-4321-8c0e-5ffbfb3139fc
I've so far got
GetUploadedUserAudioId\?friendlyName=([A-Fa-f0-9-]*)
but this is returning the full url
This is the image of where the expressions are to give you an idea of what I am trying to do.
Don't use a regex for this.
Assuming you're using C#.NET, use the static ParseQueryString() method of the System.Web.HttpUtility class that returns a NameValueCollection.
Uri myUri = new Uri("http://www.example.com?GetUploadedUserAudioIdfriendlyName=eb0c5663-a9c3-4321-8c0e-5ffbfb3139fc");
string param1 = HttpUtility.ParseQueryString(myUri.Query).Get("param1");
Check this documentation
EDIT: If you want it as a Guid after that, then cast it to one:
var paramGuid = new Guid(param1);