diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml new file mode 100644 index 0000000..8c9134b --- /dev/null +++ b/.github/workflows/action.yml @@ -0,0 +1,65 @@ +name: Mailnesia Perl unittests + +on: + push: + branches: [master] + pull_request: + branches: [master] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: checkout code + uses: actions/checkout@v4 + - name: set up Perl + uses: shogo82148/actions-setup-perl@v1 + with: + perl-version: "5.32" + + - name: print working directory + run: pwd + - name: install dependencies + run: cpanm --installdeps . --skip-satisfied + - name: create tables in postgres + run: bash ./tools/psql-create-tables.sh + env: + postgres_host: localhost + postgres_user: mailnesia + PGPASSWORD: test + - name: execute unit/function tests + run: prove -lv t + env: + postgres_host: localhost + postgres_user: mailnesia + postgres_password: test + redis_host: localhost + + # Service containers to start + services: + # Label used to access the service container + redis: + # Docker Hub image + image: redis + # TODO: password? + # + ports: + # Opens tcp port 6379 on the host and service container + - 6379:6379 + + postgres: + # Docker Hub image + image: postgres + # Provide the password for postgres + env: + POSTGRES_USER: mailnesia + POSTGRES_PASSWORD: test + # Set health checks to wait until postgres has started + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + # Maps tcp port 5432 on service container to the host + - 5432:5432 diff --git a/lib/Mailnesia/Config.pm b/lib/Mailnesia/Config.pm index b143ea5..2323fea 100644 --- a/lib/Mailnesia/Config.pm +++ b/lib/Mailnesia/Config.pm @@ -44,14 +44,14 @@ Parameters: - if true, indicates development (testing) version; does not load any values from the private.conf to %mailnesia_private (e.g. ad code, Google Analytics, Recaptcha etc) - - false: connect to Redis, true: don't connect =cut sub new { my $package = shift; my $devel = shift; - my $dont_connect_to_redis = shift; + + my $redis_host = $ENV{redis_host}; # loading private configuration items # ex: recaptcha private key - without the correct key every captcha solution will be invalid @@ -140,9 +140,12 @@ sub new { abuse => 'peter@localhost' }, - redis => $dont_connect_to_redis ? undef : Redis->new( - encoding => undef, - sock => '/var/run/redis/redis.sock' + redis => $redis_host ? Redis->new( + server => "$redis_host:6379", + reconnect => 1, + every => 500_000, + ) : Redis->new( + sock => '/var/run/redis/redis.sock', ), # name of used redis databases diff --git a/lib/Mailnesia/SQL.pm b/lib/Mailnesia/SQL.pm index b68ea54..1677316 100644 --- a/lib/Mailnesia/SQL.pm +++ b/lib/Mailnesia/SQL.pm @@ -64,22 +64,29 @@ sub connect ($;\$$&) { { # warn "connecting to SQL, warn: $warn\n"; my $db = "Pg"; - my $db_database = "mailnesia"; + my $db_database = $ENV{postgres_database} || "mailnesia"; my $db_table = "emails"; - my $user = "mailnesia"; - my $password = ""; + my $user = $ENV{postgres_user} || "mailnesia"; + my $password = $ENV{postgres_password} || ""; + my $host = $ENV{postgres_host} || "localhost"; + my $connection_string = "dbi:$db:database=$db_database;"; # connect on socket + + if ($password) { + # connect on TCP + $connection_string .= "host=$host;port=5432"; + } $dbh = DBI->connect_cached( - "dbi:$db:dbname=$db_database", - $user, - $password, - { - RaiseError => 0, - AutoCommit => 1, - PrintWarn=>1, - pg_enable_utf8 => 1 # to get the data already decoded - } - ); + $connection_string, + $user, + $password, + { + RaiseError => 0, + AutoCommit => 1, + PrintWarn=>1, + pg_enable_utf8 => 1 # to get the data already decoded + } + ); if (ref $dbh) { diff --git a/tools/psql-connection-arguments.sh b/tools/psql-connection-arguments.sh new file mode 100644 index 0000000..d7ca0d2 --- /dev/null +++ b/tools/psql-connection-arguments.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# This script can be sourced to get the connection arguments for psql in the variable `psqlArgs`. +# If a password has to be provided, it should be set in the environment variable +# `PGPASSWORD` before running this script. The same applies to the username, +# host and database name, which can be set in `postgres_user`, `postgres_host` +# and `postgres_db` respectively. If these variables are not set, the script +# will use the default values of "mailnesia" for the username and database, +# and "localhost" for the host. + +username="${postgres_user:-mailnesia}" +database="${postgres_db:-mailnesia}" +#arguments to psql +psqlArgs="--tuples-only --no-psqlrc --username=$username --quiet --dbname=$database"; +if [[ -n "$postgres_host" ]]; then + psqlArgs="$psqlArgs --host=$postgres_host --port=5432"; +fi diff --git a/tools/psql-create-tables.sh b/tools/psql-create-tables.sh index a6ab3e6..3a14387 100644 --- a/tools/psql-create-tables.sh +++ b/tools/psql-create-tables.sh @@ -2,8 +2,11 @@ # This script can be run initially to create all tables and necessary relations. +# Resolve the full path of the script +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") + #arguments to psql -psqlArgs="--tuples-only --no-psqlrc --username=mailnesia --quiet"; +source $SCRIPT_DIR/psql-connection-arguments.sh # Partitioning is used, the key being the id because that's the only # value that needs to be unique in the whole table across the partitions. @@ -77,7 +80,7 @@ createEmailPerDayTable() startPartitioning() { echo "running psql-partition-update.sh" - /bin/bash psql-partition-update.sh + /bin/bash $SCRIPT_DIR/psql-partition-update.sh echo "starting partitioning the emails table" echo " diff --git a/tools/psql-partition-update.sh b/tools/psql-partition-update.sh index 8b8d8f9..ae89929 100755 --- a/tools/psql-partition-update.sh +++ b/tools/psql-partition-update.sh @@ -12,8 +12,11 @@ #create new partition after this many rows: new_partition_rows=300000; +# Resolve the full path of the script +SCRIPT_DIR=$(dirname "$(readlink -f "$0")") + #arguments to psql -psqlArgs="--tuples-only --no-psqlrc --username=mailnesia --quiet"; +source $SCRIPT_DIR/psql-connection-arguments.sh #number of partitions to keep partition_count=30