Fork me on GitHub
#clojure-spec
<
2018-08-30
>
Daniel Hines16:08:52

I'm writing a web app that writes to our CRM. We have a bunch of third party plugins installed on this CRM that I'm not allowed to touch. One function of these plugins is to validate incoming user-inputted data; however, somewhere in the validation, the plugins are occasionally hitting fatal exceptions, but they give no clues as to what it might be. The third party won't provide any documentation, and decompiling their code is expressly forbidden in their EULA. Through significant trial and error, I've narrowed down the cause to specific combinations of input values, which appear completely arbitrary to me. There are about 100 different inputs, some of which have hundreds of possible values, and the order the inputs seems to matter, making this very difficult to address by hand. Would it make sense to use spec in this situation to systematically explore combinations of data cause errors?

jeaye17:08:43

I've hit an issue with instrumentation wherein the instrument macro generates and returns a vector of symbols of those fns instrumented which is too large for the JVM to appreciate. So, I see Method code too large! failing the compilation instead. This seems like something spec will need to address, in the long term, as more people end up spec'ing more fns. Right now, looks like this project is around 300 spec'd fns and the issue is arising. Both Clojure and ClojureScript seem to be subject to the issue.

ghadi17:08:54

can you give a repro for the case @jeaye?

jeaye17:08:22

Yup. I'll have one up in a bit.

jeaye17:08:25

A repro case in 20 lines or so. Couldn't get it going with Clojure, but it certainly happens with ClojureScript. When I look at the implementation of instrument for each, it'd seem both would be subject, but perhaps not.

jeaye17:08:31

100% repro here though.

seancorfield17:08:35

@d4hines That sounds very much like the scenario Stu Halloway was talking about in one of his presentations on spec...

seancorfield17:08:22

I don't know. I don't think I attended SL in 2016. May have watched that online tho'. I thought it was a talk from one of the Conj's or West's...

Daniel Hines17:08:51

Ok, I'll look for it. Thanks!

bbrinck19:08:27

Keep in mind that exercise will generate values that match the spec, but to get the power of shrinking (which is what you want, I expect), you’ll want to combine spec with test.check

bbrinck19:08:00

I really like the test.chuck library for this, you can write something like the following (totally untested and written in slack, so beware 🙂 )

(deftest find-bug
  (checking
     "all valid inputs don't cause exception"
     100
     [args (s/gen ::args-spec)]
     ;; replace 'string?' with whatever the actual expected return type is
     (is (string? (apply third-party-api/some-fn args)))))    

taylor18:08:50

IIRC there might be a talk he gave about writing specs for a Java charting library and finding a (JVM?) bug by "fuzzing" it with random spec checks?

jeaye18:08:34

@ghadi Is that something which you can repro?

dadair18:08:56

Has anyone encountered an open-source HL7-FHIR spec library? I have been creating one for work but I’d be interested in pulling it out into an open-source project if others wanted to collaborate on it.

ghadi18:08:25

we would find that useful @dadair

ghadi18:08:04

@jeaye haven't had a chance to try yet, but off-hand: try to get rid of the nested do https://github.com/jeaye/instrument-too-many/blob/master/src/instrument_too_many/macro.cljc#L8

ghadi18:08:25

i think the compiler special case's top-level do's but not nested ones

jeaye18:08:46

That macro's just making the fns though. That macro doesn't cause the error; the error is with instrumentation.

jeaye18:08:32

If you comment out the (stest/instrument) form, it compiles just fine.

pablore20:08:59

Is there anyway to decompose a spec definition? I want to use a s/keys spec to define a database table

pablore20:08:27

oh using s/describe