Hi Christoph.
This error is coming from clojure.tools.deps.alpha
and seems to want to prevent linking outside of a project.
One solution I came up with is to create a jar out of the test resources and then test metabase with both jars on the classpath.
Making a test resources jar
Add the following two aliases to the deps.edn
file:
;; want a jar with only the test sources in it
:test-jar
{:replace-deps {}}
;; run with `clojure -T:build test-jar`
:build-test-jar
{:replace-paths ["test"]
:replace-deps {}
:extra-deps {io.github.clojure/tools.build {:git/tag "v0.8.2"
:git/sha "ba1a2bf"}}
:ns-default build}
We need a build.clj
file in the root of the project directory
(ns build
(:require [clojure.tools.build.api :as b]))
(def class-dir "target/classes")
(def test-basis (b/create-basis {:project "deps.edn"
:aliases [:test-jar]}))
(defn clean [_]
(b/delete {:path "target"}))
(defn test-jar
"Build a jar containing test sources."
[_]
(clean nil)
(b/write-pom {:class-dir class-dir
:basis test-basis
:lib 'exasol-metabase-driver/test-sources ;' close quot for preview in discourse
:version "1.0"})
(b/copy-dir {:target-dir class-dir
:src-dirs ["test"]})
(b/jar {:class-dir class-dir
:jar-file "exasol-test-sources.jar"}))
The gist of this is that we just want a jar with the test files so rather than deal with directories outside of the metabase project, we'll just have some namespaces we can find.
We can build this jar with clj -T:build-test-jar test-jar
.
An issue with the current exasol driver
For whatever reason, the following call to (log-driver-version)
is breaking the build.
(defn- log-driver-version []
(log/info (u/format-color 'green (format "Loading Exasol Metabase driver %s, Exasol JDBC driver: %s"
(get-driver-version) (get-jdbc-driver-version)))))
(log-driver-version)
^^^^^^^^^^^^^^^
When you run the tests with this line present, you get errors like
ERROR in metabase.driver.exasol-test/join-test (classloader.clj:128)
Uncaught exception, not in assertion.
clojure.lang.ExceptionInfo: clojure/tools/logging/impl/LoggerFactory
classloader: #object[clojure.lang.DynamicClassLoader 0x1ec4fdcf "clojure.lang.DynamicClassLoader@1ec4fdcf"]
classpath-urls: ("file:/Users/dan/projects/work/metabase/plugins/exasol.metabase-driver.jar")
system-classpath: ("/Users/dan/.m2/repository/amalloy/ring-buffer/1.3.1/ring-buffer-1.3.1.jar"
"/Users/dan/.m2/repository/amalloy/ring-gzip-middleware/0.1.4/ring-gzip-middleware-0.1.4.jar"
"/Users/dan/.m2/repository/aopalliance/aopalliance/1.0/aopalliance-1.0.jar"
"/Users/dan/.m2/repository/aysylu/loom/1.0.2/loom-1.0.2.jar"
"/Users/dan/.m2/repository/better-cond/better-cond/2.0.1-SNAPSHOT/better-cond-2.0.1-SNAPSHOT.jar"
"/Users/dan/.m2/repository/bigml/histogram/4.1.4/histogram-4.1.4.jar"
"/Users/dan/.m2/repository/buddy/buddy-core/1.10.413/buddy-core-1.10.413.jar"
"/Users/dan/.m2/repository/buddy/buddy-sign/3.4.333/buddy-sign-3.4.333.jar"
"/Users/dan/.m2/repository/cheshire/cheshire/5.10.2/cheshire-5.10.2.jar"
"/Users/dan/.m2/repository/cider/cider-nrepl/0.26.0/cider-nrepl-0.26.0.jar"
...)
I think this is because it is AOT compiling a reference to a particular logger and that's not valid when we actually use the jar. In any case, remove that offending line and then we build the jar as we did before:
clojure -X:build :project-dir "\"$(pwd)\""
Run the tests
So now we have:
- a jar with test sources in it (
clojure -T:build-test-jar test-jar
creates exasol-test-sources.jar
in the root directory)
- a jar with the exasol driver in it (
clojure -X:build :project-dir "\"$(pwd)\""
creates target/exasol.metabase-driver.jar
the driver itself)
We just need to run the tests.
From the metabase directory, I run:
DRIVERS=exasol clj -Sdeps '{:deps {exasol/exasol-driver {:local/root "../metabase-driver/target/exasol.metabase-driver.jar"} exasol/exasol-tests {:local/root "../metabase-driver/exasol-test-sources.jar" }}}' -X:dev:test :only metabase.driver.exasol-test
This looks unwieldy but break it down to its constituent parts:
DRIVERS=exasol
don't want to test h2 or anything else. Setting the driver i'm interested in testing
clj
can use clojure
or clj
.
-Sdeps '{:deps {exasol/exasol-driver {:local/root "../metabase-driver/target/exasol.metabase-driver.jar"} exasol/exasol-tests {:local/root "../metabase-driver/exasol-test-sources.jar" }}}'
Here i'm adding the two jars we created above onto the classpath. These can be moved anywhere you like for convenience. I am just referring to them where they are created.
X:dev:test
: runs our test runner
:only metabase.driver.exasol-test
: specify which namespace i want to test. I only want to test the exasol driver
For me I get the following output:
[ten lines or so of warnings about new Clojure 1.11.1 functions]
Finding tests took 26.2 s.
Running 14 tests
0/14 0% [ ] ETA: --:--[exasol] DROP SCHEMA "CAM_153" CASCADE
[exasol] CREATE SCHEMA "CAM_153"
ERROR in metabase.driver.exasol-test/join-test (interface.clj:660)
Uncaught exception, not in assertion.
java.lang.Exception: In order to test exasol, you must specify the env var MB_EXASOL_TEST_HOST.
metabase.test.data.interface/db-test-env-var-or-throw interface.clj: 660
metabase.test.data.interface/db-test-env-var-or-throw interface.clj: 656
This looks bad at first glance but its a proper error from your driver:
In order to test exasol, you must specify the env var MB_EXASOL_TEST_HOST.
At the moment I'm not sure how to have an exasol instance running but this seems like it has the driver and tests on the classpath and it is trying to run some tests.
I get 14 of these errors all complaining about the env var for the exasol host not being set so it seems like all tests are running. Hopefully with that env var set all tests will pass.
Helpful links