The idea is to filter the sources, replacing @<var>@ occurrences with the mapping for <var> (which is currently hard-coded). @@ -> @. In order to make this work, I had to move the doc sources one directory down (into akka-docs/rst) so that the filtered result could be in a sibling directory so that relative links (to _sphinx plugins or real code) would continue to work. While I was at it I also changed it so that WARNINGs and ERRORs are not swallowed into the debug dump anymore but printed at [warn] level (minimum). One piece of fallout is that the (online) html build is now run after the normal one, not in parallel.
This commit is contained in:
parent
c0f60da8cc
commit
9bc01ae265
266 changed files with 270 additions and 182 deletions
225
akka-docs/rst/dev/multi-jvm-testing.rst
Normal file
225
akka-docs/rst/dev/multi-jvm-testing.rst
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
|
||||
.. _multi-jvm-testing:
|
||||
|
||||
###################
|
||||
Multi-JVM Testing
|
||||
###################
|
||||
|
||||
Support for running applications (objects with main methods) and
|
||||
ScalaTest tests in multiple JVMs.
|
||||
|
||||
|
||||
Setup
|
||||
=====
|
||||
|
||||
The multi-JVM testing is an sbt plugin that you can find here:
|
||||
|
||||
http://github.com/typesafehub/sbt-multi-jvm
|
||||
|
||||
You can add it as a plugin by adding the following to your project/plugins.sbt::
|
||||
|
||||
addSbtPlugin("com.typesafe.sbt" % "sbt-multi-jvm" % "0.3.0")
|
||||
|
||||
You can then add multi-JVM testing to ``project/Build.scala`` by including the ``MultiJvm``
|
||||
settings and config. For example, here is an example of how the akka-remote-tests project adds
|
||||
multi-JVM testing (Simplified for clarity):
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
import sbt._
|
||||
import Keys._
|
||||
import com.typesafe.sbt.SbtMultiJvm
|
||||
import com.typesafe.sbt.SbtMultiJvm.MultiJvmKeys.{ MultiJvm, extraOptions }
|
||||
|
||||
object AkkaBuild extends Build {
|
||||
|
||||
lazy val remoteTests = Project(
|
||||
id = "akka-remote-tests",
|
||||
base = file("akka-remote-tests"),
|
||||
dependencies = Seq(remote, actorTests % "test->test", testkit % "test->test"),
|
||||
settings = defaultSettings ++ Seq(
|
||||
// disable parallel tests
|
||||
parallelExecution in Test := false,
|
||||
extraOptions in MultiJvm <<= (sourceDirectory in MultiJvm) { src =>
|
||||
(name: String) => (src ** (name + ".conf")).get.headOption.map("-Dakka.config=" + _.absolutePath).toSeq
|
||||
},
|
||||
test in Test <<= (test in Test) dependsOn (test in MultiJvm)
|
||||
)
|
||||
) configs (MultiJvm)
|
||||
|
||||
lazy val buildSettings = Defaults.defaultSettings ++ SbtMultiJvm.multiJvmSettings ++ Seq(
|
||||
organization := "com.typesafe.akka",
|
||||
version := "@version@",
|
||||
scalaVersion := "@scalaVersion@",
|
||||
crossPaths := false
|
||||
)
|
||||
|
||||
lazy val defaultSettings = buildSettings ++ Seq(
|
||||
resolvers += "Typesafe Repo" at "http://repo.typesafe.com/typesafe/releases/"
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
You can specify JVM options for the forked JVMs::
|
||||
|
||||
jvmOptions in MultiJvm := Seq("-Xmx256M")
|
||||
|
||||
|
||||
Running tests
|
||||
=============
|
||||
|
||||
The multi-jvm tasks are similar to the normal tasks: ``test``, ``test-only``,
|
||||
and ``run``, but are under the ``multi-jvm`` configuration.
|
||||
|
||||
So in Akka, to run all the multi-JVM tests in the akka-remote project use (at
|
||||
the sbt prompt):
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
akka-remote-tests/multi-jvm:test
|
||||
|
||||
Or one can change to the ``akka-remote-tests`` project first, and then run the
|
||||
tests:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
project akka-remote-tests
|
||||
multi-jvm:test
|
||||
|
||||
To run individual tests use ``test-only``:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
multi-jvm:test-only akka.remote.RandomRoutedRemoteActor
|
||||
|
||||
More than one test name can be listed to run multiple specific
|
||||
tests. Tab-completion in sbt makes it easy to complete the test names.
|
||||
|
||||
It's also possible to specify JVM options with ``test-only`` by including those
|
||||
options after the test names and ``--``. For example:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
multi-jvm:test-only akka.remote.RandomRoutedRemoteActor -- -Dsome.option=something
|
||||
|
||||
|
||||
Creating application tests
|
||||
==========================
|
||||
|
||||
The tests are discovered, and combined, through a naming convention. MultiJvm tests are
|
||||
located in ``src/multi-jvm/scala`` directory. A test is named with the following pattern:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
{TestName}MultiJvm{NodeName}
|
||||
|
||||
That is, each test has ``MultiJvm`` in the middle of its name. The part before
|
||||
it groups together tests/applications under a single ``TestName`` that will run
|
||||
together. The part after, the ``NodeName``, is a distinguishing name for each
|
||||
forked JVM.
|
||||
|
||||
So to create a 3-node test called ``Sample``, you can create three applications
|
||||
like the following::
|
||||
|
||||
package sample
|
||||
|
||||
object SampleMultiJvmNode1 {
|
||||
def main(args: Array[String]) {
|
||||
println("Hello from node 1")
|
||||
}
|
||||
}
|
||||
|
||||
object SampleMultiJvmNode2 {
|
||||
def main(args: Array[String]) {
|
||||
println("Hello from node 2")
|
||||
}
|
||||
}
|
||||
|
||||
object SampleMultiJvmNode3 {
|
||||
def main(args: Array[String]) {
|
||||
println("Hello from node 3")
|
||||
}
|
||||
}
|
||||
|
||||
When you call ``multi-jvm:run sample.Sample`` at the sbt prompt, three JVMs will be
|
||||
spawned, one for each node. It will look like this:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
> multi-jvm:run sample.Sample
|
||||
...
|
||||
[info] Starting JVM-Node1 for sample.SampleMultiJvmNode1
|
||||
[info] Starting JVM-Node2 for sample.SampleMultiJvmNode2
|
||||
[info] Starting JVM-Node3 for sample.SampleMultiJvmNode3
|
||||
[JVM-Node1] Hello from node 1
|
||||
[JVM-Node2] Hello from node 2
|
||||
[JVM-Node3] Hello from node 3
|
||||
[success] Total time: ...
|
||||
|
||||
|
||||
Naming
|
||||
======
|
||||
|
||||
You can change what the ``MultiJvm`` identifier is. For example, to change it to
|
||||
``ClusterTest`` use the ``multiJvmMarker`` setting::
|
||||
|
||||
multiJvmMarker in MultiJvm := "ClusterTest"
|
||||
|
||||
Your tests should now be named ``{TestName}ClusterTest{NodeName}``.
|
||||
|
||||
|
||||
Configuration of the JVM instances
|
||||
==================================
|
||||
|
||||
You can define specific JVM options for each of the spawned JVMs. You do that by creating
|
||||
a file named after the node in the test with suffix ``.opts`` and put them in the same
|
||||
directory as the test.
|
||||
|
||||
For example, to feed the JVM options ``-Dakka.remote.port=9991`` to the ``SampleMultiJvmNode1``
|
||||
let's create three ``*.opts`` files and add the options to them.
|
||||
|
||||
``SampleMultiJvmNode1.opts``::
|
||||
|
||||
-Dakka.remote.port=9991
|
||||
|
||||
``SampleMultiJvmNode2.opts``::
|
||||
|
||||
-Dakka.remote.port=9992
|
||||
|
||||
``SampleMultiJvmNode3.opts``::
|
||||
|
||||
-Dakka.remote.port=9993
|
||||
|
||||
ScalaTest
|
||||
=========
|
||||
|
||||
There is also support for creating ScalaTest tests rather than applications. To
|
||||
do this use the same naming convention as above, but create ScalaTest suites
|
||||
rather than objects with main methods. You need to have ScalaTest on the
|
||||
classpath. Here is a similar example to the one above but using ScalaTest::
|
||||
|
||||
package sample
|
||||
|
||||
import org.scalatest.WordSpec
|
||||
import org.scalatest.matchers.MustMatchers
|
||||
|
||||
class SpecMultiJvmNode1 extends WordSpec with MustMatchers {
|
||||
"A node" should {
|
||||
"be able to say hello" in {
|
||||
val message = "Hello from node 1"
|
||||
message must be("Hello from node 1")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class SpecMultiJvmNode2 extends WordSpec with MustMatchers {
|
||||
"A node" should {
|
||||
"be able to say hello" in {
|
||||
val message = "Hello from node 2"
|
||||
message must be("Hello from node 2")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
To run just these tests you would call ``multi-jvm:test-only sample.Spec`` at
|
||||
the sbt prompt.
|
||||
Loading…
Add table
Add a link
Reference in a new issue