Thursday, December 22, 2011

Для чего нам нужен Foreach

Постановка задачи.
Ответ (response, он же респонс - мильпардон за слэнг) одного из запросов (request, он же реквест) возвращает несколько числовых значений одновременно, из которых потом нужно сформировать строку определённого вида ("[1,2,3,4,5]") и засунуть её в переменную для дальнейшего использования в качестве параметра в другом запросе.

Для описанного ниже регулярного выражения, запрос возвращал респонс, состоящий из нескольких элементов (с разными значениями, естественно).

"335817" : {
"name" : "Price",
"id" : 335817,
"type" : "price",
"source" : "UTP",
"mId" : 335816
}
На выходе мне нужно было получить строку, которая бы содержала все id в виде ['<'id1'>','<'id2'>',...,'<'idn'>']

Шаг первый - дёргаем группы.
Делается это элементарно. К первому респонсу (что возвращает, в том числе, и искомые числовые значения), добавляем как child (дочерний элемент) Regular Expression Extractor c такими параметрами:


Где
Name ставите произвольное.
Apply to - где будете искать. Мне нужно искать в основном семпле (не в дочерних запросах).
Response field to check - в каком месте запроса искать нужное. Мне нужно искать в самом теле запроса.
Reference Name - имя "переменной", по которой мы будем обращаться к наденному фрагменту(ам).
Regular Expression - само регулярное выражение. Я проверяю его с помощью очень удобного фришного инструмента - Rad Software Regular Expression Designer.
Template - какую порядковую группу из найденных мы используем (если ищем несколько, можем и искать несколько). У меня единственная, она же первая группа.
Match No - тут поступаем так:
Если нужно использовать любое из найденных, ставим 0.
Если нужно использовать какое-то n-ное вхождение, ставим целое положительное n. (Например, 1 будет нам находить первое вхождение из группы).
Чтобы выгрести все - используем отрицательное значение (именно поэтому у меня стоит -1).
Default Value - исходное значение, которое будет подставляться, если искомый фрагмент(ы) не найден.


Шаг второй. Используем ForEach контроллер.

После запроса, из которого мы дёрнули группу, добавляем ForEach контроллер с такими параметрами:

Где
Name ставите произвольное.
Input variable prefix - то самое Reference Name из предыдушего запроса, по которому мы будем обращаться к выделенной группе.
Output variable name - куда мы будем складывать полученное значение.


Шаг третий. Слепляем элементы группы в одну строчку.
К нашему Foreach контроллеру как дочерний элемент добавляем BeanShell Sampler, в коде которого мы пишем, как именно мы хотим видеть строчку.

Я написала так:
String y=vars.get("mIds");

if (y.length() != 0)
{
     y=y.substring(0,y.length()-2);
     y+=",";
}
else
{
     y+="[";
}

y+=String.valueOf("${
meterval}");
y+="]";
vars.put("
mIds",y);


Где переменная mIds была описана в User Defined Variables с пустым значением.

На выходе из ForEach мы получим переменную mIds, которую в дальнейшем можно использовать где угодно. Значением этой переменной и будет искомая строчка.


ПыСы. При отладке запроса, использующего нашу переменную (mIds), не забываем enabl'ить шаги, с помощью которых мы эту переменную получаем :))))
ПыПыСы. Программист из меня тот ещё... Только что дошло, как убрать 4й шаг :)
Потому апдейтим скрипт.

Friday, December 16, 2011

Как запомнить HTTP статусы :)

Не могла удержаться и не свистнуть вот отсюда.

Огромное спасибо автору GirlieMac, aka Tomomi Imura за позитив!





































Wednesday, December 14, 2011

Как подружить Jmeter и Jenkins?

У нас на проекте существует какая-никакая Continuous Integration (CI) с выделенным серваком и прикрученным к нему Дженкинсом (вариант Hudson - оба являются CI-серверами).

Постановка задачи: для начала прикрутить два несложных джиметровских скрипта с тем, чтобы можно было смотреть что-то типа aggregate report родного Джиметра. Имя хоста передаётся параметром.

Шаг 1. Установить на Jenkins Performance Plugin путём стандартных средств Дженкинса: Jenkins -> Manage Jenkins -> Manage Plugins -> Available. Найти нужный и нажать [Install].

