unix.exp 30.7 KB
Newer Older
1
2
3
4
5
# The values in this file can be overridden by creating localcfg.exp 
# and setting them there.  This is useful if you are working against
# the CVS repository and make a purely local change (such as setting
# the timeout value to a low value).

Per Cederqvist's avatar
Per Cederqvist committed
6
7
# Set this to 1 to cause the test suite to wait while you attach to
# the process that is being tested.
David Byers's avatar
David Byers committed
8
9
10
11
12
13
14
15
16

if { ![info exists ATTACH] } {
    set ATTACH no
}

if { ![info exists MEMTRACE] } {
    set MEMTRACE /dev/null
}

David Byers's avatar
Server:    
David Byers committed
17
18
19
20
if { ![info exists DBCK_MEMTRACE] } {
    set DBCK_MEMTRACE /dev/null
}

David Byers's avatar
David Byers committed
21
22
23
24
25
26
27
28
29
30
31
if { ![info exists EFENCE] } {
    set EFENCE 0
}

# The attach option

if { $ATTACH == "yes" } {
    set attach 1
} else {
    set attach 0
}
Per Cederqvist's avatar
Per Cederqvist committed
32
33

# Set this to 1 if test-l2g was linked with Electric Fence.
David Byers's avatar
David Byers committed
34
35
36
37
38
if { $EFENCE == "yes" } {
    set efence 1
} else {
    set efence 0
}
Per Cederqvist's avatar
Per Cederqvist committed
39

40
41
# Set MEMTRACE to the file where the trace should be sent.
# This is typically the tty where you are running the attached gdb.
David Byers's avatar
David Byers committed
42

Per Cederqvist's avatar
Per Cederqvist committed
43
44
# Some of the machines we run the Xenofarm tests on are really, really
# slow, so we have to increase the timeout.
45
set timeout [expr {3 * $timeout}]
Per Cederqvist's avatar
Per Cederqvist committed
46

47
48
49
50
# Set the timeout value to something small for quicker testing, if you
# have a fast enough machine.
#set timeout 5

Per Cederqvist's avatar
Per Cederqvist committed
51
# Some useful constants.
Per Cederqvist's avatar
Per Cederqvist committed
52
53
54
set nl "\r?\n"
set any "\[ -\]"
set deep_any "\\\[ -\\\]"
Per Cederqvist's avatar
Per Cederqvist committed
55
set hollerith "\[0-9\]*H$any*"
Per Cederqvist's avatar
Per Cederqvist committed
56
set any_time "\[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]*"
Per Cederqvist's avatar
Per Cederqvist committed
57
58
# 1970-01-01 GMT, but with some fuzziness to allow for local time zones.
set epoch_time "0 0 \[0-9\]* (1|31) (0|11) (70|69) (4|3) (0|364) \[01\]"
Per Cederqvist's avatar
Per Cederqvist committed
59
set any_num "\[0-9\]\[0-9\]*"
Per Cederqvist's avatar
Per Cederqvist committed
60

61
# The port that is used for Protocol A connections by the test suite.
Per Cederqvist's avatar
Per Cederqvist committed
62
set clientport 53262
Per Cederqvist's avatar
Per Cederqvist committed
63

64
set aux_item_default_conf_file "$top_srcdir/run-support/aux-items.conf"
65

Per Cederqvist's avatar
Per Cederqvist committed
66
# Fix the tty settings for minimum impact on the data flow.
67
set stty_init "-echo -onlcr -istrip -isig erase '^-' kill '^-' werase '^-'"
Per Cederqvist's avatar
Per Cederqvist committed
68

Per Cederqvist's avatar
Per Cederqvist committed
69
70
71
# State variables.
set line_leader ""
set meta_line_leader ""
Per Cederqvist's avatar
Per Cederqvist committed
72

73
74
75
# Values that show up in protocol messages
set lyskomd_host [exec python -c "import socket\nprint socket.gethostbyaddr(\"127.0.0.1\")\[0\]"]

76
77
# valgrind support
set valgrindix 0
78

Per Cederqvist's avatar
Per Cederqvist committed
79
80
81
# Recursive lock count.
set lock_count 0

Per Cederqvist's avatar
Per Cederqvist committed
82
83
84
85
86
87
88
89
90
91
proc efence_blurb {} {
    global efence

    if {$efence} {
	simple_expect "" "efence blank line"
	simple_expect "  Electric Fence .* Copyright .* Bruce Perens." \
		"efence init"
    }
}

