The goal of this project is to be able to support IMAP protocol into Gatling.
For now only the following commands are supported:
-
APPEND
-
CAPABILITY
-
CHECK
-
CLOSE
-
ENABLE
-
EXPUNGE
-
FETCH
-
GETACL (RFC-4314)
-
GETQUOTAROOT (RFC-2087)
-
IDLE (RFC-2177)
-
LIST
-
LOGIN
-
LOGOUT
-
LSUB
-
MYRIGHTS (RFC-4314)
-
NAMESPACE (RFC-2342)
-
NOOP
-
SEARCH
-
SELECT
-
STATUS
-
STORE
-
UID FETCH
-
UID SEARCH
-
UNSELECT (RFC-3691)
-
SUBSCRIBE
-
UNSUBSCRIBE
-
CREATE FOLDER
-
DELETE FOLDER
-
RENAME FOLDER
-
EXAMINE FOLDER
-
MOVE (RFC-6851)
-
COPY
-
GETQUOTA (RFC-2087)
-
SETQUOTA (RFC-2087)
-
UID COPY
-
UID EXPUNGE
-
UID MOVE
-
UID STORE
-
COMPRESS (RFC-4978)
-
ok: last response is OK
-
no: last response is NO
-
bad: last response is BAD
-
hasFolder(String): one LIST response contains the folder
-
hasRecent(Int): one response contains xxx RECENT
-
hasNoRecent: one response contains 0 RECENT
-
hasUid(Uid): one response contains UID xxx
-
contains(String): one response contains the provided string
-
debug: print current responses on standard output
You can find a full example into ImapAuthenticationScenario. Here is the interesting part:
val feeder = Array(Map("username"->"user1", "password"->"password")).circular val UserCount: Int = 10 val scn = scenario("ImapAuthentication").feed(feeder) .exec(imap("Connect").connect()).exitHereIfFailed .exec(imap("login").login("${username}","${password}").check(ok)) .exec(imap("list").list("", "*").check(ok, hasFolder("INBOX"))) .exec(imap("select").select("INBOX").check(ok, hasRecent(0))) .exec(imap("append").append("INBOX", Some(Seq("\\Flagged")), Option.empty[Calendar], """From: expeditor@example.com |To: recipient@example.com |Subject: test subject | |Test content""".stripMargin).check(ok)) .exec(imap("fetch").fetch(Seq(One(1), One(2), Range(3,5), From(3), One(8), To(1)), AttributeList("BODY", "UID")).check(ok, hasUid(Uid(1)), contains("TEXT"))) setUp(scn.inject(constantUsersPerSec(UserCount).during(2.seconds))).protocols(imap.host("localhost"))
You can set up the following system properties:
-
TARGET_HOSTNAME
which is set tolocalhost
by default -
IMAP_PORT
which is set to143
by default -
IMAP_PROTOCOL
(imap
orimaps
) which is set toimap
by default.
To easily launch provided integration tests and gatling test, you can run a Cyrus instance with the following commands.
First run Cyrus via Docker:
$ docker run -d --name cyrus -p 143:143 linagora/cyrus-imap
Then create a user:
$ docker exec -ti cyrus bash -c 'echo password | saslpasswd2 -u test -c user1 -p'
And create its INBOX:
$ telnet localhost 143 . LOGIN cyrus cyrus A1 CREATE user.user1 A2 CREATE user.user1.INBOX
Then you can check all is fine with a new telnet session:
$ telnet localhost 143 . LOGIN user1 password A1 SELECT INBOX
You should obtain the following result:
$ telnet localhost 143 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. * OK [CAPABILITY IMAP4rev1 LITERAL+ ID ENABLE AUTH=PLAIN SASL-IR] test Cyrus IMAP v2.4.17-caldav-beta10-Debian-2.4.17+caldav~beta10-18 server ready . LOGIN user1 password . OK [CAPABILITY IMAP4rev1 LITERAL+ ID ENABLE ACL RIGHTS=kxte QUOTA MAILBOX-REFERRALS NAMESPACE UIDPLUS NO_ATOMIC_RENAME UNSELECT CHILDREN MULTIAPPEND BINARY CATENATE CONDSTORE ESEARCH SORT SORT=MODSEQ SORT=DISPLAY THREAD=ORDEREDSUBJECT THREAD=REFERENCES ANNOTATEMORE LIST-EXTENDED WITHIN QRESYNC SCAN XLIST X-REPLICATION URLAUTH URLAUTH=BINARY LOGINDISABLED COMPRESS=DEFLATE IDLE] User logged in SESSIONID=<cyrus-28-1478786954-1> A1 SELECT INBOX * 0 EXISTS * 0 RECENT * FLAGS (\Answered \Flagged \Draft \Deleted \Seen) * OK [PERMANENTFLAGS (\Answered \Flagged \Draft \Deleted \Seen \*)] Ok * OK [UIDVALIDITY 1478786897] Ok * OK [UIDNEXT 1] Ok * OK [HIGHESTMODSEQ 1] Ok * OK [URLMECH INTERNAL] Ok A1 OK [READ-WRITE] Completed
Some simple integration tests are available via:
$ sbt GatlingIt/test
Finally, execute your gatling scenarios:
$ sbt gatling:test
Or only the specified one:
$ sbt "gatling:testOnly com.linagora.gatling.imap.scenario.ImapAuthenticationScenario"
You can also pass parameter to scenario that accept it like that:
$ JAVA_OPTS="-DnumberOfMailInInbox=15 -DpercentageOfMailToExpunge=30 -DmaxDuration=20" sbt "gatling:testOnly com.linagora.gatling.imap.scenario.ImapExpungeScenario"
In the case of expunge scenario the maxDuration parameter is in minutes
You can use a custom local jenkins runner with the Jenkinsfile
at the root of this project to build the project.
This will automatically do for you:
-
checkout and compile the latest code of Gatling-imap project
-
launch Gatling integration tests
To launch it you need to have docker installed. From the root of this project, you can build the Jenkins runner locally yourself:
docker build -t local-jenkins-runner dockerfiles/jenkins-runner
And then you need to launch it with the Jenkinsfile:
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v ${PWD}/dockerfiles/jenkins-runner/Jenkinsfile:/workspace/Jenkinsfile --network=host local-jenkins-runner
If you don’t want the build to redownload everytime all the sbt dependencies (it can be heavy) you can mount
your local sbt repository as a volume by adding -v $HOME/.ivy2/cache:/root/.ivy2/cache
to the above command.