summaryrefslogtreecommitdiffstats
path: root/tests/bigdata.test
blob: 52aa278d5e729e6a80df4891d5d6fe0015dcce4b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
# Test cases for large sized data
#
# Copyright © 2023 Ashok P. Nadkarni
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

if {"::tcltest" ni [namespace children]} {
    package require tcltest

    namespace import -force ::tcltest::*
}

#
# Hints:
#
# - To save time, when commands do not modify operands, generate the test data
# and run multiple variants of the command in a single test.
# - Do NOT use -setup clauses that generate large data. They seem to be run
# irrespective of whether the test itself is run.

# Wrapper to generate compiled and uncompiled cases for a test.
# If $args does not contain a -body key, $comment is treated as the test body
proc bigtest {id comment result args} {
    if {[dict exists $args -body]} {
        set body [dict get $args -body]
        dict unset args -body
    } else {
        set body $comment
    }
    dict lappend args -constraints bigdata

    uplevel 1 [list test $id.uncompiled "$comment (uncompiled)" \
                   -body [list testevalex $body] \
                   -result $result \
                   {*}$args]

    uplevel 1 [list test $id.compiled-script "$comment (compiled script)" \
                   -body [list try $body] \
                   -result $result \
                   {*}$args]

    return

    # TODO - is this required separately from the compile-script above?
    dict append args -setup \n[list proc testxproc {} $body]
    dict append args -cleanup "\nrename testxproc {}"
    uplevel 1 [list test $id.compiled-proc "$comment (compiled proc)" \
                   -body {testxproc} \
                   -result $result \
                   {*}$args]
}

# Like bigtest except that both compiled and uncompiled are combined into one
# test using the same inout argument. This saves considerable time but for
# obvious reasons should only be used when the input argument is not modified.
proc bigtestRO {id comment result args} {
    if {[dict exists $args -body]} {
        set body [dict get $args -body]
        dict unset args -body
    } else {
        set body $comment
    }
    dict lappend args -constraints bigdata

    set wrapper ""
    set body "{$body}"
    append wrapper "set uncompiled_result \[testevalex $body]" \n
    append wrapper "set compiled_result \[try $body]" \n
    append wrapper {list $uncompiled_result $compiled_result}
    uplevel 1 [list test $id {$comment} \
                   -body $wrapper \
                   -result [list $result $result] \
                   {*}$args]
    return
}

interp alias {} bigString {} testbigdata string
proc xxbigString args {
    puts bigStringEnter:$args
    set xx [testbigdata string {*}$args]
    puts bigStringExit
    return $xx
}
interp alias {} bigBinary {} testbigdata bytearray
interp alias {} bigList {} testbigdata list
proc bigPatLen {} {
    proc bigPatLen {} "return [string length [testbigdata string]]"
    bigPatLen
}

# Returns list of expected elements at the indices specified
proc bigStringIndices {indices} {
    set pat [testbigdata string]
    set patlen [string length $pat]
    lmap idx $indices {
        string index $pat [expr {$idx%$patlen}]
    }
}

# Returns the largest multiple of the pattern length that is less than $limit
proc bigPatlenMultiple {limit} {
    set patlen [bigPatLen]
    return [expr {($limit/$patlen)*$patlen}]
}

set ::bigLengths(intmax) 0x7fffffff
set ::bigLengths(uintmax) 0xffffffff
# Some tests are more convenient if operands are multiple of pattern length
set ::bigLengths(patlenmultiple) [bigPatlenMultiple $::bigLengths(intmax)]
set ::bigLengths(upatlenmultiple) [bigPatlenMultiple $::bigLengths(uintmax)]