Per Cederqvist's avatar
Per Cederqvist committed
92
93
94
95
96
97
proc obtain_lock {} {
    global lock_count
    global nl
    global spawn_id
    global lock_id
    global any
98
    global srcdir
Per Cederqvist's avatar
Per Cederqvist committed
99
100
101
102

    if {$lock_count == 0} {
	set redo 1
	while {$redo} {
103
	    spawn python $srcdir/locksuite.py
Per Cederqvist's avatar
Per Cederqvist committed
104
105
106
107
108
109
110
111
112
113
114
115
116
	    set lock_id $spawn_id
	    expect {
		-re "^locking...$nl" {
		    exp_continue
		}
		-re "^waiting: socket (.*)$nl" {
		    warning "Test suite locked by socket $expect_out(1,string)" 0
		    exp_continue
		}
		-re "^waiting: file (.*)$nl" {
		    warning "Test suite locked by file $expect_out(1,string)" 0
		    exp_continue
		}
117
		-re "^failed: file ($any*) (\[^ :\]*):(\[0-9\]*)$nl" {
Per Cederqvist's avatar
Per Cederqvist committed
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
		    warning "failed to obtain lock due to $expect_out(1,string)"
		    warning "removing stale lock $expect_out(1,string)"
		    system "rm $expect_out(1,string)"
		    send "exit\n"
		    expect bye
		    expect eof
		    wait
		}
		-re "^locked$nl" {
		    set redo 0
		}
		timeout {
		    exp_continue
		}
		eof {
		    fail "obtaining lock failed"
		    wait
135
		    set redo 0
Per Cederqvist's avatar
Per Cederqvist committed
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
		}
	    }
	}
    }
    set lock_count [expr {$lock_count + 1}]
}

proc release_lock {} {
    global lock_count
    global nl
    global spawn_id
    global lock_id

    if {$lock_count == 1} {
	set spawn_id $lock_id
	send "exit\n"
	expect {
	    -re "queued: socket (.*)$nl" {
		warning "Test suite blocked for $expect_out(1,string)" 0
		exp_continue
	    }
	    -re "bye$nl"
	}
	expect eof
	wait
    }
    if {$lock_count < 1} {
	error "lock already unlocked"
    } else {
	set lock_count [expr {$lock_count - 1}]
    }
}

Per Cederqvist's avatar
Per Cederqvist committed
169
170
171
proc l2g_start {} {
    global spawn_id
    global l2g
Per Cederqvist's avatar
Per Cederqvist committed
172
    global efence
Per Cederqvist's avatar
Per Cederqvist committed
173
174
175
    global l2g_id
    global deep_any
    global nl
176
177
    global expect_active
    global expect_always
178
179
    global test
    global MEMTRACE
Per Cederqvist's avatar
Per Cederqvist committed
180
    global valgrind
Per Cederqvist's avatar
Per Cederqvist committed
181

Per Cederqvist's avatar
Per Cederqvist committed
182
183
    obtain_lock

Per Cederqvist's avatar
Per Cederqvist committed
184
    if {$valgrind != ""} {
185
	spawn ./valgrind.wrap valgrind-l2g.log --suppressions=lyskomd.supp --num-callers=40 --leak-check=yes --logfile-fd=25 --show-reachable=yes $l2g
Per Cederqvist's avatar
Per Cederqvist committed
186
187
188
    } else {
	spawn $l2g
    }
Per Cederqvist's avatar
Per Cederqvist committed
189
190
    set l2g_id $spawn_id
    set expect_active($l2g_id) \
191
	    " -i $l2g_id eof { fail \"\$test (eof on l2g)\"; wait } -re \"^($deep_any*)$nl\" { fail \"\$test (unexpected line '\$expect_out(1,string)')\" } -re \"($deep_any*)l2g> \" { fail \"\$test (unexpected incomplete line '\$expect_out(1,string)')\" } timeout { fail \"\$test (timeout on l2g)\" }"
Per Cederqvist's avatar
Per Cederqvist committed
192
    set expect_always($l2g_id) \
193
	    " -i $l2g_id full_buffer { fail \"\$test (full_buffer on l2g)\" }"
Per Cederqvist's avatar
Per Cederqvist committed
194
195

    talk_to l2g
Per Cederqvist's avatar
Per Cederqvist committed
196

197
198
199
200
201
    set test "starting l2g"
    expect {
	-re "^Where does the trace want to go today. .stderr.$nl" {
	    pass "Tracing is activated ($MEMTRACE)"
	    send "$MEMTRACE\n"
202
            exp_continue
203
204
205
206
207
208
209
210
211
	}
	-re "^l2g> " {
	    pass "$test"
	}
    }
    unset test
    send "\n"
    simple_expect "^EMPTY LINE" "noop command"

Per Cederqvist's avatar
Per Cederqvist committed
212
213
214
215
216
    if {$efence} {
	l2g_send "I9"
	l2g_send "a9 3 17"
	efence_blurb
    }
Per Cederqvist's avatar
Per Cederqvist committed
217
218
219
220
221
}

proc l2g_stop {} {
    global spawn_id

222
223
    l2g_send "q"
    simple_expect "test-l2g quitting"
224
    wait
Per Cederqvist's avatar
Per Cederqvist committed
225
    close
226
    check_valgrind valgrind-l2g.log 1 1 {}
Per Cederqvist's avatar
Per Cederqvist committed
227
228

    release_lock
Per Cederqvist's avatar
Per Cederqvist committed
229
230
231
232
}

proc l2g_send {str} {
    unanchored_expect "^l2g> " "prompt before $str"
233
    verbose "sending $str"
Per Cederqvist's avatar
Per Cederqvist committed
234
235
236
    send "$str\n"
}

