clucumber 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/LICENSE +1 -1
- data/README.md +4 -9
- data/lib/clucumber/clucumber-bootstrap.lisp +32 -0
- data/lib/clucumber/vendor/cl-interpol/alias.lisp +55 -0
- data/lib/clucumber/vendor/cl-interpol/cl-interpol.asd +56 -0
- data/lib/clucumber/vendor/cl-interpol/load.lisp +53 -0
- data/lib/clucumber/vendor/cl-interpol/packages.lisp +40 -0
- data/lib/clucumber/vendor/cl-interpol/read.lisp +716 -0
- data/lib/clucumber/vendor/cl-interpol/specials.lisp +113 -0
- data/lib/clucumber/vendor/cl-interpol/test/packages.lisp +34 -0
- data/lib/clucumber/vendor/cl-interpol/test/tests.lisp +128 -0
- data/lib/clucumber/vendor/cl-interpol/test.lisp +177 -0
- data/lib/clucumber/vendor/cl-interpol/test2.lisp +6254 -0
- data/lib/clucumber/vendor/cl-interpol/unicode.lisp +13912 -0
- data/lib/clucumber/vendor/cl-interpol/util.lisp +122 -0
- data/lib/clucumber/vendor/cl-ppcre/api.lisp +1262 -0
- data/lib/clucumber/vendor/cl-ppcre/charmap.lisp +152 -0
- data/lib/clucumber/vendor/cl-ppcre/charset.lisp +242 -0
- data/lib/clucumber/vendor/cl-ppcre/chartest.lisp +98 -0
- data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-test.asd +34 -0
- data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode/packages.lisp +38 -0
- data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode/resolver.lisp +61 -0
- data/lib/clucumber/vendor/cl-ppcre/cl-ppcre-unicode.asd +58 -0
- data/lib/clucumber/vendor/cl-ppcre/cl-ppcre.asd +79 -0
- data/lib/clucumber/vendor/cl-ppcre/closures.lisp +471 -0
- data/lib/clucumber/vendor/cl-ppcre/convert.lisp +875 -0
- data/lib/clucumber/vendor/cl-ppcre/errors.lisp +84 -0
- data/lib/clucumber/vendor/cl-ppcre/lexer.lisp +737 -0
- data/lib/clucumber/vendor/cl-ppcre/lispworks-defsystem.lisp +57 -0
- data/lib/clucumber/vendor/cl-ppcre/load.lisp +67 -0
- data/lib/clucumber/vendor/cl-ppcre/optimize.lisp +578 -0
- data/lib/clucumber/vendor/cl-ppcre/packages.lisp +68 -0
- data/lib/clucumber/vendor/cl-ppcre/parser.lisp +319 -0
- data/lib/clucumber/vendor/cl-ppcre/ppcre-tests.lisp +269 -0
- data/lib/clucumber/vendor/cl-ppcre/regex-class-util.lisp +555 -0
- data/lib/clucumber/vendor/cl-ppcre/regex-class.lisp +259 -0
- data/lib/clucumber/vendor/cl-ppcre/repetition-closures.lisp +833 -0
- data/lib/clucumber/vendor/cl-ppcre/scanner.lisp +506 -0
- data/lib/clucumber/vendor/cl-ppcre/specials.lisp +172 -0
- data/lib/clucumber/vendor/cl-ppcre/test/packages.lisp +37 -0
- data/lib/clucumber/vendor/cl-ppcre/test/perl-tests.lisp +150 -0
- data/lib/clucumber/vendor/cl-ppcre/test/tests.lisp +159 -0
- data/lib/clucumber/vendor/cl-ppcre/test/unicode-tests.lisp +80 -0
- data/lib/clucumber/vendor/cl-ppcre/util.lisp +201 -0
- data/lib/clucumber/vendor/cl-unicode/alias.lisp +135 -0
- data/lib/clucumber/vendor/cl-unicode/api.lisp +412 -0
- data/lib/clucumber/vendor/cl-unicode/build/char-info.lisp +133 -0
- data/lib/clucumber/vendor/cl-unicode/build/dump.lisp +239 -0
- data/lib/clucumber/vendor/cl-unicode/build/read.lisp +280 -0
- data/lib/clucumber/vendor/cl-unicode/build/util.lisp +182 -0
- data/lib/clucumber/vendor/cl-unicode/cl-unicode.asd +90 -0
- data/lib/clucumber/vendor/cl-unicode/conditions.lisp +54 -0
- data/lib/clucumber/vendor/cl-unicode/derived.lisp +120 -0
- data/lib/clucumber/vendor/cl-unicode/hash-tables.lisp +20 -0
- data/lib/clucumber/vendor/cl-unicode/lists.lisp +10 -0
- data/lib/clucumber/vendor/cl-unicode/methods.lisp +15 -0
- data/lib/clucumber/vendor/cl-unicode/packages.lisp +76 -0
- data/lib/clucumber/vendor/cl-unicode/specials.lisp +135 -0
- data/lib/clucumber/vendor/cl-unicode/test/packages.lisp +34 -0
- data/lib/clucumber/vendor/cl-unicode/test/tests.lisp +150 -0
- data/lib/clucumber/vendor/cl-unicode/test-functions.lisp +94 -0
- data/lib/clucumber/vendor/cl-unicode/util.lisp +274 -0
- data/lib/clucumber/vendor/lift/compare/fiveam-tests.lisp +14 -0
- data/lib/clucumber/vendor/lift/compare/lift-tests.lisp +13 -0
- data/lib/clucumber/vendor/lift/compare/rt-tests.lisp +16 -0
- data/lib/clucumber/vendor/lift/compare/xlunit-tests.lisp +15 -0
- data/lib/clucumber/vendor/lift/dev/changes.lisp +61 -0
- data/lib/clucumber/vendor/lift/dev/config.lisp +354 -0
- data/lib/clucumber/vendor/lift/dev/copy-file.lisp +117 -0
- data/lib/clucumber/vendor/lift/dev/introspection.lisp +232 -0
- data/lib/clucumber/vendor/lift/dev/lift-interface.lisp +56 -0
- data/lib/clucumber/vendor/lift/dev/lift-notes.lisp +202 -0
- data/lib/clucumber/vendor/lift/dev/lift-randomized.lisp +45 -0
- data/lib/clucumber/vendor/lift/dev/lift.lisp +2383 -0
- data/lib/clucumber/vendor/lift/dev/macros.lisp +229 -0
- data/lib/clucumber/vendor/lift/dev/measuring.lisp +156 -0
- data/lib/clucumber/vendor/lift/dev/packages.lisp +161 -0
- data/lib/clucumber/vendor/lift/dev/port.lisp +151 -0
- data/lib/clucumber/vendor/lift/dev/prototypes.lisp +282 -0
- data/lib/clucumber/vendor/lift/dev/random-testing.lisp +124 -0
- data/lib/clucumber/vendor/lift/dev/report-locations.lisp +13 -0
- data/lib/clucumber/vendor/lift/dev/reports.lisp +916 -0
- data/lib/clucumber/vendor/lift/dev/utilities.lisp +242 -0
- data/lib/clucumber/vendor/lift/docs/package.lisp +6 -0
- data/lib/clucumber/vendor/lift/docs/setup.lisp +17 -0
- data/lib/clucumber/vendor/lift/examples/basic-examples.lisp +289 -0
- data/lib/clucumber/vendor/lift/examples/random-testing.lisp +32 -0
- data/lib/clucumber/vendor/lift/lift-documentation.asd +28 -0
- data/lib/clucumber/vendor/lift/lift-test.asd +35 -0
- data/lib/clucumber/vendor/lift/lift.asd +77 -0
- data/lib/clucumber/vendor/lift/test/equality-tests.lisp +40 -0
- data/lib/clucumber/vendor/lift/test/finding-tests.lisp +32 -0
- data/lib/clucumber/vendor/lift/test/lift-test.lisp +783 -0
- data/lib/clucumber/vendor/lift/test/order-of-operations.lisp +54 -0
- data/lib/clucumber/vendor/lift/test/packages.lisp +17 -0
- data/lib/clucumber/vendor/lift/test/test-config-files.lisp +20 -0
- data/lib/clucumber/vendor/lift/test/test-dynamic-variables.lisp +57 -0
- data/lib/clucumber/vendor/lift/test/test-maximum-problems.lisp +74 -0
- data/lib/clucumber/vendor/lift/test/test-prototypes.lisp +278 -0
- data/lib/clucumber/vendor/lift/test/test-timeout.lisp +37 -0
- data/lib/clucumber/vendor/lift/test/tests-in-progress.lisp +62 -0
- data/lib/clucumber/vendor/lift/test/testsuite-expects.lisp +60 -0
- data/lib/clucumber/vendor/lift/timeout/package.lisp +13 -0
- data/lib/clucumber/vendor/lift/timeout/with-timeout.lisp +123 -0
- data/lib/clucumber/vendor/lift/website/stuff/Temp.lisp +34 -0
- data/lib/clucumber/vendor/st-json/st-json.asd +3 -0
- data/lib/clucumber/vendor/st-json/st-json.lisp +310 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/backtrace.lisp +127 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/fallback.lisp +10 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/map-backtrace.lisp +103 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/mucking.lisp +75 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/packages.lisp +13 -0
- data/lib/clucumber/vendor/trivial-backtrace/dev/utilities.lisp +104 -0
- data/lib/clucumber/vendor/trivial-backtrace/test/packages.lisp +5 -0
- data/lib/clucumber/vendor/trivial-backtrace/test/test-setup.lisp +4 -0
- data/lib/clucumber/vendor/trivial-backtrace/test/tests.lisp +16 -0
- data/lib/clucumber/vendor/trivial-backtrace/trivial-backtrace-test.asd +22 -0
- data/lib/clucumber/vendor/trivial-backtrace/trivial-backtrace.asd +35 -0
- data/lib/clucumber/vendor/usocket/backend/allegro.lisp +199 -0
- data/lib/clucumber/vendor/usocket/backend/armedbear.lisp +491 -0
- data/lib/clucumber/vendor/usocket/backend/clisp.lisp +260 -0
- data/lib/clucumber/vendor/usocket/backend/cmucl.lisp +266 -0
- data/lib/clucumber/vendor/usocket/backend/lispworks.lisp +741 -0
- data/lib/clucumber/vendor/usocket/backend/mcl.lisp +369 -0
- data/lib/clucumber/vendor/usocket/backend/openmcl.lisp +206 -0
- data/lib/clucumber/vendor/usocket/backend/sbcl.lisp +424 -0
- data/lib/clucumber/vendor/usocket/backend/scl.lisp +261 -0
- data/lib/clucumber/vendor/usocket/condition.lisp +227 -0
- data/lib/clucumber/vendor/usocket/package.lisp +82 -0
- data/lib/clucumber/vendor/usocket/server.lisp +45 -0
- data/lib/clucumber/vendor/usocket/test/package.lisp +13 -0
- data/lib/clucumber/vendor/usocket/test/test-usocket.lisp +166 -0
- data/lib/clucumber/vendor/usocket/usocket-test.asd +26 -0
- data/lib/clucumber/vendor/usocket/usocket.asd +37 -0
- data/lib/clucumber/vendor/usocket/usocket.lisp +542 -0
- data/lib/clucumber/vendor/usocket/vendor/kqueue.lisp +1 -0
- data/lib/clucumber/vendor/usocket/vendor/split-sequence.lisp +245 -0
- data/lib/clucumber.rb +29 -7
- metadata +151 -5
@@ -0,0 +1,229 @@
|
|
1
|
+
(in-package #:lift)
|
2
|
+
|
3
|
+
(defvar *measures* nil
|
4
|
+
"A list of defineded measures")
|
5
|
+
|
6
|
+
(defparameter *benchmark-log-path*
|
7
|
+
(asdf:system-relative-pathname
|
8
|
+
'lift "benchmark-data/benchmarks.log"))
|
9
|
+
|
10
|
+
(defvar *count-calls-p* nil)
|
11
|
+
|
12
|
+
(defmacro undefmeasure (name)
|
13
|
+
(let ((gname (gensym "name-")))
|
14
|
+
`(let ((,gname ,(form-keyword name)))
|
15
|
+
(if (find ,gname *measures* :key #'first)
|
16
|
+
(setf *measures* (remove ,gname *measures* :key #'first))
|
17
|
+
(error "Measure ~a not found." ,gname))
|
18
|
+
,gname)))
|
19
|
+
|
20
|
+
(defmacro defmeasure (name &key (value nil) (finally nil) (type nil)
|
21
|
+
(documentation nil))
|
22
|
+
(declare (ignore documentation))
|
23
|
+
(unless value
|
24
|
+
(error "A value must be specified to define a measure."))
|
25
|
+
(cond ((atom name)
|
26
|
+
;; all is well
|
27
|
+
)
|
28
|
+
((and (eq (first name) 'quote)
|
29
|
+
(eq (length name) 2))
|
30
|
+
(warn "Name does not need to be quoted.")
|
31
|
+
(setf name (second name)))
|
32
|
+
(t
|
33
|
+
(error "Name should be a symbol.")))
|
34
|
+
(cond ((eq (first finally) 'quote)
|
35
|
+
(setf finally (second finally))))
|
36
|
+
(let ((gname (gensym "name-")))
|
37
|
+
`(let ((,gname ,(form-keyword name)))
|
38
|
+
(setf *measures* (remove ,gname *measures* :key #'first))
|
39
|
+
(push (list ,gname
|
40
|
+
:value ,value
|
41
|
+
:finally ',finally
|
42
|
+
:type ',type)
|
43
|
+
*measures*)
|
44
|
+
,gname)))
|
45
|
+
|
46
|
+
(defmacro while-measuring ((catch-errors-p &rest measures) &body body)
|
47
|
+
(let ((vars (loop for measure in measures collect
|
48
|
+
(gensym (format nil "~a-" measure))))
|
49
|
+
(gcondition (gensym "condition-"))
|
50
|
+
(gresult (gensym "result-"))
|
51
|
+
(gcatch-errors-p (gensym "catch-errors-p-")))
|
52
|
+
(labels ((measure-1 (vars measures)
|
53
|
+
(cond ((null measures) body)
|
54
|
+
(t
|
55
|
+
`((while-measuring-1 (,(first vars) ,(first measures))
|
56
|
+
,@(measure-1 (rest vars) (rest measures))))))))
|
57
|
+
`(let ((,gcondition nil)
|
58
|
+
(,gresult nil)
|
59
|
+
(,gcatch-errors-p ,catch-errors-p)
|
60
|
+
,@vars)
|
61
|
+
(setf ,gresult
|
62
|
+
(handler-case
|
63
|
+
,@(measure-1 vars measures)
|
64
|
+
(error (c)
|
65
|
+
(setf ,gcondition c)
|
66
|
+
(unless ,gcatch-errors-p
|
67
|
+
(error c)))))
|
68
|
+
(values ,gresult (list ,@vars) ,gcondition)))))
|
69
|
+
|
70
|
+
#+notyet
|
71
|
+
;; returns error as third value (and probably as first too!)
|
72
|
+
(defmacro while-measuring ((&rest measures) (&body error-body)
|
73
|
+
&body body)
|
74
|
+
(let ((vars (loop for measure in measures collect
|
75
|
+
(gensym (format nil "~a-" measure))))
|
76
|
+
(gcondition (gensym "condition-"))
|
77
|
+
(gresult (gensym "result-")))
|
78
|
+
(labels ((measure-1 (vars measures)
|
79
|
+
(cond ((null measures) body)
|
80
|
+
(t
|
81
|
+
`((while-measuring-1 (,(first vars) ,(first measures))
|
82
|
+
,@(measure-1 (rest vars) (rest measures))))))))
|
83
|
+
`(let ((,gcondition nil)
|
84
|
+
(,gresult nil)
|
85
|
+
,@vars)
|
86
|
+
(setf ,gresult
|
87
|
+
(handler-case
|
88
|
+
,@(measure-1 vars measures)
|
89
|
+
(error (c)
|
90
|
+
,@(if error-body
|
91
|
+
`((progn ,error-body
|
92
|
+
(error c)))
|
93
|
+
`((setf ,gcondition c))))))
|
94
|
+
(values ,gresult (list ,@vars) ,gcondition)))))
|
95
|
+
|
96
|
+
#+(or)
|
97
|
+
(while-measuring (space seconds)
|
98
|
+
nil
|
99
|
+
(sleep 1)
|
100
|
+
(signal "hi"))
|
101
|
+
|
102
|
+
#+(or)
|
103
|
+
(measure-time-and-conses
|
104
|
+
(sleep 1)
|
105
|
+
(signal "hi"))
|
106
|
+
|
107
|
+
(defmacro while-measuring-1 ((var measure) &body body)
|
108
|
+
(let ((ginitial (gensym "value-"))
|
109
|
+
(gresult (gensym "result-"))
|
110
|
+
(metadata (find (form-keyword measure) *measures* :key 'first)))
|
111
|
+
(unless metadata
|
112
|
+
(error "Measure `~a` not defined." measure))
|
113
|
+
(destructuring-bind (&key value finally type &allow-other-keys)
|
114
|
+
(rest metadata)
|
115
|
+
`(let ((,ginitial (,value))
|
116
|
+
(,gresult nil))
|
117
|
+
,@(when type
|
118
|
+
`((declare (type ,type ,ginitial))))
|
119
|
+
(unwind-protect
|
120
|
+
(setf ,gresult (progn ,@body))
|
121
|
+
(setf ,var ,@(if finally
|
122
|
+
`((funcall (lambda (it) ,finally)
|
123
|
+
(- (,value) ,ginitial)))
|
124
|
+
`((- ,(if type `(the ,type (,value)) `(,value))
|
125
|
+
,ginitial)))))
|
126
|
+
,gresult))))
|
127
|
+
|
128
|
+
(defmacro with-profile-report
|
129
|
+
((name style &key
|
130
|
+
(log-name *benchmark-log-path* ln-supplied?)
|
131
|
+
(count-calls-p *count-calls-p* ccp-supplied?)
|
132
|
+
(timeout nil timeout-supplied?))
|
133
|
+
&body body)
|
134
|
+
`(with-profile-report-fn
|
135
|
+
,name ,style
|
136
|
+
(lambda () (progn ,@body))
|
137
|
+
',body
|
138
|
+
,@(when ccp-supplied?
|
139
|
+
`(:count-calls-p ,count-calls-p))
|
140
|
+
,@(when ln-supplied?
|
141
|
+
`(:log-name ,log-name))
|
142
|
+
,@(when (and timeout-supplied? timeout)
|
143
|
+
`(:timeout ,timeout))))
|
144
|
+
|
145
|
+
(defmacro while-counting-repetitions ((&optional (delay 1.0)) &body body)
|
146
|
+
"Execute `body` repeatedly for `delay` seconds. Returns the number
|
147
|
+
of times `body` is executed per second. Warning: assumes that `body` will not
|
148
|
+
be executed more than a fixnum number of times. The `delay` defaults to
|
149
|
+
1.0."
|
150
|
+
(let ((gevent-count (gensym "count-"))
|
151
|
+
(gdelay (gensym "delay-"))
|
152
|
+
(gignore (gensym "ignore-"))
|
153
|
+
(gfn (gensym "fn-")))
|
154
|
+
`(let ((,gfn
|
155
|
+
(compile
|
156
|
+
nil
|
157
|
+
(lambda ()
|
158
|
+
(let ((,gevent-count 0)
|
159
|
+
(,gdelay ,delay))
|
160
|
+
(declare (type fixnum ,gevent-count))
|
161
|
+
(handler-case
|
162
|
+
(lift::with-timeout (,gdelay)
|
163
|
+
(loop
|
164
|
+
(progn ,@body)
|
165
|
+
(setf ,gevent-count (the fixnum (1+ ,gevent-count)))))
|
166
|
+
(lift::timeout-error (,gignore)
|
167
|
+
(declare (ignore ,gignore))
|
168
|
+
(if (plusp ,gevent-count)
|
169
|
+
(float (/ ,gevent-count ,gdelay))
|
170
|
+
,gevent-count))))))))
|
171
|
+
(funcall ,gfn))))
|
172
|
+
|
173
|
+
(defmacro while-counting-events ((&optional (delay 1.0)) &body body)
|
174
|
+
"Returns the count of the number of times `did-event` was called during
|
175
|
+
`delay` seconds. See also: [while-counting-repetitions][]."
|
176
|
+
(let ((gevent-count (gensym "count")))
|
177
|
+
`(let ((,gevent-count 0))
|
178
|
+
(flet ((did-event ()
|
179
|
+
(incf ,gevent-count)))
|
180
|
+
(declare (type fixnum ,gevent-count)
|
181
|
+
(ignorable (function did-event)))
|
182
|
+
(handler-case
|
183
|
+
(with-timeout (,delay)
|
184
|
+
(loop
|
185
|
+
(progn ,@body)))
|
186
|
+
(timeout-error (c)
|
187
|
+
(declare (ignore c))
|
188
|
+
(float (/ ,gevent-count ,delay))))))))
|
189
|
+
|
190
|
+
;; stolen from metatilities
|
191
|
+
(defmacro muffle-redefinition-warnings (&body body)
|
192
|
+
"Evaluate the body so that redefinition warnings will not be
|
193
|
+
signaled. (suppored in Allegro, Clozure CL, CLisp, and Lispworks)"
|
194
|
+
#+allegro
|
195
|
+
`(excl:without-redefinition-warnings
|
196
|
+
,@body)
|
197
|
+
#+(or ccl mcl)
|
198
|
+
`(let ((ccl::*warn-if-redefine* nil)
|
199
|
+
;;?? FIXME not sure if this should be here or not...
|
200
|
+
(ccl::*record-source-file* nil))
|
201
|
+
,@body)
|
202
|
+
#+clisp
|
203
|
+
`(let ((custom:*suppress-check-redefinition* t))
|
204
|
+
,@body)
|
205
|
+
#+lispworks
|
206
|
+
`(let ((lw:*handle-warn-on-redefinition* :quiet))
|
207
|
+
,@body)
|
208
|
+
#+sbcl
|
209
|
+
;; from http://www.sbcl.info/manual/Controlling-Verbosity.html
|
210
|
+
`(locally (declare (sb-ext:muffle-conditions sb-ext:compiler-note
|
211
|
+
sb-ext::style-warning))
|
212
|
+
,@body)
|
213
|
+
#-(or allegro ccl clisp mcl sbcl)
|
214
|
+
`(progn ,@body))
|
215
|
+
|
216
|
+
|
217
|
+
(defmacro defconfig-variable (name var &optional docstring)
|
218
|
+
(declare (ignore docstring))
|
219
|
+
`(defmethod handle-config-preference ((name (eql ,name)) args)
|
220
|
+
(setf ,var (first args))))
|
221
|
+
|
222
|
+
(defmacro defconfig (name &body body)
|
223
|
+
(let ((docstring nil))
|
224
|
+
(declare (ignorable docstring))
|
225
|
+
(when (stringp (first body))
|
226
|
+
(setf docstring (first body)
|
227
|
+
body (rest body)))
|
228
|
+
`(defmethod handle-config-preference ((name (eql ,name)) args)
|
229
|
+
,@body)))
|
@@ -0,0 +1,156 @@
|
|
1
|
+
(in-package #:lift)
|
2
|
+
|
3
|
+
(eval-when (:compile-toplevel)
|
4
|
+
(declaim (optimize (speed 3) (safety 1))))
|
5
|
+
|
6
|
+
(eval-when (:compile-toplevel :load-toplevel :execute)
|
7
|
+
|
8
|
+
(defmeasure :measure-seconds
|
9
|
+
:value 'get-internal-real-time
|
10
|
+
:finally '(coerce (/ it internal-time-units-per-second)
|
11
|
+
'double-float)
|
12
|
+
:type integer
|
13
|
+
:documentation
|
14
|
+
"Measure how long something takes using {hs get-internal-real-time}.
|
15
|
+
|
16
|
+
The accuracy can be no greater than {hs internal-time-units-per-second}.")
|
17
|
+
|
18
|
+
(defmeasure :measure-space
|
19
|
+
:value 'total-bytes-allocated
|
20
|
+
:type integer
|
21
|
+
:documentation
|
22
|
+
"Measure how many conses cells a computation generates.")
|
23
|
+
|
24
|
+
)
|
25
|
+
|
26
|
+
#+(or)
|
27
|
+
(while-measuring-1 (conses measure-space)
|
28
|
+
(while-measuring-1 (time measure-seconds)
|
29
|
+
blay))
|
30
|
+
|
31
|
+
#+(or)
|
32
|
+
(let ((time 0))
|
33
|
+
(while-measuring-1 (time measure-seconds)
|
34
|
+
(sleep 1))
|
35
|
+
time)
|
36
|
+
|
37
|
+
#+(or)
|
38
|
+
(let ((conses 0))
|
39
|
+
(while-measuring-1 (conses measure-space)
|
40
|
+
(sleep 1))
|
41
|
+
conses)
|
42
|
+
|
43
|
+
#+(or)
|
44
|
+
(while-measuring (measure-seconds)
|
45
|
+
(sleep 1))
|
46
|
+
|
47
|
+
(defmacro with-measuring ((var measure-fn) &body body)
|
48
|
+
(let ((ginitial (gensym "value-"))
|
49
|
+
(gcondition (gensym "condition-")))
|
50
|
+
`(let ((,ginitial (,measure-fn))
|
51
|
+
(,gcondition nil))
|
52
|
+
(prog1
|
53
|
+
(handler-case
|
54
|
+
(progn ,@body)
|
55
|
+
(error (c) (setf ,gcondition c)))
|
56
|
+
(setf ,var (- (,measure-fn) ,ginitial))
|
57
|
+
(when ,gcondition (error ,gcondition))))))
|
58
|
+
|
59
|
+
|
60
|
+
(defmacro measure-time ((var) &body body)
|
61
|
+
`(while-measuring-1 (,var measure-seconds) ,@body))
|
62
|
+
|
63
|
+
#+(or)
|
64
|
+
(let ((time 0))
|
65
|
+
(while-measuring-1 (time measure-seconds)
|
66
|
+
(sleep 1))
|
67
|
+
time)
|
68
|
+
|
69
|
+
(defmacro measure-conses ((var) &body body)
|
70
|
+
`(while-measuring-1 (,var measure-space) ,@body))
|
71
|
+
|
72
|
+
(defun measure-fn (fn &rest args)
|
73
|
+
(declare (dynamic-extent args))
|
74
|
+
(let ((bytes 0) (seconds 0) result)
|
75
|
+
(measure-time (seconds)
|
76
|
+
(measure-conses (bytes)
|
77
|
+
(setf result (apply fn args))))
|
78
|
+
(values seconds bytes result)))
|
79
|
+
|
80
|
+
(defmacro measure (seconds bytes &body body)
|
81
|
+
(let ((result (gensym)))
|
82
|
+
`(let (,result)
|
83
|
+
(measure-time (,seconds)
|
84
|
+
(measure-conses (,bytes)
|
85
|
+
(setf ,result (progn ,@body))))
|
86
|
+
(values ,result))))
|
87
|
+
|
88
|
+
(defmacro measure-time-and-conses (&body body)
|
89
|
+
(let ((seconds (gensym))
|
90
|
+
(conses (gensym))
|
91
|
+
(results (gensym)))
|
92
|
+
`(let ((,seconds 0) (,conses 0) ,results)
|
93
|
+
(setf ,results (multiple-value-list
|
94
|
+
(measure ,seconds ,conses ,@body)))
|
95
|
+
(values-list (nconc (list ,seconds ,conses)
|
96
|
+
,results)))))
|
97
|
+
|
98
|
+
(defvar *functions-to-profile* nil)
|
99
|
+
|
100
|
+
(defvar *additional-markers* nil)
|
101
|
+
|
102
|
+
(defvar *profiling-threshold* nil)
|
103
|
+
|
104
|
+
(defun make-profiled-function (fn)
|
105
|
+
(lambda (style count-calls-p)
|
106
|
+
(declare (ignorable style count-calls-p))
|
107
|
+
#+allegro
|
108
|
+
(prof:with-profiling (:type style :count count-calls-p)
|
109
|
+
(funcall fn))
|
110
|
+
#-allegro
|
111
|
+
(funcall fn)))
|
112
|
+
|
113
|
+
(defun generate-profile-log-entry (log-name name seconds conses results error)
|
114
|
+
(ensure-directories-exist log-name)
|
115
|
+
;;log
|
116
|
+
(with-open-file (output log-name
|
117
|
+
:direction :output
|
118
|
+
:if-does-not-exist :create
|
119
|
+
:if-exists :append)
|
120
|
+
(with-standard-io-syntax
|
121
|
+
(let ((*print-readably* nil))
|
122
|
+
(terpri output)
|
123
|
+
(format output "\(~11,d ~20,s ~10,s ~10,s ~{~s~^ ~} ~s ~s ~a\)"
|
124
|
+
(date-stamp :include-time? t) name
|
125
|
+
seconds conses *additional-markers*
|
126
|
+
results (current-profile-sample-count)
|
127
|
+
error)))))
|
128
|
+
|
129
|
+
(defun count-repetitions (fn delay &rest args)
|
130
|
+
(declare (dynamic-extent args))
|
131
|
+
(let ((event-count 0))
|
132
|
+
(handler-case
|
133
|
+
(with-timeout (delay)
|
134
|
+
(loop
|
135
|
+
(apply #'funcall fn args)
|
136
|
+
(incf event-count)))
|
137
|
+
(timeout-error (c)
|
138
|
+
(declare (ignore c))
|
139
|
+
(if (plusp event-count)
|
140
|
+
(/ event-count delay)
|
141
|
+
event-count)))))
|
142
|
+
|
143
|
+
#+test
|
144
|
+
(defun fibo (n)
|
145
|
+
(cond ((< n 2)
|
146
|
+
1)
|
147
|
+
(t
|
148
|
+
(+ (fibo (- n 1)) (fibo (- n 2))))))
|
149
|
+
|
150
|
+
#+test
|
151
|
+
(with-profile-report ('test :time)
|
152
|
+
(loop for i from 1 to 10 do
|
153
|
+
(fibo i))
|
154
|
+
(loop for i from 10 downto 1 do
|
155
|
+
(fibo i)))
|
156
|
+
|
@@ -0,0 +1,161 @@
|
|
1
|
+
(in-package #:common-lisp-user)
|
2
|
+
|
3
|
+
(eval-when (:compile-toplevel :load-toplevel :execute)
|
4
|
+
(unless (find-package '#:lift)
|
5
|
+
(defpackage #:lift
|
6
|
+
(:use #:common-lisp #:com.metabang.trivial-timeout)
|
7
|
+
(:import-from
|
8
|
+
#+allegro #:mop
|
9
|
+
#+clisp #:clos
|
10
|
+
#+lispworks #:clos
|
11
|
+
#+(or mcl ccl) #:ccl
|
12
|
+
#+cmu #:clos-mop
|
13
|
+
#+sbcl #:sb-mop
|
14
|
+
#+scl #:clos
|
15
|
+
#:class-direct-subclasses
|
16
|
+
#:class-direct-superclasses
|
17
|
+
#:class-precedence-list)
|
18
|
+
(:export
|
19
|
+
#:*lift-report-detail-hook*
|
20
|
+
#:*lift-report-header-hook*
|
21
|
+
#:*lift-report-footer-hook*
|
22
|
+
#:describe-test-result
|
23
|
+
#:with-timeout
|
24
|
+
|
25
|
+
#:testsuite-ambiguous
|
26
|
+
#:testsuite-not-defined)
|
27
|
+
(:export
|
28
|
+
#:test-mixin
|
29
|
+
#:test-result
|
30
|
+
#:testsuite-p
|
31
|
+
#:*test-result*
|
32
|
+
#:*current-test*
|
33
|
+
#:last-test-status
|
34
|
+
#:suite-tested-p
|
35
|
+
#:failures
|
36
|
+
#:expected-failures
|
37
|
+
#:errors
|
38
|
+
#:expected-errors
|
39
|
+
#:ensure-cases
|
40
|
+
#:ensure-random-cases
|
41
|
+
#:deftestsuite
|
42
|
+
#:addtest
|
43
|
+
#:remove-test
|
44
|
+
#:run-test
|
45
|
+
#:run-tests
|
46
|
+
|
47
|
+
#:defmeasure
|
48
|
+
#:undefmeasure
|
49
|
+
#:measure-space
|
50
|
+
#:measure-seconds
|
51
|
+
#:while-measuring
|
52
|
+
|
53
|
+
#:measure-time
|
54
|
+
#:measure-conses
|
55
|
+
|
56
|
+
#:with-profile-report
|
57
|
+
#:write-profile-information
|
58
|
+
#:profiling-threshold*
|
59
|
+
#:*benchmark-log-path*
|
60
|
+
#:count-repetitions
|
61
|
+
#:while-counting-repetitions
|
62
|
+
#:while-counting-events
|
63
|
+
|
64
|
+
;; Variables
|
65
|
+
#:*test-ignore-warnings?*
|
66
|
+
#:*test-break-on-errors?*
|
67
|
+
#:*test-break-on-failures?*
|
68
|
+
#:*test-print-length*
|
69
|
+
#:*test-print-level*
|
70
|
+
#:*test-print-when-defined?*
|
71
|
+
#:*test-evaluate-when-defined?*
|
72
|
+
#:*test-describe-if-not-successful?*
|
73
|
+
#:*test-maximum-time*
|
74
|
+
#:*test-print-testsuite-names*
|
75
|
+
#:*test-print-test-case-names*
|
76
|
+
#:*test-maximum-error-count*
|
77
|
+
#:*test-maximum-failure-count*
|
78
|
+
#:*lift-dribble-pathname*
|
79
|
+
#:*lift-report-pathname*
|
80
|
+
#:*current-asdf-system-name*
|
81
|
+
#:*test-scratchpad*
|
82
|
+
#:*test-notepad*
|
83
|
+
#:*lift-equality-test*
|
84
|
+
#:*lift-debug-output*
|
85
|
+
#:*test-show-expected-p*
|
86
|
+
#:*test-show-details-p*
|
87
|
+
#:*test-show-code-p*
|
88
|
+
|
89
|
+
;; Other
|
90
|
+
#:ensure
|
91
|
+
#:ensure-null
|
92
|
+
#:ensure-same
|
93
|
+
#:ensure-different
|
94
|
+
#:ensure-condition
|
95
|
+
#:ensure-warning
|
96
|
+
#:ensure-error
|
97
|
+
#:ensure-no-warning
|
98
|
+
|
99
|
+
;;?? Not yet
|
100
|
+
;; with-test
|
101
|
+
|
102
|
+
#:list-tests
|
103
|
+
#:print-tests
|
104
|
+
#:map-testsuites
|
105
|
+
#:testsuites
|
106
|
+
#:testsuite-tests
|
107
|
+
|
108
|
+
#:suite
|
109
|
+
#:find-testsuite
|
110
|
+
#:find-test-case
|
111
|
+
#:ensure-random-cases-failure
|
112
|
+
#:random-instance-for-suite
|
113
|
+
#:defrandom-instance
|
114
|
+
#:ensure-random-cases
|
115
|
+
#:ensure-random-cases+
|
116
|
+
#:random-element
|
117
|
+
#:random-number
|
118
|
+
#:an-integer
|
119
|
+
#:a-double-float
|
120
|
+
#:a-single-float
|
121
|
+
#:a-symbol
|
122
|
+
|
123
|
+
#:lift-result
|
124
|
+
#:lift-property
|
125
|
+
#:liftpropos
|
126
|
+
|
127
|
+
#:handle-config-preference
|
128
|
+
))))
|
129
|
+
|
130
|
+
(unless (and (find-package :asdf)
|
131
|
+
(find-symbol (symbol-name 'system-relative-pathname) :asdf)
|
132
|
+
(fboundp (find-symbol
|
133
|
+
(symbol-name 'system-relative-pathname) :asdf)))
|
134
|
+
(warn "LIFT uses asdf:system-relative-pathname which your version of ASDF
|
135
|
+
doesn't seem to include. LIFT will define these for now but you may want to consider updating to the most recent version of ASDF (see http://www.cliki.net/asdf for details).")
|
136
|
+
(intern (symbol-name 'system-source-file) :asdf)
|
137
|
+
(intern (symbol-name 'system-source-directory) :asdf)
|
138
|
+
(intern (symbol-name 'system-relative-pathname) :asdf)
|
139
|
+
(export 'asdf::system-relative-pathname :asdf)
|
140
|
+
(defun asdf::system-source-file (system-name)
|
141
|
+
(let ((system (asdf:find-system system-name)))
|
142
|
+
(make-pathname
|
143
|
+
:type "asd"
|
144
|
+
:name (asdf:component-name system)
|
145
|
+
:defaults (asdf:component-relative-pathname system))))
|
146
|
+
|
147
|
+
(defun asdf::system-source-directory (system-name)
|
148
|
+
(make-pathname :name nil
|
149
|
+
:type nil
|
150
|
+
:defaults (asdf::system-source-file system-name)))
|
151
|
+
|
152
|
+
(defun asdf::system-relative-pathname (system pathname &key name type)
|
153
|
+
(let ((directory (pathname-directory pathname)))
|
154
|
+
(when (eq (car directory) :absolute)
|
155
|
+
(setf (car directory) :relative))
|
156
|
+
(merge-pathnames
|
157
|
+
(make-pathname :name (or name (pathname-name pathname))
|
158
|
+
:type (or type (pathname-type pathname))
|
159
|
+
:directory directory)
|
160
|
+
(asdf::system-source-directory system)))))
|
161
|
+
|
@@ -0,0 +1,151 @@
|
|
1
|
+
(in-package #:lift)
|
2
|
+
|
3
|
+
(setf (documentation 'get-backtrace 'function)
|
4
|
+
"This is the function that is used internally by Hunchentoot to
|
5
|
+
show or log backtraces. It accepts a condition object ERROR and
|
6
|
+
returns a string with the corresponding backtrace.")
|
7
|
+
|
8
|
+
(defun ensure-directory (pathname)
|
9
|
+
(merge-pathnames #+clisp
|
10
|
+
(make-pathname :name "" :type "")
|
11
|
+
#-clisp
|
12
|
+
(make-pathname :name :unspecific :type :unspecific)
|
13
|
+
pathname))
|
14
|
+
|
15
|
+
(defun writable-directory-p (directory)
|
16
|
+
(let ((directory (ensure-directory directory)))
|
17
|
+
(and (probe-file directory)
|
18
|
+
#+allegro
|
19
|
+
(excl.osi:access directory excl.osi:*w-ok*))))
|
20
|
+
|
21
|
+
;; Handle missing platforms gracefully?
|
22
|
+
(defun total-bytes-allocated ()
|
23
|
+
(if (fboundp '%total-bytes-allocated)
|
24
|
+
(funcall '%total-bytes-allocated)
|
25
|
+
0))
|
26
|
+
|
27
|
+
#+allegro
|
28
|
+
(defun %total-bytes-allocated ()
|
29
|
+
(sys::gsgc-totalloc-bytes t))
|
30
|
+
|
31
|
+
#+(or digitool openmcl ccl)
|
32
|
+
(defun %total-bytes-allocated ()
|
33
|
+
(ccl::total-bytes-allocated))
|
34
|
+
|
35
|
+
#+sbcl
|
36
|
+
(defun %total-bytes-allocated ()
|
37
|
+
(cl-user::get-bytes-consed))
|
38
|
+
|
39
|
+
#+(or cmu scl)
|
40
|
+
(defun %total-bytes-allocated ()
|
41
|
+
(ext:get-bytes-consed))
|
42
|
+
|
43
|
+
#+lispworks
|
44
|
+
;; thanks to Frank Schorr, via e-mail
|
45
|
+
(defun %total-bytes-allocated ()
|
46
|
+
(hcl:total-allocation))
|
47
|
+
|
48
|
+
#+(or mcl ccl)
|
49
|
+
(defun get-backtrace (error)
|
50
|
+
(with-output-to-string (s)
|
51
|
+
(let ((*debug-io* s))
|
52
|
+
(format *terminal-io* "~@<An unhandled error condition has been signalled:~3I ~a~I~:@>~%~%"
|
53
|
+
error)
|
54
|
+
(ccl:print-call-history :detailed-p nil))))
|
55
|
+
|
56
|
+
#+allegro
|
57
|
+
(defun get-backtrace (error)
|
58
|
+
(with-output-to-string (s)
|
59
|
+
(with-standard-io-syntax
|
60
|
+
(let ((*print-readably* nil)
|
61
|
+
(*print-miser-width* 40)
|
62
|
+
(*print-pretty* t)
|
63
|
+
(tpl:*zoom-print-circle* t)
|
64
|
+
(tpl:*zoom-print-level* nil)
|
65
|
+
(tpl:*zoom-print-length* nil))
|
66
|
+
(cl:ignore-errors
|
67
|
+
(format *terminal-io* "~&~@<An unhandled error condition has been signalled:~3I ~a~I~:@>~%~%"
|
68
|
+
error))
|
69
|
+
(cl:ignore-errors
|
70
|
+
(let ((*terminal-io* s)
|
71
|
+
(*standard-output* s))
|
72
|
+
(tpl:do-command "zoom"
|
73
|
+
:from-read-eval-print-loop nil
|
74
|
+
:count t
|
75
|
+
:all t)))))))
|
76
|
+
|
77
|
+
#+(or)
|
78
|
+
(defun zoom-to-stream (condition output)
|
79
|
+
(with-standard-io-syntax
|
80
|
+
(let ((*print-readably* nil)
|
81
|
+
(*print-miser-width* 40)
|
82
|
+
(*print-pretty* t)
|
83
|
+
(tpl:*zoom-print-circle* t)
|
84
|
+
(tpl:*zoom-print-level* nil)
|
85
|
+
(tpl:*zoom-print-length* nil))
|
86
|
+
(ignore-errors
|
87
|
+
(format *terminal-io* "Creating backtrace for ~a to ~a"
|
88
|
+
condition output))
|
89
|
+
(flet ((zoom (s)
|
90
|
+
(ignore-errors
|
91
|
+
(let ((*terminal-io* s)
|
92
|
+
(*standard-output* s))
|
93
|
+
(tpl:do-command "zoom"
|
94
|
+
:from-read-eval-print-loop nil
|
95
|
+
:count t :all t)))))
|
96
|
+
(cond ((streamp output)
|
97
|
+
(zoom output))
|
98
|
+
(t
|
99
|
+
(ensure-directories-exist output)
|
100
|
+
(with-open-file (s output :direction :output
|
101
|
+
:if-exists :supersede
|
102
|
+
:if-does-not-exist :create)
|
103
|
+
(zoom s))))))))
|
104
|
+
|
105
|
+
#+lispworks
|
106
|
+
(defun get-backtrace (error)
|
107
|
+
(declare (ignore error))
|
108
|
+
(with-output-to-string (s)
|
109
|
+
(let ((dbg::*debugger-stack* (dbg::grab-stack nil :how-many most-positive-fixnum))
|
110
|
+
(*debug-io* s)
|
111
|
+
(dbg:*debug-print-level* nil)
|
112
|
+
(dbg:*debug-print-length* nil))
|
113
|
+
(dbg:bug-backtrace nil))))
|
114
|
+
|
115
|
+
#+sbcl
|
116
|
+
;; determine how we're going to access the backtrace in the next
|
117
|
+
;; function
|
118
|
+
(eval-when (:compile-toplevel :load-toplevel :execute)
|
119
|
+
(when (find-symbol "*DEBUG-PRINT-VARIABLE-ALIST*" :sb-debug)
|
120
|
+
(pushnew :hunchentoot-sbcl-debug-print-variable-alist *features*)))
|
121
|
+
|
122
|
+
#+sbcl
|
123
|
+
(defun get-backtrace (error)
|
124
|
+
(declare (ignore error))
|
125
|
+
(with-output-to-string (s)
|
126
|
+
#+:hunchentoot-sbcl-debug-print-variable-alist
|
127
|
+
(let ((sb-debug:*debug-print-variable-alist*
|
128
|
+
(list* '(*print-level* . nil)
|
129
|
+
'(*print-length* . nil)
|
130
|
+
sb-debug:*debug-print-variable-alist*)))
|
131
|
+
(sb-debug:backtrace most-positive-fixnum s))
|
132
|
+
#-:hunchentoot-sbcl-debug-print-variable-alist
|
133
|
+
(let ((sb-debug:*debug-print-level* nil)
|
134
|
+
(sb-debug:*debug-print-length* nil))
|
135
|
+
(sb-debug:backtrace most-positive-fixnum s))))
|
136
|
+
|
137
|
+
#+clisp
|
138
|
+
(defun get-backtrace (error)
|
139
|
+
(declare (ignore error))
|
140
|
+
(with-output-to-string (s)
|
141
|
+
(system::print-backtrace :out s)))
|
142
|
+
|
143
|
+
#+(or cmucl scl)
|
144
|
+
(defun get-backtrace (error)
|
145
|
+
(declare (ignore error))
|
146
|
+
(with-output-to-string (s)
|
147
|
+
(let ((debug:*debug-print-level* nil)
|
148
|
+
(debug:*debug-print-length* nil))
|
149
|
+
(debug:backtrace most-positive-fixnum s))))
|
150
|
+
|
151
|
+
|