clucumber 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|