I've got an Akka actor that reads the contents of a file in chunks of around 1500 bytes. When the actor receives a NextBlock message it replies with the next block of data wrapped in a ByteString. A couple very simple tests and manually eyeballing data indicate the actor is working correctly. I'm using Scala 2.11.5, Akka 2.3.9, ScalaTest 2.2.1 and SBT 0.13.5.
I'm having an issue setting up larger test. I want to write around 10kB or so of a test pattern data into a file then verify the Actor's output is what I expect. I'm creating the test pattern via ByteStringBuilder. When I go to write the test data to the file I'm getting NullPointerExceptions. Here is the code for a striped down version of the test that exhibits the issue:
import java.nio.ByteOrder
import java.nio.file.StandardOpenOption._
import java.nio.file.{Files, Paths}
import akka.actor.ActorSystem
import akka.testkit.TestKit
import akka.util.{ByteString, ByteStringBuilder}
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpecLike}
class ByteBufferTest extends TestKit(ActorSystem("ByteBufferTest"))
with WordSpecLike with Matchers with BeforeAndAfterAll {
implicit val byteOrder = ByteOrder.BIG_ENDIAN
val file = Paths.get("test.data")
Files.deleteIfExists(file)
createTestFile()
"A ByteBufferTest" must { "work" in { assert(true) } }
def createTestFile(): Unit = {
val out = Files.newByteChannel(file, CREATE, WRITE)
out.write(contents.toByteBuffer) // Here is where the NPE occurs
out.close()
}
val contents: ByteString = {
val builder = new ByteStringBuilder
(0 to 255).foreach(builder.putInt)
builder.result()
}
override protected def afterAll(): Unit = {
Files.delete(file)
system.shutdown()
}
}
I've tried getting around this a bunch of different ways
No matter what I try I keep ending up with something along the lines of
[debug] Running TaskDef(demo.ByteBufferTest, org.scalatest.tools.Framework$$anon$1@40fbf2c, false, [SuiteSelector])
java.lang.NullPointerException at demo.ByteBufferTest.createTestFile(ByteBufferTest.scala:32)
at demo.ByteBufferTest.<init>(ByteBufferTest.scala:21)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at java.lang.Class.newInstance(Class.java:374)
at org.scalatest.tools.Framework$ScalaTestTask.execute(Framework.scala:641)
at sbt.TestRunner.runTest$1(TestFramework.scala:84)
at sbt.TestRunner.run(TestFramework.scala:94)
at sbt.TestFramework$$anon$2$$anonfun$$init$$1$$anonfun$apply$8.apply(TestFramework.scala:219)
at sbt.TestFramework$$anon$2$$anonfun$$init$$1$$anonfun$apply$8.apply(TestFramework.scala:219)
at sbt.TestFramework$.sbt$TestFramework$$withContextLoader(TestFramework.scala:207)
at sbt.TestFramework$$anon$2$$anonfun$$init$$1.apply(TestFramework.scala:219)
at sbt.TestFramework$$anon$2$$anonfun$$init$$1.apply(TestFramework.scala:219)
at sbt.TestFunction.apply(TestFramework.scala:224)
at sbt.Tests$$anonfun$7.apply(Tests.scala:196)
at sbt.Tests$$anonfun$7.apply(Tests.scala:196)
at sbt.std.Transform$$anon$3$$anonfun$apply$2.apply(System.scala:45)
at sbt.std.Transform$$anon$3$$anonfun$apply$2.apply(System.scala:45)
at sbt.std.Transform$$anon$4.work(System.scala:64)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
at sbt.Execute$$anonfun$submit$1$$anonfun$apply$1.apply(Execute.scala:237)
at sbt.ErrorHandling$.wideConvert(ErrorHandling.scala:18)
at sbt.Execute.work(Execute.scala:244)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
at sbt.Execute$$anonfun$submit$1.apply(Execute.scala:237)
at sbt.ConcurrentRestrictions$$anon$4$$anonfun$1.apply(ConcurrentRestrictions.scala:160)
at sbt.CompletionService$$anon$2.call(CompletionService.scala:30)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Anyone have any ideas what I'm doing wrong?
I've put a example project up on github
I didn't find the exact root cause but it seems that it is related to the initialization when the test class is launched from scala test.
I suggest to put the createTestFile()
in the method of beforeAll(). Tested and it works.
override def beforeAll {
createTestFile()
}