Verified Commit 29d7a781 authored by Karel Koci's avatar Karel Koci 🤘

Add tests for download manager

These tests check if we are able to download data from internet and if
we are able to do certification pinning. There can be even more done but
let's extend these tests on need to test bases.
parent d21eba3e
......@@ -23,6 +23,7 @@
#include "logging.h"
#include "subprocess.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
......@@ -41,6 +42,22 @@ bool dump2file (const char *file, const char *text) {
return true;
}
char *readfile(const char *file) {
FILE *f = fopen(file, "r");
if (!f) {
ERROR("Read of file \"%s\" failed: %s", file, strerror(errno));
return NULL;
}
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
rewind(f);
char *ret = malloc(fsize + 1);
fread(ret, fsize, 1, f);
fclose(f);
ret[fsize] = 0;
return ret;
}
static int exec_dir_filter(const struct dirent *de) {
// ignore system paths and accept only files
return strcmp(de->d_name, ".") && strcmp(de->d_name, "..") && de->d_type == DT_REG;
......
......@@ -30,6 +30,10 @@
// Writes given text to file. Be aware that no information about failure is given.
bool dump2file (const char *file, const char *text) __attribute__((nonnull,nonnull));
// Read content of whole file and return it as string
// Returned memory has to be freed by used.
char *readfile(const char *file) __attribute__((nonnull));
// Executes all executable files in given directory
void exec_hook(const char *dir, const char *message) __attribute__((nonnull));
......
......@@ -10,6 +10,7 @@ C_TESTS := \
events \
util \
subprocess \
download \
interpreter
LUA_TESTS := \
......
-----BEGIN CERTIFICATE-----
MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAw
TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh
cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4
WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQGEwJVUzEpMCcGA1UEChMgSW50ZXJu
ZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElTUkcgUm9vdCBY
MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54rVygc
h77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+
0TM8ukj13Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6U
A5/TR5d8mUgjU+g4rk8Kb4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sW
T8KOEUt+zwvo/7V3LvSye0rgTBIlDHCNAymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyH
B5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ4Q7e2RCOFvu396j3x+UC
B5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf1b0SHzUv
KBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWn
OlFuhjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTn
jh8BCNAw1FtxNrQHusEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbw
qHyGO0aoSCqI3Haadr8faqU9GY/rOPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CI
rU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY9umbbjANBgkq
hkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL
ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ
3BebYhtF8GaV0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KK
NFtY2PwByVS5uCbMiogziUwthDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5
ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJwTdwJx4nLCgdNbOhdjsnvzqvHu7Ur
TkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nxe5AW0wdeRlN8NwdC
jNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZAJzVc
oyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq
4RgqsahDYVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPA
mRGunUHBcnWEvgJBQl9nJEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57d
emyPxgcYxn/eR44/KJ4EBs+lVDR3veyJm+kXQ99b21/+jh5Xos1AnX5iItreGCc=
-----END CERTIFICATE-----
This source diff could not be displayed because it is too large. You can view the blob instead.
-----BEGIN CERTIFICATE-----
MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUA
MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w
ZW5UcnVzdCBSb290IENBIEcxMB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAw
MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU
T3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
AoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7faYp6b
wiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX
/uMftk87ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR0
77F9jAHiOH3BX2pfJLKOYheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGP
uY4zbGneWK2gDqdkVBFpRGZPTBKnjix9xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLx
p2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO9z0M+Yo0FMT7MzUj8czx
Kselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq3ywgsNw2
TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+W
G+Oin6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPw
vFEVVJSmdz7QdFG9URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYY
EQRVzXR7z2FwefR7LFxckvzluFqrTJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUl0YhVyE1
2jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/PxN3DlCPaTKbYw
DQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E
PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kf
gLMtMrpkZ2CvuVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbS
FXJfLkur1J1juONI5f6ELlgKn0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0
V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLhX4SPgPL0DTatdrOjteFkdjpY3H1P
XlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80nR14SohWZ25g/4/I
i+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcmGS3t
TAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L91
09S5zvE/bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/Ky
Pu1svf0OnWZzsD2097+o4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJ
AwSQiumPv+i2tCqjI40cHLI5kqiPAlxAOXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj
1oxx
-----END CERTIFICATE-----
/*
* Copyright 2018, CZ.NIC z.s.p.o. (http://www.nic.cz/)
*
* This file is part of the turris updater.
*
* Updater 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.
*
* Updater 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 Updater. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ctest.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../src/lib/download.h"
#include "../src/lib/util.h"
#define HTTP_URL "http://applications-test.turris.cz"
#define HTTP_SMALL ( HTTP_URL "/li.txt" )
#define HTTP_BIG ( HTTP_URL "/lorem_ipsum.txt" )
#define SMALL_CONTENT "lorem ipsum\n"
#define SMALL_SIZE 12
START_TEST(downloader_empty) {
struct downloader *d = downloader_new(1);
ck_assert(downloader_run(d) == NULL);
downloader_free(d);
}
END_TEST
// Test simple download from http with redirect to https and Let's encrypt certificate
START_TEST(simple_download) {
struct downloader *d = downloader_new(1);
ck_assert(downloader_run(d) == NULL);
struct download_opts opts;
download_opts_def(&opts);
struct download_i *inst = download_data(d, HTTP_SMALL, &opts);
ck_assert(downloader_run(d) == NULL);
ck_assert_uint_eq(SMALL_SIZE, inst->out.buff->size);
ck_assert_str_eq(SMALL_CONTENT, (char *)inst->out.buff->data);
downloader_free(d);
}
END_TEST
// Test download to file. Otherwise it's same test as in case of simple_download.
START_TEST(file_download) {
struct downloader *d = downloader_new(1);
ck_assert(downloader_run(d) == NULL);
struct download_opts opts;
download_opts_def(&opts);
char *tmpdir = getenv("TMPDIR");
if (!tmpdir)
tmpdir = "/tmp";
char *file = aprintf("%s/updater-download.txt", tmpdir);
download_file(d, HTTP_SMALL, file, &opts);
ck_assert(downloader_run(d) == NULL);
char *str = readfile(file);
ck_assert(str);
ck_assert_uint_eq(SMALL_SIZE, strlen(str));
ck_assert_str_eq(SMALL_CONTENT, str);
free(str);
unlink(file);
downloader_free(d);
}
END_TEST
// Test that we can have multiple downloads and that all are downloaded
// Half of them are small file and half of them are bigger ones
// This test requires min. 20MB of memory.
START_TEST(multiple_downloads) {
struct downloader *d = downloader_new(4);
ck_assert(downloader_run(d) == NULL);
struct download_opts opts;
download_opts_def(&opts);
const size_t cnt = 32;
struct download_i *insts[cnt];
for (size_t i = 0; i < cnt; i++) {
if (i % 2)
insts[i] = download_data(d, HTTP_SMALL, &opts);
else
insts[i] = download_data(d, HTTP_BIG, &opts);
}
ck_assert(downloader_run(d) == NULL);
const char *s_dir = getenv("S");
if (!s_dir)
s_dir = ".";
char *lorem_ipsum_file = aprintf("%s/tests/data/lorem_ipsum.txt", s_dir);
char *big_content = readfile(lorem_ipsum_file);
size_t big_size = strlen(big_content);
for (size_t i = 0; i < cnt; i++) {
if (i % 2) {
ck_assert_uint_eq(SMALL_SIZE, insts[i]->out.buff->size);
ck_assert_str_eq(SMALL_CONTENT, (char *)insts[i]->out.buff->data);
} else {
ck_assert_uint_eq(big_size, insts[i]->out.buff->size);
ck_assert_str_eq(big_content, (char *)insts[i]->out.buff->data);
}
}
free(big_content);
downloader_free(d);
}
END_TEST
// Test failure if we access non-existent url
START_TEST(invalid) {
struct downloader *d = downloader_new(1);
ck_assert(downloader_run(d) == NULL);
struct download_opts opts;
download_opts_def(&opts);
struct download_i *inst = download_data(d, HTTP_URL "/invalid", &opts);
ck_assert_ptr_eq(downloader_run(d), inst);
downloader_free(d);
}
END_TEST
// Test that even if one of download fail that all other will be downloaded
START_TEST(invalid_continue) {
struct downloader *d = downloader_new(4);
ck_assert(downloader_run(d) == NULL);
struct download_opts opts;
download_opts_def(&opts);
const size_t cnt = 3;
struct download_i *insts[cnt];
for (size_t i = 0; i < cnt; i++)
insts[i] = download_data(d, HTTP_SMALL, &opts);
struct download_i *fail_inst = download_data(d, HTTP_URL "/invalid", &opts);
ck_assert_ptr_eq(downloader_run(d), fail_inst);
ck_assert(downloader_run(d) == NULL);
for (size_t i = 0; i < cnt; i++) {
ck_assert_uint_eq(SMALL_SIZE, insts[i]->out.buff->size);
ck_assert_str_eq(SMALL_CONTENT, (char *)insts[i]->out.buff->data);
}
downloader_free(d);
}
END_TEST
// Test certification pinning
START_TEST(cert_pinning) {
struct downloader *d = downloader_new(1);
ck_assert(downloader_run(d) == NULL);
struct download_opts opts;
download_opts_def(&opts);
const char *s_dir = getenv("S");
if (!s_dir)
s_dir = ".";
opts.cacert_file = aprintf("%s/tests/data/lets_encrypt_roots.pem", s_dir);
opts.capath = "/dev/null";
struct download_i *inst = download_data(d, HTTP_SMALL, &opts);
ck_assert(downloader_run(d) == NULL);
ck_assert_uint_eq(SMALL_SIZE, inst->out.buff->size);
ck_assert_str_eq(SMALL_CONTENT, (char *)inst->out.buff->data);
downloader_free(d);
}
END_TEST
// Test failure if we try invalid certificate
START_TEST(cert_invalid) {
struct downloader *d = downloader_new(1);
ck_assert(downloader_run(d) == NULL);
struct download_opts opts;
download_opts_def(&opts);
const char *s_dir = getenv("S");
if (!s_dir)
s_dir = ".";
opts.cacert_file = aprintf("%s/tests/data/opentrust_ca_g1.pem", s_dir);
opts.capath = "/dev/null";
struct download_i *inst = download_data(d, HTTP_SMALL, &opts);
ck_assert_ptr_eq(downloader_run(d), inst);
downloader_free(d);
}
END_TEST
Suite *gen_test_suite(void) {
Suite *result = suite_create("Download");
TCase *down = tcase_create("download");
tcase_set_timeout(down, 30);
tcase_add_test(down, downloader_empty);
tcase_add_test(down, simple_download);
tcase_add_test(down, multiple_downloads);
tcase_add_test(down, file_download);
tcase_add_test(down, invalid);
tcase_add_test(down, invalid_continue);
tcase_add_test(down, cert_pinning);
tcase_add_test(down, cert_invalid);
suite_add_tcase(result, down);
return result;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment