/*++
/* NAME
/* pol_stats_test 1t
/* SUMMARY
/* pol_stats unit tests
/* SYNOPSIS
/* ./pol_stats_test
/* DESCRIPTION
/* pol_stats_test runs and logs each configured test, reports if a
/* test is a PASS or FAIL, and returns an exit status of zero
/* if all tests are a PASS.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* porcupine.org
/*--*/
/*
* System library .
*/
#include <sys_defs.h>
#include <stdlib.h>
#include <string.h>
/*
* Utility library .
*/
#include <msg.h>
#include <msg_vstream.h>
#include <stringops.h>
#include <vstring.h>
/*
* Application - specific .
*/
#include <pol_stats.h>
/*
* Convenience wrappers for feature tests at index 0 .
*/
#define pol_stat_activate_first(stats, name) \
pol_stat_activate((stats), 0 , (name))
#define pol_stat_decide_first(stats, name, status) \
pol_stat_decide((stats), 0 , (name), (status))
struct first_test_data {
const char *target_name;
const char *final_name;
int final_status;
};
/*
* Ditto , at index 1 . Originally these were different from the definitions
* for the first field . Keep the definitions separate so that tests can be
* differentiated again if needed .
*/
#define pol_stat_activate_second(stats, name) \
pol_stat_activate((stats), 1 , (name))
#define pol_stat_decide_second(stats, name, status) \
pol_stat_decide((stats), 1 , (name), (status))
struct second_test_data {
const char *target_name;
const char *final_name;
int final_status;
};
/*
* Tests cases and test data .
*/
typedef struct TEST_CASE {
const char *label;
const char *want;
int (*action) (const struct TEST_CASE *);
struct first_test_data first_data;
struct second_test_data second_data;
} TEST_CASE;
static POL_STATS *pstats;
static VSTRING *buf;
static int test_pol_stats(const TEST_CASE *tp)
{
char *got;
int errors = 0 ;
pol_stats_revert(pstats);
VSTRING_RESET(buf);
if (tp->first_data.target_name) {
pol_stat_activate_first(pstats, tp->first_data.target_name);
if (tp->first_data.final_name)
pol_stat_decide_first(pstats, tp->first_data.final_name,
tp->first_data.final_status);
}
if (tp->second_data.target_name) {
pol_stat_activate_second(pstats, tp->second_data.target_name);
if (tp->second_data.final_name)
pol_stat_decide_second(pstats, tp->second_data.final_name,
tp->second_data.final_status);
}
pol_stats_format(buf, pstats);
got = vstring_str(buf);
if (strcmp(got, tp->want) != 0 ) {
msg_warn("got '%s', want '%s" , got, tp->want);
errors++;
}
return (errors == 0 );
}
static TEST_CASE test_cases[] = {
/* Tests for single feature at index 0 */
{"first_compliant" , "first" , test_pol_stats,
{"first" , "first" , POL_STAT_COMPLIANT}, {},
},
{"first_undecided" , "first?" , test_pol_stats,
{"first" , 0 , POL_STAT_COMPLIANT}, {},
},
{"first_unspecified_violation" , "!first" , test_pol_stats,
{"first" , "first" , POL_STAT_VIOLATION}, {},
},
{"first_downgraded_violation" , "!first:low" , test_pol_stats,
{"first" , "low" , POL_STAT_VIOLATION}, {},
},
{"first_downgraded_compliant" , "first:none" , test_pol_stats,
{"first" , "none" , POL_STAT_COMPLIANT}, {},
},
/* Tests for single feature at index 1 */
{"second_compliant" , "second" , test_pol_stats,
{}, {"second" , "second" , POL_STAT_COMPLIANT},
},
{"second_explicit_downgraded_compliant" , "second:other" , test_pol_stats,
{}, {"second" , "other" , POL_STAT_COMPLIANT},
},
{"second_explicit_downgraded_violation" , "!second:other" , test_pol_stats,
{}, {"second" , "other" , POL_STAT_VIOLATION},
},
/* Combined policy status tests. */
{"multi_feature_compliant" , "first/second:none" , test_pol_stats,
{"first" , "first" , POL_STAT_COMPLIANT},
{"second" , "none" , POL_STAT_COMPLIANT},
},
{"multi_feature_violation" , "!first/second:none" , test_pol_stats,
{"first" , "first" , POL_STAT_VIOLATION},
{"second" , "none" , POL_STAT_COMPLIANT},
},
{"multi_feature_violation" , "first/!second:none" , test_pol_stats,
{"first" , "first" , POL_STAT_COMPLIANT},
{"second" , "none" , POL_STAT_VIOLATION},
},
0 ,
};
int main(int argc, char **argv)
{
const TEST_CASE *tp;
int pass = 0 ;
int fail = 0 ;
msg_vstream_init(sane_basename((VSTRING *) 0 , argv[0 ]), VSTREAM_ERR);
pstats = pol_stats_create();
buf = vstring_alloc(100 );
for (tp = test_cases; tp->label != 0 ; tp++) {
msg_info("RUN %s" , tp->label);
if (tp->action(tp) == 0 ) {
fail++;
msg_info("FAIL %s" , tp->label);
} else {
msg_info("PASS %s" , tp->label);
pass++;
}
}
pol_stats_free(pstats);
vstring_free(buf);
msg_info("PASS=%d FAIL=%d" , pass, fail);
exit (fail != 0 );
}
Messung V0.5 in Prozent C=73 H=96 G=85
¤ Dauer der Verarbeitung: 0.20 Sekunden
(vorverarbeitet am 2026-08-08)
¤
*© Formatika GbR, Deutschland