Per Cederqvist's avatar
Per Cederqvist committed
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
proc fix_expect_after {} {
    global expect_always
    global expect_active
    global spawn_id

    set stmt "expect_after"

    foreach k [array names expect_always] {
	set stmt "$stmt $expect_always($k)"
    }

    if {[info exists spawn_id] && [info exists expect_active($spawn_id)]} {
	set stmt "$stmt $expect_active($spawn_id)"
    }

    verbose "evaluating $stmt" 2
    eval $stmt
}

proc simple_expect {regex {testname ""} {is_meta ""}} {
Per Cederqvist's avatar
Per Cederqvist committed
257
258
259
    global test
    global any
    global nl
Per Cederqvist's avatar
Per Cederqvist committed
260
261
    global line_leader
    global meta_line_leader
David Byers's avatar
David Byers committed
262
263
264
265
266
267
268
    global verbose

    if { $verbose } {
        puts -nonewline "."
        flush stdout
    }
        
Per Cederqvist's avatar
Per Cederqvist committed
269

Per Cederqvist's avatar
Per Cederqvist committed
270
271
272
273
274
    if {$is_meta == "meta"} {
	set ll $meta_line_leader
    } else {
	set ll $line_leader
    }
Per Cederqvist's avatar
Per Cederqvist committed
275
276
277
278
    set test $testname
    if {$test == ""} {
	set test "looking for $regex"
    }
279
280
281
282
283
284
285
286
287
288
289
290
    if {[regexp "^(\[=%\])(\[0-9\]*)(( )(..*))?$" "$regex" all a refno]} {
	# This looks like a protocol A reply.
	expect {
	    -re "^$ll$regex$nl"    {pass "$test"}
	    -re "^$ll=$refno$nl"   {fail "$test (unexpected reply =$refno)"}

	    -re "^${ll}(\[=%\]$refno $any*)$nl" {
		fail "$test (unexpected reply $expect_out(1,string))"
	    }

	    timeout 	           {fail "$test (timeout)"}
	    eof 		   {fail "$test (eof)"; wait}
291
	    full_buffer 	   {fail "$test (full_buffer)"}
292
293
294
295
296
297
	}
    } else {
	expect {
	    -re "^$ll$regex$nl" {pass "$test"}
	    timeout 	        {fail "$test (timeout)"}
	    eof 		{fail "$test (eof)"; wait}
298
	    full_buffer 	{fail "$test (full_buffer)"}
299
	}
Per Cederqvist's avatar
Per Cederqvist committed
300
301
302
303
    }
    unset test
}

304
305
306
307
308
309
310
311
312
313
314
315
proc lyskomd_expect {regex} {
    global current_talk_what
    global current_talk_nr

    set what $current_talk_what
    set nr $current_talk_nr

    talk_to lyskomd
    simple_expect "$regex"
    talk_to $what $nr
}

Per Cederqvist's avatar
Per Cederqvist committed
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
348
349
350
351
352
353
354
355
356
357
358
proc good_bad_expect {good_regex bad_regex {xreason ""}} {
    global test
    global any
    global nl
    global line_leader
    global meta_line_leader
    global verbose

    if { $verbose } {
        puts -nonewline "."
        flush stdout
    }
        
    set ll $line_leader

    if {![regexp "^(\[=%\])(\[0-9\]*)(( )(..*))?$" "$good_regex" all first refno]} {
	fail "$test (broken good regex)"
	unset test
	return
    }
    set bad_regex "[string range "$bad_regex" 0 0]$refno [string range "$bad_regex" 1 end]"

    set test "looking for $good_regex (or $bad_regex)"

    expect {
	-re "^${ll}($good_regex)$nl"    {
	    if {$xreason != ""} {
		setup_xfail "*-*-*" "$xreason"
	    }
	    pass "$test (got $expect_out(1,string))"
	}
	-re "^$ll$bad_regex$nl"     {
	    if {$xreason != ""} {
		setup_xfail "*-*-*" "$xreason"
	    }
	    fail "$test (bad regex matches)"
	}
	-re "^${ll}(\[=%\]$refno $any*)$nl" {
	    fail "$test (unexpected reply $expect_out(1,string))"
	}

	timeout	           {fail "$test (timeout)"}
	eof 		   {fail "$test (eof)"; wait}
359
	full_buffer 	   {fail "$test (full_buffer)"}
Per Cederqvist's avatar
Per Cederqvist committed
360
361
362
363
    }
    unset test
}

364
365
366
367
368
369
proc extracting_expect {regex var grp} {
    global test
    global any
    global nl
    global line_leader
    global $var
David Byers's avatar
David Byers committed
370
    global verbose
371
372
373

    set test "looking for $regex"

David Byers's avatar
David Byers committed
374
375
376
377
    if { $verbose } {
        puts -nonewline "."
        flush stdout
    }
378
379
380

    set $var ""

381
382
383
384
385
386
387
    expect {
	-re "^$line_leader$regex$nl" {
	    set $var $expect_out($grp,string)
	    pass "$test"
	}
	timeout 	 {fail "$test (timeout)"}
	eof 		 {fail "$test (eof)"; wait}
388
	full_buffer 	{fail "$test (full_buffer)"}
389
390
391
392
393
    }
    unset test
}


