;; GNU Shepherd --- Test the log rotation service.
;; Copyright © 2024 Ludovic Courtès <ludo@gnu.org>
;;
;; This file is part of the GNU Shepherd.
;;
;; The GNU Shepherd is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3 of the License, or (at
;; your option) any later version.
;;
;; The GNU Shepherd is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with the GNU Shepherd.  If not, see <http://www.gnu.org/licenses/>.

(define-module (test-log-rotation-internal)
  #:use-module (shepherd service log-rotation)
  #:use-module (srfi srfi-64)
  #:use-module (ice-9 ftw)
  #:use-module (ice-9 match))

(define (call-with-temporary-directory proc)
  (let ((directory (mkdtemp "/tmp/shepherd-logs-XXXXXX")))
    (dynamic-wind
      (const #t)
      (lambda ()
        (proc directory))
      (lambda ()
        (for-each (lambda (file)
                    (delete-file (in-vicinity directory file)))
                  (scandir directory
                           (lambda (file)
                             (not (member file '("." ".."))))))))))

(define (create-file file)
  (close-port (open-file file "w0")))


(test-begin "log-rotation-internal")

;; Ensure that the right files are rotated in the right order.
(test-equal "rotate-past-logs"
  '(("foo.log.3.gz" -> "foo.log.4.gz")
    ("foo.log.2" -> "foo.log.3")
    ("foo.log.1" -> "foo.log.2")
    ("bar.log.10.zst" -> "bar.log.11.zst")
    ("bar.log.1.zst" -> "bar.log.2.zst"))
  (call-with-temporary-directory
   (lambda (directory)
     (let ((result '()))
       (define (record-rotation old new)
         (set! result (cons (list old '-> new) result)))

       (for-each (lambda (base)
                   (create-file (in-vicinity directory base)))
                 '("foo.log"
                   "foo.log.1" "foo.log.2" "foo.log.3.gz"
                   "bar.log" "bar.log.1.zst" "bar.log.10.zst"))

       (rotate-past-logs (in-vicinity directory "foo.log")
                         record-rotation)
       (rotate-past-logs (in-vicinity directory "bar.log")
                         record-rotation)
       (map (match-lambda
              ((old '-> new)
               (and (string=? (dirname old) directory)
                    (string=? (dirname new) directory)
                    (list (basename old) '-> (basename new)))))
            (reverse result))))))

(test-end "log-rotation-internal")
