lvh / caesium

Modern cryptography (libsodium/NaCl) for Clojure

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

pwhash tests fail under cloverage

eploko opened this issue · comments

While working on #71 I noticed the cloverage step fails. It appears there's some trouble in calling some of the crypto_pwhash_* bindings.

STR:
lein with-profile +test cloverage --codecov -t caesium.crypto.pwhash-test

The log output follows:

Instrumented namespaces.

Testing caesium.crypto.pwhash-test

ERROR in (pwhash-str-alg-argon2i13-and-verify-test-equal) (Reflector.java:154)
Uncaught exception, not in assertion.
expected: nil
  actual: java.lang.IllegalArgumentException: No matching method crypto_pwhash_str_alg found taking 6 args for class caesium.binding.Sodium$jnr$ffi$0
 at clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:154)
    clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:102)
    caesium.crypto.pwhash$pwhash_str_alg_to_buf_BANG_.invokeStatic (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$pwhash_str_alg_to_buf_BANG_.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$pwhash_str_alg.invokeStatic (caesium/crypto/pwhash.clj:123)
    caesium.crypto.pwhash$pwhash_str_alg.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash_test$fn__10870.invokeStatic (pwhash_test.clj:109)
    caesium.crypto.pwhash_test/fn (pwhash_test.clj:108)
    clojure.test$test_var$fn__9737.invoke (test.clj:717)
    clojure.test$test_var.invokeStatic (test.clj:717)
    clojure.test$test_var.invoke (test.clj:708)
    clojure.test$test_vars$fn__9763$fn__9768.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars$fn__9763.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars.invokeStatic (test.clj:731)
    clojure.test$test_all_vars.invokeStatic (test.clj:737)
    clojure.test$test_ns.invokeStatic (test.clj:758)
    clojure.test$test_ns.invoke (test.clj:743)
    clojure.core$map$fn__5866.invoke (core.clj:2755)
    clojure.lang.LazySeq.sval (LazySeq.java:42)
    clojure.lang.LazySeq.seq (LazySeq.java:51)
    clojure.lang.Cons.next (Cons.java:39)
    clojure.lang.RT.boundedLength (RT.java:1792)
    clojure.lang.RestFn.applyTo (RestFn.java:130)
    clojure.core$apply.invokeStatic (core.clj:667)
    clojure.test$run_tests.invokeStatic (test.clj:768)
    clojure.test$run_tests.doInvoke (test.clj:768)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:665)
    clojure.core$apply.invoke (core.clj:660)
    cloverage.coverage$eval4113$fn__4115$fn__4117$run_tests__4118.invoke (coverage.clj:187)
    cloverage.coverage$eval4113$fn__4115$fn__4117.invoke (coverage.clj:193)
    cloverage.coverage$run_tests$fn__4136.invoke (coverage.clj:211)
    cloverage.coverage$form_for_suppressing_unselected_tests.invokeStatic (coverage.clj:54)
    cloverage.coverage$form_for_suppressing_unselected_tests.invoke (coverage.clj:32)
    cloverage.coverage$run_tests.invokeStatic (coverage.clj:209)
    cloverage.coverage$run_tests.invoke (coverage.clj:199)
    cloverage.coverage$run_main.invokeStatic (coverage.clj:261)
    cloverage.coverage$run_main.invoke (coverage.clj:253)
    cloverage.coverage$run_project.invokeStatic (coverage.clj:277)
    cloverage.coverage$run_project.doInvoke (coverage.clj:273)
    clojure.lang.RestFn.invoke (RestFn.java:460)
    user$eval4238.invokeStatic (form-init582277943802464326.clj:1)
    user$eval4238.invoke (form-init582277943802464326.clj:1)
    clojure.lang.Compiler.eval (Compiler.java:7177)
    clojure.lang.Compiler.eval (Compiler.java:7167)
    clojure.lang.Compiler.load (Compiler.java:7636)
    clojure.lang.Compiler.loadFile (Compiler.java:7574)
    clojure.main$load_script.invokeStatic (main.clj:475)
    clojure.main$init_opt.invokeStatic (main.clj:477)
    clojure.main$init_opt.invoke (main.clj:477)
    clojure.main$initialize.invokeStatic (main.clj:508)
    clojure.main$null_opt.invokeStatic (main.clj:542)
    clojure.main$null_opt.invoke (main.clj:539)
    clojure.main$main.invokeStatic (main.clj:664)
    clojure.main$main.doInvoke (main.clj:616)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.Var.applyTo (Var.java:705)
    clojure.main.main (main.java:40)

