doIf is true even when expecting it to be false

Hi want to iterate through a csv file of serial numbers and when I find a serial number that has not bee used create an object from it. I’m use asLongAs to loop through the csv file and a doIf when a serialNumber has been used (testing it with a get api call):

def addPNPManagedDevice: ChainBuilder = {

val snCounter = csvMDPNPFeeder.queue.readRecords.length
val count = new java.util.concurrent.atomic.AtomicInteger(0)

feed(csvMDPNPFeeder)
.asLongAs(condition = _ => count.getAndIncrement() < snCounter, exitASAP = true) {
exec(http(“Create MD Device with Unused Serial Number”)
.get("/manage/api/v8/devices?models=&page=0&pageSize=1&serialKeys=${serialNumber}")
.headers(sessionHeaders)
.check(jsonPath("$[‘contents’][0][‘id’]").exists.saveAs(“snUsed”)))
.doIf(session => session(“snUsed”).asOption[String].isEmpty) {
exec(http(“Create New PNP Device”)
.post("/manageddevice/api/v4/devices")
.headers(sessionHeaders)
.body(ElFileBody(“bodies/manageddevice/MSXCreatePNPManagedDeviceDoETemplate.json”)).asJson
.check(status.in(200 to 201))
.check(jsonPath("$[‘responseObject’][‘name’]").find.saveAs(“deviceName”))
.check(jsonPath("$[‘responseObject’][‘id’]").find.saveAs(“deviceId”)))
.pause(5)
.exec(session => {
count.set(snCounter * 2)
session
})
}
.exec(_.set(“snUsed”, “”))
}
}

The problem i am see is that my code always goes into the doIf statement whether it the get found “contents” empty or not.

This is what the empty and response looks like:
{ “page”: 0, “pageSize”: 1, “totalItems”: null, “hasNext”: false, “hasPrevious”: false, “sortBy”: null, “sortOrder”: null, “contents”: [] }

This is a segment of a response when the serialNumber is being used:
{ “page”: 0, “pageSize”: 1, “totalItems”: null, “hasNext”: true, “hasPrevious”: false, “sortBy”: null, “sortOrder”: null, “contents”: [ { “id”: “d21ed5ac-1746-4680-8f04-013629849ea0”, …

I assume that the problem is that no matter what is returned something always exists and is not “isEmpty” but don’t know how to fix.

-George

Because “.exec(_.set(“snUsed”, “”))” will always cause .doIf(session => session(“snUsed”).asOption[String].isEmpty) to succeed, even when the previous request fails.

What you want is “.exec(_.remove(“snUsed”))”

Thank you Stephane! After I sent my note to you I looked at some previous help you gave me and I applied that advice here (also I had my feeder outside the loop so it only used the first item in csv) Please let me know if this is a better solution than my previous attempt:

def addPNPManagedDevice: ChainBuilder = {
val snCounter = csvMDPNPFeeder.queue.readRecords.length
val count = new java.util.concurrent.atomic.AtomicInteger(0)

asLongAs(condition = _ => count.getAndIncrement() < snCounter, exitASAP = true) {
feed(csvMDPNPFeeder)
.exec(http(“Create Device with Unused Serial Number”)
.get("/manage/api/v8/devices?models=&page=0&pageSize=1&serialKeys=${serialNumber}")
.headers(sessionHeaders)
.check(jsonPath("$[‘hasNext’]").exists.saveAs(“hasNext”)))
.exec { session =>
val isSNUsed = if (session(“hasNext”).as[Boolean]) false else true
session.set(“boolUsed”, isSNUsed)
}
.doIf(session => session(“boolUsed”).as[Boolean]) {
exec(http(“Create New Device”)
.post("/manageddevice/api/v4/devices")
.headers(sessionHeaders)
.body(ElFileBody(“bodies/manageddevice/MSXCreatePNPManagedDeviceDoETemplate.json”)).asJson
.check(status.in(200 to 201))
.check(jsonPath("$[‘responseObject’][‘name’]").find.saveAs(“deviceName”))
.exec(session => {
count.set(snCounter * 2)
session
})
}
}
}

Hi Stephane, I started running the script below and I am expecting it to create 50 devices but it stops creating when count reaches between 4-12 devices (depending on how fast I ramp up - the faster the ramp up the more it creates). this is the most recent version of the code. Can you see why it would stop short of creating 50 devices?:

def addDevice: ChainBuilder = {

val snCounter = csvMDPNPFeeder.queue.readRecords.length
val count = new java.util.concurrent.atomic.AtomicInteger(0)

asLongAs(condition = _ => count.getAndIncrement() < snCounter, exitASAP = false) {
feed(csvMDPNPFeeder)
.exec(http(“Create Device with Unused Serial Number”)
.get("/md/devices?models=&page=0&pageSize=1&serialKeys=${serialNumber}")
.headers(sessionHeaders)
.check(jsonPath("$[‘hasNext’]").exists.saveAs(“hasNext”)))
.exec { session =>
val isSNUsed = if (session(“hasNext”).as[Boolean]) false else true //if hasNext is true then set flag to false and will not go into doIf else set to true and enters doIf
session.set(“flag”, isSNUsed)
}
.doIf(session => session(“flag”).as[Boolean]) {
exec(http(“Create New Device”)
.post("/md/api/devices")
.headers(sessionHeaders)
.body(ElFileBody(“bodies/DETemplate.json”)).asJson
.check(status.in(200 to 201))
.check(jsonPath("$[‘responset’][‘name’]").find.saveAs(“deviceName”))
.check(jsonPath("$[‘responset’][‘id’]").find.saveAs(“deviceId”)))
.pause(5)
.exec(session => {
count.set(snCounter * 2)
session
})
}
.exec(_.remove(“flag”))
}
}

You should clean up your boolean logic:

session.set(“boolUsed”, !session(“hasNext”).as[Boolean]))

What is this?

.exec(session => {
count.set(snCounter * 2)
session
}

I use it to break out of the loop when I’ve created one device with that user (I only want my 50 users to create one each device because each user represents a location)

asLongAs(condition = _ => count.getAndIncrement() < snCounter, exitASAP = false) //I force count to be greater than the snCount to break the condition

Please let me know if there is a better way (And I’m sure there is) to break out of loop
-GK

Stephane, can you explain where the “session.set(“boolUsed”, !session(“hasNext”).as[Boolean]))” statement belongs in my script? I’m still shaky on the session variable syntax LOL!! I know you are going to shoot me :grinning: