String cannot be cast to scala.collection.immutable.List Error

Hello,
I am pretty new here so please bear with me. I am extracting a number of eventids into a list and iterate over that list repeatedly to use a unique event id in the subsequent request. However, when I try to simulate this, I am getting a String cannot be cast to scala.collection.immutable.List error. Below is my code. Could you please point out where exactly is the mistake and what kind of array manipulation function could be used here.

.exec(http(“Home Page”)
.get("/")
.headers(headers_1)
.check(status.is(200))
.check(regex("""‘eventLink’\shref=’/sales/(\d+)""").findAll.saveAs(""“sales_event_id”""))
)

.repeat(4){
exec((session: Session) => { // use a simple action
val sales_event_id = session.getTypedAttributeList[String] // retrieve the eventid saved by the previous check
session.setAttribute(“sales_event_id”, sales_event_id(math.max(rnd.nextInt(sales_event_id.length), 9))) // store in the session a eventid randomly picked
})

.doIf( session => session.isAttributeDefined(“sales_event_id”))
{
exec(http(“EDP”)
.get("/sales/${sales_event_id}")
.headers(headers_1)
.check(status.is(200))
)
}
}

Which version do you use?
Does the problem occurs compile time, or runtime?
Could you provide the full stacktrace please?

Thanks for getting back, Stephane. So Im using 1.5.4 and this error happens during runtime. Her eis the full stack trace

14:37:00.331 [INFO ] c.e.e.g.h.a.HttpRequestAction - Sending Request ‘Home Page’: Scenario ‘Storefront Gatling’, UserId #1

14:37:00.459 [INFO ] c.e.e.g.h.c.CacheHandling$ - Setting LastModified for url https://abc.com:443

14:37:00.466 [INFO ] c.e.e.g.h.a.HttpRequestAction - Sending Request ‘EDP’: Scenario ‘Storefront Gatling’, UserId #1

14:37:02.799 [INFO ] c.e.e.g.h.c.CacheHandling$ - Setting LastModified for url https://abc.com:443/sales/39395

[ERROR] [07/23/2014 14:37:02.802] [GatlingSystem-akka.actor.default-dispatcher-20] [akka://GatlingSystem/user/$Ib] java.lang.String cannot be cast to scala.collection.immutable.List

java.lang.ClassCastException: java.lang.String cannot be cast to scala.collection.immutable.List

at storefront.StorefrontScenario$$anonfun$1.apply(StorefrontScenario.scala:84)

at storefront.StorefrontScenario$$anonfun$1.apply(StorefrontScenario.scala:83)

at com.excilys.ebi.gatling.core.action.SimpleAction.execute(SimpleAction.scala:37)

at com.excilys.ebi.gatling.core.action.Action$$anonfun$receive$1.apply(Action.scala:31)

at com.excilys.ebi.gatling.core.action.Action$$anonfun$receive$1.apply(Action.scala:30)

at akka.actor.Actor$class.apply(Actor.scala:318)

at com.excilys.ebi.gatling.core.action.SimpleAction.apply(SimpleAction.scala:29)

at akka.actor.ActorCell.invoke(ActorCell.scala:626)

at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:197)

at akka.dispatch.Mailbox.run(Mailbox.scala:179)

at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDispatcher.scala:516)

at akka.jsr166y.ForkJoinTask.doExec(ForkJoinTask.java:259)

at akka.jsr166y.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:975)

at akka.jsr166y.ForkJoinPool.runWorker(ForkJoinPool.java:1479)

at akka.jsr166y.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104)

14:37:03.488 [ERROR] c.e.e.g.c.a.SimpleAction - Action SimpleAction crashed, forwarding user to next one

java.lang.ClassCastException: java.lang.String cannot be cast to scala.collection.immutable.List

at storefront.StorefrontScenario$$anonfun$1.apply(StorefrontScenario.scala:84) ~[na:na]

at storefront.StorefrontScenario$$anonfun$1.apply(StorefrontScenario.scala:83) ~[na:na]

at com.excilys.ebi.gatling.core.action.SimpleAction.execute(SimpleAction.scala:37) ~[gatling-core-1.5.4.jar:na]

at com.excilys.ebi.gatling.core.action.Action$$anonfun$receive$1.apply(Action.scala:31) ~[gatling-core-1.5.4.jar:na]

at com.excilys.ebi.gatling.core.action.Action$$anonfun$receive$1.apply(Action.scala:30) ~[gatling-core-1.5.4.jar:na]

at akka.actor.Actor$class.apply(Actor.scala:318) ~[akka-actor-2.0.4.jar:2.0.4]

at com.excilys.ebi.gatling.core.action.SimpleAction.apply(SimpleAction.scala:29) ~[gatling-core-1.5.4.jar:na]

at akka.actor.ActorCell.invoke(ActorCell.scala:626) ~[akka-actor-2.0.4.jar:2.0.4]

at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:197) ~[akka-actor-2.0.4.jar:2.0.4]

at akka.dispatch.Mailbox.run(Mailbox.scala:179) ~[akka-actor-2.0.4.jar:2.0.4]

at akka.dispatch.ForkJoinExecutorConfigurator$MailboxExecutionTask.exec(AbstractDispatcher.scala:516) [akka-actor-2.0.4.jar:2.0.4]

at akka.jsr166y.ForkJoinTask.doExec(ForkJoinTask.java:259) [akka-actor-2.0.4.jar:2.0.4]

at akka.jsr166y.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:975) [akka-actor-2.0.4.jar:2.0.4]

at akka.jsr166y.ForkJoinPool.runWorker(ForkJoinPool.java:1479) [akka-actor-2.0.4.jar:2.0.4]

at akka.jsr166y.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104) [akka-actor-2.0.4.jar:2.0.4]

14:37:03.488 [INFO ] c.e.e.g.h.a.HttpRequestAction - Sending Request ‘EDP’: Scenario ‘Storefront Gatling’, UserId #1

14:37:03.704 [WARN ] c.e.e.g.h.a.GatlingAsyncHandlerActor - Request ‘EDP’ failed : Check ‘is’ failed, found 304 but expected 200

14:37:03.712 [DEBUG] c.e.e.g.h.a.GatlingAsyncHandlerActor -

Request:

EDP: KO Check ‘is’ failed, found 304 but expected 200

This doesn’t make sense?!
Are you sure that you’re not using “sales_event_id” for storing a single String before that?

Nope. This is the first time I am using a sales_event_id variable and my intention is to capture a list of event_ids here. Just for your review, Here is my complete script.

package storefront
import com.excilys.ebi.gatling.core.Predef._
import com.excilys.ebi.gatling.http.Predef._
import StorefrontHeaders._
import akka.util.duration._
import bootstrap._
import scala.util._
import scala.util.Random

object pod1Scenario {

// val r = scala.util.Random
// var x = r.nextInt(20)
val testTimeSecs = 1800
val minWaitMs = 10000 milliseconds
val maxWaitMs = 30000 milliseconds
val rnd = new scala.util.Random
val range = 1 to 20
val id = (range(rnd.nextInt(range length)))

val scn = scenario(“Storefront Pod1”)

.during(testTimeSecs) {

pauseExp(15 seconds)
.exec(http(“XX_LoginPage”)
.get("/login")
.headers(headers_1)
)
.pause(minWaitMs, maxWaitMs)

.feed(csv(“storefront_users.csv”).random)

.pause(minWaitMs, maxWaitMs)

// RAILS Login Request

.exec(http(“XX_LoginPOST”)
.post("/customers/sign-in.json")
.headers(headers_23)
.param(""“email”"", “${username}”)
.param(""“password”"", “${password}”)
.param(""“keepLogIn”"", “”“0"”")
.param(""“applicationType”"", “”“storefront”"")
.param(""“format”"", “”“json”""))
// RAILS Login Request

.repeat(4){
pause(minWaitMs, maxWaitMs)
exec(http(“Home Page”)
.get(“https://abc.com/homepage”)
.headers(headers_1)
.check(status.is(200))
.check(regex("""‘eventLink’\shref=’/sales/(\d+)""").findAll.saveAs(""“sales_event_id”""))
)}

.exec((session: Session) => { // use a simple action
val sales_event_id = session.getTypedAttributeList[String] // retrieve the keywords saved by the previous check
session.setAttribute(“sales_event_id”, sales_event_id(math.max(rnd.nextInt(sales_event_id.length), 9))) // store in the session a keywork randomly picked
})

.pause(minWaitMs, maxWaitMs)

.doIf( session => session.isAttributeDefined(“sales_event_id”))
{
repeat(13){
pause(minWaitMs, maxWaitMs)
exec(http(“XX_EDP”)
.get("/sales/${sales_event_id}")
.headers(headers_1)
.check(status.is(200))
.check(regex(""“data-product-id=’(\d+)”"").find(id).exists.saveAs(""“product_id”""))
)
}}

.exec(http(“XX_To_Retrieve_SKU”)
.get("/product/${sales_event_id}/${product_id}")
.headers(headers_1)
// .check(status.is(200))
.check(regex("""“id”:(\d+),“quantity”:[1-9]*[0-9],“reservable_quantity”:\d+,“on_hold”:false,“price”:""").find(0).exists.saveAs(""“sku_id”""))
)

.pause(minWaitMs, maxWaitMs)

.doIf( session => session.isAttributeDefined(“product_id”))
{
repeat(13){
pause(minWaitMs, maxWaitMs)
exec(http(“XX_PDP Storefront”)
.get("/product/${sales_event_id}/${product_id}")
.headers(headers_1)
.check(status.is(200))
// .check(regex("""‘selectSkuId’\sname=‘skuId’\stype=‘hidden’\svalue=’(\d+)’>""").find.exists.saveAs(""“sku_id”""))
// .check(regex("""<input\sid=‘selectSkuId’\sname=‘skuId’\stype=‘hidden’\svalue=’(\d+)""").find(0).exists.saveAs(""“sku_id”""))
//check to see if a product is sold out. If yes, then dont add to cart
// .check(regex("""<button class=‘addToCart trackAddToCart’ type=‘submit’>Add To Cart</button>""").find.exists.saveAs(""“available”""))

)
} }

.exec(http(“XX_Logout”)
.get("/logout")
.headers(headers_1)
)

}
}

You have two very different snippets of code posted, now. Did you change your code (and are you getting the same error in the same place?), or is it a copy/paste error (and which one is actually correct)? I could tell you exactly what’s going wrong with your first piece of code (where the repeat() is around the session function) - on the first iteration, it was setting the sales_event_id attribute to a single element of the list (a string), and then trying to get that string as a list on the second iteration.

Thanks for the reply, Michelle. Sorry about the second code - it is my old code. I understand your explanation about my original snippet. So could you please tell me how do I extract dynamic valuse from the list ‘sales_event_id’ and use it in the subsequent requests. I also tried the loop{chain} from this example https://gist.github.com/slandelle/2469375, but not much luck there. Getting an error- value loop is not a member of com.excilys.ebi.gatling.core.structure.ChainBuilder’. Appreciate your time.

Hey Stephane,
I also tried with the loop chain to iterate over the list that I have. Here is the code. However, during compilation I get an error stating that ‘value loop is not a member of com.excilys.ebi.gatling.core.structure.ChainBuilder’. Still wondering how to i iterate over a list of sales_event_ids that I extracted from the home page. Appreciate your time.

.exec(http(“Home Page”)
.get(“https://load01.newokl.com/homepage”)
.headers(headers_1)
.check(regex(""“href=’/sales/(\d+)”"").findAll.saveAs(""“sales_event_id”""))
)

.loop(
chain
.exec((session: Session) => { // use a simple action
val keywords = session.getTypedAttributeList[String] // retrieve the keywords saved by the previous check
session.setAttribute(“sales_event_id”, keywords(math.max(rnd.nextInt(sales_event_id.length), 9))) // store in the session a keywork randomly picked
})
.exec(http(“XX_EDP”).get("/sales/${sales_event_id}")))
.counterName(“eventidCounter”)
.asLongAs((session: Session) => {
val sales_event_id = session.getTypedAttributeList[String]
session.getCounterValue(“eventidCounter”) < math.max(sales_event_id.length, 10)
})

Never mind. I figured out how to do it. This piece worked.

.repeat(session => session.getTypedAttributeList[String].size, “loopIndex”) {
exec(http(“XX_EDP for product id”)
.get("/sales/${sales_event_id(loopIndex)}"))
}