Per Cederqvist's avatar
Per Cederqvist committed
394
395
396
397
proc unanchored_expect {regex testname} {
    global test
    global any
    global nl
David Byers's avatar
David Byers committed
398
    global verbose
Per Cederqvist's avatar
Per Cederqvist committed
399
400

    set test $testname
David Byers's avatar
David Byers committed
401
402
403
404
405
406
407

    if { $verbose } {
        puts -nonewline "."
        flush stdout
    }
        

Per Cederqvist's avatar
Per Cederqvist committed
408
409
410
    expect {
	-re "$regex" 	{pass "$test"}
	timeout 	{fail "$test (timeout)"}
411
	full_buffer 	{fail "$test (full_buffer)"}
Per Cederqvist's avatar
Per Cederqvist committed
412
413
	eof 		{fail "$test (eof)"; wait}
	-re "($any*)$nl" {
414
	    fail "$test (unexpected line '$expect_out(1,string)' waiting for '$regex')"
Per Cederqvist's avatar
Per Cederqvist committed
415
	    exp_continue
Per Cederqvist's avatar
Per Cederqvist committed
416
	}
417
418
	-re "($any*)l2g> " {
	    fail "$test (unexpected incomplete line '$expect_out(1,string)' waiting for '$regex')"
Per Cederqvist's avatar
Per Cederqvist committed
419
420
421
422
	}
    }
    unset test
}
Per Cederqvist's avatar
Per Cederqvist committed
423

424
proc spawn_lyskomd {logfile arg} {
425
426
427
428
    global valgrind
    global spawn_id

    set cmd "spawn"
429
    if {$valgrind != ""} {
430
	set cmd "$cmd ./valgrind.wrap"
431
	set cmd "$cmd $logfile"
432
	# set cmd "$cmd -v"
433
	set cmd "$cmd --num-callers=40"
434
	set cmd "$cmd --suppressions=lyskomd.supp"
435
	set cmd "$cmd --leak-check=yes"
436
	set cmd "$cmd --logfile-fd=25"
437
	set cmd "$cmd --show-reachable=yes"
438
439
440
    }
    set cmd "$cmd ../lyskomd"
    if { $arg == "" } {
441
	set cmd "$cmd -f config/lyskomd-config"
442
443
444
445
446
447
448
    } else {
	set cmd "$cmd $arg"
    }
    set pid [eval $cmd]
    return $pid
}

Per Cederqvist's avatar
Per Cederqvist committed
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
proc unpack_db {basename} {
    global srcdir

    # Check that we are in in the correct directory before removing
    # directories...
    set f [open "../lyskomd" "r"]
    close $f

    system "rm -rf db etc"
    system "mkdir db etc"
    system "cp $srcdir/lyskomd.0/$basename.data db/lyskomd-data"
    system "cp $srcdir/lyskomd.0/$basename.texts db/lyskomd-texts"
    system "chmod 644 db/lyskomd-data db/lyskomd-texts"
    if {[file exists "$srcdir/lyskomd.0/$basename.nr"]} {
	system "cp $srcdir/lyskomd.0/$basename.nr db/number.txt"
	system "chmod 644 db/number.txt"
    }
}

468
469
470
proc lyskomd_start {{aux_item_conf_file ""} \
	{extra_config ""} \
	{base_config ""} \
471
	{args ""} \
Per Cederqvist's avatar
Per Cederqvist committed
472
473
474
475
476
477
478
	{db_suffix ""} \
	{log_messages {}} \
	{init_db 1} \
	{want_stale 0} \
	{confs 6} \
	{texts 1} \
	{nogarb 0}} {
479

Per Cederqvist's avatar
Per Cederqvist committed
480
481
482
    global spawn_id
    global server_id
    global test
483
    global deep_any
Per Cederqvist's avatar
Per Cederqvist committed
484
    global nl
Per Cederqvist's avatar
Per Cederqvist committed
485
486
    global attach
    global timeout
487
488
    global expect_active
    global expect_always
David Byers's avatar
David Byers committed
489
    global clientport
490
    global aux_item_default_conf_file
491
    global lyskomd_pid
492
    global top_srcdir
493
    global debug_calls
494
495
    global mem_trace
    global MEMTRACE
496
497
    global line_leader
    global any
498

Per Cederqvist's avatar
Per Cederqvist committed
499
500
    obtain_lock

501
502
503
    if { $aux_item_conf_file == "" } {
        set aux_item_conf_file $aux_item_default_conf_file
    }
504
505
506
507
508

    # Check that we are in in the correct directory before removing
    # directories...
    set f [open "../lyskomd" "r"]
    close $f
509
510
511
512
513
514
515
516
    if {$init_db} {
	system "rm -rf db etc"
	system "mkdir db etc"
	system "cp $top_srcdir/db-crypt/db/lyskomd-data$db_suffix db/lyskomd-data"
	system "cp $top_srcdir/db-crypt/db/lyskomd-texts db/"
	system "cp $top_srcdir/db-crypt/db/number.txt db/"
	system "chmod 644 db/lyskomd-data db/lyskomd-texts db/number.txt"
    }
517
518

    set cf [open "config/lyskomd-config" "w"]
David Byers's avatar
David Byers committed
519
    puts $cf "Client port: $clientport"
520
    puts $cf "Prefix: [pwd]"
David Byers's avatar
David Byers committed
521
522
523
524
525
    if { $base_config == "" } {
        if { [regexp -nocase "Max conferences" $extra_config] == 0 } {
            puts $cf "Max conferences: 2000"
        }
        if { [regexp -nocase "Max texts" $extra_config] == 0 } {
526
            puts $cf "Max texts: 20000"
David Byers's avatar
David Byers committed
527
        }
528
        puts $cf "Aux-item definition file: $aux_item_conf_file"
David Byers's avatar
David Byers committed
529
530
531
    } else {
        puts $cf $base_config
    }
532
    puts $cf $extra_config
David Byers's avatar
David Byers committed
533
534
    close $cf

535
    set pid [spawn_lyskomd valgrind-lyskomd.log $args]
536
    set lyskomd_pid $pid
David Byers's avatar
David Byers committed
537

Per Cederqvist's avatar
Per Cederqvist committed
538
    set server_id $spawn_id
Per Cederqvist's avatar
Per Cederqvist committed
539
    set expect_active($server_id) \
540
	    " -i $server_id -re \"($deep_any*)$nl\" { fail \"\$test (unexpected line from lyskomd: \$expect_out(1,string))\"; exp_continue } -i $server_id eof { fail \"\$test (eof on lyskomd)\"; wait } timeout { fail \"\$test (timeout on lyskomd)\" }"
Per Cederqvist's avatar
Per Cederqvist committed
541
    set expect_always($server_id) \
542
	    " -i $server_id full_buffer { fail \"\$test (full_buffer on lyskomd)\" } -i $server_id eof { fail \"\$test (eof on lyskomd)\" }"
Per Cederqvist's avatar
Per Cederqvist committed
543
544
545

    talk_to lyskomd
    set test "server started"
Per Cederqvist's avatar
Per Cederqvist committed
546
547
    set t $timeout
    set timeout [expr {2 * $timeout}]
548
    set debug_calls 0
549
550
    set mem_trace 0
    set unattached $attach
Per Cederqvist's avatar
Per Cederqvist committed
551
    expect {
552
	-re "^Where does the trace want to go today. .stderr." {
553
554
555
556
557
558
559
560
561
562
563
564
565
	    pass "Tracing is activated ($MEMTRACE)"
	    if {$unattached} {
		send_user "Please attach to lyskomd pid $pid and hit RETURN\n"
		set timeout 3600
		set t 3600
		expect_user {
		    -re .
		}
		send_user "Continuing with timeout set to $timeout\n"
		set unattached 0
	    }
	    send "$MEMTRACE\n"
	    set mem_trace 1
566
            exp_continue
567
	}
568
569
570
	-re "^${line_leader}... Version $any* .process $any*. started.$nl" {
	}
	timeout         {fail "$test (timeout)"}
571
	full_buffer 	{fail "$test (full_buffer)"}
572
573
574
	eof 		{fail "$test (eof)"; wait}
    }

575
    set stale 0
576
577
    set test "Lock created"
    expect {
578
	-re "^${line_leader}WARNING: This server was compiled with --with-debug-calls\\.$nl" {
579
	    expect -re "^${line_leader}It isn.t safe to use in a production environment.$nl"
580
	    pass "debug calls are enabled"
581
	    set debug_calls 1
582
            exp_continue
583
	}
584
585
586
587
588
589
590
591
592
	-re "^${line_leader}Removed stale lock file left by ($any*):($any*).$nl" {
	    if {$stale == 1} {
		fail "$test (more than one stale lock file removed)"
	    } elseif {$want_stale == 0} {
		fail "$test (lyskomd removed a stale lock file)"
	    }
	    set stale 1
	    exp_continue
	}
593
594
595
	-re "^${line_leader}Created lock ($any*)$nl" {
	    pass "$test (lock file $expect_out(1,string)"
	}
Per Cederqvist's avatar
Per Cederqvist committed
596
	timeout         {fail "$test (timeout)"}
597
	full_buffer 	{fail "$test (full_buffer)"}
Per Cederqvist's avatar
Per Cederqvist committed
598
	eof 		{fail "$test (eof)"; wait}
599
    }   
Per Cederqvist's avatar
Per Cederqvist committed
600
    set timeout $t
601
602
603
    if {$stale == 0 && $want_stale == 1} {
	fail "$test (no stale lock file removed)"
    }
604
605
606
607
608
609
610
611
612
    unset test

    simple_expect "Listening for clients on $clientport."
    simple_expect "Database = [pwd]/db/lyskomd-data"
    simple_expect "Backup = [pwd]/db/lyskomd-backup"
    simple_expect "2nd Backup = [pwd]/db/lyskomd-backup-prev"
    simple_expect "Lock File = [pwd]/db/lyskomd-lock"
    simple_expect "MSG: init_cache: using datafile."
    simple_expect "Database saved on $any*"
Per Cederqvist's avatar
Per Cederqvist committed
613
    simple_expect "Read $confs confs/persons and $texts texts"
614
615
616
617
618

    foreach logmsg $log_messages {
	simple_expect "$logmsg"
    }

Per Cederqvist's avatar
Per Cederqvist committed
619
620
621
622
    if {$nogarb == 0} {
	simple_expect "MSG: garb started."
	simple_expect "MSG: garb ready. 0 texts deleted."
    }
Per Cederqvist's avatar
Per Cederqvist committed
623

624
    if {$unattached} {
Per Cederqvist's avatar
Per Cederqvist committed
625
626
627
628
629
630
631
	send_user "Please attach to lyskomd process $pid and press RETURN\n"
	set timeout 3600
	expect_user {
	    -re .
	}
	send_user "Continuing with timeout set to $timeout\n"
    }
Per Cederqvist's avatar
Per Cederqvist committed
632
633
}

634
635
proc lyskomd_fail_start {log_messages
			 {aux_item_conf_file "" }
David Byers's avatar
David Byers committed
636
637
638
639
640
641
                         {extra_config ""}
                         {base_config ""}
                         {args ""}} {
    global spawn_id
    global server_id
    global test
642
643
    global deep_any
    global any
David Byers's avatar
David Byers committed
644
    global nl
645
    global line_leader
David Byers's avatar
David Byers committed
646
647
648
649
650
651
    global timeout
    global expect_active
    global expect_always
    global clientport
    global aux_item_default_conf_file
    global lyskomd_pid
652
    global top_srcdir
653
    global MEMTRACE
654
    global debug_calls
David Byers's avatar
David Byers committed
655

Per Cederqvist's avatar
Per Cederqvist committed
656
657
    obtain_lock

David Byers's avatar
David Byers committed
658
659
660
661
662
663
664
665
666
667
    if { $aux_item_conf_file == "" } {
        set aux_item_conf_file $aux_item_default_conf_file
    }

    # Check that we are in in the correct directory before removing
    # directories...
    set f [open "../lyskomd" "r"]
    close $f
    system "rm -rf db etc"
    system "mkdir db etc"
668
669
    system "cp $top_srcdir/db-crypt/db/lyskomd-data db/"
    system "cp $top_srcdir/db-crypt/db/lyskomd-texts db/"
670
    system "cp $top_srcdir/db-crypt/db/number.txt db/"
671
672

    set cf [open "config/lyskomd-config" "w"]
David Byers's avatar
David Byers committed
673
674
675
676
    puts $cf "Client port: $clientport"
    if { $base_config == "" } {
        puts $cf "Max conferences: 2000"
        puts $cf "Max texts: 2000"
677
678
        puts $cf "Prefix: [pwd]"
        puts $cf "Aux-item definition file: $aux_item_conf_file"
David Byers's avatar
David Byers committed
679
680
681
682
683
684
    } else {
        puts $cf $base_config
    }
    puts $cf $extra_config
    close $cf

685
    set pid [spawn_lyskomd valgrind-lyskomdfail.log $args]
David Byers's avatar
David Byers committed
686
687
688
689
    set lyskomd_pid $pid

    set server_id $spawn_id
    set expect_active($server_id) \
690
	    " -i $server_id -re \"($deep_any*)$nl\" { fail \"\$test (unexpected line from lyskomd: \$expect_out(1,string))\"; exp_continue } -i $server_id eof { fail \"\$test (eof on lyskomd)\"; wait } timeout { fail \"\$test (timeout on lyskomd)\" }"
David Byers's avatar
David Byers committed
691
    set expect_always($server_id) \
692
	    " -i $server_id full_buffer { fail \"\$test (full_buffer on lyskomd)\" } -i $server_id eof { fail \"\$test (eof on lyskomd)\" }"
David Byers's avatar
David Byers committed
693
694
695
696
697
698
699

    talk_to lyskomd
    set test "server start failed"
    set t $timeout
    set timeout [expr {2 * $timeout}]
    
    expect {
700
	-re "^Where does the trace want to go today. .stderr." {
701
702
	    pass "Tracing is activated ($MEMTRACE)"
	    send "$MEMTRACE\n"
703
            exp_continue
704
	}
705
706
	-re "^${line_leader}... Version $any* .process $any*. started.$nl" {
	}
David Byers's avatar
David Byers committed
707
	timeout         {fail "$test (timeout)" }
708
	full_buffer 	{fail "$test (full_buffer)" }
David Byers's avatar
David Byers committed
709
710
711
	eof 		{fail "$test (eof)"; wait}
    }

712
713
714
715
716
717
718
719
720
721
722
    set debug_calls 0
    expect {
	-re "^${line_leader}WARNING: This server was compiled with --with-debug-calls\\.$nl" {
	    expect -re "^${line_leader}It isn.t safe to use in a production environment.$nl"
	    pass "debug calls are enabled"
	    set debug_calls 1
            exp_continue
	}
	-notransfer -re "^${line_leader}."
    }

723
724
725
726
727
728
    foreach logmsg $log_messages {
	simple_expect "$logmsg"
    }
    simple_expect "Previous message is fatal. Will dump core now."
    simple_expect "Search for the core in [pwd]"

David Byers's avatar
David Byers committed
729
730
731
732
733
734
735
    set timeout $t

    set test "server died"
    expect {
        timeout   { fail "$test (timeout)" }
        eof       { pass "$test"; wait }
    }
736
    check_valgrind valgrind-lyskomdfail.log 0 0 {}
Per Cederqvist's avatar
Per Cederqvist committed
737
738

    release_lock
David Byers's avatar
David Byers committed
739
740
}

David Byers's avatar
David Byers committed
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
proc check_memory_usage {} {
    set allocated_strings 0
    set allocated_blocks 0

    set f [ open "etc/memory-usage" ]
    while { [ gets $f line] >= 0 } {
        if { [regexp "Allocated blocks .grand total." $line] } {
            set allocated_blocks [lindex "$line" [expr [llength "$line"] - 1]]
        } elseif { [regexp "Allocated strings" $line] } {
            set allocated_strings [lindex "$line" [expr [llength "$line"] - 1]]
        }
    }
    close $f

    if { $allocated_blocks != 0 } {
        fail "Allocated blocks on exit"
    } else {
        pass "Allocated blocks on exit"
    }
    if { $allocated_strings != 0 } {
        fail "Allocated strings on exit"
    } else {
        pass "Allocated strings on exit"
    }
}

767
768
769
770
771
772
773
774
775
776
777
778
proc parse_valgrind_leak {f} {
    if {[gets $f line] < 0} {
	fail "valgrind EOF in leak summary"
	return 999
    }
    if {[regexp ":  *\[0-9\]* bytes in (\[0-9\]*) block" "$line" all blocks]} {
	return $blocks
    }
    fail "valgrind leak report parse error"
    return 998
}

779
proc check_valgrind {logfile need_leaks need_errs expected_leaks} {
780
781
782
783
784
785
786
    # The "expected_leaks" argument should be a such as:
    #
    #   {"Bug 99 & Bug 93" 4 3 9}
    #
    # that indicates that due to Bug 99 and Bug 93 there will be 4
    # definite leaks, 3 possible leaks, and 9 still reachable blocks.
    
787
788
    global valgrindix
    global valgrind
789
    global test
790

791
    if {$valgrind == ""} {
792
793
794
795
796
797
798
799
	return
    }

    set errfound 0
    set memfound 0
    set errcount 0
    set leakcount 0

800
801
802
803
804
805
806
807
808
809
810
    # Rename the file.  $saved holds the new name.
    while {[file exists "valgrind-$valgrindix.log"]} {
	set valgrindix [expr $valgrindix + 1]
    }
    set saved "valgrind-$valgrindix.log"
    system "mv $logfile $saved"

    # Should the log file be kept?
    set keep 0

    set f [open $saved]
811
812
813
    while {[gets $f line] >= 0} {
	if {[regexp "ERROR SUMMARY: (\[0-9\]*) errors" $line match errs]} {
	    if {$errfound} {
814
815
		fail "check_valgrind logic error due to $saved"
		set keep 1
816
817
818
819
820
821
	    } else {
		set errfound 1
		set errcount $errs
	    }
	}
	if {[regexp "LEAK SUMMARY:" $line]} {
Per Cederqvist's avatar
Per Cederqvist committed
822
	    set memfound 1
823
824
825
	    set definite [parse_valgrind_leak $f]
	    set possible [parse_valgrind_leak $f]
	    set reachable [parse_valgrind_leak $f]
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
	    if {$expected_leaks != {}} {
		set xreason [lindex $expected_leaks 0]
		set exp_def [lindex $expected_leaks 1]
		set exp_pos [lindex $expected_leaks 2]
		set exp_rea [lindex $expected_leaks 3]

		setup_xfail "*-*-*" $xreason
		if {$exp_def == $definite
		    && $exp_pos == $possible
		    && $exp_rea == $reachable} {

		    fail "memory leaks: $definite definite, $possible possible"
		    
		    set definite 0
		    set possible 0
		    set reachable 0
		} else {
		    pass "wrong memory leak count found"
		}
	    }
846
847
848
849
850
851
	    set leakcount [expr $definite + $possible]
	    # Ignore up to 10 reachable blocks.  libc leaks some blocks...
	    if {$reachable > 10} {
		set leakcount "$reachable"
	    }
	}
Per Cederqvist's avatar
Per Cederqvist committed
852
853
854
	if {[regexp "No malloc'd blocks -- no leaks are possible" $line]} {
	    set memfound 1
	}
855
856
    }
    close $f
857
858
859
    if {$errfound == 0 && $need_errs == 1} {
	fail "no error summary in valgrind output $saved"
	set keep 1
860
861
    }

862
863
864
    if {$memfound == 0 && $need_leaks == 1} {
	fail "no malloc summary in valgrind output $saved"
	set keep 1
Per Cederqvist's avatar
Per Cederqvist committed
865
866
    }

867
868
869
870
    if {$errcount == 0} {
	pass "valgrind found no errors"
    } else {
	fail "valgrind found $errcount error(s).  See $saved."
871
	set keep 1
872
873
874
875
876
877
    }
    if {$leakcount == 0} {
	pass "valgrind found no leaks"
    } else {
	if {$definite} {
	    fail "valgrind found $definite definite leaks.  See $saved."
878
	    set keep 1
879
880
881
	}
	if {$possible} {
	    fail "valgrind found $possible possible leaks.  See $saved."
882
	    set keep 1
883
884
885
	}
	if {$reachable} {
	    fail "valgrind found $reachable reachable blocks.  See $saved."
886
	    set keep 1
887
888
	}
    }
889
890
891
892

    if {$keep == 0} {
	system rm $saved
    }
893
894
}

895
proc lyskomd_death {{expected_leaks {}} {reason 5}} {
896
    # See check_valgrind for a description of "expected_leaks".
Per Cederqvist's avatar
Per Cederqvist committed
897
898
899
    global spawn_id
    global server_id
    global test
900
    global any
Per Cederqvist's avatar
Per Cederqvist committed
901
    global nl
902
903
    global expect_active
    global expect_always
Per Cederqvist's avatar
Per Cederqvist committed
904
905

    talk_to lyskomd
906
907
908
909
910
911
912
    if {$reason == "signal"} {
	simple_expect "Signal HUP received. Shutting down server."
    } else {
	simple_expect "shutdown initiated by person $reason $any*"
    }
    simple_expect "../lyskomd terminated normally."
    simple_expect "Press enter to terminate lyskomd"
913
    send "\n"
Per Cederqvist's avatar
Per Cederqvist committed
914
915
916
917
918
    set test "server died"
    expect {
	timeout  { fail "$test (timeout)" }
	eof      { pass "$test"; wait }
    }
919
920
921
922
923
    unset expect_active($server_id)
    unset expect_always($server_id)
    unset spawn_id
    fix_expect_after

924
    system "cat etc/memory-usage >> usage.all"
David Byers's avatar
David Byers committed
925
    check_memory_usage
926
    check_valgrind valgrind-lyskomd.log 1 1 $expected_leaks
Per Cederqvist's avatar
Per Cederqvist committed
927
    dbck_run
Per Cederqvist's avatar
Per Cederqvist committed
928
929

    release_lock
Per Cederqvist's avatar
Per Cederqvist committed
930
931
}

Per Cederqvist's avatar
Per Cederqvist committed
932
933
934
935
proc kill_lyskomd {} {
    global lyskomd_pid
    global test
    global spawn_id
936
937
938
    global expect_active
    global expect_always
    global server_id
Per Cederqvist's avatar
Per Cederqvist committed
939
940
941
942
943
944
945
946

    talk_to lyskomd
    system "kill -KILL $lyskomd_pid"
    set test "server died"
    expect {
	timeout  { fail "$test (timeout)" }
	eof      { pass "$test"; wait }
    }
947
948
949
950
951
    unset expect_active($server_id)
    unset expect_always($server_id)
    unset spawn_id
    fix_expect_after

Per Cederqvist's avatar
Per Cederqvist committed
952
953
954
    release_lock
}

Per Cederqvist's avatar
Per Cederqvist committed
955
956
957
958
proc dbck_run {} {
    global nl
    global test
    global any_num
David Byers's avatar
Server:    
David Byers committed
959
    global DBCK_MEMTRACE
Per Cederqvist's avatar
Per Cederqvist committed
960
    global valgrind
961
    global spawn_id
Per Cederqvist's avatar
Per Cederqvist committed
962

Per Cederqvist's avatar
Per Cederqvist committed
963
    if {$valgrind != ""} {
964
	spawn ./valgrind.wrap valgrind-dbck.log --suppressions=lyskomd.supp --num-callers=40 --logfile-fd=25 --show-reachable=yes ../dbck -d config/lyskomd-config
Per Cederqvist's avatar
Per Cederqvist committed
965
966
967
    } else {
	spawn ../dbck -d config/lyskomd-config
    }
Per Cederqvist's avatar
Per Cederqvist committed
968
969
970
971
972
973
    set test "dbck started"
    expect_after {
	timeout { fail "$test (timeout)" }
	eof { fail "$test (eof)" }
    }
    expect {
David Byers's avatar
Server:    
David Byers committed
974
975
976
	-re "^Where does the trace want to go today. .stderr.$nl" {
	    pass "Tracing is activated ($DBCK_MEMTRACE)"
	    send "$DBCK_MEMTRACE\n"
977
            exp_continue
David Byers's avatar
Server:    
David Byers committed
978
979
980
981
	}
	-re "^MSG: init_cache: using datafile\.$nl" { 
            pass "$test" 
        }
Per Cederqvist's avatar
Per Cederqvist committed
982
    }
David Byers's avatar
Server:    
David Byers committed
983

Per Cederqvist's avatar
Per Cederqvist committed
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
    set test "dbck sent second line"
    expect {
	-re "^Read $any_num confs/persons and $any_num texts, eof at $any_num$nl" {
	    pass "$test"
	}
    }
    set test "dbck sent final line"
    expect {
	-re "^Press enter to terminate dbck$nl" {
	    pass "$test"
	}
    }
    send "\n"
    set test "dbck died"
    expect {
	eof { pass "$test"; wait }
    }