diff --git a/.travis.yml b/.travis.yml index 54b3b3c7..22e024ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,7 +18,8 @@ install: before_script: - docker-compose -v - docker-compose -f tests/build.yml build - + - sudo -- sh -c 'mkdir -p /mailu && cp -r tests/certs /mailu && chmod 600 /mailu/certs/*' + script: # test.py, test name and timeout between start and tests. - python tests/compose/test.py core 1 diff --git a/tests/certs/cert.pem b/tests/certs/cert.pem new file mode 100644 index 00000000..d6dc928f --- /dev/null +++ b/tests/certs/cert.pem @@ -0,0 +1,29 @@ +-----BEGIN CERTIFICATE----- +MIIE/jCCAuagAwIBAgIJAKVnyadXS7SuMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV +BAMMCWxvY2FsaG9zdDAeFw0xODEwMzExMDE1MzFaFw0yODEwMjgxMDE1MzFaMBQx +EjAQBgNVBAMMCWxvY2FsaG9zdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC +ggIBAOQ2ZDqR+YvW5FKykBXz/Ec+jSb0Lv7GYQkT5t+TB1NXuR+QH1LfNWFmXOo7 +YXcPVXlmcuLDuUldrctdS59fx8dnFu5gRRUqJwZuEQICypsX0rTDtsV6xqZB8c8y +2+BztP9OHfPpZdnU1IBx2fDbjpdKUaoAMFMFvyTaEcIyp6aGAhejvJCwc3D8fIJI +NhWA2O11sZQHUs7/MHzpu/IHpgutgk8EsNOUNLwB3+9p3IlOlTT6GilIXOYeTzoD +hiI6B5BQqXHsRrkao3v0YL6Ekun4hOx3MYx09AZtmuyrlq1mkNueKS5JwKDrXXbq +Ta0oyJ18UTZFRwVqApcuR4CA8vuhI9PsoDCvBQH1rW6FyiM4bhybatFJAYjQAODe +gwh2p6JWux5C1gaBUubOrKO7o5ePI6s0MmK8ZxrL4PpBYt3B33ztFfjWmVbCTSvP +GuQ2Ux73OY2NNxx2aNt4Th0IxrvMdsGLrZsdma2rWa5eTJTAuqbSjI/Wb1zjO0pi +pwoxk6f1COFLopo2xgJj6+KKG1nKLfOzQFexcpdq/mpuulcVcLDPJzJTLX3qsgtD +iBpm1ozNRT+M7XUavg8aHNfn6S+TcDb5hp+1yZ6obZq/VlA6atk0fuPzf+ndQ0fq +YN1jlAIzZXt/Dpc+ObjS09WGDVQXobGesdwA6BH14OV+TxOHAgMBAAGjUzBRMB0G +A1UdDgQWBBQy7kA8FbdcFpVU1AoFgzE7Fw1QqDAfBgNVHSMEGDAWgBQy7kA8Fbdc +FpVU1AoFgzE7Fw1QqDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IC +AQBLFlQKxztxm7MtsHs01Pl8/FpKzWekWK1ksf15d8mHBT30OTs+NXaJDuHTGL4r +rPeFf3NZ1PZkGRnJCEWur+8e8Y5KwuMAaagneSYXU0gcZfvTidvf865Jiml8xO5x +PAo8qTZQCHmYcvJQwBXMkq/2sFJCYeMOLoJdXXbTTe2ZQ/N3MSQbpgWJ8pF7srKU +biw2RkNH39QPq9GpWRQGx2gwvZDy2oFG8cM1hJYmz0Y9clpBE0mSqypvA1E8ufKC +uaUc0tpPI5H4efeWv/ObnFAJ3DMEmzUnQ8hdM/7cpf6AL8VRm4Wrw112gK7SbSdd +mMsUfFIDfyE9vsZ3OC8C8LqXKLwMcm7Fdq0ym0NINtoVW0ukmVJzB78CdWaJ7ux1 +WqitcnewgiMWuuwuepBmNurZtgDrg+zgMhNpuK0NzYyE+ZReoJIOJCub3SSEsWdl +x5aJEYuFYJR5EvmxWeYv5p1GVOTL1TJqW7iRodzRoMc9u2vb0+tCbM5XSZVPul6P +QimDui2Ogq0zYNbSkHaUGBpjGDvHYG0zXO2sWrdrAJQMHo8dGEe7FuSuAlWbQdb/ +xgN4uwejxV6B2e6rjT6YMni+r5Qw0EhNka+Xohw5E68bEcQSrCP8j64qQLAeipuz +ImqBTNyyR4WTcL+1HIVM7ZIw3igHH55zo5qTvyjKyZX9Uw== +-----END CERTIFICATE----- diff --git a/tests/certs/key.pem b/tests/certs/key.pem new file mode 100644 index 00000000..938633fd --- /dev/null +++ b/tests/certs/key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +W3079UVfBB4hkfN2721fqyj+r/0z+R0= +-----END PRIVATE KEY----- diff --git a/tests/compose/core/00_create_users.sh b/tests/compose/core/00_create_users.sh new file mode 100755 index 00000000..fd998a15 --- /dev/null +++ b/tests/compose/core/00_create_users.sh @@ -0,0 +1,4 @@ +echo "Creating users ..." +docker-compose -f tests/compose/core/docker-compose.yml exec admin python manage.py admin admin mailu.io password || exit 1 +docker-compose -f tests/compose/core/docker-compose.yml exec admin python manage.py user --hash_scheme='SHA512-CRYPT' user mailu.io 'password' || exit 1 +echo "Admin and user successfully created!" \ No newline at end of file diff --git a/tests/compose/core/01_email_test.sh b/tests/compose/core/01_email_test.sh new file mode 100755 index 00000000..97dd6e4b --- /dev/null +++ b/tests/compose/core/01_email_test.sh @@ -0,0 +1 @@ +python3 tests/email_test.py message-core \ No newline at end of file diff --git a/tests/compose/core/mailu.env b/tests/compose/core/mailu.env index dabd523f..9a744e35 100644 --- a/tests/compose/core/mailu.env +++ b/tests/compose/core/mailu.env @@ -29,7 +29,7 @@ SECRET_KEY=HGZCYGVI6FVG31HS DOMAIN=mailu.io # Hostnames for this server, separated with comas -HOSTNAMES=mail.mailu.io +HOSTNAMES=localhost # Postmaster local part (will append the main mail domain) POSTMASTER=admin diff --git a/tests/compose/fetchmail/mailu.env b/tests/compose/fetchmail/mailu.env index ef78508b..a987c853 100644 --- a/tests/compose/fetchmail/mailu.env +++ b/tests/compose/fetchmail/mailu.env @@ -29,7 +29,7 @@ SECRET_KEY=JS48Q9KE3B6T97E6 DOMAIN=mailu.io # Hostnames for this server, separated with comas -HOSTNAMES=mail.mailu.io +HOSTNAMES=localhost # Postmaster local part (will append the main mail domain) POSTMASTER=admin diff --git a/tests/compose/filters/01_email_test.sh b/tests/compose/filters/01_email_test.sh new file mode 100755 index 00000000..5af395c4 --- /dev/null +++ b/tests/compose/filters/01_email_test.sh @@ -0,0 +1,6 @@ +python3 tests/email_test.py message-virus "tests/compose/filters/eicar.com" +if [ $? -eq 99 ]; then + exit 0 +else + exit 1 +fi \ No newline at end of file diff --git a/tests/compose/filters/eicar.com b/tests/compose/filters/eicar.com new file mode 100644 index 00000000..704cac85 --- /dev/null +++ b/tests/compose/filters/eicar.com @@ -0,0 +1 @@ +X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H* diff --git a/tests/compose/filters/mailu.env b/tests/compose/filters/mailu.env index ab97e191..8609a287 100644 --- a/tests/compose/filters/mailu.env +++ b/tests/compose/filters/mailu.env @@ -29,7 +29,7 @@ SECRET_KEY=11H6XURLGE7GW3U1 DOMAIN=mailu.io # Hostnames for this server, separated with comas -HOSTNAMES=mail.mailu.io +HOSTNAMES=localhost # Postmaster local part (will append the main mail domain) POSTMASTER=admin diff --git a/tests/compose/rainloop/mailu.env b/tests/compose/rainloop/mailu.env index 747dac58..678ea048 100644 --- a/tests/compose/rainloop/mailu.env +++ b/tests/compose/rainloop/mailu.env @@ -29,7 +29,7 @@ SECRET_KEY=V5J4SHRYVW9PZIQU DOMAIN=mailu.io # Hostnames for this server, separated with comas -HOSTNAMES=mail.mailu.io +HOSTNAMES=localhost # Postmaster local part (will append the main mail domain) POSTMASTER=admin diff --git a/tests/compose/roundcube/mailu.env b/tests/compose/roundcube/mailu.env index e87d1f61..b8a8b266 100644 --- a/tests/compose/roundcube/mailu.env +++ b/tests/compose/roundcube/mailu.env @@ -29,7 +29,7 @@ SECRET_KEY=PGGO2JRQ59QV3DW7 DOMAIN=mailu.io # Hostnames for this server, separated with comas -HOSTNAMES=mail.mailu.io +HOSTNAMES=localhost # Postmaster local part (will append the main mail domain) POSTMASTER=admin diff --git a/tests/compose/test.py b/tests/compose/test.py index 819c7222..690855d4 100755 --- a/tests/compose/test.py +++ b/tests/compose/test.py @@ -3,6 +3,7 @@ import os import time import docker from colorama import Fore, Style +import subprocess # Declare variables for service name and sleep time test_name=sys.argv[1] @@ -17,21 +18,22 @@ containers = [] # Stop containers def stop(exit_code): print_logs() - os.system("docker-compose -f " + compose_file + " -p ${DOCKER_ORG:-mailu} down") + sys.stdout.flush() + print(subprocess.check_output("docker-compose -f " + compose_file + " down", shell=True).decode()) sys.exit(exit_code) - + # Sleep for a defined amount of time def sleep(): print(Fore.LIGHTMAGENTA_EX + "Sleeping for " + str(timeout) + "m" + Style.RESET_ALL) time.sleep(timeout*60) - + def health_checks(): exit_code = 0 #Iterating trough all containers dictionary for container in client.containers(all=True): #Perform "docker container inspect" on container based on container ID and save output to a dictionary container_inspect = client.inspect_container(container['Id']) #Dict - + if "Health" in container_inspect['State'].keys(): if container_inspect['State']['Health']['Status'] == "healthy": print(Fore.GREEN + "Health status for " + container_inspect['Name'].replace("/", "") + " : " + Fore.CYAN + container_inspect['State']['Health']['Status'] + Style.RESET_ALL) @@ -46,41 +48,50 @@ def health_checks(): if container_inspect['State']['Status'] != "running": print(Fore.RED + "Container " + container_inspect['Name'].replace("/", "") + " state is: " + Fore.YELLOW + container_inspect['State']['Status'] + Style.RESET_ALL) exit_code = 1 - + #Saving Id, Name and state to a new dictionary containers_dict = {} containers_dict['Name'] = container_inspect['Name'].replace("/", "") containers_dict['Id'] = container_inspect['Id'] containers_dict['State'] = container_inspect['State'] - + #Adding the generated dictionary to a list containers.append(containers_dict) - + if exit_code != 0: stop(exit_code) - + def print_logs(): print("Printing logs ...") #Iterating through docker container inspect list and print logs for container in containers: print(Fore.LIGHTMAGENTA_EX + "Printing logs for: " + Fore.GREEN + container['Name'] + Style.RESET_ALL) - os.system('docker container logs ' + container['Name']) - -#Iterating over hooks in test folder and running them + sys.stdout.flush() + print(subprocess.check_output('docker container logs ' + container['Name'], shell=True).decode()) + +#Iterating over hooks in test folder and running them def hooks(): - print("Running hooks") + print(Fore.LIGHTMAGENTA_EX + "Running hooks" + Style.RESET_ALL) for test_file in sorted(os.listdir(test_path)): - if test_file.endswith(".py"): - os.system("python3 " + test_path + test_file) - elif test_file.endswith(".sh"): - os.system("./" + test_path + test_file) - + try: + if test_file.endswith(".py"): + sys.stdout.flush() + print(subprocess.check_output("python3 " + test_path + test_file, shell=True).decode()) + elif test_file.endswith(".sh"): + sys.stdout.flush() + print(subprocess.check_output("./" + test_path + test_file, shell=True).decode()) + except subprocess.CalledProcessError as e: + sys.stderr.write("[ERROR]: output = %s, error code = %s\n" % (e.output.decode(), e.returncode)) + stop(1) + # Start up containers -os.system("docker-compose -f " + compose_file + " -p ${DOCKER_ORG:-mailu} up -d ") +sys.stdout.flush() +print(subprocess.check_output("docker-compose -f " + compose_file + " up -d", shell=True).decode()) print() sleep() print() -os.system("docker ps -a") +sys.stdout.flush() +print(subprocess.check_output("docker ps -a", shell=True).decode()) print() health_checks() print() diff --git a/tests/compose/webdav/mailu.env b/tests/compose/webdav/mailu.env index ac7b434c..21dd3981 100644 --- a/tests/compose/webdav/mailu.env +++ b/tests/compose/webdav/mailu.env @@ -29,7 +29,7 @@ SECRET_KEY=XVDDSWOAGVF5J9QJ DOMAIN=mailu.io # Hostnames for this server, separated with comas -HOSTNAMES=mail.mailu.io +HOSTNAMES=localhost # Postmaster local part (will append the main mail domain) POSTMASTER=admin diff --git a/tests/email_test.py b/tests/email_test.py new file mode 100755 index 00000000..853b76b5 --- /dev/null +++ b/tests/email_test.py @@ -0,0 +1,59 @@ +import smtplib +import imaplib +import time +import sys +from email.mime.multipart import MIMEMultipart +from email.mime.text import MIMEText +import ntpath +from email.mime.base import MIMEBase +from email import encoders + +msg = MIMEMultipart() +msg['From'] = "admin@mailu.io" +msg['To'] = "user@mailu.io" +msg['Subject'] = "File Test" +msg.attach(MIMEText(sys.argv[1], 'plain')) + +if len(sys.argv) == 3: + part = MIMEBase('application', 'octet-stream') + part.set_payload((open(sys.argv[2], "rb")).read()) + encoders.encode_base64(part) + part.add_header('Content-Disposition', "attachment; filename=%s" % ntpath.basename(sys.argv[2])) + msg.attach(part) + +try: + smtp_server = smtplib.SMTP('localhost') + smtp_server.set_debuglevel(1) + smtp_server.connect('localhost', 587) + smtp_server.ehlo() + smtp_server.starttls() + smtp_server.ehlo() + smtp_server.login("admin@mailu.io", "password") + + smtp_server.sendmail("admin@mailu.io", "user@mailu.io", msg.as_string()) + smtp_server.quit() +except: + sys.exit(25) + +time.sleep(30) + +try: + imap_server = imaplib.IMAP4_SSL('localhost') + imap_server.login('user@mailu.io', 'password') +except: + sys.exit(110) + +stat, count = imap_server.select('inbox') +try: + stat, data = imap_server.fetch(count[0], '(UID BODY[TEXT])') +except : + sys.exit(99) + +if sys.argv[1] in str(data[0][1]): + print("Success sending and receiving email!") +else: + print("Failed receiving email with message %s" % sys.argv[1]) + sys.exit(99) + +imap_server.close() +imap_server.logout()