mirror of
https://github.com/Mercantec-GHC/h4-projekt-gruppe-0-sm.git
synced 2025-04-27 16:24:07 +02:00
add backend action
This commit is contained in:
parent
6a4f965536
commit
f79adeaef3
81
.github/workflows/backend_build_and_test.yml
vendored
Normal file
81
.github/workflows/backend_build_and_test.yml
vendored
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
name: "Backend: Build and Test"
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "main" ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ "main" ]
|
||||||
|
|
||||||
|
env:
|
||||||
|
BACKEND_SERVER_HOSTNAME: 'http://localhost:8080'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_debug:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: ./backend
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: build release with tests
|
||||||
|
run: make -B INCLUDE_TESTS=1
|
||||||
|
- name: run tests
|
||||||
|
run: ./build/server --run-tests
|
||||||
|
|
||||||
|
build_release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: ./backend
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: build release with tests
|
||||||
|
run: make -B RELEASE=1 INCLUDE_TESTS=1
|
||||||
|
- name: run tests
|
||||||
|
run: ./build/server --run-tests
|
||||||
|
|
||||||
|
test_debug:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: ./backend
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: denoland/setup-deno@v2
|
||||||
|
with:
|
||||||
|
deno-version: v2.x
|
||||||
|
- name: cache dependencies
|
||||||
|
run: deno cache --check test/test.ts
|
||||||
|
- name: build release with tests
|
||||||
|
run: make -B
|
||||||
|
- name: setup database
|
||||||
|
run: make drop_database
|
||||||
|
- name: test
|
||||||
|
timeout-minutes: 1
|
||||||
|
run: |
|
||||||
|
./build/server &
|
||||||
|
sleep 1
|
||||||
|
deno test --allow-env --allow-net test/test.ts
|
||||||
|
|
||||||
|
test_release:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: ./backend
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: denoland/setup-deno@v2
|
||||||
|
with:
|
||||||
|
deno-version: v2.x
|
||||||
|
- name: cache dependencies
|
||||||
|
run: deno cache --check test/test.ts
|
||||||
|
- name: build release with tests
|
||||||
|
run: make -B RELEASE=1
|
||||||
|
- name: setup database
|
||||||
|
run: make drop_database
|
||||||
|
- name: test
|
||||||
|
timeout-minutes: 1
|
||||||
|
run: |
|
||||||
|
./build/server &
|
||||||
|
sleep 1
|
||||||
|
deno test --allow-env --allow-net test/test.ts
|
@ -36,13 +36,16 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(RUN_TESTS),1)
|
ifeq ($(INCLUDE_TESTS),1)
|
||||||
C_FLAGS += -DRUN_TESTS
|
C_FLAGS += -DINCLUDE_TESTS
|
||||||
endif
|
endif
|
||||||
|
|
||||||
PUBLIC_DIR_PATH=$(shell readlink -f ./public)
|
PUBLIC_DIR_PATH=$(shell readlink -f ./public)
|
||||||
C_FLAGS += -DPUBLIC_DIR_PATH='"$(PUBLIC_DIR_PATH)"'
|
C_FLAGS += -DPUBLIC_DIR_PATH='"$(PUBLIC_DIR_PATH)"'
|
||||||
|
|
||||||
|
DB_FILEPATH=database.db
|
||||||
|
C_FLAGS += -DDB_FILEPATH='"$(DB_FILEPATH)"'
|
||||||
|
|
||||||
HEADERS = $(shell find src/ -name *.h)
|
HEADERS = $(shell find src/ -name *.h)
|
||||||
C_FILES = $(shell find src/ -name *.c)
|
C_FILES = $(shell find src/ -name *.c)
|
||||||
O_FILES = $(patsubst src/%.c,build/%.o,$(C_FILES))
|
O_FILES = $(patsubst src/%.c,build/%.o,$(C_FILES))
|
||||||
@ -64,5 +67,5 @@ clean:
|
|||||||
rm -rf build/
|
rm -rf build/
|
||||||
|
|
||||||
drop_database:
|
drop_database:
|
||||||
rm -rf database.db && sqlite3 database.db < prepare.sql
|
rm -rf $(DB_FILEPATH) && sqlite3 $(DB_FILEPATH) < prepare.sql
|
||||||
|
|
||||||
|
@ -8,5 +8,7 @@
|
|||||||
-pedantic-errors
|
-pedantic-errors
|
||||||
-Wno-unused-parameter
|
-Wno-unused-parameter
|
||||||
-Wno-unused-function
|
-Wno-unused-function
|
||||||
|
-DINCLUDE_TESTS
|
||||||
-DPUBLIC_DIR_PATH="./public"
|
-DPUBLIC_DIR_PATH="./public"
|
||||||
|
-DDB_FILEPATH="database.db"
|
||||||
|
|
||||||
|
@ -106,19 +106,19 @@
|
|||||||
return &found->value; \
|
return &found->value; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RUN_TESTS
|
#ifdef INCLUDE_TESTS
|
||||||
#include "../utils/panic.h"
|
#include "../utils/panic.h"
|
||||||
|
|
||||||
DEFINE_KV_MAP(int, int, IntMap, int_map)
|
DEFINE_KV_MAP(int, int, TestIntMap, test_int_map)
|
||||||
|
|
||||||
static inline void test_collections_kv_map(void)
|
static inline void test_collections_kv_map(void)
|
||||||
{
|
{
|
||||||
IntMap map;
|
TestIntMap map;
|
||||||
int_map_construct(&map);
|
test_int_map_construct(&map);
|
||||||
|
|
||||||
int_map_set(&map, 1, 10);
|
test_int_map_set(&map, 1, 10);
|
||||||
int_map_set(&map, 3, 30);
|
test_int_map_set(&map, 3, 30);
|
||||||
int_map_set(&map, 5, 50);
|
test_int_map_set(&map, 5, 50);
|
||||||
|
|
||||||
int data[][2] = {
|
int data[][2] = {
|
||||||
{ 0, 0 },
|
{ 0, 0 },
|
||||||
@ -131,28 +131,28 @@ static inline void test_collections_kv_map(void)
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i) {
|
for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i) {
|
||||||
int idx
|
int idx = (int)test_int_map_internal_insert_idx(
|
||||||
= (int)int_map_internal_insert_idx(&map, 0, map.size, data[i][0]);
|
&map, 0, map.size, data[i][0]);
|
||||||
if (idx != data[i][1]) {
|
if (idx != data[i][1]) {
|
||||||
PANIC("wrong insert index, expected %d, got %d", data[i][1], idx);
|
PANIC("wrong insert index, expected %d, got %d", data[i][1], idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int* val = int_map_get(&map, 3);
|
int* val = test_int_map_get(&map, 3);
|
||||||
if (!val || *val != 30) {
|
if (!val || *val != 30) {
|
||||||
PANIC("failed to find value");
|
PANIC("failed to find value");
|
||||||
}
|
}
|
||||||
|
|
||||||
val = int_map_get(&map, 4);
|
val = test_int_map_get(&map, 4);
|
||||||
if (val != NULL) {
|
if (val != NULL) {
|
||||||
PANIC("found wrong value");
|
PANIC("found wrong value");
|
||||||
}
|
}
|
||||||
|
|
||||||
const int* const_val = int_map_get_const(&map, 5);
|
const int* const_val = test_int_map_get_const(&map, 5);
|
||||||
if (!const_val || *const_val != 50) {
|
if (!const_val || *const_val != 50) {
|
||||||
PANIC("failed to find value");
|
PANIC("failed to find value");
|
||||||
}
|
}
|
||||||
|
|
||||||
int_map_destroy(&map);
|
test_int_map_destroy(&map);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,36 +27,17 @@ static inline char* get_str_safe(sqlite3_stmt* stmt, int col)
|
|||||||
#define GET_INT(COL) sqlite3_column_int64(stmt, COL)
|
#define GET_INT(COL) sqlite3_column_int64(stmt, COL)
|
||||||
#define GET_STR(COL) get_str_safe(stmt, COL)
|
#define GET_STR(COL) get_str_safe(stmt, COL)
|
||||||
|
|
||||||
Db* db_sqlite_new(void)
|
|
||||||
{
|
|
||||||
Db* db = malloc(sizeof(Db));
|
|
||||||
|
|
||||||
sqlite3* connection;
|
|
||||||
int res = sqlite3_open("database.db", &connection);
|
|
||||||
if (res != SQLITE_OK) {
|
|
||||||
fprintf(stderr, "error: could not open sqlite 'database.db'\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
sqlite3_close(connection);
|
|
||||||
|
|
||||||
return db;
|
|
||||||
}
|
|
||||||
|
|
||||||
void db_sqlite_free(Db* db)
|
|
||||||
{
|
|
||||||
// sqlite3_close(db->connection);
|
|
||||||
free(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline DbRes connect(sqlite3** connection)
|
static inline DbRes connect(sqlite3** connection)
|
||||||
{
|
{
|
||||||
int res = sqlite3_open_v2("database.db",
|
const char* filepath = DB_FILEPATH;
|
||||||
|
int res = sqlite3_open_v2(filepath,
|
||||||
connection,
|
connection,
|
||||||
SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX,
|
SQLITE_OPEN_READWRITE | SQLITE_OPEN_NOMUTEX,
|
||||||
NULL);
|
NULL);
|
||||||
if (res != SQLITE_OK) {
|
if (res != SQLITE_OK) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"error: could not open sqlite 'database.db'\n %s\n",
|
"error: could not open sqlite '%s'\n %s\n",
|
||||||
|
filepath,
|
||||||
sqlite3_errmsg(*connection));
|
sqlite3_errmsg(*connection));
|
||||||
return DbRes_Error;
|
return DbRes_Error;
|
||||||
}
|
}
|
||||||
@ -80,6 +61,26 @@ static inline void disconnect(sqlite3* connection)
|
|||||||
disconnect(connection); \
|
disconnect(connection); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Db* db_sqlite_new(void)
|
||||||
|
{
|
||||||
|
Db* db = malloc(sizeof(Db));
|
||||||
|
|
||||||
|
sqlite3* connection;
|
||||||
|
if (connect(&connection) != DbRes_Ok) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
disconnect(connection);
|
||||||
|
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
|
void db_sqlite_free(Db* db)
|
||||||
|
{
|
||||||
|
// No need to disconnect.
|
||||||
|
|
||||||
|
free(db);
|
||||||
|
}
|
||||||
|
|
||||||
DbRes db_user_insert(Db* db, const User* user)
|
DbRes db_user_insert(Db* db, const User* user)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(User) == 40, "model has changed");
|
static_assert(sizeof(User) == 40, "model has changed");
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "collections/kv_map.h"
|
||||||
#include "controllers/controllers.h"
|
#include "controllers/controllers.h"
|
||||||
#include "db/db_sqlite.h"
|
#include "db/db_sqlite.h"
|
||||||
#include "http/http.h"
|
#include "http/http.h"
|
||||||
@ -8,17 +9,24 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
void test(void);
|
typedef struct {
|
||||||
|
bool run_tests;
|
||||||
|
} Args;
|
||||||
|
|
||||||
|
static inline Args parse_args(int argc, char** argv);
|
||||||
|
static inline void run_tests(void);
|
||||||
|
|
||||||
HttpServer* server;
|
HttpServer* server;
|
||||||
|
|
||||||
int main(void)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
srand((unsigned int)time(NULL));
|
srand((unsigned int)time(NULL));
|
||||||
|
|
||||||
#ifdef RUN_TESTS
|
Args args = parse_args(argc, argv);
|
||||||
test();
|
|
||||||
#endif
|
if (args.run_tests) {
|
||||||
|
run_tests();
|
||||||
|
}
|
||||||
|
|
||||||
Db* db = db_sqlite_new();
|
Db* db = db_sqlite_new();
|
||||||
|
|
||||||
@ -81,13 +89,30 @@ int main(void)
|
|||||||
db_sqlite_free(db);
|
db_sqlite_free(db);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RUN_TESTS
|
static inline Args parse_args(int argc, char** argv)
|
||||||
void test(void)
|
|
||||||
{
|
{
|
||||||
|
Args args = {
|
||||||
|
.run_tests = false,
|
||||||
|
};
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
if (strcmp(argv[i], "--run-tests") == 0) {
|
||||||
|
args.run_tests = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void run_tests(void)
|
||||||
|
{
|
||||||
|
#ifdef INCLUDE_TESTS
|
||||||
test_util_str();
|
test_util_str();
|
||||||
test_collections_kv_map();
|
test_collections_kv_map();
|
||||||
printf("\n\x1b[1;97m ALL TESTS \x1b[1;92mPASSED"
|
printf("\n\x1b[1;97m ALL TESTS \x1b[1;92mPASSED"
|
||||||
" \x1b[1;97mSUCCESSFULLY 💅\x1b[0m\n\n");
|
" \x1b[1;97mSUCCESSFULLY 💅\x1b[0m\n\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
#else
|
||||||
|
fprintf(stderr,
|
||||||
|
"warning: tests not build."
|
||||||
|
" '--run-tests' passed without building with INCLUDE_TESTS=1\n");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
@ -313,7 +313,7 @@ char* str_random(size_t length)
|
|||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef RUN_TESTS
|
#ifdef INCLUDE_TESTS
|
||||||
void test_util_str(void)
|
void test_util_str(void)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
|
@ -47,6 +47,6 @@ uint64_t str_fast_hash(const char* input);
|
|||||||
|
|
||||||
char* str_random(size_t length);
|
char* str_random(size_t length);
|
||||||
|
|
||||||
#ifdef RUN_TESTS
|
#ifdef INCLUDE_TESTS
|
||||||
void test_util_str(void);
|
void test_util_str(void);
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { assertEquals, assertMatch, assertNotEquals } from "jsr:@std/assert";
|
import { assertEquals, assertMatch, assertNotEquals } from "jsr:@std/assert";
|
||||||
|
|
||||||
const url = `http://127.0.0.1:8080`;
|
const url = Deno.env.get("BACKEND_SERVER_HOSTNAME") ?? `http://127.0.0.1:8080`;
|
||||||
// const url = `http://10.135.51.114:8080`;
|
|
||||||
|
|
||||||
const name = "Maksim";
|
const name = "Maksim";
|
||||||
const email = `mash.skp_${Math.floor(Math.random() * 100000)}@edu.mercantec.dk`;
|
const email = `mash.skp_${Math.floor(Math.random() * 100000)}@edu.mercantec.dk`;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user