#
# string cat
bigtest string-cat-bigdata-1 "string cat large small result > INT_MAX" 1 -body {
    string equal \
        [string cat [bigString $::bigLengths(patlenmultiple)] [bigString]] \
        [bigString [expr {[bigPatLen]+$::bigLengths(patlenmultiple)}]]
}
bigtest string-cat-bigdata-2 "string cat small large result > INT_MAX" 1 -body {
    string equal \
        [string cat [bigString] [bigString $::bigLengths(patlenmultiple)]] \
        [bigString [expr {[bigPatLen]+$::bigLengths(patlenmultiple)}]]
}
bigtest string-cat-bigdata-3 "string cat result > UINT_MAX" 1 -body {
    set s [bigString $::bigLengths(patlenmultiple)]
    string equal \
        [string cat $s [bigString] $s] \
        [bigString [expr {[bigPatLen]+2*$::bigLengths(patlenmultiple)}]]
}

#
# string compare/equal
bigtestRO string-equal/compare-bigdata-1 "string compare/equal equal strings" {0 1} -body {
    list [string compare $s1 $s2] [string equal $s1 $s2]
} -setup {
    set len [expr {$::bigLengths(intmax)+1}]
    set s1 [bigString $len]
    set s2 [bigString $len]; # Use separate string to avoid Tcl_Obj * being same
} -cleanup {
    unset -nocomplain s1 s2
}
bigtestRO string-equal/compare-bigdata-2 "string compare/equal -length unequal strings" {-1 0 0 1} -body {
    # Also tests lengths do not wrap
    set result {}
    lappend result [string compare $s1 $s2]
    lappend result [string equal $s1 $s2]
    # Check lengths > UINT_MAX
    # Also that lengths do not truncate to sizeof(int)
    lappend result [string compare -length $len $s1 $s2]
    lappend result [string equal -length $len $s1 $s2]
} -setup {
    set len [expr {$::bigLengths(uintmax)+2}]
    set s1 [bigString $len]
    set s2 [bigString $len $len]; # Differs in last char
} -cleanup {
    unset -nocomplain s1 s2
}

#
# string first
bigtestRO string-first-bigdata-1 "string first > INT_MAX" {2147483648 -1 2147483650 1} -body {
    list \
        [string first X $s] \
        [string first Y $s] \
        [string first 0 $s 0x80000000] \
        [string first 1 $s end-0x80000010]
} -setup {
    set s [bigString 0x8000000a 0x80000000]
} -cleanup {
    unset -nocomplain s
} -constraints bug-a814ee5bbd

bigtestRO string-first-bigdata-2 "string first > UINT_MAX" {4294967296 -1 4294967300 1} -body {
    list \
        [string first X $s] \
        [string first Y $s] \
        [string first 0 $s 0x100000000] \
        [string first 1 $s end-0x100000010]
} -setup {
    set s [bigString 0x10000000a 0x100000000]
} -cleanup {
    unset -nocomplain s
} -constraints bug-a814ee5bbd

bigtestRO string-first-bigdata-3 "string first - long needle" 10 -body {
    string first $needle $s
} -setup {
    set s [bigString 0x10000000a 0]
    set needle [bigString 0x100000000]
} -cleanup {
    unset -nocomplain s needle
} -constraints bug-a814ee5bbd

#
# string last
bigtestRO string-last-bigdata-1 "string last > INT_MAX" {2 -1 2147483640 11} -body {
    set s [bigString 0x80000010 2]
    list \
        [string last X $s] \
        [string last Y $s] \
        [string last 0 $s 0x80000000] \
        [string last 1 $s end-0x80000000]
} -setup {
    set s [bigString 0x80000010 2]
} -cleanup {
    unset -nocomplain s
} -constraints bug-a814ee5bbd

bigtestRO string-last-bigdata-2 "string last > UINT_MAX" {4294967300 -1 4294967290 1} -body {
    list \
        [string last 0 $s] \
        [string last Y $s] \
        [string last 0 $s 0x100000000] \
        [string last 1 $s end-0x100000010]
} -setup {
    set s [bigString 0x10000000a 2]
} -cleanup {
    unset -nocomplain s
} -constraints bug-a814ee5bbd

