@@ -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