ScalaTest: Suites are being executed but no test cases are actually running? - scala

I am using the latest version of Play framework, along with the following test dependencies from by build.sbt file:
"org.scalatest" %% "scalatest" % "3.0.0",
"org.scalatestplus.play" % "scalatestplus-play_2.11" % "2.0.0-M1"
I have a base specification all of my test cases extend from. I return a Future[Assertion] in each one of my clauses, it looks like this:
trait BaseSpec extends AsyncWordSpec with TestSuite with OneServerPerSuite with MustMatchers with ParallelTestExecution
An example spec looks like this:
"PUT /v1/user/create" should {
"create a new user" in {
wsClient
.url(s"http://localhost:${port}/v1/user")
.put(Json.obj(
"name" -> "username",
"email" -> "email",
"password" -> "hunter12"
)).map { response => response.status must equal(201) }
}
}
I decided to rewrite my current tests using the AsyncWordSpec provided by the newer version of ScalaTest, but when I run the test suite, this is the output that I get:
[info] UserControllerSpec:
[info] PUT /v1/user/create
[info] application - ApplicationTimer demo: Starting application at 2016-11-13T01:29:12.161Z.
[info] application - ApplicationTimer demo: Stopping application at 2016-11-13T01:29:12.416Z after 1s.
[info] application - ApplicationTimer demo: Stopping application at 2016-11-13T01:29:12.438Z after 0s.
[info] application - ApplicationTimer demo: Stopping application at 2016-11-13T01:29:12.716Z after 0s.
[info] application - ApplicationTimer demo: Stopping application at 2016-11-13T01:29:13.022Z after 1s.
[info] ScalaTest
[info] Run completed in 13 seconds, 540 milliseconds.
[info] Total number of tests run: 0
[info] Suites: completed 4, aborted 0
[info] Tests: succeeded 0, failed 0, canceled 0, ignored 0, pending 0
[info] No tests were executed.
[info] Passed: Total 0, Failed 0, Errors 0, Passed 0
[success] Total time: 20 s, completed Nov 12, 2016 8:29:13 PM
All of my test classes are found, built, and seemingly run by the test runner when invoking sbt test. I have also tried using the IDEA test runner, and it reports Empty Test Suite under each one of my test classes. I have exhaustively attempted to RTFM but I cannot see what I am doing wrong. The synchronous versions of my tests are running totally fine.
EDIT 1: A friend suggested to attempt doing whenReady() { /* clause */ } on my Future[WSResponse], but this too has failed.

I was having the same problem while using a test suite with multiple traits. I got it to work by removing all the other traits except for AsyncFlatSpec. I will add them back one at a time as I need them.

Related

OSRM Extract Silently Fails

I'm trying to setup a OSRM backend server using Docker. The host machine is a MacBook Pro with 32GB RAM running OS 10.14 (Mojave).
Having downloaded the england-latest.osm.pbf file I've tried to start the process with the following command.
docker run -t -v $(pwd):/data osrm/osrm-backend osrm-extract -p /opt/car.lua /data/england-latest.osm.pbf
The output is as follows:
[info] Parsed 0 location-dependent features with 0 GeoJSON polygons
[info] Using script /opt/car.lua
[info] Input file: england-latest.osm.pbf
[info] Profile: car.lua
[info] Threads: 6
[info] Parsing in progress..
[info] input file generated by osmium/1.8.0
[info] timestamp: 2018-11-02T21:15:02Z
[info] Using profile api version 4
[info] Found 3 turn restriction tags:
[info] motorcar
[info] motor_vehicle
[info] vehicle
[info] Parse relations ...
[info] Parse ways and nodes ...
[info] Using profile api version 4
[info] Using profile api version 4
[info] Using profile api version 4
[info] Using profile api version 4
[info] Using profile api version 4
At this point the process silently fails and doesn't write any of the files you'd expect. If I use the greater-london-latest.osm.pbf file then everything works fine so I'm guessing it's some sort of memory constraint. How do I go about identifying the problem and fixing it?
After running into the same issue on my Mac, I solved it by increasing the memory available to Docker. Look for the whale icon on the menubar, click then select Preferences > Advanced. Change the slider to a higher amount, press Apply & Restart, then try running again.
https://docs.docker.com/docker-for-mac/#memory
I could run within the 2GB default limit with a 415MB file (Canada > British Columbia) but nothing larger. Given the England file is 422MB, you can probably increase to 4GB and have it work. (Trying to run for all of Canada, a 2.4GB file, needed >8GB of RAM.)

sbt using multiple classloaders

Sbt seems to be using different classloaders, making some tests failing when run more than once in an sbt session, with the following error:
[info] java.lang.ClassCastException: net.i2p.crypto.eddsa.EdDSAPublicKey cannot be cast to net.i2p.crypto.eddsa.EdDSAPublicKey
[info] at com.advancedtelematic.libtuf.crypt.EdcKeyPair$.generate(RsaKeyPair.scala:120)
I tried equivalent code using pattern matching instead of asInstanceOf and I get the same result.
How can I make sure sbt uses the same class loader for all test executions in the same session?
I think it's related to this: Do security providers cause ClassLoader leaks in Java?. Basically Security is re-using providers from old class-loaders. So this could happen in any multi-classpath environment (like OSGi), not just SBT.
Fix for your build.sbt (without forking):
testOptions in Test += Tests.Cleanup(() =>
java.security.Security.removeProvider("BC"))
Experiment:
sbt-classloader-issue$ sbt
> test
[success] Total time: 1 s, completed Jul 6, 2017 11:43:53 PM
> test
[success] Total time: 0 s, completed Jul 6, 2017 11:43:55 PM
Explanation:
As I can see from your code (published here):
Security.addProvider(new BouncyCastleProvider)
you're reusing the same BouncyCastleProvider provider every-time you run a test, as your Security.addProvider works only first time. As sbt creates new class-loader for every "test" run, but re-uses the same JVM - Security is kind-of JVM-scoped singleton as it was loaded by JVM-bootstrap, so classOf[java.security.Security].getClassLoader() == null and sbt cannot reload/reinitialize this class.
And you can easily check that
classOf[org.bouncycastle.jce.spec.ECParameterSpec].getClassLoader()
res30: ClassLoader = URLClassLoader with NativeCopyLoader with RawResources
org.bouncycastle classes are loaded with custom classloader (from sbt) which changes every-time you run test.
So this code:
val generator = KeyPairGenerator.getInstance("ECDSA", "BC")
gets instance of class loaded from old classloader (the one used for first "test" run) and you're trying to initialize it with spec from new classloader:
generator.initialize(ecSpec)
That's why you're getting "parameter object not a ECParameterSpec" exception. The reasoning around "net.i2p.crypto.eddsa.EdDSAPublicKey cannot be cast to net.i2p.crypto.eddsa.EdDSAPublicKey" is basically same.

Changing the Default Play Framework HTTP Port (without Using System Property)

There's an oft-asked question about changing the HTTP port to which a Play application will bind. James Ward's answer is generally accepted as the most complete, but it involves overriding the default by setting a http.port system property. However, is it possible to change this default without having to manually add it to the run command at development time, tweak the environment, or package an override in a runtime configuration?
This can be accomplished by setting the playDefaultPort key, as follows:
import PlayKeys._
playDefaultPort := 9123
Afterwards, you'll be able to run and testProd without needing to remember the desired port.
This works in both development:
$ sbt run
[info] Loading project definition from /Users/michaelahlers/Projects/MyApp/project
[info] Set current project to MyApp (in build file:/Users/michaelahlers/Projects/MyApp/)
--- (Running the application, auto-reloading is enabled) ---
[info] p.c.s.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9123
(Server started, use Ctrl+D to stop and go back to the console...)
And production modes:
$ sbt testProd
[info] Loading project definition from /Users/michaelahlers/Projects/MyApp/project
[info] Set current project to MyApp (in build file:/Users/michaelahlers/Projects/MyApp/)
[info] Packaging /Users/michaelahlers/Projects/MyApp/target/scala-2.11/MyApp_2.11-1.0.0-SNAPSHOT-web-assets.jar ...
[info] Done packaging.
(Starting server. Type Ctrl+D to exit logs, the server will remain in background)
2016-04-08 13:09:45,594 [info] a.e.s.Slf4jLogger - Slf4jLogger started
2016-04-08 13:09:45,655 [info] play.api.Play - Application started (Prod)
2016-04-08 13:09:45,767 [info] p.c.s.NettyServer - Listening for HTTP on /0:0:0:0:0:0:0:0:9123

How to configure sbt test / ScalaTest to only show failures?

Is there a way to truncate the test results to only show result text for unit tests only when the unit test has failed? I'm working on a Scala project that has 850 unit tests, and the green text from the successful unit tests makes it difficult to focus on just the failures.
Example of what I'm talking about:
[info] - should have colors
[info] - should not be dead
//.... x 100
[info] - animals should not be rainbows *** FAILED ***
[info] -"[rainbow]s" was not equal to "[ponie]s" (HappinessSpec.scala:31)
What I would like is something that just shows the failure(s):
[info] - animals should not be rainbows *** FAILED ***
[info] -"[rainbow]s" was not equal to "[ponie]s" (HappinessSpec.scala:31)
I realize there is the test-quick sbt command, but it's still running 300 successful
unit tests in my case when there are only 30 failures.
Something along the lines of this in terms of usage is what I'm looking for:
sbt> ~ test -showOnlyFailures
I would also be happy with something that shows all of the failures at the end of running
the unit tests. IIRC, this is how RSpec works in Ruby...
After adding the following to build.sbt, scalaTest will show a fail summary after the standart report:
testOptions in Test += Tests.Argument("-oI")
I - show reminder of failed and canceled tests without stack traces
T - show reminder of failed and canceled tests with short stack traces
G - show reminder of failed and canceled tests with full stack traces
There is also a "drop TestSucceeded events" flag, but I have failed to use it:
http://www.scalatest.org/user_guide/using_the_runner
Updated answer for Scalatest 3.
Here's the new syntax for your build.sbt file to reprint all the failures at the bottom of the test suite run:
testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-oI")
You might also want to suppress the info notifications, so it's easier to see the failures.
testOptions in Test += Tests.Argument(TestFrameworks.ScalaTest, "-oNCXELOPQRM")
Here's what all the options represent:
N - drop TestStarting events
C - drop TestSucceeded events
X - drop TestIgnored events
E - drop TestPending events
H - drop SuiteStarting events
L - drop SuiteCompleted events
O - drop InfoProvided events
P - drop ScopeOpened events
Q - drop ScopeClosed events
R - drop ScopePending events
M - drop MarkupProvided events
"-oI" prints the error notifications again at the end of the test suite run whereas "-oNCXELOPQRM" only shows the tests that fail.
See the configuring reporters section on the ScalaTest website for more detail.
For those using maven with the scalatest-maven-plugin, you can add this configuration:
<configuration>
<stdout>I</stdout>
</configuration>
You could try the sbt command
last-grep error test
This should show you the errors/failures only.

Play2 & ReactiveMongo testing issue: db connection right after test fails

I am implementing a file storage service, which is taking a file and saving it into gridFS with special metadata. Of course, I want to be sure everything's working in integration -- files are really stored in database and then retrieved from it.
I use Play Framework 2.1.3 Scala and ReactiveMongo 0.9.
My test cases looks like the following:
"show empty uploaded size on init" in {
running(FakeApplication()) {
Await.result(FileStorage.getFilesSize(profileId), duration) must beNone
}
}
I have tried to wrap every case with running, or all cases, or even Thread.sleep. But database is always up after test fails.
[error] There is no started application
[error] play.api.Play$$anonfun$current$1.apply(Play.scala:51)
[error] play.api.Play$$anonfun$current$1.apply(Play.scala:51)
[error] play.api.Play$.current(Play.scala:51)
[error] content.FileStorage$.db$lzycompute(FileStorage.scala:32)
...
[info] Total for specification FileStorageSpec
[info] Finished in 21 ms
[info] 5 examples, 1 failure, 4 errors
[info]
[info] application - ReactiveMongoPlugin starting...
[info] application - ReactiveMongoPlugin successfully started with db 'test'! Servers:
[localhost:27017]
[info] play - Starting application default Akka system.
[info] play - Shutdown application default Akka system.
What am I doing wrong? How do you test ReactiveMongo applications?
In the FileStorage object you have these lines:
lazy val db = ReactiveMongoPlugin.db
val gridFS = GridFS(db, "file")
val collection = db.collection[JSONCollection]("file.files")
collection.indexesManager.ensure(Index(Seq("metadata.profileId" -> IndexType.Ascending)))
When the object is instantiated, the above lines of code are executed. Since you have no control of object instantiation you can not be sure when that happens.
It will probably help to change the lines into this:
def db = ReactiveMongoPlugin.db
def gridFS = GridFS(db, "file")
def collection = {
val collection = db.collection[JSONCollection]("file.files")
collection.indexesManager.ensure(Index(Seq("metadata.profileId" -> IndexType.Ascending)))
collection
}