@ -4,3 +4,92 @@
#:parachute )
( :documentation "Test suite for ddns-updater." ) )
( in-package #:tests )
( defparameter *application-root* ( asdf:system-source-directory :ddns-updater ) )
( defparameter *test-directory* ( merge-pathnames "tests/" *application-root* ) )
( defparameter *test-config-filename* "test-config.json" )
( defparameter *test-config-file-path*
( merge-pathnames *test-config-filename* *test-directory* ) )
( define-test "Can make test configuration file."
( utils:make-config-file *test-config-file-path* )
( true ( uiop:file-exists-p *test-config-file-path* ) ) )
( define-test "Back-Up file is created when configuration file already exists."
( utils:make-config-file *test-config-file-path* )
( is = 2 ( count-if
( lambda ( file ) ( search *test-config-filename* ( namestring file ) ) )
( uiop:directory-files *test-directory* ) ) ) )
( define-test "Configuration file matches expected schema."
( let ( ( data ( utils:read-config-file *test-config-file-path* ) ) )
( skip "Not ready yet." ) ) )
( define-test "Can add timestamp pre-fix to configuration filename."
;; And example of what the timestamped string should look like:
;; 20231217_14298_config.json If the date is the 2nd (for example) of the
;; month, the the '0' is ommitted. So, 5th Feb. 2024 will look like '202425'
;; instead of '20240205'.
( let ( ( regex "^\\d*_\\d*_" )
( test-text ( utils::add-filename-safe-timestamp *test-config-filename* ) ) )
;; '0' denotes start of matched string.`NIL' returned if no substring found.
( is = 0 ( cl-ppcre:scan regex test-text ) ) ) )
( define-test "Can get IP address."
( let ( ( regex "^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}$" )
( test-text ( utils::get-ip-address ) ) )
;; '0' denotes start of matched string.`NIL' returned if no substring found.
( is = 0 ( cl-ppcre:scan regex test-text ) ) ) )
( define-test "Can update IP address in configuration file."
( let* ( ( conf-file ( utils:read-config-file *test-config-file-path* ) )
( conf-old-ip ( gethash "last-recorded-ip" conf-file ) )
( test-data-new-ip "192.168.1.1" ) ) ; Use (utils::get-ip-address) typically.
( utils::update-conf-file-to-latest-ip
conf-file test-data-new-ip *test-config-file-path* )
( isnt string= conf-old-ip
( gethash "last-recorded-ip"
( utils:read-config-file *test-config-file-path* ) ) ) ) )
( define-test "Clean-up of test run is valid."
;; This doesn't test the system, it just deletes temporary files used when
;; running the unit tests. The test part is for verification.
( mapc
( lambda ( file )
( when ( search *test-config-filename* ( namestring file ) )
( delete-file file ) ) )
( uiop:directory-files *test-directory* ) )
( is = 0 ( count-if
( lambda ( file )
( search *test-config-filename* ( namestring file ) ) )
( uiop:directory-files *test-directory* ) ) ) )
#| Manual Testing Required
================================================================================
Unfortunately, there are some tests which cannot be ran without valid DNSimple
and/or Telegram accounts. Because of this, the test suite cannot test all the
functionality provided by this program, in an automated fashion.
Once you have entered you valid DNSimple and/or Telegram account details in the
config.json file, you can test the following functions below ( in the utils
package ) . The most likely way you 'll do that is via SLIME/SLY in Emacs or via
something like SBCL, using your CLI.
Non-Exported ( private ) functions:
- ( get-accounts ( conf-data path )
- ( get-domain-zones ( conf-data path )
- ( get-records-in-zone ( conf-data path )
Exported ( public ) functions:
- ( send-notification ( api-token chat-id message )
- ( update-ip-addresses ( conf-data conf-path )
The same applies to the CLI ( binary ) part of the program. You can 't test it
without valid DNSimple and/or Telegram accounts. Unfortunately, those details
are specific to you and can 't be included here ( in a generalised, for everyone
kinda way ) .
| #