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

manpage attempt

parent 79f6a380
Branches
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