How to set value for a variable in Jmeter - jmeter

I am using JSR223 Sampler and trying for arithmetic operations..
try {
setStrictJava(true);
int a=1;
int b=2;
int c = a+b;
vars.put("c",c);
} catch(Exception ex) {
log.error("something wrong", ex);
throw ex;
}
Getting following error..
2018-12-18 18:19:59,554 ERROR o.a.j.p.j.s.JSR223Sampler: Problem in JSR223 script JSR223 Sampler, message: javax.script.ScriptException: Sourced file: inline evaluation of: ``try{ setStrictJava(true); int a=1; int b=2; int c = a+b; vars.put("c",c); } catc . . . '' : Error in method invocation: Method put( java.lang.String, int ) not found in class'org.apache.jmeter.threads.JMeterVariables' : at Line: 6 : in file: inline evaluation of: ``try{ setStrictJava(true); int a=1; int b=2; int c = a+b; vars.put("c",c); } catc . . . '' : vars .put ( "c" , c )
in inline evaluation of: ``try{ setStrictJava(true); int a=1; int b=2; int c = a+b; vars.put("c",c); } catc . . . '' at line number 6
javax.script.ScriptException: Sourced file: inline evaluation of: ``try{ setStrictJava(true); int a=1; int b=2; int c = a+b; vars.put("c",c); } catc . . . '' : Error in method invocation: Method put( java.lang.String, int ) not found in class'org.apache.jmeter.threads.JMeterVariables' : at Line: 6 : in file: inline evaluation of: ``try{ setStrictJava(true); int a=1; int b=2; int c = a+b; vars.put("c",c); } catc . . . '' : vars .put ( "c" , c )
How to resolve this?

You either need to convert your variable to String in order to be able to use vars.put() function like:
vars.put("c", String.valueOf(c));
or use vars.putObject() function instead
vars.putObject("c", c);
Also be aware that you should be using Groovy language in the JSR223 Sampler, in this case you will have to remove setStrictJava(true); line otherwise your code will not work.

You have to convert to string your numeric variable:
int a = 1;
int b = 2;
int c = a + b;
vars.put("c", c.toString());

Related

Why cant we use a pointer to traverse the vector?

I am trying to print all the elements in a vector using a pointer. What is wrong in the code?
#include <bits/stdc++.h>
using namespace std;
int main() {
vector <int> v = {1,2,3};
int * p;
for(p=v.begin();p != v.end();p++)
cout<<*p<<" ";
}
I get a compilation error.
You can use a pointer, you just really don't want to
using namespace std;
int main() {
vector <int> v = {1,2,3};
int * p;
for(p=v.data(); p != (&v[v.size()-1])+1 ; p++)
cout<<*p<<" ";
}
p=v.data() get you the pointer to the underlying element storage. See https://en.cppreference.com/w/cpp/container/vector/data
(&v[v.size()-1]) get you the address of the last element. +1to get the first invalid address.
Now why your code doesn't compile.
The type of v.begin() is std::vector::iterator. And an iterator cannot be cast to a pointer, that why you get the error :
cannot convert 'std::vector<int>::iterator {aka __gnu_cxx::__normal_iterator<int*, std::vector<int> >}' to 'int*' in assignment
Now, how to print all the elements ?
vector <int> v = {1,2,3};
for(const int& e : v )
cout<<e<<" ";
Or with iterator :
vector <int> v = {1,2,3};
for(auto it = v.begin(); it != v.end() ; it++ )
cout<<*it<<" ";
Or the fancy way :
vector <int> v = {1,2,3};
std::copy( v.begin(), v.end(), std::ostream_iterator<int>( std::cout, " "));
Note:
In the general case, you can find the type of an expression with
template <class T>
struct td ;
using namespace std;
int main() {
vector <int> v ;
td<decltype(v.begin())> d;
}
This will give you an error with the type:
error: aggregate 'td<__gnu_cxx::__normal_iterator<int*, std::vector<int> > > d'
has incomplete type and cannot be defined
What is wrong in the code?
You are using p in the for loop as though it is an iterator. Iterators and pointers are related but they are not the same.
Change p to be an iterator. There is nothing to be gained by making it a pointer.
std::vector<int>::iterator p;
for(p=v.begin();p != v.end();p++)
cout<<*p<<" ";

