This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-10-30
Channels
- # announcements (15)
- # beginners (99)
- # boot (15)
- # cider (105)
- # cljdoc (2)
- # cljs-dev (17)
- # clojure (132)
- # clojure-conj (1)
- # clojure-dev (5)
- # clojure-italy (19)
- # clojure-losangeles (2)
- # clojure-nl (20)
- # clojure-spec (70)
- # clojure-uk (50)
- # clojurescript (153)
- # core-logic (9)
- # cryogen (4)
- # cursive (6)
- # datomic (40)
- # duct (5)
- # figwheel-main (10)
- # fulcro (245)
- # hoplon (1)
- # jobs (3)
- # leiningen (12)
- # mount (8)
- # nrepl (11)
- # off-topic (1)
- # pathom (16)
- # pedestal (3)
- # planck (17)
- # re-frame (3)
- # reitit (8)
- # shadow-cljs (64)
- # spacemacs (3)
- # specter (20)
- # tools-deps (21)
I have an interesting case where I call stest/check
from the REPL (lein + cider nrepl) and it doesn’t finish. Anyone familiar with that one?
how do you know it won’t finish? did you solve the halting problem!?
$ clj -A:test:repl
user=> (stest/check `str)
({:spec #object[clojure.spec.alpha$fspec_impl$reify__2524 0x3a94964 "clojure.spec.alpha$fspec_impl$reify__2524@3a94964"], :clojure.spec.test.check/ret {:result true, :pass? true, :num-tests 1000, :time-elapsed-ms 19215, :seed 1540906061983}, :sym clojure.core/str})
user=> ^D
Borkdude@borkdude ~/Dropbox/dev/clojure/speculative (borkdude*) $ lein repl
nREPL server started on port 57033 on host 127.0.0.1 -
(require '[REPL-y 0.3.7, nREPL 0.2.12
Clojure 1.10.0-RC1
Java HotSpot(TM) 64-Bit Server VM 1.8.0_45-b14
...
user=> (require '[speculative.core])
nil
user=> (require '[clojure.spec.test.alpha :as stest])
nil
user=> (stest/check `str)
;; still nothing after a looooong time
Have you tried at least a few times from the command line? Tests that probabilistically take a Long Time can be misleading like that with just a few data points
@gfredericks trying.
hmm, now clj
lingers after printing the result of stests:
$ clj -A:test -e "(require,'[speculative.core])" -e "(require,'[clojure.spec.test.alpha,:as,stest])" -e "(stest/check \`str)"
({:spec #object[clojure.spec.alpha$fspec_impl$reify__2524 0x3e14c16d "clojure.spec.alpha$fspec_impl$reify__2524@3e14c16d"], :clojure.spec.test.check/ret {:result true, :pass? true, :num-tests 1000, :time-elapsed-ms 15108, :seed 1540911818977}, :sym clojure.core/str})
it just takes a long time before it returns to the cmd line. maybe garbage collecting?
is it exactly 60s?
this is the output with time
:
$ time clj -A:test -e "(require,'[speculative.core])" -e "(require,'[clojure.spec.test.alpha,:as,stest])" -e "(stest/check \`str)"
({:spec #object[clojure.spec.alpha$fspec_impl$reify__2524 0x3e14c16d "clojure.spec.alpha$fspec_impl$reify__2524@3e14c16d"], :clojure.spec.test.check/ret {:result true, :pass? true, :num-tests 1000, :time-elapsed-ms 14804, :seed 1540911992271}, :sym clojure.core/str})
clj -A:test -e "(require,'[speculative.core])" -e -e "(stest/check \`str)" 25.76s user 1.40s system 35% cpu 1:16.86 total
I meant 60s following the end of the tests
if so, then adding (shutdown-agents)
after the stest/check
call should help
Repro:
;; run with:
;; clj -Srepro -Sdeps '{:deps {org.clojure/clojure {:mvn/version "RELEASE"} org.clojure/test.check {:mvn/version "RELEASE"}}}' -i stest_time.clj
(ns stest-time
(:require
[clojure.test :as t]
[clojure.spec.alpha :as s]
[clojure.spec.test.alpha :as stest]))
(s/fdef clojure.core/str
:args (s/* any?)
:ret string?)
(stest/check `str)
(println "after stest")
(shutdown-agents)
(println "after shutdown agents")
Still takes 13s after printing the last message.that sounds very strange
I mean it does, but I don't think a JVM needs to GC on shutdown
you just burn it all down and let the OS sort it out
kill -3
says there's an agent thread running generator stuff
so that code launches a future somehow
I think shutdown-agents
might not be synchronous in its effect
so the fact that it waits longer when there's a future in the background that hasn't completed isn't surprising
but why there's a future in this case I don't know
(I haven't used clojure.spec.test.alpha
much)
at clojure.spec.test.alpha$quick_check.invokeStatic(alpha.clj:310)
at clojure.spec.test.alpha$quick_check.invoke(alpha.clj:303)
at clojure.spec.test.alpha$check_1.invokeStatic(alpha.clj:336)
at clojure.spec.test.alpha$check_1.invoke(alpha.clj:324)
at clojure.spec.test.alpha$check$fn__3088.invoke(alpha.clj:412)
at clojure.core$pmap$fn__8342$fn__8343.invoke(core.clj:6994)
:thinking_face:check uses pmap
ah well there you go then
gotta spend 15 seconds generating a few last giant piles of garbage in case somebody wants them
@borkdude the most recent alpha of test.check might be a bit better about this. I can't remember, and also don't know what version you get by specifying RELEASE
oh; nevermind then
for this kind of test it's probably best to use a smaller max-size for the gen/any
I wonder if gen/any
should just have a smaller default size universally :thinking_face:
no, I'm not sure of the exact syntax for sizing control in spec
if you don't mind affecting the whole generator, I think the stest/check
call lets you pass max size
for finer grained control you'd probably set an override specific to the any?
spec
Any idea how to do this? I tried by using a :gen
override for :clojure.core/any?
but that doesn’t work, because any?
is a builtin I think:
https://github.com/clojure/spec.alpha/blob/31165fec69ff86129a1ada8b3f50864922dfc88a/src/main/clojure/clojure/spec/gen/alpha.clj#L118
I wouldn't have expected that, but assuming you're right and you can't override builtins, another option would be having your own (def ::any any?)
that you can override
unfortunate if you have to do that, but should work at least
@alexmiller if you want I can post that script in an issue if you think it’s something that should be improved over time
I don’t understand what we’re talking about
check returns a lazy seq - you need to consume it
As noted in the doc string
So wrap a doall around the call to check
I slightly envy your pun-creation skills.
I'm not sure if this is a bad idea or something but I'd love to always have stest/instrument
switched on during development.
Is there some way to keep functions instrumented after re-defining them in the REPL?
I see there's (defonce ^:private instrumented-vars (atom {}))
in spec.alpha, but I don't see it publicly exposed. Something that came to mind was using that to re-instrument things that were previously instrumented?
If you are using something like Component or Integrant you can wrap their system reset functions with calls to instrument
I’ve considered that but often I’m just working in one namespace in the REPL and restarting the system seems like overkill in a way
I guess I should just bind stest/Instrument to a hotkey
@martinklepsch I hook up stest/instrument with component. So when I restart the system, my new fns are instrumented.
somehow this also lingers after the test has executed, even with doall
:
(ns spec-keys-test
(:require
[clojure.test :as t :refer [deftest testing is]]
[clojure.spec.alpha :as s]
[clojure.spec.test.alpha :as stest]))
(defn foo [n] n)
(s/fdef foo
:args (s/cat :n number?)
:ret number?)
(deftest repro-test
(testing "output of check"
(let [r (doall (stest/check `foo))
c (count r)]
(println "count" c)
(is (= c (count (keep :spec r))))
(is (= c (count (keep :sym r))))
(is (= c (count (keep :clojure.spec.test.check/ret r)))))))
(t/run-tests)
I think shutdown-agents
was mentioned before, but wasn't sure whether you had tried it. If your code calls future
directly (or indirectly through one of several other functions), it can cause a 60-second pause at the end before the JVM exits: http://clojuredocs.org/clojure.core/future
e.g. pmap
clojure.java.shell/sh