ERROR in (pwhash-argon2i-alg-argon2i13-test) (Reflector.java:154)
expected: (= "75a10fdb4db0836498f824f1f0cc9ab9d3bb194d41b8dd66bd1ca6f0cf686810" (u/hexify (p/argon2i 32 "password" salt p/argon2i-opslimit-min p/argon2i-memlimit-interactive p/argon2i-alg-argon2i13)))
  actual: java.lang.IllegalArgumentException: No matching method crypto_pwhash_argon2i found taking 8 args for class caesium.binding.Sodium$jnr$ffi$0
 at clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:154)
    clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:102)
    caesium.crypto.pwhash$pwhash_argon2i_to_buf_BANG_.invokeStatic (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$pwhash_argon2i_to_buf_BANG_.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$argon2i.invokeStatic (caesium/crypto/pwhash.clj:154)
    caesium.crypto.pwhash$argon2i.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash_test$fn__10880.invokeStatic (pwhash_test.clj:122)
    caesium.crypto.pwhash_test/fn (pwhash_test.clj:120)
    clojure.test$test_var$fn__9737.invoke (test.clj:717)
    clojure.test$test_var.invokeStatic (test.clj:717)
    clojure.test$test_var.invoke (test.clj:708)
    clojure.test$test_vars$fn__9763$fn__9768.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars$fn__9763.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars.invokeStatic (test.clj:731)
    clojure.test$test_all_vars.invokeStatic (test.clj:737)
    clojure.test$test_ns.invokeStatic (test.clj:758)
    clojure.test$test_ns.invoke (test.clj:743)
    clojure.core$map$fn__5866.invoke (core.clj:2755)
    clojure.lang.LazySeq.sval (LazySeq.java:42)
    clojure.lang.LazySeq.seq (LazySeq.java:51)
    clojure.lang.Cons.next (Cons.java:39)
    clojure.lang.RT.boundedLength (RT.java:1792)
    clojure.lang.RestFn.applyTo (RestFn.java:130)
    clojure.core$apply.invokeStatic (core.clj:667)
    clojure.test$run_tests.invokeStatic (test.clj:768)
    clojure.test$run_tests.doInvoke (test.clj:768)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:665)
    clojure.core$apply.invoke (core.clj:660)
    cloverage.coverage$eval4113$fn__4115$fn__4117$run_tests__4118.invoke (coverage.clj:187)
    cloverage.coverage$eval4113$fn__4115$fn__4117.invoke (coverage.clj:193)
    cloverage.coverage$run_tests$fn__4136.invoke (coverage.clj:211)
    cloverage.coverage$form_for_suppressing_unselected_tests.invokeStatic (coverage.clj:54)
    cloverage.coverage$form_for_suppressing_unselected_tests.invoke (coverage.clj:32)
    cloverage.coverage$run_tests.invokeStatic (coverage.clj:209)
    cloverage.coverage$run_tests.invoke (coverage.clj:199)
    cloverage.coverage$run_main.invokeStatic (coverage.clj:261)
    cloverage.coverage$run_main.invoke (coverage.clj:253)
    cloverage.coverage$run_project.invokeStatic (coverage.clj:277)
    cloverage.coverage$run_project.doInvoke (coverage.clj:273)
    clojure.lang.RestFn.invoke (RestFn.java:460)
    user$eval4238.invokeStatic (form-init582277943802464326.clj:1)
    user$eval4238.invoke (form-init582277943802464326.clj:1)
    clojure.lang.Compiler.eval (Compiler.java:7177)
    clojure.lang.Compiler.eval (Compiler.java:7167)
    clojure.lang.Compiler.load (Compiler.java:7636)
    clojure.lang.Compiler.loadFile (Compiler.java:7574)
    clojure.main$load_script.invokeStatic (main.clj:475)
    clojure.main$init_opt.invokeStatic (main.clj:477)
    clojure.main$init_opt.invoke (main.clj:477)
    clojure.main$initialize.invokeStatic (main.clj:508)
    clojure.main$null_opt.invokeStatic (main.clj:542)
    clojure.main$null_opt.invoke (main.clj:539)
    clojure.main$main.invokeStatic (main.clj:664)
    clojure.main$main.doInvoke (main.clj:616)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.Var.applyTo (Var.java:705)
    clojure.main.main (main.java:40)

