Skip to content
Snippets Groups Projects
Commit 715e36c5 authored by TwilCynder's avatar TwilCynder
Browse files

manpage attempt

parent 79f6a380
No related branches found
No related tags found
No related merge requests found
#include <stdlib.h>
#include <stdio.h>
#include "../execution.h"
#include "test.h"
char *const e1args[] = {path, "-f", "3", "-t", "3", 0};
typedef struct {
int number;
} TestState;
void test_initialize(void **state, void *context)
{
TestState *newtstate = (TestState *) malloc(sizeof(TestState));
newtstate->number = 100;
*state = (void *) newtstate;
}
void test_read(void *state, void *context, const char *buffer, int nread)
{
printf("Out : %s", buffer);
if (nread < BUFFER_SIZE) {
((TestState *)state)->number += 1;
}
}
int test_finalize(void *state, void *context)
{
return ((TestState *)state)->number;
}
void test_test(){
Tester test_tester = {
.init = test_initialize,
.read = test_read,
.finalize = test_finalize,
.name = "Test"
};
Execution e1 = {
.args = e1args,
.testers = &test_tester,
.nb_testers = 1
};
execute_test(&e1);
}
\ No newline at end of file
#pragma once
void test_test();
\ No newline at end of file
/*******************************************************
Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
This file is part of Mojitos.
Mojitos 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.
Mojitos 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 MojitO/S. If not, see <https://www.gnu.org/licenses/>.
*******************************************************/
#include <stdlib.h>
#include <stdio.h>
#include "../execution.h"
#include "../util.h"
#include "timing.h"
#define TOLERANCE 1
typedef struct {
char* frequency;
char* duration;
} TimingExecutionArgs;
TimingExecutionArgs timingExecutionsArgs[] = {
{.duration = "1", .frequency = "1"},
{.duration = "10", .frequency = "2"},
{.duration = "5", .frequency = "10"},
{.duration = "3", .frequency = "3"},
{.duration = "4", .frequency = "4"}
};
typedef struct {
int count;
} TimingState;
typedef struct {
int expected_result;
} TimingContext;
void timing_init(void** state, void* context){
*state = calloc(1, sizeof(TimingState));
}
void timing_reader(void* state, void* context, const char* buffer, int nread){
TimingState* tstate = state;
if (buffer[nread - 1] == '\n'){
//buffer contains a line
tstate->count++;
}
printf("Out : %s", buffer);
}
int timing_finalize(void* state, void* context){
TimingState* tstate = state;
TimingContext* tcontext = context;
PRINT("Expected %d | Got %d (tolerance : %d)\n", tcontext->expected_result, tstate->count, TOLERANCE);
int count = tstate->count;
int expected = tcontext->expected_result;
return abs(count - expected) <= TOLERANCE;
}
/**
* @brief Calculates the number of expected outputs from the duration of frequency (in the form of strings).
*
* May be a signficantly useless overhead given that i could have just hard-coded the result as an int, but wanted
* to make sure that there is no error on this value. Also, we go from string to int instead of having exerything coded as int
* and then converting to string to be passed to the exec because string->int costs less than int->string with static strings.
* @param args the TimingExecutionArgs containing our two values as strings.
*/
int calc_expected_result(TimingExecutionArgs* args){
return atoi(args->duration) * atoi(args->frequency);
}
/**
* @brief Performs all the timing related tests.
*/
void timing_test(){
Tester tester = {
.init = timing_init,
.read = timing_reader,
.finalize = timing_finalize,
.name = "Outputs amount"
};
TimingContext tcontext;
char* args[] = {path, "-t", 0, "-f", 0, 0};
Execution execution = {
.testers = &tester,
.nb_testers = 1,
.context = &tcontext,
.args = args,
};
for (unsigned int i = 0; i < ARRAY_LENGTH(timingExecutionsArgs); i++){
TimingExecutionArgs current_values = timingExecutionsArgs[i];
args[2] = current_values.duration;
args[4] = current_values.frequency;
((TimingContext*)execution.context)->expected_result = calc_expected_result(&current_values);
execute_test(&execution);
}
}
\ No newline at end of file
#pragma once
void timing_test();
\ No newline at end of file
.Dd April 3, 2023
.Dt MOJITOS_TESTER 1
.Os
.Sh NAME
.Nm mojitos_tester
.Nd A testing tool for MojitO/S
.Sh SYNOPSIS
.Nm mojitos_tester
.Sh DESCRIPTION
.Nm runs mojitos and verfies its output.
.Nm runs on GNU/Linux.
.Sh EXIT STATUS
Exits with the error count as the exit status.
.Sh MAKING TESTS
Tests are made directly in-code. Build and run the current test code with make run.
For each test run, an Execution object must be made.
.Bd -literal -offset indent
typedef struct {
char *const *args; //Arguments to be passed to mojitos
Tester *testers; //Tests that are going to be performed (concurrently) durning this run.
int nb_testers; //Number of tests.
void *context; //Pointer to an object containing the context for this run (we can modify its content and then reuse the same Execution to run multiple test runs with the same tests.)
} Execution;
.Ed
.Pp
Calling execute_test(exec) with exec being a pointer to an Execution object will run mojitos with the given parameters.
Tests are performed on that run through the "testers" property, an array of Tester objects.
.Bd -literal -offset indent
typedef struct {
TesterInit init; //init function
TesterReader read; //reader function (called for each output)
TesterFinalizer finalize; //the finalizer function (gives the results of the test)
void *state; //a pointer that will be passed to each function, as a double pointer in the case of the init function (so it can allocate memory for state storage)
const char *name; //the name of this test, for output clarity
} Tester;
.Ed
.Pp
The three function pointers follow these signatures
.Bd -literal -offset indent
typedef void(*TesterInit)(void **state, void *context);
typedef void(*TesterReader)(void *state, void *context, const char *buffer, int read_size);
typedef int(*TesterFinalizer)(void *state, void *context);
.Ed
.Pp
The TesterInit function of a Tester is called once before mojitos is ran. It is given a pointer pointer to the state pointer, that will then be passed directly to the two other functions.
The TesterReader function of a Tester is called everytime mojitos outputs something. It is given a pointer to the null-terminated string that was read on mojitos output.
The TesterFinalizer function of a Tester is called once mojitos exits, and should return a non-zero value if the test failed (incorrect mojitos output), or 0 otherwise.
.Pp
Notice how every function is also give a *context pointer. This pointer is the context property of the current Execution.
.Sh EXAMPLES
Example tests are provided in the doc/examples/executions directory. Keep in mind that, like all test files, they simply define a function that must then be called by main.
.Sh LICENSE
This tester is part of the MojitO/S project, published under the GPL3 license and is part of the
.Lk https://www.irit.fr/energumen/ [Energumen Project]
.Sh BUGS
Absolutely none.
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment