Я написал этот гладкий DAO и его модульный тест в specs2.Состояние гонки в Slick Code
Мой код имеет расу условия. Когда я запускаю те же тесты, я получаю разные результаты.
The гонки условия существуют, хотя в обеих функциях я Await.result (будущее, Duration.Inf)
DAO
package com.example
import slick.backend.DatabasePublisher
import slick.driver.H2Driver.api._
import scala.concurrent.ExecutionContext.Implicits.global
import slick.jdbc.meta._
import scala.concurrent._
import ExecutionContext.Implicits.global
import scala.concurrent.duration._
case class Person(id: Int, firstname: String, lastname: String)
class People(tag: Tag) extends Table[Person](tag, "PEOPLE") {
def id = column[Int]("PERSON_ID", O.PrimaryKey)
def firstname = column[String]("PERSON_FIRST_NAME")
def lastname = column[String]("PERSON_LAST_NAME")
def * = (id, firstname, lastname) <> (Person.tupled, Person.unapply _)
}
object PersonDAO {
private def createList(numRows: Int) : List[Person] = {
def recFunc(counter: Int, result: List[Person]) : List[Person] = {
counter match {
case x if x <= numRows => recFunc(counter + 1, Person(counter, "test" + counter, "user" + counter) :: result)
case _ => result
}
}
recFunc(1, List[Person]())
}
val db = Database.forConfig("test1")
val people = TableQuery[People]
def createAndPopulate(numRows: Int) = {
val action1 = people.schema.create
val action2 = people ++= Seq(createList(numRows) : _*)
val combined = db.run(action1 andThen action2)
val future1 = combined.map { result =>
result map {x =>
println(s"number of rows inserted $x")
x
}
}
Await.result(future1, Duration.Inf).getOrElse(0)
}
def printAll() = {
val a = people.result
val b = db.run(a)
val y = b map { result =>
result map {x => x}
}
val z = Await.result(y, Duration.Inf)
println(z)
println(z.length)
z
}
}
Unit Test
import org.specs2.mutable._
import com.example._
class HelloSpec extends Specification {
"This usecase " should {
"should insert rows " in {
val x = PersonDAO.createAndPopulate(100)
x === 100
}
}
"This usecase " should {
"return 100 rows" in {
val x = PersonDAO.printAll()
val y = PersonDAO.printAll()
y.length === 100
}
}
}
Когда я бегу этот же код с использованием activator test
Я вижу 2 разных типа выходов на разных трассах
иногда код получает за исключением
количество строк, вставленных 100 [Информация] HelloSpec [Информация] [Информация] Этот UseCase следует [Информация] + должен вставить строки [информация] [информация ] Эта информация должна быть [info]! return 100 rows [ошибка] JdbcSQLException:: Таблица PEOPLE не найдена; SQL: [ошибка] выберите x2. «PERSON_ID», x2. «PERSON_FIRST_NAME», x2. «PERSON_LAST_NAME» из «PEOPLE» x2 [42S02-60] (Message.java:84) [error] org.h2. message.Message.getSQLException (Message.java:84) [ошибка] org.h2.message.Message.getSQLException (Message.java:88) [ошибка] org.h2.message.Message.getSQLException (Message.java: 66)
Иногда вызов первой функции возвращает 0 строк и вызов второй функции возвращает 100 значений
SLF4J: Не удалось загрузить класс «org.slf4j.impl.StaticLoggerBinder». SLF4J: Реализация регистратора без операции (NOP) SLF4J: См. http://www.slf4j.org/codes.html#StaticLoggerBinder для получения дополнительной информации. Число вставленных строк 100 Vector() Вектор (100, test100, user100), Person (99, test99, user99), Person (98, test98, user98), Person (97, test97, user97) , Person (96, test96, user96), Person (95, test95, user95), Person (94, test94, user94), Person (93, test93, user93), Person (92, test92, user92), Person (91, test91, user91), лицо (90, test90, user90), лицо (89, test89, user89), лицо (88, test88, user88), лицо (87, test87, user87), Person
I не понимаю, почему мой код имеет эти условия гонки, потому что я блокирую будущее в каждом методе.