ERROR in (argon2i-str-needs-rehash-test) (Reflector.java:154)
Uncaught exception, not in assertion.
expected: nil
  actual: java.lang.IllegalArgumentException: No matching method crypto_pwhash_str_alg found taking 6 args for class caesium.binding.Sodium$jnr$ffi$0
 at clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:154)
    clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:102)
    caesium.crypto.pwhash$pwhash_str_alg_to_buf_BANG_.invokeStatic (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$pwhash_str_alg_to_buf_BANG_.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$pwhash_str_alg.invokeStatic (caesium/crypto/pwhash.clj:123)
    caesium.crypto.pwhash$pwhash_str_alg.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash_test$fn__10895.invokeStatic (pwhash_test.clj:135)
    caesium.crypto.pwhash_test/fn (pwhash_test.clj:134)
    clojure.test$test_var$fn__9737.invoke (test.clj:717)
    clojure.test$test_var.invokeStatic (test.clj:717)
    clojure.test$test_var.invoke (test.clj:708)
    clojure.test$test_vars$fn__9763$fn__9768.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars$fn__9763.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars.invokeStatic (test.clj:731)
    clojure.test$test_all_vars.invokeStatic (test.clj:737)
    clojure.test$test_ns.invokeStatic (test.clj:758)
    clojure.test$test_ns.invoke (test.clj:743)
    clojure.core$map$fn__5866.invoke (core.clj:2755)
    clojure.lang.LazySeq.sval (LazySeq.java:42)
    clojure.lang.LazySeq.seq (LazySeq.java:51)
    clojure.lang.Cons.next (Cons.java:39)
    clojure.lang.RT.boundedLength (RT.java:1792)
    clojure.lang.RestFn.applyTo (RestFn.java:130)
    clojure.core$apply.invokeStatic (core.clj:667)
    clojure.test$run_tests.invokeStatic (test.clj:768)
    clojure.test$run_tests.doInvoke (test.clj:768)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:665)
    clojure.core$apply.invoke (core.clj:660)
    cloverage.coverage$eval4113$fn__4115$fn__4117$run_tests__4118.invoke (coverage.clj:187)
    cloverage.coverage$eval4113$fn__4115$fn__4117.invoke (coverage.clj:193)
    cloverage.coverage$run_tests$fn__4136.invoke (coverage.clj:211)
    cloverage.coverage$form_for_suppressing_unselected_tests.invokeStatic (coverage.clj:54)
    cloverage.coverage$form_for_suppressing_unselected_tests.invoke (coverage.clj:32)
    cloverage.coverage$run_tests.invokeStatic (coverage.clj:209)
    cloverage.coverage$run_tests.invoke (coverage.clj:199)
    cloverage.coverage$run_main.invokeStatic (coverage.clj:261)
    cloverage.coverage$run_main.invoke (coverage.clj:253)
    cloverage.coverage$run_project.invokeStatic (coverage.clj:277)
    cloverage.coverage$run_project.doInvoke (coverage.clj:273)
    clojure.lang.RestFn.invoke (RestFn.java:460)
    user$eval4238.invokeStatic (form-init582277943802464326.clj:1)
    user$eval4238.invoke (form-init582277943802464326.clj:1)
    clojure.lang.Compiler.eval (Compiler.java:7177)
    clojure.lang.Compiler.eval (Compiler.java:7167)
    clojure.lang.Compiler.load (Compiler.java:7636)
    clojure.lang.Compiler.loadFile (Compiler.java:7574)
    clojure.main$load_script.invokeStatic (main.clj:475)
    clojure.main$init_opt.invokeStatic (main.clj:477)
    clojure.main$init_opt.invoke (main.clj:477)
    clojure.main$initialize.invokeStatic (main.clj:508)
    clojure.main$null_opt.invokeStatic (main.clj:542)
    clojure.main$null_opt.invoke (main.clj:539)
    clojure.main$main.invokeStatic (main.clj:664)
    clojure.main$main.doInvoke (main.clj:616)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.Var.applyTo (Var.java:705)
    clojure.main.main (main.java:40)

ERROR in (argon2id-str-needs-rehash-test) (Reflector.java:154)
Uncaught exception, not in assertion.
expected: nil
  actual: java.lang.IllegalArgumentException: No matching method crypto_pwhash_str_alg found taking 6 args for class caesium.binding.Sodium$jnr$ffi$0
 at clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:154)
    clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:102)
    caesium.crypto.pwhash$pwhash_str_alg_to_buf_BANG_.invokeStatic (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$pwhash_str_alg_to_buf_BANG_.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$pwhash_str_alg.invokeStatic (caesium/crypto/pwhash.clj:123)
    caesium.crypto.pwhash$pwhash_str_alg.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash_test$fn__10910.invokeStatic (pwhash_test.clj:151)
    caesium.crypto.pwhash_test/fn (pwhash_test.clj:150)
    clojure.test$test_var$fn__9737.invoke (test.clj:717)
    clojure.test$test_var.invokeStatic (test.clj:717)
    clojure.test$test_var.invoke (test.clj:708)
    clojure.test$test_vars$fn__9763$fn__9768.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars$fn__9763.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars.invokeStatic (test.clj:731)
    clojure.test$test_all_vars.invokeStatic (test.clj:737)
    clojure.test$test_ns.invokeStatic (test.clj:758)
    clojure.test$test_ns.invoke (test.clj:743)
    clojure.core$map$fn__5866.invoke (core.clj:2755)
    clojure.lang.LazySeq.sval (LazySeq.java:42)
    clojure.lang.LazySeq.seq (LazySeq.java:51)
    clojure.lang.Cons.next (Cons.java:39)
    clojure.lang.RT.boundedLength (RT.java:1792)
    clojure.lang.RestFn.applyTo (RestFn.java:130)
    clojure.core$apply.invokeStatic (core.clj:667)
    clojure.test$run_tests.invokeStatic (test.clj:768)
    clojure.test$run_tests.doInvoke (test.clj:768)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:665)
    clojure.core$apply.invoke (core.clj:660)
    cloverage.coverage$eval4113$fn__4115$fn__4117$run_tests__4118.invoke (coverage.clj:187)
    cloverage.coverage$eval4113$fn__4115$fn__4117.invoke (coverage.clj:193)
    cloverage.coverage$run_tests$fn__4136.invoke (coverage.clj:211)
    cloverage.coverage$form_for_suppressing_unselected_tests.invokeStatic (coverage.clj:54)
    cloverage.coverage$form_for_suppressing_unselected_tests.invoke (coverage.clj:32)
    cloverage.coverage$run_tests.invokeStatic (coverage.clj:209)
    cloverage.coverage$run_tests.invoke (coverage.clj:199)
    cloverage.coverage$run_main.invokeStatic (coverage.clj:261)
    cloverage.coverage$run_main.invoke (coverage.clj:253)
    cloverage.coverage$run_project.invokeStatic (coverage.clj:277)
    cloverage.coverage$run_project.doInvoke (coverage.clj:273)
    clojure.lang.RestFn.invoke (RestFn.java:460)
    user$eval4238.invokeStatic (form-init582277943802464326.clj:1)
    user$eval4238.invoke (form-init582277943802464326.clj:1)
    clojure.lang.Compiler.eval (Compiler.java:7177)
    clojure.lang.Compiler.eval (Compiler.java:7167)
    clojure.lang.Compiler.load (Compiler.java:7636)
    clojure.lang.Compiler.loadFile (Compiler.java:7574)
    clojure.main$load_script.invokeStatic (main.clj:475)
    clojure.main$init_opt.invokeStatic (main.clj:477)
    clojure.main$init_opt.invoke (main.clj:477)
    clojure.main$initialize.invokeStatic (main.clj:508)
    clojure.main$null_opt.invokeStatic (main.clj:542)
    clojure.main$null_opt.invoke (main.clj:539)
    clojure.main$main.invokeStatic (main.clj:664)
    clojure.main$main.doInvoke (main.clj:616)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.Var.applyTo (Var.java:705)
    clojure.main.main (main.java:40)

ERROR in (pwhash-alg-default-test) (Reflector.java:154)
expected: (= "86b902e6577791ff5e1aaa73a57d21ee7a8822ed8e183940af4fa1ba6ab9803c" (u/hexify (p/pwhash 32 "password" salt p/opslimit-min p/memlimit-min p/alg-default)))
  actual: java.lang.IllegalArgumentException: No matching method crypto_pwhash found taking 8 args for class caesium.binding.Sodium$jnr$ffi$0
 at clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:154)
    clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:102)
    caesium.crypto.pwhash$pwhash_to_buf_BANG_.invokeStatic (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$pwhash_to_buf_BANG_.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$pwhash.invokeStatic (caesium/crypto/pwhash.clj:93)
    caesium.crypto.pwhash$pwhash.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash_test$fn__10845.invokeStatic (pwhash_test.clj:85)
    caesium.crypto.pwhash_test/fn (pwhash_test.clj:83)
    clojure.test$test_var$fn__9737.invoke (test.clj:717)
    clojure.test$test_var.invokeStatic (test.clj:717)
    clojure.test$test_var.invoke (test.clj:708)
    clojure.test$test_vars$fn__9763$fn__9768.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars$fn__9763.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars.invokeStatic (test.clj:731)
    clojure.test$test_all_vars.invokeStatic (test.clj:737)
    clojure.test$test_ns.invokeStatic (test.clj:758)
    clojure.test$test_ns.invoke (test.clj:743)
    clojure.core$map$fn__5866.invoke (core.clj:2755)
    clojure.lang.LazySeq.sval (LazySeq.java:42)
    clojure.lang.LazySeq.seq (LazySeq.java:51)
    clojure.lang.Cons.next (Cons.java:39)
    clojure.lang.RT.boundedLength (RT.java:1792)
    clojure.lang.RestFn.applyTo (RestFn.java:130)
    clojure.core$apply.invokeStatic (core.clj:667)
    clojure.test$run_tests.invokeStatic (test.clj:768)
    clojure.test$run_tests.doInvoke (test.clj:768)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:665)
    clojure.core$apply.invoke (core.clj:660)
    cloverage.coverage$eval4113$fn__4115$fn__4117$run_tests__4118.invoke (coverage.clj:187)
    cloverage.coverage$eval4113$fn__4115$fn__4117.invoke (coverage.clj:193)
    cloverage.coverage$run_tests$fn__4136.invoke (coverage.clj:211)
    cloverage.coverage$form_for_suppressing_unselected_tests.invokeStatic (coverage.clj:54)
    cloverage.coverage$form_for_suppressing_unselected_tests.invoke (coverage.clj:32)
    cloverage.coverage$run_tests.invokeStatic (coverage.clj:209)
    cloverage.coverage$run_tests.invoke (coverage.clj:199)
    cloverage.coverage$run_main.invokeStatic (coverage.clj:261)
    cloverage.coverage$run_main.invoke (coverage.clj:253)
    cloverage.coverage$run_project.invokeStatic (coverage.clj:277)
    cloverage.coverage$run_project.doInvoke (coverage.clj:273)
    clojure.lang.RestFn.invoke (RestFn.java:460)
    user$eval4238.invokeStatic (form-init582277943802464326.clj:1)
    user$eval4238.invoke (form-init582277943802464326.clj:1)
    clojure.lang.Compiler.eval (Compiler.java:7177)
    clojure.lang.Compiler.eval (Compiler.java:7167)
    clojure.lang.Compiler.load (Compiler.java:7636)
    clojure.lang.Compiler.loadFile (Compiler.java:7574)
    clojure.main$load_script.invokeStatic (main.clj:475)
    clojure.main$init_opt.invokeStatic (main.clj:477)
    clojure.main$init_opt.invoke (main.clj:477)
    clojure.main$initialize.invokeStatic (main.clj:508)
    clojure.main$null_opt.invokeStatic (main.clj:542)
    clojure.main$null_opt.invoke (main.clj:539)
    clojure.main$main.invokeStatic (main.clj:664)
    clojure.main$main.doInvoke (main.clj:616)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.Var.applyTo (Var.java:705)
    clojure.main.main (main.java:40)

ERROR in (str-needs-rehash-test) (Reflector.java:154)
Uncaught exception, not in assertion.
expected: nil
  actual: java.lang.IllegalArgumentException: No matching method crypto_pwhash_str_alg found taking 6 args for class caesium.binding.Sodium$jnr$ffi$0
 at clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:154)
    clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:102)
    caesium.crypto.pwhash$pwhash_str_alg_to_buf_BANG_.invokeStatic (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$pwhash_str_alg_to_buf_BANG_.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$pwhash_str_alg.invokeStatic (caesium/crypto/pwhash.clj:123)
    caesium.crypto.pwhash$pwhash_str_alg.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash_test$fn__10875.invokeStatic (pwhash_test.clj:114)
    caesium.crypto.pwhash_test/fn (pwhash_test.clj:113)
    clojure.test$test_var$fn__9737.invoke (test.clj:717)
    clojure.test$test_var.invokeStatic (test.clj:717)
    clojure.test$test_var.invoke (test.clj:708)
    clojure.test$test_vars$fn__9763$fn__9768.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars$fn__9763.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars.invokeStatic (test.clj:731)
    clojure.test$test_all_vars.invokeStatic (test.clj:737)
    clojure.test$test_ns.invokeStatic (test.clj:758)
    clojure.test$test_ns.invoke (test.clj:743)
    clojure.core$map$fn__5866.invoke (core.clj:2755)
    clojure.lang.LazySeq.sval (LazySeq.java:42)
    clojure.lang.LazySeq.seq (LazySeq.java:51)
    clojure.lang.Cons.next (Cons.java:39)
    clojure.lang.RT.boundedLength (RT.java:1792)
    clojure.lang.RestFn.applyTo (RestFn.java:130)
    clojure.core$apply.invokeStatic (core.clj:667)
    clojure.test$run_tests.invokeStatic (test.clj:768)
    clojure.test$run_tests.doInvoke (test.clj:768)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:665)
    clojure.core$apply.invoke (core.clj:660)
    cloverage.coverage$eval4113$fn__4115$fn__4117$run_tests__4118.invoke (coverage.clj:187)
    cloverage.coverage$eval4113$fn__4115$fn__4117.invoke (coverage.clj:193)
    cloverage.coverage$run_tests$fn__4136.invoke (coverage.clj:211)
    cloverage.coverage$form_for_suppressing_unselected_tests.invokeStatic (coverage.clj:54)
    cloverage.coverage$form_for_suppressing_unselected_tests.invoke (coverage.clj:32)
    cloverage.coverage$run_tests.invokeStatic (coverage.clj:209)
    cloverage.coverage$run_tests.invoke (coverage.clj:199)
    cloverage.coverage$run_main.invokeStatic (coverage.clj:261)
    cloverage.coverage$run_main.invoke (coverage.clj:253)
    cloverage.coverage$run_project.invokeStatic (coverage.clj:277)
    cloverage.coverage$run_project.doInvoke (coverage.clj:273)
    clojure.lang.RestFn.invoke (RestFn.java:460)
    user$eval4238.invokeStatic (form-init582277943802464326.clj:1)
    user$eval4238.invoke (form-init582277943802464326.clj:1)
    clojure.lang.Compiler.eval (Compiler.java:7177)
    clojure.lang.Compiler.eval (Compiler.java:7167)
    clojure.lang.Compiler.load (Compiler.java:7636)
    clojure.lang.Compiler.loadFile (Compiler.java:7574)
    clojure.main$load_script.invokeStatic (main.clj:475)
    clojure.main$init_opt.invokeStatic (main.clj:477)
    clojure.main$init_opt.invoke (main.clj:477)
    clojure.main$initialize.invokeStatic (main.clj:508)
    clojure.main$null_opt.invokeStatic (main.clj:542)
    clojure.main$null_opt.invoke (main.clj:539)
    clojure.main$main.invokeStatic (main.clj:664)
    clojure.main$main.doInvoke (main.clj:616)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.Var.applyTo (Var.java:705)
    clojure.main.main (main.java:40)

