Mercurial > sci
view tests/test-db.c @ 64:562372396019
misc: improve manual pages and documentation
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 18 Aug 2022 20:17:18 +0200 |
parents | 081e1c258e64 |
children |
line wrap: on
line source
/* * test-db.c -- test database access * * Copyright (c) 2021-2022 David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <stdio.h> #include <string.h> #include <err.h> #define GREATEST_USE_ABBREVS 0 #include <greatest.h> #include "db.h" #include "types.h" #include "util.h" #define DB "test.db" static void setup(void *data) { (void)data; remove(DB); if (db_open(DB) < 0) err(1, "unable to create database"); } static void teardown(void *data) { (void)data; db_finish(); remove(DB); } GREATEST_TEST test_projects_add(void) { struct project proj = {0}; proj.name = "test"; proj.desc = "Test project"; proj.url = "example.org"; proj.script = "#!/bin/sh exit 0"; GREATEST_ASSERT_EQ(db_project_add(&proj), 0); GREATEST_ASSERT(proj.id > 0); GREATEST_PASS(); } GREATEST_TEST test_projects_list(void) { struct project projs[] = { { .name = "example 1", .desc = "Example project 1", .url = "example.org", .script = "#!/bin/sh exit 0" }, { .name = "example 2", .desc = "Example project 2", .url = "example.org", .script = "#!/bin/sh exit 0" } }; struct db_ctx ctx; for (size_t i = 0; i < UTIL_SIZE(projs); ++i) { GREATEST_ASSERT_EQ(db_project_add(&projs[i]), 0); GREATEST_ASSERT(projs[i].id > 0); } memset(projs, 0, sizeof (projs)); GREATEST_ASSERT_EQ(db_project_list(&ctx, projs, UTIL_SIZE(projs)), 2LL); GREATEST_ASSERT(projs[0].id > 0); GREATEST_ASSERT_STR_EQ(projs[0].name, "example 1"); GREATEST_ASSERT_STR_EQ(projs[0].desc, "Example project 1"); GREATEST_ASSERT_STR_EQ(projs[0].url, "example.org"); GREATEST_ASSERT_STR_EQ(projs[0].script, "#!/bin/sh exit 0"); GREATEST_ASSERT(projs[1].id > 0); GREATEST_ASSERT_STR_EQ(projs[1].name, "example 2"); GREATEST_ASSERT_STR_EQ(projs[1].desc, "Example project 2"); GREATEST_ASSERT_STR_EQ(projs[1].url, "example.org"); GREATEST_ASSERT_STR_EQ(projs[1].script, "#!/bin/sh exit 0"); db_ctx_finish(&ctx); GREATEST_PASS(); } GREATEST_TEST test_projects_find(void) { struct project projs[] = { { .name = "example 1", .desc = "Example project 1", .url = "example.org", .script = "#!/bin/sh exit 0" }, { .name = "example 2", .desc = "Example project 2", .url = "example.org", .script = "#!/bin/sh exit 0" } }; struct project find = { .name = "example 2" }; struct db_ctx ctx; for (size_t i = 0; i < UTIL_SIZE(projs); ++i) { GREATEST_ASSERT_EQ(db_project_add(&projs[i]), 0); GREATEST_ASSERT(projs[i].id > 0); } GREATEST_ASSERT_EQ(db_project_find(&ctx, &find), 0); GREATEST_ASSERT_EQ(find.id, 2); GREATEST_ASSERT_STR_EQ(find.name, "example 2"); GREATEST_ASSERT_STR_EQ(find.desc, "Example project 2"); GREATEST_ASSERT_STR_EQ(find.url, "example.org"); GREATEST_ASSERT_STR_EQ(find.script, "#!/bin/sh exit 0"); db_ctx_finish(&ctx); GREATEST_PASS(); } GREATEST_TEST test_projects_find_id(void) { struct project projs[] = { { .name = "example 1", .desc = "Example project 1", .url = "example.org", .script = "#!/bin/sh exit 0" }, { .name = "example 2", .desc = "Example project 2", .url = "example.org", .script = "#!/bin/sh exit 0" } }; struct project find = { .id = 2 }; struct db_ctx ctx; for (size_t i = 0; i < UTIL_SIZE(projs); ++i) { GREATEST_ASSERT_EQ(db_project_add(&projs[i]), 0); GREATEST_ASSERT(projs[i].id > 0); } /* First generated id should start at 1. */ GREATEST_ASSERT_EQ(db_project_find_id(&ctx, &find), 0); GREATEST_ASSERT_EQ(find.id, 2); GREATEST_ASSERT_STR_EQ(find.name, "example 2"); GREATEST_ASSERT_STR_EQ(find.desc, "Example project 2"); GREATEST_ASSERT_STR_EQ(find.url, "example.org"); GREATEST_ASSERT_STR_EQ(find.script, "#!/bin/sh exit 0"); db_ctx_finish(&ctx); GREATEST_PASS(); } GREATEST_TEST test_projects_update(void) { struct project proj = { .name = "example 1", .desc = "Example project 1", .url = "example.org", .script = "#!/bin/sh exit 0" }; struct project find; struct db_ctx ctx; GREATEST_ASSERT_EQ(db_project_add(&proj), 0); GREATEST_ASSERT(proj.id > 0); /* Update name. */ memset(&find, 0, sizeof (find)); find.id = 1; proj.name = "updated example 1"; GREATEST_ASSERT_EQ(db_project_update(&proj), 0); GREATEST_ASSERT_EQ(db_project_find_id(&ctx, &find), 0); GREATEST_ASSERT_STR_EQ(find.name, "updated example 1"); GREATEST_ASSERT_STR_EQ(find.desc, "Example project 1"); GREATEST_ASSERT_STR_EQ(find.url, "example.org"); GREATEST_ASSERT_STR_EQ(find.script, "#!/bin/sh exit 0"); db_ctx_finish(&ctx); /* Update desc. */ memset(&find, 0, sizeof (find)); find.id = 1; proj.desc = "updated Example project 1"; GREATEST_ASSERT_EQ(db_project_update(&proj), 0); GREATEST_ASSERT_EQ(db_project_find_id(&ctx, &find), 0); GREATEST_ASSERT_STR_EQ(find.name, "updated example 1"); GREATEST_ASSERT_STR_EQ(find.desc, "updated Example project 1"); GREATEST_ASSERT_STR_EQ(find.url, "example.org"); GREATEST_ASSERT_STR_EQ(find.script, "#!/bin/sh exit 0"); db_ctx_finish(&ctx); /* Update url. */ memset(&find, 0, sizeof (find)); find.id = 1; proj.url = "updated example.org"; GREATEST_ASSERT_EQ(db_project_update(&proj), 0); GREATEST_ASSERT_EQ(db_project_find_id(&ctx, &find), 0); GREATEST_ASSERT_STR_EQ(find.name, "updated example 1"); GREATEST_ASSERT_STR_EQ(find.desc, "updated Example project 1"); GREATEST_ASSERT_STR_EQ(find.url, "updated example.org"); GREATEST_ASSERT_STR_EQ(find.script, "#!/bin/sh exit 0"); db_ctx_finish(&ctx); /* Update script. */ memset(&find, 0, sizeof (find)); find.id = 1; proj.script = "#!/bin/sh exit 1"; GREATEST_ASSERT_EQ(db_project_update(&proj), 0); GREATEST_ASSERT_EQ(db_project_find_id(&ctx, &find), 0); GREATEST_ASSERT_STR_EQ(find.name, "updated example 1"); GREATEST_ASSERT_STR_EQ(find.desc, "updated Example project 1"); GREATEST_ASSERT_STR_EQ(find.url, "updated example.org"); GREATEST_ASSERT_STR_EQ(find.script, "#!/bin/sh exit 1"); db_ctx_finish(&ctx); GREATEST_PASS(); } GREATEST_SUITE(suite_projects) { GREATEST_SET_SETUP_CB(setup, NULL); GREATEST_SET_TEARDOWN_CB(teardown, NULL); GREATEST_RUN_TEST(test_projects_add); GREATEST_RUN_TEST(test_projects_list); GREATEST_RUN_TEST(test_projects_find); GREATEST_RUN_TEST(test_projects_find_id); GREATEST_RUN_TEST(test_projects_update); } GREATEST_TEST test_workers_add(void) { struct worker wk = {0}; wk.name = "test"; wk.desc = "Test worker"; GREATEST_ASSERT_EQ(db_worker_add(&wk), 0); GREATEST_ASSERT(wk.id > 0); GREATEST_PASS(); } GREATEST_TEST test_workers_list(void) { struct worker wks[] = { { .name = "example 1", .desc = "Example worker 1", }, { .name = "example 2", .desc = "Example worker 2", } }; struct db_ctx ctx; for (size_t i = 0; i < UTIL_SIZE(wks); ++i) { GREATEST_ASSERT_EQ(db_worker_add(&wks[i]), 0); GREATEST_ASSERT(wks[i].id > 0); } memset(wks, 0, sizeof (wks)); GREATEST_ASSERT_EQ(db_worker_list(&ctx, wks, UTIL_SIZE(wks)), 2LL); GREATEST_ASSERT(wks[0].id > 0); GREATEST_ASSERT_STR_EQ(wks[0].name, "example 1"); GREATEST_ASSERT_STR_EQ(wks[0].desc, "Example worker 1"); GREATEST_ASSERT(wks[1].id > 0); GREATEST_ASSERT_STR_EQ(wks[1].name, "example 2"); GREATEST_ASSERT_STR_EQ(wks[1].desc, "Example worker 2"); db_ctx_finish(&ctx); GREATEST_PASS(); } GREATEST_TEST test_workers_find(void) { struct worker wks[] = { { .name = "example 1", .desc = "Example worker 1", }, { .name = "example 2", .desc = "Example worker 2", } }; struct worker find = { .name = "example 1" }; struct db_ctx ctx; for (size_t i = 0; i < UTIL_SIZE(wks); ++i) { GREATEST_ASSERT_EQ(db_worker_add(&wks[i]), 0); GREATEST_ASSERT(wks[i].id > 0); } GREATEST_ASSERT_EQ(db_worker_find(&ctx, &find), 0); GREATEST_ASSERT_EQ(find.id, 1); GREATEST_ASSERT_STR_EQ(find.name, "example 1"); GREATEST_ASSERT_STR_EQ(find.desc, "Example worker 1"); db_ctx_finish(&ctx); GREATEST_PASS(); } GREATEST_TEST test_workers_find_id(void) { struct worker wks[] = { { .name = "example 1", .desc = "Example worker 1", }, { .name = "example 2", .desc = "Example worker 2", } }; struct worker find = { .id = 1 }; struct db_ctx ctx; for (size_t i = 0; i < UTIL_SIZE(wks); ++i) { GREATEST_ASSERT_EQ(db_worker_add(&wks[i]), 0); GREATEST_ASSERT(wks[i].id > 0); } /* First generated id should start at 1. */ GREATEST_ASSERT_EQ(db_worker_find_id(&ctx, &find), 0); GREATEST_ASSERT_EQ(find.id, 1); GREATEST_ASSERT_STR_EQ(find.name, "example 1"); GREATEST_ASSERT_STR_EQ(find.desc, "Example worker 1"); db_ctx_finish(&ctx); GREATEST_PASS(); } GREATEST_SUITE(suite_workers) { GREATEST_SET_SETUP_CB(setup, NULL); GREATEST_SET_TEARDOWN_CB(teardown, NULL); GREATEST_RUN_TEST(test_workers_add); GREATEST_RUN_TEST(test_workers_list); GREATEST_RUN_TEST(test_workers_find); GREATEST_RUN_TEST(test_workers_find_id); } GREATEST_TEST test_jobs_add(void) { struct project proj = {0}; struct job job = {0}; proj.name = "test"; proj.desc = "Test project"; proj.url = "example.org"; proj.script = "#!/bin/sh exit 0"; GREATEST_ASSERT_EQ(db_project_add(&proj), 0); GREATEST_ASSERT(proj.id > 0); job.project_id = proj.id; job.tag = "123456"; GREATEST_ASSERT_EQ(db_job_add(&job), 0); GREATEST_ASSERT(job.id > 0); GREATEST_PASS(); } GREATEST_TEST test_jobs_todo(void) { struct project proj = {0}; struct job job = {0}; struct worker wk = {0}; struct job todo[16] = {0}; struct db_ctx ctx; proj.name = "test"; proj.desc = "Test project"; proj.url = "example.org"; proj.script = "#!/bin/sh exit 0"; GREATEST_ASSERT_EQ(db_project_add(&proj), 0); GREATEST_ASSERT(proj.id > 0); job.project_id = proj.id; job.tag = "123456"; GREATEST_ASSERT_EQ(db_job_add(&job), 0); GREATEST_ASSERT(job.id > 0); wk.name = "test"; wk.desc = "Test worker"; GREATEST_ASSERT_EQ(db_worker_add(&wk), 0); GREATEST_ASSERT(wk.id > 0); GREATEST_ASSERT_EQ(db_job_todo(&ctx, todo, UTIL_SIZE(todo), wk.id), 1); GREATEST_ASSERT(todo[0].id > 0); GREATEST_ASSERT_STR_EQ(todo[0].tag, "123456"); GREATEST_ASSERT_EQ(todo[0].project_id, proj.id); db_ctx_finish(&ctx); GREATEST_PASS(); } GREATEST_SUITE(suite_jobs) { GREATEST_SET_SETUP_CB(setup, NULL); GREATEST_SET_TEARDOWN_CB(teardown, NULL); GREATEST_RUN_TEST(test_jobs_add); GREATEST_RUN_TEST(test_jobs_todo); } GREATEST_TEST test_jobresults_add(void) { struct project projs[] = { { .name = "example 1", .desc = "Example project 1", .url = "example.org", .script = "#!/bin/sh exit 0" }, { .name = "example 2", .desc = "Example project 2", .url = "example.org", .script = "#!/bin/sh exit 0" } }; struct job jobs[] = { { .project_id = 0, /* will be project 1 */ .tag = "123456" }, { .project_id = 0, /* will be project 2 */ .tag = "abcdef" }, }; struct worker wks[] = { { .name = "alpine-aarch64", .desc = "alpine-aarch64" }, { .name = "alpine-armhf", .desc = "alpine-armhf" }, }; struct job todo[16] = {0}; struct jobresult res = {0}; struct db_ctx ctx; for (size_t i = 0; i < UTIL_SIZE(projs); ++i) { GREATEST_ASSERT_EQ(db_project_add(&projs[i]), 0); GREATEST_ASSERT(projs[i].id > 0); } /* Update jobs with newly created projects. */ jobs[0].project_id = projs[0].id; jobs[1].project_id = projs[1].id; for (size_t i = 0; i < UTIL_SIZE(jobs); ++i) { GREATEST_ASSERT_EQ(db_job_add(&jobs[i]), 0); GREATEST_ASSERT(jobs[i].id > 0); } for (size_t i = 0; i < UTIL_SIZE(wks); ++i) { GREATEST_ASSERT_EQ(db_worker_add(&wks[i]), 0); GREATEST_ASSERT(wks[i].id > 0); } /* * Now add a jobresult for worker alpine-aarch64 and the job "abcdef", * this means that this worker will only have the job "123456" to do * while the other worker will have all to do. */ res.job_id = jobs[1].id; res.worker_id = wks[0].id; res.exitcode = 0; res.log = "Success"; GREATEST_ASSERT_EQ(db_jobresult_add(&res), 0); GREATEST_ASSERT(res.id > 0); /* 1 job left for alpine-aarch64 -> [123456]. */ GREATEST_ASSERT_EQ(db_job_todo(&ctx, todo, UTIL_SIZE(todo), wks[0].id), 1); GREATEST_ASSERT(todo[0].id > 0); GREATEST_ASSERT_STR_EQ(todo[0].tag, "123456"); GREATEST_ASSERT_EQ(todo[0].project_id, projs[0].id); db_ctx_finish(&ctx); /* 2 jobs left for alpine-armhf -> [123456, abcdef]. */ GREATEST_ASSERT_EQ(db_job_todo(&ctx, todo, UTIL_SIZE(todo), wks[1].id), 2); GREATEST_ASSERT(todo[0].id > 0); GREATEST_ASSERT_STR_EQ(todo[0].tag, "123456"); GREATEST_ASSERT_EQ(todo[0].project_id, projs[0].id); GREATEST_ASSERT(todo[1].id > 0); GREATEST_ASSERT_STR_EQ(todo[1].tag, "abcdef"); GREATEST_ASSERT_EQ(todo[1].project_id, projs[1].id); db_ctx_finish(&ctx); GREATEST_PASS(); } GREATEST_SUITE(suite_jobresults) { GREATEST_SET_SETUP_CB(setup, NULL); GREATEST_SET_TEARDOWN_CB(teardown, NULL); GREATEST_RUN_TEST(test_jobresults_add); } GREATEST_MAIN_DEFS(); int main(int argc, char **argv) { GREATEST_MAIN_BEGIN(); GREATEST_RUN_SUITE(suite_projects); GREATEST_RUN_SUITE(suite_workers); GREATEST_RUN_SUITE(suite_jobs); GREATEST_RUN_SUITE(suite_jobresults); GREATEST_MAIN_END(); }