bigtestRO string-last-bigdata-3 "string last - long needle" 0 -body {
    string last $needle $s
} -setup {
    set s [bigString 0x10000000a 0x10000000a]
    set needle [bigString 0x100000000]
} -cleanup {
    unset -nocomplain s needle
} -constraints bug-a814ee5bbd

bigtestRO string-index-bigdata-1 "string index" {6 7 5 {} 5 4 {} 9 {}} -body {
    list \
        [string index $s 0x100000000] \
        [string index $s 0x100000000+1] \
        [string index $s 0x100000000-1] \
        [string index $s 0x10000000a] \
        [string index $s end] \
        [string index $s end-1] \
        [string index $s end+1] \
        [string index $s end-0x100000000] \
        [string index $s end-0x10000000a]
} -setup {
    set s [bigString 0x10000000a]
} -cleanup {
    unset -nocomplain s
}

#
# string is
bigtestRO string-is-bigdata-1 "string is" {1 0 0 4294967296} -body {
    set result {}
    unset -nocomplain failat
    lappend result [string is alnum -failindex failat $s] [info exists failat]
    lappend result [string is digit -failindex failat $s] $failat
} -setup {
    set s [bigString 0x10000000a 0x100000000]
} -cleanup {
    unset -nocomplain s failat
}

#
# string length
bigtestRO string-length-bigdata-1 {string length $s} 4294967296 -setup {
    set s [bigString 0x100000000]
} -cleanup {
    unset -nocomplain s
}

#
# string map
bigtestRO string-map-bigdata-1 {string map} {5 0 0 5} -body {
    set s2 [string map {0 5 5 0} $s]
    list \
        [string index $s2 0] \
        [string index $s2 5] \
        [string index $s2 end] \
        [string index $s2 end-5]
} -setup {
    set s [bigString 0x100000000]
} -cleanup {
    unset -nocomplain s s2
}

#
# string match
bigtestR0 string-match-bigdata-1 {string match} {1 0 1} -body {
    list \
        [string match 0*5 $s] \
        [string match 0*4 $s] \
        [string match $s $s]
} -setup {
    set s [bigString 0x100000000]
} -cleanup {
    unset -nocomplain s pat
}

#
# string range
bigtestRO string-range-bigdata-1 "string range" {6 7 5 {} 5 4 {} 9 {}} -body {
    list \
        [string range $s 0x100000000 0x100000000] \
        [string range $s 0x100000000+1 0x100000000+1] \
        [string range $s 0x100000000-1 0x100000000-1] \
        [string range $s 0x10000000a 0x10000000a] \
        [string range $s end end] \
        [string range $s end-1 end-1] \
        [string range $s end+1 end+1] \
        [string range $s end-0x100000000 end-0x100000000] \
        [string range $s end-0x10000000a end-0x10000000a]
} -setup {
    set s [bigString 0x10000000a]
} -cleanup {
    unset -nocomplain s
} -constraints bug-ad9361fd20f0
# TODO - once above bug is fixed, add tests for large result range

#
# string repeat
bigtest string-repeat-bigdata-1 "string repeat single char" {4294967296 0123456789abcdef 0123456789abcdef} -body {
    set s [string repeat 0123456789abcdef [expr 0x100000000/16]]
    list \
        [string length $s] \
        [string range $s 0 15] \
        [string range $s end-15 end]
} -cleanup {
    unset -nocomplain s
}

foreach len {0x7fffffff 0xffffffff 0x100000000} {
    set body "string length \[string repeat x $len\]"
    bigtest string-repeat-bigdata-1-$len $body $len
}

foreach len {0x7fffffff 0xffffffff 0x100000000} {
    break; # Skip for now
    set body "llength \[lrepeat $len x\]"
    bigtest lrepeat-bigdata-1-$len $body $len
}

# cleanup
::tcltest::cleanupTests
return

# Local Variables:
# mode: tcl
# fill-column: 78
# End: