labfy-investigation/tests/test_transaction.c

321 lines
5.9 KiB
C

/******************************************************************************
* @file test_transaction.c
* @brief Tests du module DatabaseTransaction.
******************************************************************************/
#include "database/database.h"
#include "database/statement.h"
#include "database/transaction.h"
#include "database/error.h"
#include <assert.h>
#include <stdio.h>
/**
* @brief Crée la table utilisée par les tests.
*/
static void test_create_table(
Database *database
)
{
DatabaseStatement *statement = NULL;
statement = database_statement_prepare(
database,
"CREATE TABLE transaction_test"
"("
" value TEXT NOT NULL"
");"
);
assert(statement != NULL);
assert(
database_statement_step(statement) ==
DATABASE_STATEMENT_STEP_DONE
);
database_statement_finalize(statement);
}
/**
* @brief Insère une valeur dans la table de test.
*/
static void test_insert_value(
Database *database,
const char *value
)
{
DatabaseStatement *statement = NULL;
statement = database_statement_prepare(
database,
"INSERT INTO transaction_test (value)"
" VALUES (?);"
);
assert(statement != NULL);
assert(
database_statement_bind_text(
statement,
1,
value
)
);
assert(
database_statement_step(statement) ==
DATABASE_STATEMENT_STEP_DONE
);
database_statement_finalize(statement);
}
/**
* @brief Compte les lignes de la table de test.
*/
static int64_t test_count_values(
Database *database
)
{
DatabaseStatement *statement = NULL;
int64_t count = INT64_C(0);
statement = database_statement_prepare(
database,
"SELECT COUNT(*) FROM transaction_test;"
);
assert(statement != NULL);
assert(
database_statement_step(statement) ==
DATABASE_STATEMENT_STEP_ROW
);
assert(
database_statement_column_int64(
statement,
0,
&count
)
);
database_statement_finalize(statement);
return count;
}
/**
* @brief Vérifie qu'un commit conserve les modifications.
*/
static void test_transaction_commit(void)
{
Database *database = NULL;
database = database_open(":memory:");
assert(database != NULL);
test_create_table(database);
assert(
database_transaction_begin(database)
);
test_insert_value(
database,
"valeur validée"
);
assert(
database_transaction_commit(database)
);
assert(
test_count_values(database) ==
INT64_C(1)
);
database_close(database);
}
/**
* @brief Vérifie qu'un rollback annule les modifications.
*/
static void test_transaction_rollback(void)
{
Database *database = NULL;
database = database_open(":memory:");
assert(database != NULL);
test_create_table(database);
assert(
database_transaction_begin(database)
);
test_insert_value(
database,
"valeur annulée"
);
assert(
database_transaction_rollback(database)
);
assert(
test_count_values(database) ==
INT64_C(0)
);
database_close(database);
}
/**
* @brief Vérifie le refus des états de transaction invalides.
*/
static void test_invalid_transaction_states(void)
{
Database *database = NULL;
database = database_open(":memory:");
assert(database != NULL);
assert(
!database_transaction_commit(database)
);
assert(
!database_transaction_rollback(database)
);
assert(
database_transaction_begin(database)
);
assert(
!database_transaction_begin(database)
);
assert(
database_transaction_rollback(database)
);
assert(
!database_transaction_rollback(database)
);
assert(
!database_transaction_begin(NULL)
);
assert(
!database_transaction_commit(NULL)
);
assert(
!database_transaction_rollback(NULL)
);
database_close(database);
}
/**
* @brief Vérifie l'enregistrement des erreurs de transaction.
*/
static void test_transaction_error_state(void)
{
Database *database = NULL;
const char *error_message = NULL;
database = database_open(":memory:");
assert(database != NULL);
/*
* Aucun commit n'est possible sans transaction active.
*/
assert(
!database_transaction_commit(database)
);
assert(
database_error_get_code(database) ==
DATABASE_ERROR_INVALID_STATE
);
error_message = database_error_get_message(
database
);
assert(error_message != NULL);
assert(error_message[0] != '\0');
/*
* Un début de transaction valide efface l'erreur précédente.
*/
assert(
database_transaction_begin(database)
);
assert(
database_error_get_code(database) ==
DATABASE_ERROR_NONE
);
/*
* Une transaction imbriquée est refusée.
*/
assert(
!database_transaction_begin(database)
);
assert(
database_error_get_code(database) ==
DATABASE_ERROR_INVALID_STATE
);
database_error_clear(database);
assert(
database_transaction_rollback(database)
);
assert(
database_error_get_code(database) ==
DATABASE_ERROR_NONE
);
/*
* Un second rollback est impossible.
*/
assert(
!database_transaction_rollback(database)
);
assert(
database_error_get_code(database) ==
DATABASE_ERROR_INVALID_STATE
);
database_close(database);
}
int main(void)
{
test_transaction_commit();
test_transaction_rollback();
test_invalid_transaction_states();
test_transaction_error_state();
printf(
"DatabaseTransaction : tous les tests sont valides.\n"
);
return 0;
}