Если нельзя, но очень хочется, то нужно обязательно и ничего в мире не стоит того, чтобы делать из этого проблему!


Интересна Java? Кликай по ссылке и изучай!
Если тебе полезно что-то из того, чем я делюсь в своем блоге - можешь поделиться своими деньгами со мной.
с пожеланием
столько времени читатели провели на блоге - 
сейчас онлайн - 

понедельник, 31 декабря 2012 г.

Apache JMeter: Создаем 500 юзеров на Moodle автоматом

Задача возникла - для целей тестирования нагрузки надо создать 500 временных пользователей  на Moodle и заасайнить их на тренинг.

Ну что начнем.

Для начала вот хорошая статья о том, как записать хождение пользователя по сайту. JMeter встраивается ка прокси между браузером и сайтом, и все, что делает пользователь записывается в сценарий текущего TestPlan.

Итак я запустил свой C:\Java\apache-jmeter-2.6\bin\jmeter.bat

После Test Plan -> Add -> Thread Group



После Test Group -> Add -> Logic Control -> Recording Controller



Добавил HTTP Cookie Manager Test Plan -> Add -> Config Element -> HTTP Cookie Manager



Далее WorkBench -> Add -> Non-Test Elements -> HTTP Proxy Server



После связал Recording Cpntroller с Proxy Server (порт 8080 выставил)



После натравил мой Firefox на прокси (на порт 8080 localhost'а)



Запустил Proxy



И зашел в браузере на Moodle. Запись пошла...

Т.к. во время хождени по сайту грузятся всякие разные скрипты и прочая лабуда (касающаяся, например, дизайна) то можно сразу же настроить фильтр, чтобы в сценарий записывалось только полезное. Наприер при хождении по Moodle :) очень много запросов было в сторону /moodle/theme потому я добавил такие два фильтра



Стоит так же обратить внимание, что если в браузере включен кеш (рисунков и js), то скорее всего он не будет посылать никаких дополнительных запросов, а возьмет все из своего кеша. Это с одной стороны (как у меня) помагает, но с другой стороны может где-то вылезти.

Вообще я после того как записал скрипт, почистил его полностью, оставив только те действия которые нужны для создания пользователя: залогиниться под админом, создать юзера, записать его на курс, вылогиниться. Промежуточные операции, которые нужны были мне для того, чтобы добраться до соответствующего скрина я удалил. И вот что получилось.



Добавил подглядывалку (Add-> listener -> View result tree)



После остановил прокси. Запустил свой сценарий, нажав зеленую кнопочку (или Ctrl-R) и изучил то, что мне вывел мой новый друг View result tree.



Response data я вставил как html файл на рабочий стол и посомтрел что отрендерит браузер



Так я столкнулся с бедой, под названием user session id.



Дело в том, что Moodle после залогинивания передает пользователю ключ, с которым он ходит по страничкам (передает через GET/POST) и так Moodle определяет что можно позволить пользователю, а что нет. И при каждом новом залогинивании это ключ, естественно, другой. Обычно используются куки (для этого и нужен был в прошлой статье Add -> Config Element -> HTTP Cookie Manager), но не в моем случае. А вот как выкусить sessionid и встраивать потом во все линки подскажет умная статья.

Значит ищем то место, после выполнения которого настраничке появится хоть один линк с sesskey - думаю это случится после залогинивания. Как минимум один линк (Logout) на домашне страничке Moodle модержит его.



Мы могли бы добавить процессор непосредственно в тот запрос, в котором он требуется, и тогда (пре)процессор обработает результат предыдущего запроса, найдет там sesskey и вставит его куда надо.

Но так как нам sesskey может понадобиться и в других местах, то я его вынесу на уровень выше - сразу для всех страниц. Значит добавляем к первому запросу на Recording Control -> Add-> pre processor-> HTTP URL Re-writing Modifier



Далее указываем, что нас интересует именно sesskey и ставим галочку!



А потом во всех запросах, в параметрах меняем sesskey на символ *



После этого снова пробуем запуститься. И смотрим, что sesskey проинджектился как надо.



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



Добавим на эту страничку такой же препроцессор  Add-> pre processor-> HTTP URL Re-writing Modifier