bad_lexical_cast Exception handling in c++

i am using lexical cast in a function for three different variables. Now if a bad_lexical_cast exception occurs i have to set default values respective to each variable. now how to find from which statement the exception is thrown?
You can assign the default values first and then wrap each boost::lexical_cast into a try-catch block.
Or, better, extract a function that does it for you:
#include <boost/lexical_cast.hpp>
#include <iostream>
template<class T, class S>
T lexical_cast_or_default(S s, T default_value) noexcept {
T value;
return boost::conversion::try_lexical_convert(s, value)
? value
: default_value
;
}
int main() {
double a = lexical_cast_or_default("abc", 3.14);
double b = lexical_cast_or_default("123", 3.14);
int c = lexical_cast_or_default<int>("456", 3.14);
std::cout << a << '\n';
std::cout << b << '\n';
std::cout << c << '\n';
}
Outputs:
3.14
123
456

Fixing a parameter when using std::bind

This code doesn't compile, I don't get why:
struct C { int a;};
void foo(C c, int s)
{
cout << c.a << s;
}
int main()
{
std::function<void(C,int)> call = std::bind(&foo,std::placeholders::_1,5);
C c;
c.a = 5;
call(c);
return 0;
}
I get:
No match for call to std::function<void(C,int)> (C&)
The bind() expression std::bind(&foo, _1, 5) produces a unary function. You try to use a unary function to initialize a binary std::function<void(c, int)>. Did you mean to use something like this?
std::function<void(C)> call = std::bind(&foo, _1, 5);

How can I add a reference to a value-type in vala

In c++ I can add a reference to a value type, for example :
int a = 12;
int &b = a;
a--;
cout << "a = " << a << ", b = " << b << endl;
Will give :
a = 11, b = 11
Is there a way to do the same in vala without using pointers ?
Is there a way to do the same in vala
Yes.
without using pointers ?
No.
If, however, you are passing them to a function, you can use a ref parameter:
void decrement (ref value) {
value--;
}
void do_stuff () {
int a = 12;
decrement (ref a);
assert (a == 11);
}

How to perform a range-based c++11 for loop on char* argv[]?

I would like to try out c++11 range-based for loop on char* argv[] but I am getting errors. By current approach is :
for( char* c : argv )
{
printf("param: %s \n", c);
}
and in my makefile I have the following line :
g++ -c -g -std=c++11 -O2 file.cc
argv is an array of pointers to raw strings, you can't obtain a range from it directly.
With C++17 you can use std::string_view to avoid allocating strings:
for (auto && str : std::vector<std::string_view> { argv, argv + argc })
{
std::printf("%s\n", str.data()); // Be careful!
std::cout << str << std::endl; // Always fine
fmt::print("{}\n", str); // <3
}
Take caution when using string_view with printf because:
Unlike std::basic_string::data() and string literals, data() may return a pointer to a buffer that is not null-terminated.
argv always contains null-terminated strings so you're fine here though.
Without C++17 you can simply use std::string:
for (auto && str : std::vector<std::string> { argv, argv + argc })
std::printf("param: %s\n", str.c_str());
Starting from C++20 you can use std::span:
for (auto && str : std::span(argv, argc))
std::printf("param: %s\n", str);
You can't use the range-based loop since you don't have a range.
You can either write your own range wrapper (a kind of "array view"), or just use a normal loop:
for (char ** p = argv, e = argv + argc; p != e; ++p)
{
// use *p
}
With a wrapper:
#include <cstddef>
template <typename T>
struct array_view
{
T * first, * last;
array_view(T * a, std::size_t n) : first(a), last(a + n) {}
T * begin() const { return first; }
T * end() const { return last; }
};
template <typename T>
array_view<T> view_array(T * a, std::size_t n)
{
return array_view<T>(a, n);
}
Usage:
for (auto s : view_array(argv, argc))
{
std::cout << s << "\n";
}

Resources