From 931db95a1690f993a58e1eff35e3a4124d803e7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Sowi=C5=84ski?= Date: Tue, 22 Oct 2024 21:04:35 +0200 Subject: [PATCH 1/2] Fix Jena tests getting stuck in a deadlock (#190) See this issue: https://github.com/apache/jena/issues/2787 Regardless of whether this behavior of Jena is a bug or not, this PR should fix it. It simply calls JenaSystem.init() in a static block before anything related to Jena is done. Amen. --- build.sbt | 4 ++-- .../ostrzyciel/jelly/examples/ExamplesSpec.scala | 3 ++- .../jelly/integration_tests/BackCompatSpec.scala | 8 ++------ .../integration_tests/CrossStreamingSpec.scala | 8 ++------ .../integration_tests/ForwardCompatSpec.scala | 6 +++--- .../jelly/integration_tests/io/IoSerDesSpec.scala | 9 ++------- .../io/NonDelimitedDesSpec.scala | 4 ++-- .../convert/jena/JenaDecoderConverterSpec.scala | 3 ++- .../convert/jena/JenaIterableAdapterSpec.scala | 3 ++- .../jelly/convert/jena/JenaProtoEncoderSpec.scala | 3 ++- .../jena/fuseki/JellyFusekiLifecycleSpec.scala | 4 ++-- .../jelly/convert/jena/traits/JenaTest.scala | 15 +++++++++++++++ 12 files changed, 38 insertions(+), 32 deletions(-) create mode 100644 jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/traits/JenaTest.scala diff --git a/build.sbt b/build.sbt index c3dd3058..e6dae0f5 100644 --- a/build.sbt +++ b/build.sbt @@ -207,7 +207,7 @@ lazy val integrationTests = (project in file("integration-tests")) ), commonSettings, ) - .dependsOn(stream, jena, rdf4j) + .dependsOn(stream, jena % "compile->compile;test->test", rdf4j) lazy val examples = (project in file("examples")) .settings( @@ -220,4 +220,4 @@ lazy val examples = (project in file("examples")) excludeDependencies ++= grpcExclusions, commonSettings, ) - .dependsOn(grpc, stream, jena, rdf4j) + .dependsOn(grpc, stream, jena % "compile->compile;test->test", rdf4j) diff --git a/examples/src/test/scala/eu/ostrzyciel/jelly/examples/ExamplesSpec.scala b/examples/src/test/scala/eu/ostrzyciel/jelly/examples/ExamplesSpec.scala index 87fba098..36d28300 100644 --- a/examples/src/test/scala/eu/ostrzyciel/jelly/examples/ExamplesSpec.scala +++ b/examples/src/test/scala/eu/ostrzyciel/jelly/examples/ExamplesSpec.scala @@ -1,9 +1,10 @@ package eu.ostrzyciel.jelly.examples +import eu.ostrzyciel.jelly.convert.jena.traits.JenaTest import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec -class ExamplesSpec extends AnyWordSpec, Matchers: +class ExamplesSpec extends AnyWordSpec, Matchers, JenaTest: val examples: Seq[shared.Example] = Seq( JenaRiot, JenaRiotStreaming, diff --git a/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/BackCompatSpec.scala b/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/BackCompatSpec.scala index cfbfdc6b..f2d649b7 100644 --- a/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/BackCompatSpec.scala +++ b/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/BackCompatSpec.scala @@ -1,20 +1,16 @@ package eu.ostrzyciel.jelly.integration_tests import eu.ostrzyciel.jelly.convert.jena.riot.JellyLanguage +import eu.ostrzyciel.jelly.convert.jena.traits.JenaTest import org.apache.jena.riot.{Lang, RDFDataMgr} import org.apache.jena.sparql.core.DatasetGraphFactory -import org.apache.jena.sys.JenaSystem -import org.scalatest.BeforeAndAfterAll import org.scalatest.concurrent.ScalaFutures import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec import scala.jdk.CollectionConverters.* -class BackCompatSpec extends AnyWordSpec, Matchers, ScalaFutures, BeforeAndAfterAll: - override def beforeAll(): Unit = - JenaSystem.init() - +class BackCompatSpec extends AnyWordSpec, Matchers, ScalaFutures, JenaTest: private val testCases = Seq( ("riverbench_main", "RiverBench main metadata", Seq("v1_0_0")), ("riverbench_nanopubs", "RiverBench nanopubs dataset metadata", Seq("v1_0_0")), diff --git a/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/CrossStreamingSpec.scala b/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/CrossStreamingSpec.scala index 25b1de82..bde4cd44 100644 --- a/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/CrossStreamingSpec.scala +++ b/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/CrossStreamingSpec.scala @@ -1,5 +1,6 @@ package eu.ostrzyciel.jelly.integration_tests +import eu.ostrzyciel.jelly.convert.jena.traits.JenaTest import eu.ostrzyciel.jelly.core.* import eu.ostrzyciel.jelly.core.proto.v1.RdfStreamOptions import eu.ostrzyciel.jelly.stream.* @@ -7,10 +8,8 @@ import org.apache.jena.graph.Graph import org.apache.jena.riot.{Lang, RDFDataMgr, RDFParser} import org.apache.jena.sparql.core.DatasetGraph import org.apache.jena.sparql.util.IsoMatcher -import org.apache.jena.sys.JenaSystem import org.apache.pekko.actor.ActorSystem import org.apache.pekko.stream.scaladsl.* -import org.scalatest.BeforeAndAfterAll import org.scalatest.concurrent.ScalaFutures import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec @@ -46,16 +45,13 @@ object CrossStreamingSpec extends AnyWordSpec, Matchers: } -class CrossStreamingSpec extends AnyWordSpec, Matchers, ScalaFutures, BeforeAndAfterAll: +class CrossStreamingSpec extends AnyWordSpec, Matchers, ScalaFutures, JenaTest: import CrossStreamingSpec.* given actorSystem: ActorSystem = ActorSystem() given ExecutionContext = actorSystem.getDispatcher given PatienceConfig = PatienceConfig(timeout = 5.seconds, interval = 50.millis) - override def beforeAll(): Unit = - JenaSystem.init() - private val implementations: Seq[(String, TestStream)] = Seq( ("Jena", JenaTestStream), ("RDF4J", Rdf4jTestStream), diff --git a/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/ForwardCompatSpec.scala b/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/ForwardCompatSpec.scala index c3e97163..b74dfdac 100644 --- a/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/ForwardCompatSpec.scala +++ b/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/ForwardCompatSpec.scala @@ -1,9 +1,9 @@ package eu.ostrzyciel.jelly.integration_tests import eu.ostrzyciel.jelly.convert.jena.JenaConverterFactory +import eu.ostrzyciel.jelly.convert.jena.traits.JenaTest import eu.ostrzyciel.jelly.core.* -import eu.ostrzyciel.jelly.core.proto.v1 -import eu.ostrzyciel.jelly.core.proto.future +import eu.ostrzyciel.jelly.core.proto.{future, v1} import org.scalatest.concurrent.ScalaFutures import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec @@ -11,7 +11,7 @@ import org.scalatest.wordspec.AnyWordSpec /** * Tests checking forward compatibility of Jelly with future versions of the protocol. */ -class ForwardCompatSpec extends AnyWordSpec, Matchers, ScalaFutures: +class ForwardCompatSpec extends AnyWordSpec, Matchers, ScalaFutures, JenaTest: private val futureFrame = future.RdfStreamFrame(Seq( future.RdfStreamRow(future.RdfStreamRow.Row.Options( future.RdfStreamOptions( diff --git a/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/io/IoSerDesSpec.scala b/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/io/IoSerDesSpec.scala index 144da0ed..628fbdaf 100644 --- a/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/io/IoSerDesSpec.scala +++ b/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/io/IoSerDesSpec.scala @@ -1,27 +1,22 @@ package eu.ostrzyciel.jelly.integration_tests.io +import eu.ostrzyciel.jelly.convert.jena.traits.JenaTest import eu.ostrzyciel.jelly.core.* import eu.ostrzyciel.jelly.core.proto.v1.RdfStreamOptions import eu.ostrzyciel.jelly.integration_tests.TestCases -import org.apache.jena.sys.JenaSystem import org.apache.pekko.actor.ActorSystem -import org.scalatest.BeforeAndAfterAll import org.scalatest.concurrent.ScalaFutures import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec import java.io.{ByteArrayInputStream, ByteArrayOutputStream, File, FileInputStream} -import scala.concurrent.ExecutionException /** * Tests for IO ser/des (Jena RIOT, Jena RIOT streaming, RDF4J Rio, and semi-reactive IO over Pekko Streams). */ -class IoSerDesSpec extends AnyWordSpec, Matchers, ScalaFutures, BeforeAndAfterAll: +class IoSerDesSpec extends AnyWordSpec, Matchers, ScalaFutures, JenaTest: given ActorSystem = ActorSystem("test") - override def beforeAll(): Unit = - JenaSystem.init() - val presets: Seq[(RdfStreamOptions, Int, String)] = Seq( (JellyOptions.smallGeneralized, 1, "small generalized"), (JellyOptions.smallRdfStar, 1_000_000, "small RDF-star"), diff --git a/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/io/NonDelimitedDesSpec.scala b/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/io/NonDelimitedDesSpec.scala index 20adc95e..d646d3b4 100644 --- a/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/io/NonDelimitedDesSpec.scala +++ b/integration-tests/src/test/scala/eu/ostrzyciel/jelly/integration_tests/io/NonDelimitedDesSpec.scala @@ -1,6 +1,7 @@ package eu.ostrzyciel.jelly.integration_tests.io import eu.ostrzyciel.jelly.convert.jena.JenaConverterFactory +import eu.ostrzyciel.jelly.convert.jena.traits.JenaTest import eu.ostrzyciel.jelly.core.JellyOptions import eu.ostrzyciel.jelly.core.proto.v1.* import eu.ostrzyciel.jelly.integration_tests.TestCases @@ -17,8 +18,7 @@ import scala.jdk.CollectionConverters.* * [[eu.ostrzyciel.jelly.integration_tests.io.IoSerDesSpec]]. * More fine-grained tests for delimited/non-delimited detection can be found in the jelly-core module. */ -class NonDelimitedDesSpec extends AnyWordSpec, Matchers: - +class NonDelimitedDesSpec extends AnyWordSpec, Matchers, JenaTest: val presets: Seq[(RdfStreamOptions, String)] = Seq( (JellyOptions.smallGeneralized, "small generalized"), (JellyOptions.bigGeneralized, "big generalized"), diff --git a/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/JenaDecoderConverterSpec.scala b/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/JenaDecoderConverterSpec.scala index 16fb9047..72f3ee04 100644 --- a/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/JenaDecoderConverterSpec.scala +++ b/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/JenaDecoderConverterSpec.scala @@ -1,10 +1,11 @@ package eu.ostrzyciel.jelly.convert.jena +import eu.ostrzyciel.jelly.convert.jena.traits.JenaTest import org.apache.jena.sparql.core.Quad import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec -class JenaDecoderConverterSpec extends AnyWordSpec, Matchers: +class JenaDecoderConverterSpec extends AnyWordSpec, Matchers, JenaTest: val instance = JenaDecoderConverter() "JenaDecoderConverter" should { diff --git a/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/JenaIterableAdapterSpec.scala b/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/JenaIterableAdapterSpec.scala index c7c87552..a624f7cc 100644 --- a/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/JenaIterableAdapterSpec.scala +++ b/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/JenaIterableAdapterSpec.scala @@ -1,5 +1,6 @@ package eu.ostrzyciel.jelly.convert.jena +import eu.ostrzyciel.jelly.convert.jena.traits.JenaTest import org.apache.jena.graph.{NodeFactory, Triple} import org.apache.jena.query.DatasetFactory import org.apache.jena.rdf.model.impl.ModelCom @@ -8,7 +9,7 @@ import org.apache.jena.sparql.graph.GraphFactory import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec -class JenaIterableAdapterSpec extends AnyWordSpec, Matchers: +class JenaIterableAdapterSpec extends AnyWordSpec, Matchers, JenaTest: import JenaIterableAdapter.* val triples = Set( diff --git a/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/JenaProtoEncoderSpec.scala b/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/JenaProtoEncoderSpec.scala index 49aa851b..d4df5b4c 100644 --- a/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/JenaProtoEncoderSpec.scala +++ b/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/JenaProtoEncoderSpec.scala @@ -1,5 +1,6 @@ package eu.ostrzyciel.jelly.convert.jena +import eu.ostrzyciel.jelly.convert.jena.traits.JenaTest import eu.ostrzyciel.jelly.core.* import eu.ostrzyciel.jelly.core.proto.v1.* import org.apache.jena.sparql.core.Quad @@ -10,7 +11,7 @@ import org.scalatest.wordspec.AnyWordSpec /** * Test the handling of the many ways to represent the default graph in Jena. */ -class JenaProtoEncoderSpec extends AnyWordSpec, Matchers: +class JenaProtoEncoderSpec extends AnyWordSpec, Matchers, JenaTest: private val encodedDefaultGraph = RdfStreamRow( RdfStreamRow.Row.GraphStart( RdfGraphStart(RdfDefaultGraph()) diff --git a/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/fuseki/JellyFusekiLifecycleSpec.scala b/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/fuseki/JellyFusekiLifecycleSpec.scala index a0735687..3c545624 100644 --- a/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/fuseki/JellyFusekiLifecycleSpec.scala +++ b/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/fuseki/JellyFusekiLifecycleSpec.scala @@ -1,14 +1,14 @@ package eu.ostrzyciel.jelly.convert.jena.fuseki import eu.ostrzyciel.jelly.convert.jena.riot.JellySubsystemLifecycle +import eu.ostrzyciel.jelly.convert.jena.traits.JenaTest import org.apache.jena.fuseki.DEF -import org.apache.jena.sys.JenaSystem import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AnyWordSpec import scala.jdk.CollectionConverters.* -class JellyFusekiLifecycleSpec extends AnyWordSpec, Matchers: +class JellyFusekiLifecycleSpec extends AnyWordSpec, Matchers, JenaTest: "JellyFusekiLifecycle" should { "initialize after JenaSubsystemLifecycle" in { val jenaModule = JellySubsystemLifecycle() diff --git a/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/traits/JenaTest.scala b/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/traits/JenaTest.scala new file mode 100644 index 00000000..95b6b6e0 --- /dev/null +++ b/jena/src/test/scala/eu/ostrzyciel/jelly/convert/jena/traits/JenaTest.scala @@ -0,0 +1,15 @@ +package eu.ostrzyciel.jelly.convert.jena.traits + +import org.apache.jena.sys.JenaSystem + +object JenaTest: + JenaSystem.init() + +/** + * Trait that should be included in all tests that use Jena. + * Guarantees that Jena is initialized before the tests are run and that we don't run into wonky issues like + * this one: https://github.com/apache/jena/issues/2787 + */ +trait JenaTest: + // Touch the object to run the static initializer + JenaTest.toString From cc12b68a04d248e823354d19382bdbb219ad5614 Mon Sep 17 00:00:00 2001 From: Scala Steward <43047562+scala-steward@users.noreply.github.com> Date: Tue, 22 Oct 2024 21:08:52 +0200 Subject: [PATCH 2/2] Update sbt-ci-release to 1.9.0 (#188) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Piotr SowiƄski --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 4084ff4b..3620042c 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,6 @@ addSbtPlugin("com.thesamet" % "sbt-protoc" % "1.0.7") addSbtPlugin("org.apache.pekko" % "pekko-grpc-sbt-plugin" % "1.1.0") -addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.8.0") +addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.9.0") addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "2.3.0") addDependencyTreePlugin