ERROR in (pwhash-argon2id-alg-argon2id13-test) (Reflector.java:154)
expected: (= "86b902e6577791ff5e1aaa73a57d21ee7a8822ed8e183940af4fa1ba6ab9803c" (u/hexify (p/argon2id 32 "password" salt p/argon2id-opslimit-min p/argon2id-memlimit-min p/argon2id-alg-argon2id13)))
  actual: java.lang.IllegalArgumentException: No matching method crypto_pwhash_argon2id found taking 8 args for class caesium.binding.Sodium$jnr$ffi$0
 at clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:154)
    clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:102)
    caesium.crypto.pwhash$argon2id_to_buf_BANG_.invokeStatic (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$argon2id_to_buf_BANG_.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$argon2id.invokeStatic (caesium/crypto/pwhash.clj:190)
    caesium.crypto.pwhash$argon2id.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash_test$fn__10900.invokeStatic (pwhash_test.clj:143)
    caesium.crypto.pwhash_test/fn (pwhash_test.clj:141)
    clojure.test$test_var$fn__9737.invoke (test.clj:717)
    clojure.test$test_var.invokeStatic (test.clj:717)
    clojure.test$test_var.invoke (test.clj:708)
    clojure.test$test_vars$fn__9763$fn__9768.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars$fn__9763.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars.invokeStatic (test.clj:731)
    clojure.test$test_all_vars.invokeStatic (test.clj:737)
    clojure.test$test_ns.invokeStatic (test.clj:758)
    clojure.test$test_ns.invoke (test.clj:743)
    clojure.core$map$fn__5866.invoke (core.clj:2755)
    clojure.lang.LazySeq.sval (LazySeq.java:42)
    clojure.lang.LazySeq.seq (LazySeq.java:51)
    clojure.lang.Cons.next (Cons.java:39)
    clojure.lang.RT.boundedLength (RT.java:1792)
    clojure.lang.RestFn.applyTo (RestFn.java:130)
    clojure.core$apply.invokeStatic (core.clj:667)
    clojure.test$run_tests.invokeStatic (test.clj:768)
    clojure.test$run_tests.doInvoke (test.clj:768)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:665)
    clojure.core$apply.invoke (core.clj:660)
    cloverage.coverage$eval4113$fn__4115$fn__4117$run_tests__4118.invoke (coverage.clj:187)
    cloverage.coverage$eval4113$fn__4115$fn__4117.invoke (coverage.clj:193)
    cloverage.coverage$run_tests$fn__4136.invoke (coverage.clj:211)
    cloverage.coverage$form_for_suppressing_unselected_tests.invokeStatic (coverage.clj:54)
    cloverage.coverage$form_for_suppressing_unselected_tests.invoke (coverage.clj:32)
    cloverage.coverage$run_tests.invokeStatic (coverage.clj:209)
    cloverage.coverage$run_tests.invoke (coverage.clj:199)
    cloverage.coverage$run_main.invokeStatic (coverage.clj:261)
    cloverage.coverage$run_main.invoke (coverage.clj:253)
    cloverage.coverage$run_project.invokeStatic (coverage.clj:277)
    cloverage.coverage$run_project.doInvoke (coverage.clj:273)
    clojure.lang.RestFn.invoke (RestFn.java:460)
    user$eval4238.invokeStatic (form-init582277943802464326.clj:1)
    user$eval4238.invoke (form-init582277943802464326.clj:1)
    clojure.lang.Compiler.eval (Compiler.java:7177)
    clojure.lang.Compiler.eval (Compiler.java:7167)
    clojure.lang.Compiler.load (Compiler.java:7636)
    clojure.lang.Compiler.loadFile (Compiler.java:7574)
    clojure.main$load_script.invokeStatic (main.clj:475)
    clojure.main$init_opt.invokeStatic (main.clj:477)
    clojure.main$init_opt.invoke (main.clj:477)
    clojure.main$initialize.invokeStatic (main.clj:508)
    clojure.main$null_opt.invokeStatic (main.clj:542)
    clojure.main$null_opt.invoke (main.clj:539)
    clojure.main$main.invokeStatic (main.clj:664)
    clojure.main$main.doInvoke (main.clj:616)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.Var.applyTo (Var.java:705)
    clojure.main.main (main.java:40)

ERROR in (pwhash-str-alg-and-verify-test-equal) (Reflector.java:154)
Uncaught exception, not in assertion.
expected: nil
  actual: java.lang.IllegalArgumentException: No matching method crypto_pwhash_str_alg found taking 6 args for class caesium.binding.Sodium$jnr$ffi$0
 at clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:154)
    clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:102)
    caesium.crypto.pwhash$pwhash_str_alg_to_buf_BANG_.invokeStatic (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$pwhash_str_alg_to_buf_BANG_.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$pwhash_str_alg.invokeStatic (caesium/crypto/pwhash.clj:123)
    caesium.crypto.pwhash$pwhash_str_alg.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash_test$fn__10865.invokeStatic (pwhash_test.clj:104)
    caesium.crypto.pwhash_test/fn (pwhash_test.clj:103)
    clojure.test$test_var$fn__9737.invoke (test.clj:717)
    clojure.test$test_var.invokeStatic (test.clj:717)
    clojure.test$test_var.invoke (test.clj:708)
    clojure.test$test_vars$fn__9763$fn__9768.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars$fn__9763.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars.invokeStatic (test.clj:731)
    clojure.test$test_all_vars.invokeStatic (test.clj:737)
    clojure.test$test_ns.invokeStatic (test.clj:758)
    clojure.test$test_ns.invoke (test.clj:743)
    clojure.core$map$fn__5866.invoke (core.clj:2755)
    clojure.lang.LazySeq.sval (LazySeq.java:42)
    clojure.lang.LazySeq.seq (LazySeq.java:51)
    clojure.lang.Cons.next (Cons.java:39)
    clojure.lang.RT.boundedLength (RT.java:1792)
    clojure.lang.RestFn.applyTo (RestFn.java:130)
    clojure.core$apply.invokeStatic (core.clj:667)
    clojure.test$run_tests.invokeStatic (test.clj:768)
    clojure.test$run_tests.doInvoke (test.clj:768)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:665)
    clojure.core$apply.invoke (core.clj:660)
    cloverage.coverage$eval4113$fn__4115$fn__4117$run_tests__4118.invoke (coverage.clj:187)
    cloverage.coverage$eval4113$fn__4115$fn__4117.invoke (coverage.clj:193)
    cloverage.coverage$run_tests$fn__4136.invoke (coverage.clj:211)
    cloverage.coverage$form_for_suppressing_unselected_tests.invokeStatic (coverage.clj:54)
    cloverage.coverage$form_for_suppressing_unselected_tests.invoke (coverage.clj:32)
    cloverage.coverage$run_tests.invokeStatic (coverage.clj:209)
    cloverage.coverage$run_tests.invoke (coverage.clj:199)
    cloverage.coverage$run_main.invokeStatic (coverage.clj:261)
    cloverage.coverage$run_main.invoke (coverage.clj:253)
    cloverage.coverage$run_project.invokeStatic (coverage.clj:277)
    cloverage.coverage$run_project.doInvoke (coverage.clj:273)
    clojure.lang.RestFn.invoke (RestFn.java:460)
    user$eval4238.invokeStatic (form-init582277943802464326.clj:1)
    user$eval4238.invoke (form-init582277943802464326.clj:1)
    clojure.lang.Compiler.eval (Compiler.java:7177)
    clojure.lang.Compiler.eval (Compiler.java:7167)
    clojure.lang.Compiler.load (Compiler.java:7636)
    clojure.lang.Compiler.loadFile (Compiler.java:7574)
    clojure.main$load_script.invokeStatic (main.clj:475)
    clojure.main$init_opt.invokeStatic (main.clj:477)
    clojure.main$init_opt.invoke (main.clj:477)
    clojure.main$initialize.invokeStatic (main.clj:508)
    clojure.main$null_opt.invokeStatic (main.clj:542)
    clojure.main$null_opt.invoke (main.clj:539)
    clojure.main$main.invokeStatic (main.clj:664)
    clojure.main$main.doInvoke (main.clj:616)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.Var.applyTo (Var.java:705)
    clojure.main.main (main.java:40)

ERROR in (pwhash-alg-argon2i-test) (Reflector.java:154)
expected: (= "75a10fdb4db0836498f824f1f0cc9ab9d3bb194d41b8dd66bd1ca6f0cf686810" (u/hexify (p/pwhash 32 "password" salt p/argon2i-opslimit-min p/argon2i-memlimit-interactive p/alg-argon2i13)))
  actual: java.lang.IllegalArgumentException: No matching method crypto_pwhash found taking 8 args for class caesium.binding.Sodium$jnr$ffi$0
 at clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:154)
    clojure.lang.Reflector.invokeInstanceMethod (Reflector.java:102)
    caesium.crypto.pwhash$pwhash_to_buf_BANG_.invokeStatic (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$pwhash_to_buf_BANG_.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash$pwhash.invokeStatic (caesium/crypto/pwhash.clj:93)
    caesium.crypto.pwhash$pwhash.invoke (caesium/crypto/pwhash.clj:1)
    caesium.crypto.pwhash_test$fn__10850.invokeStatic (pwhash_test.clj:91)
    caesium.crypto.pwhash_test/fn (pwhash_test.clj:89)
    clojure.test$test_var$fn__9737.invoke (test.clj:717)
    clojure.test$test_var.invokeStatic (test.clj:717)
    clojure.test$test_var.invoke (test.clj:708)
    clojure.test$test_vars$fn__9763$fn__9768.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars$fn__9763.invoke (test.clj:735)
    clojure.test$default_fixture.invokeStatic (test.clj:687)
    clojure.test$default_fixture.invoke (test.clj:683)
    clojure.test$test_vars.invokeStatic (test.clj:731)
    clojure.test$test_all_vars.invokeStatic (test.clj:737)
    clojure.test$test_ns.invokeStatic (test.clj:758)
    clojure.test$test_ns.invoke (test.clj:743)
    clojure.core$map$fn__5866.invoke (core.clj:2755)
    clojure.lang.LazySeq.sval (LazySeq.java:42)
    clojure.lang.LazySeq.seq (LazySeq.java:51)
    clojure.lang.Cons.next (Cons.java:39)
    clojure.lang.RT.boundedLength (RT.java:1792)
    clojure.lang.RestFn.applyTo (RestFn.java:130)
    clojure.core$apply.invokeStatic (core.clj:667)
    clojure.test$run_tests.invokeStatic (test.clj:768)
    clojure.test$run_tests.doInvoke (test.clj:768)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.core$apply.invokeStatic (core.clj:665)
    clojure.core$apply.invoke (core.clj:660)
    cloverage.coverage$eval4113$fn__4115$fn__4117$run_tests__4118.invoke (coverage.clj:187)
    cloverage.coverage$eval4113$fn__4115$fn__4117.invoke (coverage.clj:193)
    cloverage.coverage$run_tests$fn__4136.invoke (coverage.clj:211)
    cloverage.coverage$form_for_suppressing_unselected_tests.invokeStatic (coverage.clj:54)
    cloverage.coverage$form_for_suppressing_unselected_tests.invoke (coverage.clj:32)
    cloverage.coverage$run_tests.invokeStatic (coverage.clj:209)
    cloverage.coverage$run_tests.invoke (coverage.clj:199)
    cloverage.coverage$run_main.invokeStatic (coverage.clj:261)
    cloverage.coverage$run_main.invoke (coverage.clj:253)
    cloverage.coverage$run_project.invokeStatic (coverage.clj:277)
    cloverage.coverage$run_project.doInvoke (coverage.clj:273)
    clojure.lang.RestFn.invoke (RestFn.java:460)
    user$eval4238.invokeStatic (form-init582277943802464326.clj:1)
    user$eval4238.invoke (form-init582277943802464326.clj:1)
    clojure.lang.Compiler.eval (Compiler.java:7177)
    clojure.lang.Compiler.eval (Compiler.java:7167)
    clojure.lang.Compiler.load (Compiler.java:7636)
    clojure.lang.Compiler.loadFile (Compiler.java:7574)
    clojure.main$load_script.invokeStatic (main.clj:475)
    clojure.main$init_opt.invokeStatic (main.clj:477)
    clojure.main$init_opt.invoke (main.clj:477)
    clojure.main$initialize.invokeStatic (main.clj:508)
    clojure.main$null_opt.invokeStatic (main.clj:542)
    clojure.main$null_opt.invoke (main.clj:539)
    clojure.main$main.invokeStatic (main.clj:664)
    clojure.main$main.doInvoke (main.clj:616)
    clojure.lang.RestFn.applyTo (RestFn.java:137)
    clojure.lang.Var.applyTo (Var.java:705)
    clojure.main.main (main.java:40)

Ran 19 tests containing 150 assertions.
0 failures, 9 errors.
Ran tests.

The same tests complete successfully under the usual clojure.test runner:

$ lein with-profile +test test caesium.crypto.pwhash-test

lein test caesium.crypto.pwhash-test

Ran 19 tests containing 150 assertions.
0 failures, 0 errors.

Reading https://github.com/cloverage/cloverage#illegalargumentexception-no-matching-field-found-foo-for-class-userbar hints that there may be some issue with cloverage instrumenting the calls. And indeed, if I instruct cloverage to not instrument the caesium.crypto.pwhash ns, the coverage run succeeds fine:

$ lein with-profile +test cloverage --codecov -t caesium.crypto.pwhash-test -e caesium.crypto.pwhash
...
Instrumented namespaces.

Testing caesium.crypto.pwhash-test

Ran 19 tests containing 150 assertions.
0 failures, 0 errors.
Ran tests.

What puzzles me, this ns is not much different to other binding nses we have in caesium. Yet these particular calls fail under cloverage.

I'm not sure, but... could it be related to cloverage/cloverage#309?

@lvh, you seem to be one of the main contributors on https://github.com/cloverage/cloverage. Any chance you have any input on this issue?

Meanwhile I'm looking into the implementation for the pwhash binding fns in an attempt to try to spot any difference in the way they are implemented in comparison to other fns that don't cause any cloverage issues.

I've ran the subject tests through a version of cloverage with both of the yet open PRs on the cloverage repo (cloverage/cloverage#311 and cloverage/cloverage#310) applied. They don't seem to have an impact on this issue: the result stays the same.

I've ran the subject tests through a version of cloverage with both of the yet open PRs on the cloverage repo (cloverage/cloverage#311 and cloverage/cloverage#310) applied. They don't seem to have an impact on this issue: the result stays the same.

Actually, please disregard the above. The mentioned pull requests fix the issue. I had incorrectly ran it against the released version instead of the patched one.

Below is the output from 1.2.1-SNAPSHOT with the PRs applied:

$ CLOVERAGE_VERSION=1.2.1-SNAPSHOT lein with-profile +test cloverage --codecov -t caesium.crypto.pwhash-test

Reflection warning, clojure/data/xml.clj:337:17 - call to method createXMLStreamReader can't be resolved (target class is unknown).
Loading namespaces:  (caesium.byte-bufs caesium.binding caesium.crypto.auth caesium.util caesium.crypto.pwhash caesium.sodium caesium.randombytes caesium.crypto.secretbox caesium.crypto.hash caesium.crypto.generichash caesium.crypto.shorthash caesium.crypto.core.ristretto255 caesium.crypto.core.ristretto255.scalar caesium.crypto.scalarmult caesium.crypto.kx caesium.crypto.box caesium.crypto.kdf caesium.magicnonce.secretbox caesium.crypto.scalarmult.ristretto255 caesium.crypto.sign caesium.crypto.aead)
Test namespaces:  (caesium.crypto.pwhash-test)
Instrumented caesium.byte-bufs
Instrumented caesium.binding
Instrumented caesium.crypto.auth
Reflection warning, caesium/util.clj:1:6458 - reference to field toByteArray can't be resolved.
Reflection warning, caesium/util.clj:1:6458 - call to static method alength on clojure.lang.RT can't be resolved (argument types: unknown).
Instrumented caesium.util
Instrumented caesium.crypto.pwhash
Instrumented caesium.sodium
Instrumented caesium.randombytes
Instrumented caesium.crypto.secretbox
Instrumented caesium.crypto.hash
Instrumented caesium.crypto.generichash
Instrumented caesium.crypto.shorthash
Instrumented caesium.crypto.core.ristretto255
Instrumented caesium.crypto.core.ristretto255.scalar
Instrumented caesium.crypto.scalarmult
Reflection warning, caesium/crypto/kx.clj:1:6458 - call to method crypto_kx_client_session_keys on caesium.binding.Sodium can't be resolved (argument types: unknown, unknown, unknown, unknown, unknown).
Reflection warning, caesium/crypto/kx.clj:1:6458 - call to method crypto_kx_server_session_keys on caesium.binding.Sodium can't be resolved (argument types: unknown, unknown, unknown, unknown, unknown).
Instrumented caesium.crypto.kx
Instrumented caesium.crypto.box
Instrumented caesium.crypto.kdf
Instrumented caesium.magicnonce.secretbox
Instrumented caesium.crypto.scalarmult.ristretto255
Instrumented caesium.crypto.sign
Instrumented caesium.crypto.aead
Instrumented 21 namespaces in 4.1 seconds.

Testing caesium.crypto.pwhash-test

Ran 19 tests containing 150 assertions.
0 failures, 0 errors.
Ran tests.

Yay.

So I reckon we better just wait for the PRs to be merged in cloverage and then propagate the new version to caesium.

commented

Somehow I never got a notification for those PRs being open. I'll go review them.

commented

I've merged both PRs and released a new version of cloverage.