Шаг 2. Заливаем на сервер джиметр. У меня на сервере живёт бубунта, и её стандартный package manager ставит джиметр версии 2.3. Потому я сверху установленного 2.3 стянула последнюю версию и распаковала её в другом месте _path_. Потом мы на это место будем ссылаться.

Шаг 3. Делаем job для каждого скрипта и запускаем его, дабы создались директории в /var/lib/hudson/jobs

Шаг4. Если мы задаём имя хоста в User Defined Variables, то там пишем следующее:
HOST (имя переменной) ${__P(server,_defaultHost_)} (значение переменной)
Где _defaultHost_ - имя хоста по умолчанию, а server - имя параметра, передаваемого в командной строке.
Такой скрипт можно гонять как из ГУИ, так и из командной строки.

Шаг 5. Для каждого job'a копируем в папку /var/lib/hudson/jobs/_JobName_/workspace/ необходимый параметризованный джиметровский скрипт и csv файлы. Допустим, у нас есть скрипт testjm.jmx.

Шаг 6. Настраиваем job'ы. (Configure)
Для этого открываем в Дженкинсе нужный Job (для каждого из двух скриптов был создан отдельный) и делаем следующее:

- Ставим галочку для "This build is parameterized" и пишем что-то типа
Name hostname
Default Value _servername_
Description Host name where the test will be run


- В разделе Build жмём кнопочку [Add build step] -> Execute shell.
В поле Command пишем:

echo $WORKSPACE
JMETER_HOME=/home/hudson/jakarta-jmeter-2.5/bin (_path_ куда был записан свежий джиметр)
PATH=$JMETER_HOME:$PATH
java -jar $JMETER_HOME/ApacheJMeter.jar -n -t $WORKSPACE/testjm.jmx -Jserver=${hostname} -l $WORKSPACE/jmeter.jtl


Этот скрипт будет выполнять наш скрипт testjm.jmx (-t) в командной строке (-n), передавая туда переменную для джиметра server, значение которой будет равняться параметру, заданному hostname.
Также в папку /var/lib/hudson/jobs/_JobName_/workspace/ будет положен лог джиметра с именем jmeter.jtl (-l).

- Ставим галочку Publish Performance test result report. Тут же нажимаем [Add a new report] и выбираем JMeter. В Report Files пишем имя нашего лога - jmeter.jtl

Шаг 7. Сохраняем.

Шаг 8. Бегаем.


Для того, чтобы после выполнения посмотреть лог, идём на

http://_server_/view/_path_/job/_JobName_/lastBuild/performance/

Тут _server_ - имя Дженкинс-сервера.
_path_ - путь до папочки "jobs".
_JobName_ - имя текущего job'a.

Перебираем все строки в csv файле.

За помощь в неравной борьюе большое спасибо Илье Пономаренко и Дэну Аркуше.

Постановка задачи: необходимо, чтобы цикл выполнялся ровно столько раз, сколько есть строк в csv-файле. Для каждого треда отдельно.
Т.е., если у нас есть
Готового решения в инете я не нашла (может, искала плохо, конечно).

Раньше проблема решалась таким образом: я создавала Loop Counter, задавала число проходов равным числу строк в csv, которое мне надо было пройти, и тогда всё работало замечательно.

Но проблема заключалась в том, что файл мог меняться, сответственно, могло меняться и количество строк в этом файле. Да и интересно было заставить джиметр автоматом считать, сколько раз нужно бегать.

Мучилась я долго, но придумала, наконец, нижеследующее.

Допустим, у меня есть csv файл с такими полями: userName,Pwd,grName. Точнее, файл содержит столбцы, чьи столбцы парсятся в переменные JMeter c именами userName,Pwd,grName.
В этом файле Х строк.

1. Редактируем файл, ставим в Х+1 строке слово FALSE в первом столбце (отвечающем за переменную userName). Сохраняем изменения.

2. Создаем Add -> Logic Controller -> While Controller, которому ставим значение для Condition (function or variable) равное ${username}

3. Добавляем в этот контроллер CSV Data Set Config, в котором прописываем нужный нам csv файл и все необходимые имена переменных из него.

4. Добавляем в контролер все шаги, которые необходимо выполнить в цикле.

Профит! :)

Единственный минус - цикл выполняется не Х, а Х+1 раз, и последний раз вместо значения переменной userName передаётся FALSE.

Но, как по мне, это лучше, чем править ручками.

Если кто знает лучший способ - буду рада, если поделитесь.