Skip to content

Commit d2965aa

Browse files
authored
Merge pull request #49 from plattfot/refactor_runner
Refactor test runner to make it easier to read the code.
2 parents 6b95534 + b5f6d74 commit d2965aa

1 file changed

Lines changed: 203 additions & 150 deletions

File tree

‎tests/runner.scm‎

Lines changed: 203 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,189 @@ Return the path to the modified CONFIGFILE if it is defined otherwise #f."
337337
test-config-file)
338338
#f))
339339

340+
(define (setup sender-snapshots
341+
sender-dir
342+
receiver-snapshots
343+
receiver-dir
344+
latest
345+
create-snapshot-proc)
346+
"Create the test directory structure.
347+
348+
SENDER-SNAPSHOTS a list of <snapshot> for the sender.
349+
350+
SENDER-DIR is the path to the sender directory.
351+
352+
RECEIVER-SNAPSHOTS a list of <snapshot> for the receiver.
353+
354+
RECEIVER-DIR is the path to the receiver directory.
355+
356+
LATEST A path to a snapshot or #f which it will create a symlink to
357+
named `latest`.
358+
359+
CREATE-SNAPSHOT-PROC is a procedure to create a snapshot expects a
360+
path and a <snapshot>.
361+
"
362+
(mkdir (dirname sender-dir))
363+
(mkdir sender-dir)
364+
(for-each
365+
(lambda (snapshot)
366+
(create-snapshot-proc
367+
(path-join sender-dir (snapshot-id snapshot))
368+
snapshot))
369+
sender-snapshots)
370+
;; FIXME: write a proper mkdir -p
371+
(mkdir (dirname receiver-dir))
372+
(mkdir receiver-dir)
373+
(for-each
374+
(lambda (snapshot)
375+
(create-snapshot-proc
376+
(path-join receiver-dir (snapshot-id snapshot))
377+
snapshot))
378+
receiver-snapshots)
379+
(when latest
380+
(symlinkat receiver-dir latest "latest")))
381+
382+
(define (run command configfile options test-dir sender-dir receiver-dir)
383+
"Run COMMAND and return the exit status.
384+
385+
CONFIGFILE is either a path to a config file or #f if not set.
386+
387+
OPTIONS are the cli options from main.
388+
389+
TEST-DIR is the root of the current test.
390+
391+
SENDER-DIR is the path to the sender directory.
392+
393+
RECEIVER-DIR is the path to the receiver directory.
394+
"
395+
(let* ((append-ssh (lambda (address dir)
396+
(if address
397+
(string-append address ":" dir)
398+
dir)))
399+
(if-set (lambda (check value)
400+
(if check value '())))
401+
(prefix-if-set (lambda (check prefix value)
402+
(if check (list prefix value) (list value))))
403+
(test-config-file (configure-config-file
404+
configfile
405+
options
406+
test-dir
407+
sender-dir
408+
receiver-dir))
409+
(command-with-path
410+
(append
411+
command
412+
(if-set test-config-file (list "--configfile" test-config-file))
413+
(if (option-ref options 'src-dest #f)
414+
(append
415+
(if-set (not (option-ref options 'src-config #f))
416+
(prefix-if-set
417+
(option-ref options 'dest-config #f)
418+
"--source"
419+
(append-ssh (option-ref options 'src-ssh #f) sender-dir)))
420+
(if-set (not (option-ref options 'dest-config #f))
421+
(prefix-if-set
422+
(option-ref options 'src-config #f)
423+
"--dest"
424+
(append-ssh (option-ref options 'dest-ssh #f) receiver-dir))))
425+
(if-set
426+
(not (option-ref options 'path-config #f))
427+
(list (append-ssh (option-ref options 'dest-ssh #f)
428+
(dirname receiver-dir))))))))
429+
(format #t "Running command: ~a…~%" command-with-path)
430+
(setenv "BAKSNAPPER_TEST_RUNNER_SENDER_ROOT" test-dir)
431+
(let ((pipe (apply open-pipe* OPEN_READ command-with-path)))
432+
(format #t "~a~%" (get-string-all pipe))
433+
(status:exit-val (close-pipe pipe)))))
434+
435+
(define (check receiver-dir expected-snapshots expected-latest make-snapshot-from-read)
436+
"Check the resulting snapshots lines up with the expected result.
437+
438+
RECEIVER-DIR: the directory where the receiver snapshots are.
439+
440+
EXPECTED-SNAPSHOTS: List of expected snapshots
441+
442+
EXPECTED-LATEST: boolean if it should check for the latest link or not.
443+
444+
MAKE-SNAPSHOT-FROM-READ: Procedure to create snapshots from reading
445+
data on disk.
446+
447+
Evaluates to #t if everything is good."
448+
(let* ((result-snapshots
449+
(alist->hash-table
450+
(assq-remove!
451+
(map (lambda (data)
452+
(let ((snapshot (make-snapshot-from-read data)))
453+
(cons (snapshot-id snapshot) snapshot)))
454+
(cdr (read-snapshots
455+
(cons (dirname receiver-dir)
456+
(file-system-tree receiver-dir)))))
457+
'latest)))
458+
(mismatch-result
459+
(hash-fold
460+
(lambda (id snapshot mismatch)
461+
(match (hash-get-handle expected-snapshots id)
462+
(#f (cons (cons snapshot #f) mismatch))
463+
((id . expected-snapshot)
464+
(if (equal? snapshot expected-snapshot)
465+
mismatch
466+
(cons (cons snapshot expected-snapshot) mismatch)))))
467+
'()
468+
result-snapshots))
469+
(missing-expected
470+
(hash-fold
471+
(lambda (id snapshot mismatch)
472+
(if (hash-get-handle result-snapshots id)
473+
mismatch
474+
(cons snapshot mismatch)))
475+
'()
476+
expected-snapshots)))
477+
(for-each
478+
(match-lambda
479+
((($ <snapshot> result-id result-parent result-state) . #f)
480+
(format (current-error-port)
481+
"[FAIL] Snapshot ~a exists → p:~a s:~a~%"
482+
result-id result-parent result-state))
483+
((($ <snapshot> result-id result-parent result-state) .
484+
($ <snapshot> expected-id expected-parent expected-state))
485+
(format (current-error-port)
486+
"[FAIL] Snapshot `~a` differs~%" result-id)
487+
(when (not (equal? result-parent expected-parent))
488+
(format (current-error-port)
489+
" → parent is `~a` expected `~a`~%"
490+
result-parent expected-parent))
491+
(when (not (equal? result-state expected-state))
492+
(format (current-error-port)
493+
" → state is `~a` expected `~a`~%"
494+
result-state expected-state))))
495+
mismatch-result)
496+
(for-each
497+
(match-lambda
498+
(($ <snapshot> expected-id expected-parent expected-state)
499+
(format (current-error-port)
500+
"[FAIL] Expected snapshot `~a` to exists with parent `~a` and state `~a`~%"
501+
expected-id expected-parent expected-state)))
502+
missing-expected)
503+
(and (null-list? mismatch-result)
504+
(null-list? missing-expected)
505+
(check-latest expected-latest receiver-dir))))
506+
507+
(define (clean-up test-dir)
508+
"Remove everything in TEST-DIR."
509+
(nftw test-dir
510+
(lambda (filename statinfo flag base level)
511+
(match flag
512+
('directory-processed (rmdir filename))
513+
((or 'regular symlink) (delete-file filename))
514+
(_ (format
515+
(current-error-port)
516+
"cannot clean up file: ~a of type ~a~%"
517+
filename
518+
statinfo)))
519+
#t)
520+
'depth
521+
'physical))
522+
340523
(define (main args)
341524
(let* ((option-spec
342525
`((config (single-char #\c) (value #t))
@@ -414,6 +597,7 @@ Fredrik \"PlaTFooT\" Salomonsson
414597
(remove string-null? (string-split (option-ref options input "") #\,))))
415598
(type (string->symbol (option-ref options 'type "snapper")))
416599
(config (option-ref options 'config "root"))
600+
(configfile (option-ref options 'configfile #f))
417601
(sender (parse-comma-option 'sender))
418602
(receiver (parse-comma-option 'receiver))
419603
(expected (parse-comma-option 'expected))
@@ -422,23 +606,14 @@ Fredrik \"PlaTFooT\" Salomonsson
422606
(string-trim-right (or (getenv "TEMP") "/tmp") #\/)
423607
"baksnapper-test-XXXXXX")))
424608
(sender-dir (path-join test-dir config ".snapshots"))
425-
(receiver-root-dir (path-join test-dir "receiver"))
426-
(receiver-dir (path-join receiver-root-dir config))
427-
(configfile (option-ref options 'configfile #f))
428-
(create-snapshot-func (match type
429-
('denotebak create-denotebak-snapshot)
430-
(_ create-snapper-snapshot)))
431-
(make-snapshot-from-read (match type
432-
('denotebak make-snapshot-from-denotebak-read)
433-
(_ make-snapshot-from-snapper-read))))
609+
(receiver-dir (path-join test-dir "receiver" config)))
434610
;; Needed for nftw to be able to read the directory
435611
(chmod test-dir #o744)
436612
(format #t "Test ~a~%" test-dir)
437613
(format #t " sender: ~a~%" sender)
438614
(format #t " receiver: ~a~%" receiver)
439615
(format #t " expected: ~a~%" expected)
440-
(let ((exit-status 0)
441-
(sender-snapshots
616+
(let ((sender-snapshots
442617
(map (lambda (input)
443618
(make-snapshot-from input))
444619
sender))
@@ -452,143 +627,21 @@ Fredrik \"PlaTFooT\" Salomonsson
452627
(let ((snapshot (make-snapshot-from input)))
453628
(cons (snapshot-id snapshot) snapshot)))
454629
expected))))
455-
;; Setup
456-
;; FIXME: write a proper mkdir -p
457-
(mkdir (path-join test-dir config))
458-
(mkdir sender-dir)
459-
(for-each
460-
(lambda (snapshot)
461-
(create-snapshot-func
462-
(path-join sender-dir (snapshot-id snapshot))
463-
snapshot))
464-
sender-snapshots)
465-
;; FIXME: write a proper mkdir -p
466-
(mkdir (path-join test-dir "receiver"))
467-
(mkdir receiver-dir)
468-
(for-each
469-
(lambda (snapshot)
470-
(create-snapshot-func
471-
(path-join receiver-dir (snapshot-id snapshot))
472-
snapshot))
473-
receiver-snapshots)
474-
(and-let* ((latest (option-ref options 'latest #f)))
475-
(symlinkat receiver-dir latest "latest"))
476-
;; Run command
477-
(let* ((append-ssh (lambda (address dir)
478-
(if address
479-
(string-append address ":" dir)
480-
dir)))
481-
(if-set (lambda (check value)
482-
(if check value '())))
483-
(prefix-if-set (lambda (check prefix value)
484-
(if check (list prefix value) (list value))))
485-
(test-config-file (configure-config-file
486-
configfile
487-
options
488-
test-dir
489-
sender-dir
490-
receiver-dir))
491-
(command-with-path
492-
(append
493-
command
494-
(if-set test-config-file (list "--configfile" test-config-file))
495-
(if (option-ref options 'src-dest #f)
496-
(append
497-
(if-set (not (option-ref options 'src-config #f))
498-
(prefix-if-set
499-
(option-ref options 'dest-config #f)
500-
"--source"
501-
(append-ssh (option-ref options 'src-ssh #f) sender-dir)))
502-
(if-set (not (option-ref options 'dest-config #f))
503-
(prefix-if-set
504-
(option-ref options 'src-config #f)
505-
"--dest"
506-
(append-ssh (option-ref options 'dest-ssh #f) receiver-dir))))
507-
(if-set
508-
(not (option-ref options 'path-config #f))
509-
(list (append-ssh (option-ref options 'dest-ssh #f) receiver-root-dir)))))))
510-
(format #t "Running command: ~a…~%" command-with-path)
511-
(setenv "BAKSNAPPER_TEST_RUNNER_SENDER_ROOT" test-dir)
512-
(let ((pipe (apply open-pipe* OPEN_READ command-with-path)))
513-
(format #t "~a~%" (get-string-all pipe))
514-
(set! exit-status (status:exit-val (close-pipe pipe)))))
515-
516-
;; Check
517-
(let* ((result-snapshots
518-
(alist->hash-table
519-
(assq-remove!
520-
(map (lambda (data)
521-
(let ((snapshot (make-snapshot-from-read data)))
522-
(cons (snapshot-id snapshot) snapshot)))
523-
(cdr (read-snapshots
524-
(cons (dirname receiver-dir)
525-
(file-system-tree receiver-dir)))))
526-
'latest)))
527-
(mismatch-result
528-
(hash-fold
529-
(lambda (id snapshot mismatch)
530-
(match (hash-get-handle expected-snapshots id)
531-
(#f (cons (cons snapshot #f) mismatch))
532-
((id . expected-snapshot)
533-
(if (equal? snapshot expected-snapshot)
534-
mismatch
535-
(cons (cons snapshot expected-snapshot) mismatch)))))
536-
'()
537-
result-snapshots))
538-
(missing-expected
539-
(hash-fold
540-
(lambda (id snapshot mismatch)
541-
(if (hash-get-handle result-snapshots id)
542-
mismatch
543-
(cons snapshot mismatch)))
544-
'()
545-
expected-snapshots)))
546-
(for-each
547-
(match-lambda
548-
((($ <snapshot> result-id result-parent result-state) . #f)
549-
(format (current-error-port)
550-
"[FAIL] Snapshot ~a exists → p:~a s:~a~%"
551-
result-id result-parent result-state))
552-
((($ <snapshot> result-id result-parent result-state) .
553-
($ <snapshot> expected-id expected-parent expected-state))
554-
(format (current-error-port)
555-
"[FAIL] Snapshot `~a` differs~%" result-id)
556-
(when (not (equal? result-parent expected-parent))
557-
(format (current-error-port)
558-
" → parent is `~a` expected `~a`~%"
559-
result-parent expected-parent))
560-
(when (not (equal? result-state expected-state))
561-
(format (current-error-port)
562-
" → state is `~a` expected `~a`~%"
563-
result-state expected-state))))
564-
mismatch-result)
565-
(for-each
566-
(match-lambda
567-
(($ <snapshot> expected-id expected-parent expected-state)
568-
(format (current-error-port)
569-
"[FAIL] Expected snapshot `~a` to exists with parent `~a` and state `~a`~%"
570-
expected-id expected-parent expected-state)))
571-
missing-expected)
572-
(when (or (not (null-list? mismatch-result))
573-
(not (null-list? missing-expected))
574-
(not (check-latest
575-
(option-ref options 'expected-latest #f)
576-
receiver-dir)))
577-
(set! exit-status 1)))
578-
579-
;; Clean up
580-
(nftw test-dir
581-
(lambda (filename statinfo flag base level)
582-
(match flag
583-
('directory-processed (rmdir filename))
584-
((or 'regular symlink) (delete-file filename))
585-
(_ (format
586-
(current-error-port)
587-
"cannot clean up file: ~a of type ~a~%"
588-
filename
589-
statinfo)))
590-
#t)
591-
'depth
592-
'physical)
593-
(exit exit-status)))))
630+
(setup sender-snapshots
631+
sender-dir
632+
receiver-snapshots
633+
receiver-dir
634+
(option-ref options 'latest #f)
635+
(match type
636+
('denotebak create-denotebak-snapshot)
637+
(_ create-snapper-snapshot)))
638+
(exit (and
639+
(= (run command configfile options test-dir sender-dir receiver-dir) 0)
640+
(check receiver-dir
641+
expected-snapshots
642+
(option-ref options 'expected-latest #f)
643+
(match type
644+
('denotebak make-snapshot-from-denotebak-read)
645+
(_ make-snapshot-from-snapper-read)))
646+
(clean-up test-dir)))))))
594647

0 commit comments

Comments
 (0)