И встроим его в параметр userid запроса




Важно! Препроцессор  будет искать параметр userid=xxx на результате выполнения предыдущего запроса, а значит, если на прошлой страничке его нет, то он вставит * - но это мы можем легко проверить, посмотрев результат выполнения...



Оно-то вставило, но вставило не совсем того юзера. Айдишку 5 имеет юзер, под которым мы вошли. Значит, надо придумать другую историю...

Попробуем так. Добавляем переменную, в которой будет храниться имя нового пользователя. затем воспользуемся ею при создании пользователя. Затем найдем пользователя по имени а из результирующей странички выкусим где-то айдишку новосозданного пользователя.

Итак добавляем новую переменную Thread Group -> Add -> Coding Element -> user DefinaedVariables



Добавляем туда переменную



Далее на страничке регистрации воспользуемся ею дважды - один раз для имени, второй для еmail (тоже должен быть уникальным).



Проверить все ли правильно сработало можно после запуска.



Супер! Теперь надо анйти на Moodle запрос, который вернет по имени пользователя его айдишку... Я нашел соответсвующий скрин, записал (через Recording Controller+Proxy Server) как я с помощью фильтра по email получаю своего юзера. И вставил страничку перед той, в которой мне понадобится айдишка нового пользователя. Что классно, так это то, что он автоматом подставил переменную user_name за меня. Ну а в sesskey я записал символ '*' сам.



Теперь осталось выкусить айдишку пользователя из внутренностей. Я выбрал suspend=xxx потому как это едиснтвенный параметр с таким именем и используется он для того чтобы указать айдишку пользователя, который надо спрятать (фича Moodle)...



Супер! Теперь на страничке, на которой нам нужна эта айдишка надо настроить препроцессор так, как мы это делали раньше...



Настроить его на выкусывание suspend



И в параметры запроса прописать вставку его значения



Только вот не прокатило :) Видать препроцессор не хранит то, что выкусывает в одноименных пропертях. Нужна другая лазейка. и я нашел xpath построцессор - по названию я догадался, что его стоит добавлять в запрос, с результатом выполнения которого мы хотим поизгаляться.



Затем я подобрал опытным путем необходимый элемент (пользовался плагином Firefox Firebug+Firepath)



Но надо получить подстроку, а потому xpath выражение будет таким



Теперь настроим постпроцессор



И наконец, запустив порадуемся результату!



Теперь весь наш сценарий работает!

Но еще не все :) Поскольку нам надо создать 500 юзеров, то необходимосделать цикл в котором будет меняться наша user_name переменная... Но как? Google подскзывает...



А как достучаться до переменной цикла? Создадим счетчик Recording Controller -> Add -> Coding Element -> Counter



Далее стоит удалить созданный ранее (Thread Group -> Add -> Coding Element -> user DefinaedVariables), которые как оказалось играют роль констант и вставить локальные переменные (Recording Controller -> Add -> Pre Processors -> User Parameters)



Скопировать туда старое значение user_name немного модифицировав его



Теперь если запустить и посмотреть на результат выполнения, то увидим, что все ок!



Наверное было бы намного быстрее, если бы я написал SQL и проинджектил в базу новых записей, но я хочу изчуть что-то новое.

А вот и тест план, что у меня получился в результате. Может кому-то пригодится.

P.S. Немного улучшенная модификация скрипта выглядит немного по другому. Тут в группа (1) запускается только 1 раз, тут странички логина (2) и логаута (5) выполняются только один раз. Весь остальной контент циклически выполняется в цикле (3) со своим хитрым синтаксисом проверки каунтера. Так же сюда пришлось добавить обнуление фильтра (4) в котором искали юзера, поскольку фильтр сохраняется для залогиненного пользователя. Вцелом это работает на треть быстрее.


Теперь точно все! Иду потихоньку за стол, праздновать ДР. Сейчас уже 23:24 :)

3 комментария:

  1. Супер!спасибо за отличную статью!!!

    ОтветитьУдалить
  2. Вы себе даже не представляете какую кашу в моей голове вы выстроили в цепочку :) Спасибо вам!

    ОтветитьУдалить