当前位置: 首页 > 知识库问答 >
问题:

如何在Gatling负载测试中为多个虚拟用户使用单个OAuth2.0令牌

温峻熙
2023-03-14

我需要加载测试一个需要OAuth2的API。0通过Gatling获得的代币(我完全是新手!)但希望每个虚拟用户使用相同的令牌。我正在检索令牌ok(我想)并将其放入一个名为“access”的变量中,但在测试本身开始时,我一直得到“没有定义名为“access”的属性”。

我的令牌检索如下所示(以及下面使用的httpConf):

 class MySimulation extends Simulation {

 val httpConf = http        
    .baseUrl("https://MyBaseUrl.Com/")
    .acceptHeader("application/json") 
    .doNotTrackHeader("1")
    .acceptLanguageHeader("en-UK,en;q=0.5")
    .acceptEncodingHeader("gzip, deflate")
    .userAgentHeader("Mozilla/5.0 (Macintosh; Intel Mac OS X 10.8; rv:16.0) Gecko/20100101 Firefox/16.0")
    .shareConnections

 val header = Map("Content-Type" -> """application/x-www-form-urlencoded""")

 al auth = scenario("Retrieve Token")
 .exec(http("POST OAuth Req")
 .post("https://SomeTokenUrl")
 .formParam("resource", "someresource")
 .formParam("grant_type", "somegranttype")
 .formParam("client_secret", "someclientsecret")
 .formParam("client_id", "someclientid")
 .headers(header).check(status.is(200)).check(jsonPath("$.access_token").find.saveAs("access"))) 

然后,我尝试将负载测试设置为(注意:我最初确实放了“Map”,而不是可变变量,但在某个地方读到默认值是不可变的,我想知道这是否是标头无法更新的原因):

 val headers_10 = scala.collection.mutable.Map("Content-Type" -> "application/json; charset=ISO-8859-1", "Authorization" -> "Bearer ${access}")

 val scn = scenario("MyService Gatling test run")       
           .exec(http("")               
           .post("Myservice/api")
           .headers(headers_10.toMap)                
           .body(StringBody("""{"SomeProperty": "Some Value"}"""))
           .asJson
           .check(status.is(200)))

 setUp(
    auth.inject(constantUsersPerSec(1) during (2 seconds)),
    scn.inject(nothingFor(2 seconds),
    constantUsersPerSec(10) during (10 seconds) 
    ).protocols(httpConf))
    .assertions(global.responseTime.max.lt(500)) 
    .assertions(forAll.failedRequests.percent.lte(1)) 
    .assertions(global.responseTime.mean.lte(100)) 

其想法是,令牌检索将在负载测试开始之前完成,“访问”变量随后将被负载测试场景使用,但它给出了以下结果:

  ERROR : Failed to build request: No attribute named 'access' is defined 

我已经筋疲力尽了。我猜这可能与作用域有关,而且可能变量没有延续到负载测试场景中,但我在其他地方看到过一些示例,它们似乎完全推荐这种设置,所以我不知道这些其他示例是否部分完成,或者是什么。

共有3个答案

端木震博
2023-03-14

我也在尝试这种情况,但当我尝试添加. exec{会话=时,我得到了错误

       val scn = scenario("MyService Gatling test run")
       .exec{session => { token = session("access").as[String] session}}  
      .exec(http("")               
       .post("Myservice/api")
       .headers(headers_10.toMap)                
       .body(StringBody("""{"SomeProperty": "Some Value"}"""))
       .asJson
       .check(status.is(200)))

我还分别尝试了以下步骤中的更改:-

  setUp(auth.inject(constantUsersPerSec(1) during (2 seconds)),
  .exec{session => { token = session("access").as[String] session}}
  scn.inject(nothingFor(2 seconds),
  constantUsersPerSec(10) during (10 seconds) 
  ).protocols(httpConf))
  .assertions(global.responseTime.max.lt(500)) 
  .assertions(forAll.failedRequests.percent.lte(1)) 
  .assertions(global.responseTime.mean.lte(100)) 

但没有一个成功。你能建议我把代码放在哪里吗。

东方明亮
2023-03-14

会话按用户分配,用户之间不共享会话数据。因此,虽然有一个用户运行“auth”场景并保存令牌,但运行“scn”的是两个不同的用户,他们无权访问auth用户的会话值。

这不是推荐的做法,但您可以通过将身份验证令牌推送到常规scalavar并在身份验证场景中设置this并在主场景中读取它来解决这个问题-您只需要确保身份验证始终在注入任何其他用户之前完成。

var token: String = ""

然后在auth场景中,在最后有一个步骤,例如

.exec(session => {
    token = session("access").as[String]
    session
})

然后在scn场景的开始有一个步骤来设置会话变量

.exec(session.set("access", token))

我用这个模式在过去和它的工作但我相信有更好的方法来做到这一点

宗冠宇
2023-03-14

今天我为我的项目实现了这个场景。请参阅下面的代码,它也适用于您。

注意:我已经用API所需的参数编写了这段代码。您可以根据需要修改此代码。目前,这段代码是在一个类中编写的。我以适当的格式实现了这段代码,并使用了不同的类和属性文件。我也会发布这个。

对于单个类,代码如下所示:

`

package aapi

    import io.gatling.core.Predef._
    import io.gatling.http.Predef._

     class manifestSimulation extends Simulation {    

    private var token = ""

    object authAvi{
     // This is the request(API) which we are going to use for generating the auth token 1 time and then will feed this token into subsequent request.
     var postBody = "{\"username\":\"devusername\”,\”password\”:\”devpassword”}”

    val auth = scenario("Retrieve our auth Token which will be used in the subsequent request“)
        .exec(
            http("POST OAuth Req")
            .post(“User Post URL“)
            .body(StringBody(postBody))
            .header("ClientId", “test”)
    .header("DSN", “devDB”)
    .header("accept", "application/json")
    .header("Accept-Language", "en-us")
    .header("Content-Type", "application/json")
            .check(status.is(200))
    .check(jsonPath("$.token")
    .saveAs("token")))
            .exitHereIfFailed
            .exec{session => { token = session("token").as[String]
                             session}}       
    }
    object manifest {
     // This is the request(API) which we are going to hit multiple times using the token which we generated from the previous auth API

        var manifestHeaders = Map("ClientId" -> “test”, "DSN" -> "devDB", "Token" -> "${token}")

        val manifestMethod = exec(session => session.set("token", token))            
            .exec(http("Manifest Details")              
                .get(“Your get URL“)
                .headers(manifestHeaders)
                .check(status.is(200))
                 )
    }   

    val scn = scenario(“**********This is your actual load test*******************”)
        .exec(manifest.manifestMethod)
       setUp(
      authAvi.auth.inject(constantUsersPerSec(1) during (1 seconds)), // fire 1 requests per second for 1 second to retrieve token
    scn.inject(nothingFor(4 seconds), // waits 4 seconds as a margin to process token and this time varies for every user
        constantUsersPerSec(5) during (5 seconds))) // fire 5 requests per second for 5 seconds which will result in 25 (5*5) requests and overall 26 requests when the report gets generated (because we have 1 request for auth token and 25 requests of our intended API (25+1 = 26)

     }`
 类似资料:
  • 我试图在jmeter中运行一个包含3000个用户和50个循环的负载测试,但它显示了这个错误。 我还尝试使用-来增加堆大小 但同样的OutOfMemory问题依然存在。笔记本电脑的RAM-8GB感谢帮助

  • 我正在尝试进行一个模拟,其中Gatling中的每个虚拟用户都有一个唯一的登录/身份验证,并执行我记录和编码的一系列操作。但我正在努力正确设置授权。这是我的代码 因此,当我在静态声明中提供用户名和密码时(我已经注释掉了.basicAuth行),它就可以工作了。然而,就服务器而言,gatling创建的每个虚拟用户都是相同的用户。如果我运行我在这里添加的代码,我的所有请求都会得到http 401s,这是

  • 假设我需要编写一个gatling负载测试脚本,它需要调用两个api A1和A2。它首先需要调用A1,A1将返回一个JSON负载,它需要在JSON负载中提取一个字段,并在调用第二个API时使用该字段值。有人能告诉我怎么做吗?此脚本用于负载测试通过HTTP的服务器restful API。

  • 我是加特林和斯卡拉的新手,我需要你的建议。我想获得n用户的负载测试。每个用户都必须发送创建不同帐户的请求。这是通过发送带有适当对象数组的json文件(在本例中为“条目”)获得的。每个用户必须发送不同的登录名,因为我们的后端系统正在检查用户名是否唯一。不知何故,我们必须确保gatling为每个虚拟用户以及每个条目发送不同的数据。我们注意到有一个会话元素,它代表虚拟用户的状态。问题是,下面显示的代码将

  • 我想写一个gatling负载测试模拟类。我有三个请求:请求1、请求2和请求3。我希望能够在5秒内完成300个用户的负载测试。我还需要测试总共运行20分钟。 现在,我需要同时运行这三个请求,但需要90%的吞吐量、5%的吞吐量和5%的吞吐量。例如:如果有100个请求,90个必须是请求1和请求2的5,以及请求3的5。 到目前为止,我的课程是: 我不确定如何将这三个api放在一个场景中并分别使用updat

  • 我如何负载测试一个同时有300个用户使用jmeter的登录页面(而不是一个又一个用户。同时有300个用户登录)?线程组的设置应该是什么?