Gatling exe c блок и переменные сеанса - PullRequest
0 голосов
/ 13 февраля 2020

У меня есть несколько симуляций Гатлинга, которые я пытаюсь структурировать таким образом, чтобы повторно использовать низкоуровневые вызовы (например, HTTP-вызовы) при создании другого сценария ios. По этой причине у меня есть следующая структура (функция echo используется для объяснения текущего состояния):

// File UserAction.scala contains all low-level actions like load a specific page, login, logout etc. All functions return HttpRequestBuilder so that each simulation can perform its own set of checks on the responses.
object UserAction {
    ...
    def echo(): HttpRequestBuilder = {
        http("Postman Echo Service Call")
            .get("https://postman-echo.com/get")
            .headers(headers("headers_0"))
    }
    ...
}

// File TestSimulation.scala
class TestSimulation extends ParameterizedSimulation {
    private val accountFeeder = csv("data/accounts.csv")

    private val testScenario = scenario("Test Simulation")
        .feed(accountFeeder)
        .exec { session =>
            session.set("attributes", session.attributes.filterKeys(key => key.startsWith("some_prefix_")))
        }
        .doIfOrElse(session => session("schema_attributes").as[Map[String, String]].isEmpty) {
            exec(
                echo()
                    .check(bodyString.saveAs("responseBody"))
            )
        } {
            exec(
                echo()
                    .formParamMap("${schema_attributes}")
                    .check(bodyString.saveAs("responseBody"))
            )
        }
        .exec { session => println(session("responseBody").as[String]); session }
    ...
}

В представленном выше тестовом моделировании мы подаем данные из файла и выбираем подмножество атрибутов. который мы храним как карту в сессии. Если такие атрибуты найдены в файле, мы добавляем их в качестве параметров формы при отправке эхо-запроса. В противном случае мы не делаем. В обоих случаях мы храним тело ответа и распечатываем его также. Это отлично работает.

Когда я пытаюсь передать Map в качестве параметра, echo () - это когда начинаются проблемы. Предположим, у меня есть следующая реализация echo:

def echo(extraParameters: Map[String, Any]): HttpRequestBuilder = {
    val request = http("Postman Echo Service Call")
        .get("https://postman-echo.com/get")
        .headers(headers("headers_0"))

    if (extraParameters.nonEmpty) {
        request.formParamMap(extraParameters)
    }

    request
}

и что симуляция делает следующее:

.exec { session =>
            session.set("schema_attributes", session.attributes.filterKeys(key => key.startsWith("some_prefix_")))
}
.exec { session =>
    echo(session.attributes.filterKeys(key => key.startsWith("some_prefix_")))
        .check(bodyString.saveAs("responseBody"))
    session
}
.exec { session => println(session("responseBody").as[String]); session }

Запросы не запускаются, и я получаю следующую ошибку о bodyString отсутствует

[ERROR] i.g.c.a.b.SessionHookBuilder$$anon$1 - 'hook-1' crashed with 'j.u.NoSuchElementException: No attribute named 'responseBody' is defined', forwarding to the next one

Альтернатива, которую я пробовал, состояла в том, чтобы заставить echo принять Expression[Map[String, Any]] и использовать обычный блок exe c (т.е. не тот, который был введен в сеанс). В этом случае я не смог получить реальную карту из сеанса!

Кажется, что bodyString доступен только при использовании exe c (), а не exe c {session => ...; сессия} Мои Scala знания очень малы, что добавляет мне путаницы.

Я чувствую, что упускаю что-то очень фундаментальное в этом. Будем благодарны за любую помощь.

ОБНОВЛЕНИЕ # 1

На основании полученных комментариев, насколько я понимаю, использование функции exec(sessionFunction: Expression[Session]) создает ActionBuilders во время время выполнения, поэтому они не используются (они просто создаются и удаляются).

В попытке сохранить все проверки внутри сценария, сохраняя определение запросов HTTP для другой функции, я попробовал следующую альтернативу:

def echo(): HttpRequestBuilder = {
    http("Postman Echo Service Call")
        .get("https://postman-echo.com/get")
        .headers(headers("headers_0"))
        .formParamMap("${schema_attributes}")
}

// Used as
.feed(myFeeder)
.exec { session => session.set("schemaAttributes", session.attributes.filterKeys(key => key.startsWith("some_prefix_")))
}
.exec(
    echo()
        .check(bodyString.saveAs("responseBody"))
)

Таким образом, у меня проблема в том, что если карта пуста (т.е. информация отсутствует в файле) formParamMap не будет работать. Есть ли способ по желанию добавить formParamMap, если карта на самом деле содержит данные?

В общем, есть ли предпочтительный шаблон / метод для передачи параметров функциям, которые возвращают HttpRequestBuilder s из сценария? Например, если у меня есть другая функция, которая принимает Int в качестве параметра и создает HTTP-запрос с номером в запросе, который должен быть отправлен, как бы я go сделал это?

1 Ответ

1 голос
/ 14 февраля 2020

В ваших примерах echo возвращает HttpRequestBuilder. Как работает gatling, сборщики должны все создаваться при запуске, а затем использоваться для создания запросов, поэтому, когда вы включаете это в функцию сеанса, Builder получает созданный во время выполнения, но затем фактически никогда не выполняется и не изменяется сеанс возвращается.

Чтобы это работало, вам нужно будет вывести echo из функции сеанса. Как вы уже поняли, вам, вероятно, придется изменить сигнатуру метода, чтобы принять какое-то выражение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...