I'm trying to use ostrich as configuration library in my new application (previously I had a positive experience using it for runtime statistics). But I can't get it work using the code snippet from the readme.
Here is my code:
class Boot {
val bootLogger = LoggerFactory.getLogger(this.getClass)//slf4j
val confPath = Option(System.getenv("CONF_FILE"))
//living inside akka-kernel, so there is no access to real args
val args: Array[String] = confPath match {
case Some(path) => Array("-f", path)
case None => Array()
}
bootLogger.info(Class.forName("la.myproject.Config").toString)
val runtime = RuntimeEnvironment(this, args)
val server = runtime.loadRuntimeConfig[Server]()
try {
server.start()
} catch {
case e: Exception =>
bootLogger.error("Server start failed", e)
}
}
And this is my config:
new la.myproject.Config {
//use the defaults
}
The program successfully loads the configuration class and fails with the following eror:
Error in config file: ../../src/main/conf/myproject.scala
com.twitter.util.Eval$CompilerException: Compiler exception error: line 3: not found: value la
new la.myproject.Config {
I guess that it is a class loading problem. But digging through sources gave me no clue why it happens. Ostrich as well as Eval utility don't touch classloading at all.
In your config file:
import la.myproject.Config
Related
At work we've created this plugin, and from one of its inputKey it's suppose to log an exception (whenever that occurs). For demonstration purposes I've only used the relevant stuff, so have a look at the following code:
theTask := {
streams.value.log
val args: Seq[String] = spaceDelimited("<arg>").parsed
args.foreach { arg =>
val env = SomeLogicThatPotentiallyThrowsException(arg)
}
}
object SomeLogicThatPotentiallyThrowsException {
def apply(arg: String): String = {
if(arg==throwexception) throw Exception("Boom!")
else arg
}
}
so whenever I'm trying to use the plugin and execute the task as follows:
sbt theTask throwexception
The error is only logged whenever I've added streams.value.log as a statement in the theTask task..
So yeah.. am I doing anything wrong here or is this a bug in sbt?
Thanks for reading people
Using Play 2.7. In a test class, I want to test a service that reads the configuration (properties) file conf/fun.conf.
I could not find any example how to carry out this feat. I have looked at the Play documentation and also questions here, but found nothing.
The service I wrote gets Configuration through injection:
class MyFunService #Inject() (config: Configuration) extends FunService {
override def getValue(key: String) = config.get[String](key)
}
I want to call this service from a test:
class FunSpec(implicit ee: ExecutionEnv) extends Specification {
sequential
"The FunService" should {
"retrieve a value" in new WithApplication() {
//Oops! Does not actually read the conf file...
val env = play.api.Environment.simple()
val config = play.api.Configuration.load(env)
//...so getting an Exception here.
val f = Future(new MyFunService(config).getValue("fun_stuff"))
f must beEqualTo("having_fun").await(retries = 0, timeout = 5.seconds)
}
}
}
I'm using this code to read test resources
import com.google.common.base.Charsets.UTF_8
import com.google.common.io.Resources
object ResourceFileSupport {
def read(file: String) =
Resources.toString(
Option( this.getClass.getClassLoader.getResource(file) ).getOrElse {
throw new IllegalArgumentException(s"resource $file not found in classpath.")
}, UTF_8)
}
Consider the following code:
import chisel3._
import chisel3.util._
import chisel3.iotesters._
class Inverter extends Module {
val io = IO(new Bundle {
val a = Input(UInt(4.W))
val s = Output(UInt(4.W))
})
io.s := ~io.a
}
class InverterTester(c: Inverter) extends PeekPokeTester(c) {
poke(c.io.a, 8)
step(1)
expect(c.io.s, 8) // Should be 7 here
}
object TestMain extends App {
chisel3.iotesters.Driver.execute(args, () => new Inverter()) {
c => new InverterTester(c)
}
}
Now I run sbt 'test:runMain TestMain' and got this line (info is in purple):
[info] [0.002] EXPECT AT 1 io_s got 7 expected 8 FAIL
And the exit value of sbt is zero.
I need that line to be an error (with red color):
[error] [0.002] EXPECT AT 1 io_s got 7 expected 8 FAIL
As well as making the above sbt command exit with a non-zero value.
How can I achieve it with minimal change to existing code?
First the easy part. You can get a non-zero result code by using the result of chisel.execute like this.
val result = chisel3.iotesters.Driver.execute(args, () => new Inverter()) {
c => new InverterTester(c)
}
System.exit(if(result) 0 else 1)
Changing the logging level, unfortunately requires changing each of the separate backends in the chisel-testers repo. The following is an example of changing the TreadleBackend.scala, one of the three.
def expect(signal: InstanceId, expected: BigInt, msg: => String)
(implicit logger: TestErrorLog, verbose: Boolean, base: Int) : Boolean = {
signal match {
case port: Element =>
val name = portNames(port)
val got = treadleTester.peek(name)
val good = got == expected
if (!good) {
logger error
s"""EXPECT AT $stepNumber $msg $name got ${bigIntToStr(got, base)} expected ${bigIntToStr(expected, base)}""" +
s""" ${if (good) "PASS" else "FAIL"}"""
}
else if (verbose) {
logger info
s"""EXPECT AT $stepNumber $msg $name got ${bigIntToStr(got, base)} expected ${bigIntToStr(expected, base)}""" +
s""" ${if (good) "PASS" else "FAIL"}"""
}
if(good) treadleTester.expectationsMet += 1
good
case _ => false
}
}
This would not be an unreasonable issue to file, I think a logger.error would make more sense on an expect failure. There is some concern that changing this could have unexpected consequences for existing users, who are looking for that string.
But I'd like to encourage you to take a look at freechipsproject/chisel-testers2 repo. It's where the team is putting most of their testing development time. It would be easier to change, it has a lot of other nice features for building unit tests, and we are looking at ways we can make it better than chisel-testers.
Is it prohibited by design or am I doing something wrong?
val ext = 1
class Test extends Actor {
def receive = { case _ => println(ext) }
}
try {
val sys = ActorSystem("lol")
sys.actorOf(Props[Test], "test") ! true
} catch {
case e: Throwable => println(e)
}
once I send a message to Test I get an exception java.lang.IllegalArgumentException: no matching constructor found on class HelloAkkaScala$Test$1 for arguments [].
I don't have this exception if I don't reference ext inside of Test class.
I'm using Akka 2.3.4
There is nothing wrong in accessing val (not var or any other mutable state) defined outside of the actor.
Just tried to run your example code in Akka 2.3.5 and it works fine. You probably have a typo somwhere in your original code.
UPDATE
Looking closer at the error you are getting it seems like you've defined Test class inside some other class.
In this case inner class (Test) will receive reference to outer class behind the scenes in order to be able to close on it's members (ext).
This also means that constructor of the inner class will take reference to the outer class (syntactic sugar hides this).
This also explains why you are getting the error (you pass 0 args to constructor but there actually some hidden ones that you are not supplying).
Here is the example that reproduces this:
class Boot {
val ext = 1
class Test extends Actor {
def receive = { case _ => println(ext) }
}
try {
val sys = ActorSystem("lol")
sys.actorOf(Props[Test], "test") ! true
} catch {
case e: Throwable => println(e)
}
}
object Boot extends App {
new Boot
}
... and here is a quick workaround (in this case I make Test and ext "static" by moving them to companion object, but you can achieve similar results by referencing ext as a member of some other instance, passed to constructor):
class Boot {
import Boot.Test
try {
val sys = ActorSystem("lol")
sys.actorOf(Props[Test], "test") ! true
} catch {
case e: Throwable => println(e)
}
}
object Boot extends App {
val ext = 1
class Test extends Actor {
def receive = { case _ => println(ext) }
}
new Boot
}
This is my source code for testing:
import org.openqa.selenium.firefox.FirefoxDriver
import org.scalatest.FlatSpec
import org.scalatest.Matchers
import play.api.test.FakeApplication
import play.api.test.WithApplication
class FunctionalSpec extends FlatSpec with Matchers {
def withDriver(f: FirefoxDriver => Unit) = {
val driver = new FirefoxDriver
try {
new WithApplication(
new FakeApplication(additionalConfiguration = Map("application.secret" -> "secret"))) {
f(driver)
}
} finally {
driver.quit
}
}
}
It doesn't show any compile-error in Eclipse. But when I execute the test command it shows a very long error message. This is the first line of the errors:
symbol value f$1 does not exist in test.FunctionalSpec$$anon$1$delayedInit$body.apply
I tried to play around a bit by modifying the code as shown below:
def withDriver(f: FirefoxDriver => Unit) = {
val driver = new FirefoxDriver
try {
val g = f
val driver2 = driver
new WithApplication(
new FakeApplication(additionalConfiguration = Map("application.secret" -> "secret"))) {
val h = g
val driver3 = driver2
h(driver3)
}
} finally {
driver.quit
}
}
There are no errors thrown when I executed the test command. Any idea what's happening? Is there any limit of how deep a block of code can go in order to keep the identifiers recognised?
EDIT:
Using my modified code above results in runtime-error. I added the code below:
"The admin" should "be able to login and logout correctly" in withDriver { implicit driver =>
// Don't do anything yet.
}
This one is displayed in one line of the runtime-error messages:
Cause: java.lang.NoSuchFieldError: g$1
Any suggestion for a workaround?
ADDITIONAL NOTE:
All the codes above compile just fine. Neither Eclipse or scalac complain. All the errors above happen only when I do the test command from the Play command shell.
This doesn't directly answer your question, but I would do two things:
Use Specs2 instead of ScalaTest
Rewrite your tests as described here: http://www.playframework.com/documentation/2.2.x/ScalaFunctionalTest