Permalink
Browse files

Hardcode Tests (#1243)

* Add basic hardcode test framework. Closes #1238

Now go forth and write all the tests!

* Rename all the softcode test case files.

testFOO.pl -> testFOO.t because they're not actually proper perl scripts
and that was bugging me and causing syntax highlighting problems in
editors.

* Fix a couple of typos/formatting bugs.

* Add some more test cases.

* Add some utf8 tests.

* Support ancient perl, and better error handling on failed tsort invocation.

* More tests and run the tests after loading the database.

* Add tests for map_file()
  • Loading branch information...
shawnw committed Sep 16, 2018
1 parent e0017a4 commit 0a0a9ad45350edb69a7906b44c35ac52fbae6077
Showing with 927 additions and 97 deletions.
  1. +5 −2 Makefile.in
  2. +21 −0 hdrs/tests.h
  3. +24 −15 src/Makefile.in
  4. +53 −36 src/bsd.c
  5. +76 −0 src/charconv.c
  6. +33 −0 src/command.c
  7. +57 −0 src/map_file.c
  8. +124 −14 src/parse.c
  9. +224 −2 src/strutil.c
  10. +74 −0 src/testframework.c
  11. +77 −0 src/tests.inc
  12. +1 −1 test/PennMUSH.pm
  13. +0 −26 test/README
  14. +71 −0 test/README.md
  15. +1 −1 test/alltests.sh.in
  16. 0 test/{testalias.pl → testalias.t}
  17. 0 test/{testatree.pl → testatree.t}
  18. 0 test/{testdecompose.pl → testdecompose.t}
  19. 0 test/{testdigest.pl → testdigest.t}
  20. 0 test/{testdistxd.pl → testdistxd.t}
  21. 0 test/{testfirstof.pl → testfirstof.t}
  22. 0 test/{testflags.pl → testflags.t}
  23. 0 test/{testgrep.pl → testgrep.t}
  24. 0 test/{testhastype.pl → testhastype.t}
  25. 0 test/{testinsert.pl → testinsert.t}
  26. 0 test/{testjson.pl → testjson.t}
  27. 0 test/{testjust.pl → testjust.t}
  28. 0 test/{testletq.pl → testletq.t}
  29. 0 test/{testlnum.pl → testlnum.t}
  30. 0 test/{testmath.pl → testmath.t}
  31. 0 test/{testnull.pl → testnull.t}
  32. 0 test/{testpage.pl → testpage.t}
  33. 0 test/{testrand.pl → testrand.t}
  34. 0 test/{testreswitch.pl → testreswitch.t}
  35. 0 test/{testsetfuns.pl → testsetfuns.t}
  36. 0 test/{testsidefx.pl → testsidefx.t}
  37. 0 test/{testsort.pl → testsort.t}
  38. 0 test/{testsoundex.pl → testsoundex.t}
  39. 0 test/{teststringsecs.pl → teststringsecs.t}
  40. 0 test/{teststrreplace.pl → teststrreplace.t}
  41. 0 test/{testtime.pl → testtime.t}
  42. 0 test/{testtr.pl → testtr.t}
  43. 0 test/{testtrim.pl → testtrim.t}
  44. +86 −0 utils/mkcmds.pl
@@ -49,9 +49,9 @@ config.h: configure
@echo "to suppress this message and continue compiling."
@exit 1
autogen: hdrs/cmds.h hdrs/funs.h hdrs/switches.h hdrs/gitinfo.h
autogen: hdrs/cmds.h hdrs/funs.h hdrs/switches.h hdrs/gitinfo.h src/tests.inc
hdrs/cmds.h: src/cmds.c src/command.c src/cque.c src/help.c src/set.c src/sql.c Patchlevel
hdrs/cmds.h: src/cmds.c src/command.c src/cque.c src/extchat.c src/help.c src/set.c src/sql.c Patchlevel
@PERL@ utils/mkcmds.pl commands
hdrs/switches.h: src/SWITCHES Patchlevel
@@ -63,6 +63,9 @@ src/switchinc.c: src/SWITCHES Patchlevel
hdrs/funs.h: src/fun*.c src/bsd.c src/conf.c src/connlog.c src/extmail.c src/help.c src/markup.c src/wiz.c src/sql.c Patchlevel src/cque.c
@PERL@ utils/mkcmds.pl functions
src/tests.inc: src/*.c
@PERL@ utils/mkcmds.pl tests
hdrs/gitinfo.h: $(wildcard .git/HEAD .git/index)
@if [ -f ".git/HEAD" ]; then \
echo "#define GIT_REVISION \"$(shell git rev-parse --short HEAD)\"" > $@; \
@@ -0,0 +1,21 @@
/** \file tests.h
*
* \brief Headers to support hardcode test framework.
*/
#pragma once
#include "log.h"
#define TEST_GROUP(name) void test_##name (int *success, int *failure)
#define TEST(name, t) \
do { \
if (t) { \
*success += 1; \
} else { \
*failure += 1; \
do_rawlog(LT_TRACE, "%s:%d: Test %s failed!", __FILE__, __LINE__, name); \
} \
} while (0)
bool run_tests(void);
@@ -29,9 +29,9 @@ C_FILES=access.c atr_tab.c attrib.c boolexp.c bsd.c bufferq.c \
pcg_basic.c player.c plyrlist.c predicat.c privtab.c \
info_master.c ptab.c remember.c rob.c services.c set.c sig.c \
sort.c speech.c spellfix.c sql.c sqlite3.c ssl_master.c \
strdup.c strtree.c strutil.c tables.c timer.c tz.c unparse.c \
utf_impl.c utils.c version.c wait.c warnings.c websock.c \
wild.c wiz.c
strdup.c strtree.c strutil.c tables.c testframework.c timer.c \
tz.c unparse.c utf_impl.c utils.c version.c wait.c warnings.c \
websock.c wild.c wiz.c
# .o versions of above - these are used in the build
@@ -47,9 +47,9 @@ O_FILES=access.o atr_tab.o attrib.o boolexp.o bsd.o bufferq.o \
pcg_basic.o player.o plyrlist.o predicat.o privtab.o \
info_master.o ptab.o remember.o rob.o services.o set.o sig.o \
sort.o speech.o spellfix.o sql.o sqlite3.o ssl_master.o \
strdup.o strtree.o strutil.o tables.o timer.o tz.o unparse.o \
utf_impl.o utils.o version.o wait.o warnings.o websock.o \
wild.o wiz.o
strdup.o strtree.o strutil.o tables.o testframework.o timer.o \
tz.o unparse.o utf_impl.o utils.o version.o wait.o warnings.o \
websock.o wild.o wiz.o
# This is a dummy target, in case you type 'make' in the source
# directory (likely for emacs users who M-x compile.)
@@ -375,6 +375,9 @@ bsd.o: ../hdrs/charconv.h
bsd.o: ../hdrs/myutf8.h
bsd.o: ../hdrs/connlog.h
bsd.o: ../hdrs/charclass.h
bsd.o: ../hdrs/memcheck.h
bsd.o: ../hdrs/map_file.h
bsd.o: ../hdrs/tests.h
bsd.o: ../hdrs/wait.h
bsd.o: ../hdrs/lookup.h
bsd.o: ../hdrs/ssl_slave.h
@@ -448,7 +451,6 @@ cmdlocal.o: ../config.h
cmdlocal.o: ../confmagic.h
cmdlocal.o: ../options.h
cmdlocal.o: ../hdrs/copyrite.h
cmdlocal.o: ../config.h
cmdlocal.o: ../hdrs/cmds.h
cmdlocal.o: ../hdrs/command.h
cmdlocal.o: ../hdrs/boolexp.h
@@ -469,7 +471,6 @@ cmdlocal.o: ../hdrs/mypcre.h
cmdlocal.o: ../hdrs/parse.h
cmdlocal.o: ../hdrs/mushsql.h
cmdlocal.o: ../hdrs/sqlite3.h
cmdlocal.o: ../confmagic.h
cmds.o: ../config.h
cmds.o: ../confmagic.h
cmds.o: ../options.h
@@ -882,7 +883,6 @@ flaglocal.o: ../config.h
flaglocal.o: ../confmagic.h
flaglocal.o: ../options.h
flaglocal.o: ../hdrs/copyrite.h
flaglocal.o: ../config.h
flaglocal.o: ../hdrs/conf.h
flaglocal.o: ../hdrs/htab.h
flaglocal.o: ../hdrs/mushtype.h
@@ -896,7 +896,6 @@ flaglocal.o: ../hdrs/dbio.h
flaglocal.o: ../hdrs/ptab.h
flaglocal.o: ../hdrs/chunk.h
flaglocal.o: ../hdrs/mypcre.h
flaglocal.o: ../confmagic.h
flags.o: ../config.h
flags.o: ../confmagic.h
flags.o: ../options.h
@@ -1110,7 +1109,6 @@ funlocal.o: ../config.h
funlocal.o: ../confmagic.h
funlocal.o: ../options.h
funlocal.o: ../hdrs/copyrite.h
funlocal.o: ../config.h
funlocal.o: ../hdrs/conf.h
funlocal.o: ../hdrs/htab.h
funlocal.o: ../hdrs/mushtype.h
@@ -1128,7 +1126,6 @@ funlocal.o: ../hdrs/function.h
funlocal.o: ../hdrs/parse.h
funlocal.o: ../hdrs/mushsql.h
funlocal.o: ../hdrs/sqlite3.h
funlocal.o: ../confmagic.h
funmath.o: ../config.h
funmath.o: ../confmagic.h
funmath.o: ../options.h
@@ -1409,7 +1406,6 @@ local.o: ../config.h
local.o: ../confmagic.h
local.o: ../options.h
local.o: ../hdrs/copyrite.h
local.o: ../config.h
local.o: ../hdrs/command.h
local.o: ../hdrs/boolexp.h
local.o: ../hdrs/chunk.h
@@ -1432,7 +1428,6 @@ local.o: ../hdrs/lock.h
local.o: ../hdrs/parse.h
local.o: ../hdrs/mushsql.h
local.o: ../hdrs/sqlite3.h
local.o: ../confmagic.h
lock.o: ../config.h
lock.o: ../confmagic.h
lock.o: ../options.h
@@ -1594,10 +1589,10 @@ markup.o: ../hdrs/parse.h
markup.o: ../hdrs/mushsql.h
markup.o: ../hdrs/sqlite3.h
markup.o: ../hdrs/pueblo.h
markup.o: ../hdrs/map_file.h
markup.o: ../hdrs/strutil.h
markup.o: ../hdrs/charconv.h
markup.o: ../hdrs/myutf8.h
markup.o: ../hdrs/map_file.h
markup.o: htmltab.c
match.o: ../config.h
match.o: ../confmagic.h
@@ -1836,6 +1831,7 @@ parse.o: ../hdrs/memcheck.h
parse.o: ../hdrs/mymalloc.h
parse.o: ../hdrs/notify.h
parse.o: ../hdrs/strutil.h
parse.o: ../hdrs/tests.h
pcg_basic.o: ../config.h
pcg_basic.o: ../confmagic.h
pcg_basic.o: ../options.h
@@ -2230,6 +2226,17 @@ strutil.o: ../hdrs/charclass.h
tables.o: ../config.h
tables.o: ../confmagic.h
tables.o: ../options.h
testframework.o: ../config.h
testframework.o: ../confmagic.h
testframework.o: ../options.h
testframework.o: ../hdrs/sqlite3.h
testframework.o: ../hdrs/tests.h
testframework.o: ../hdrs/log.h
testframework.o: ../hdrs/bufferq.h
testframework.o: ../hdrs/mushtype.h
testframework.o: ../hdrs/copyrite.h
testframework.o: ../hdrs/cJSON.h
testframework.o: tests.inc
timer.o: ../config.h
timer.o: ../confmagic.h
timer.o: ../options.h
@@ -2428,6 +2435,8 @@ websock.o: ../hdrs/sqlite3.h
websock.o: ../confmagic.h
websock.o: ../hdrs/strutil.h
websock.o: ../hdrs/notify.h
websock.o: ../hdrs/mymalloc.h
websock.o: ../hdrs/connlog.h
websock.o: ../hdrs/websock.h
websock.o: ../hdrs/function.h
wild.o: ../config.h
@@ -111,6 +111,7 @@
#include "cJSON.h"
#include "memcheck.h"
#include "map_file.h"
#include "tests.h"
#include "websock.h"
#ifndef WIN32
@@ -497,6 +498,7 @@ main(int argc, char **argv)
{
FILE *newerr;
bool detach_session __attribute__((__unused__)) = 1;
bool enable_tests = 0, only_test = 0;
/* disallow running as root on unix.
* This is done as early as possible, before translation is initialized.
@@ -564,8 +566,15 @@ main(int argc, char **argv)
}
} else if (strcmp(argv[n], "--no-pcre-jit") == 0) {
pcre_study_flags = 0;
} else
} else if (strcmp(argv[n], "--tests") == 0) {
enable_tests = 1;
} else if (strcmp(argv[n], "--only-tests") == 0) {
enable_tests = 1;
only_test = 1;
detach_session = 0;
} else {
fprintf(stderr, "%s: unknown option \"%s\"\n", argv[0], argv[n]);
}
} else {
mush_strncpy(confname, argv[n], BUFFER_LEN);
break;
@@ -711,6 +720,18 @@ main(int argc, char **argv)
set_signals();
if (enable_tests) {
bool r = run_tests();
if (r) {
do_rawlog(LT_ERR, "Hardcode tests all passed!");
} else {
do_rawlog(LT_ERR, "Hardcode tests had failures!");
}
if (only_test || !r) {
exit(r ? 0 : 1);
}
}
#ifdef INFO_SLAVE
init_info_slave();
#endif
@@ -1071,13 +1092,13 @@ handle_curl_msg(CURLMsg *msg)
if (is_utf8) {
latin1 = utf8_to_latin1(body, body_size, &len, 1, "string");
if (len >= BUFFER_LEN) {
resp->too_big = 1;
resp->too_big = 1;
latin1[BUFFER_LEN - 1] = '\0';
}
} else {
latin1 = body;
if (body_size >= BUFFER_LEN) {
resp->too_big = 1;
resp->too_big = 1;
body[BUFFER_LEN - 1] = '\0';
}
}
@@ -1114,7 +1135,7 @@ handle_curl_msg(CURLMsg *msg)
static int
check_status()
{
/* Check signal handler flags */
/* Check signal handler flags */
#ifndef WIN32
if (dump_error) {
if (WIFSIGNALED(dump_status)) {
@@ -1573,7 +1594,7 @@ gameloop()
struct timeval current_time;
while (!shutdown_flag) {
/** let's find out how long we should wait */
/** let's find out how long we should wait */
#define min_timeout(store, func) \
timeout_check = func; \
if (timeout_check < store) \
@@ -1696,13 +1717,13 @@ new_connection(int oldsock, int *result, conn_source source)
int remote_uid = -1;
bool good_to_read = 1;
/* As soon as the SSL slave opens a new connection to the mush, it
writes a string of the format 'IP^HOSTNAME\r\n'. This will thus
not block unless somebody's being naughty. People obviously can
be. So we'll wait a short time for readable data, and use a
non-blocking socket read anyways. If the client doesn't send
the hostname string fast enough, oh well.
*/
/* As soon as the SSL slave opens a new connection to the mush, it
writes a string of the format 'IP^HOSTNAME\r\n'. This will thus
not block unless somebody's being naughty. People obviously can
be. So we'll wait a short time for readable data, and use a
non-blocking socket read anyways. If the client doesn't send
the hostname string fast enough, oh well.
*/
#ifdef HAVE_POLL
{
@@ -1973,12 +1994,12 @@ fcache_read(FBLOCK *fb, const char *filename)
MAPPED_FILE *mf = map_file(filename, 0);
if (mf) {
/* Copy instead of using the mapped file directly because what
happens when a mapped file is edited, even if it's a private
map? There don't seem to be any promises. */
happens when a mapped file is edited, even if it's a private
map? There don't seem to be any promises. */
fb->buff = mush_malloc(mf->len + 1, "fcache_data");
if (!fb->buff) {
unmap_file(mf);
return -1;
unmap_file(mf);
return -1;
}
memcpy(fb->buff, mf->data, mf->len);
fb->buff[mf->len] = '\0';
@@ -2053,10 +2074,9 @@ fcache_load(dbref player)
who = fcache_read(&fcache.who_fcache[i], options.who_file[i]);
if (player != NOTHING) {
notify_format(player,
T("%s sizes: NewUser...%d Connect...%d "
"Guest...%d Motd...%d Wizmotd...%d Quit...%d "
"Register...%d Down...%d Full...%d Who...%d"),
notify_format(player, T("%s sizes: NewUser...%d Connect...%d "
"Guest...%d Motd...%d Wizmotd...%d Quit...%d "
"Register...%d Down...%d Full...%d Who...%d"),
i ? "HTMLFile" : "File", new, conn, guest, motd, wiz, quit,
reg, down, full, who);
}
@@ -3510,15 +3530,14 @@ http_bounce_mud_url(DESC *d)
char buf[BUFFER_LEN];
char *bp = buf;
bool has_url = strncmp(MUDURL, "http", 4) == 0;
safe_format(buf, &bp,
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset:iso-8859-1\r\n"
"Pragma: no-cache\r\n"
"Connection: Close\r\n"
"\r\n"
"<!DOCTYPE html>\r\n"
"<HTML><HEAD>"
"<TITLE>Welcome to %s!</TITLE>",
safe_format(buf, &bp, "HTTP/1.1 200 OK\r\n"
"Content-Type: text/html; charset:iso-8859-1\r\n"
"Pragma: no-cache\r\n"
"Connection: Close\r\n"
"\r\n"
"<!DOCTYPE html>\r\n"
"<HTML><HEAD>"
"<TITLE>Welcome to %s!</TITLE>",
MUDNAME);
if (has_url) {
safe_format(buf, &bp, "<meta http-equiv=\"refresh\" content=\"5; url=%s\">",
@@ -3766,7 +3785,7 @@ process_http_input(DESC *d, char *buf, int len)
break;
}
/* Reset the timer, but only if there is one. */
/* Reset the timer, but only if there is one. */
waitmore:
d->conn_timer = sq_register_in(2, http_finished_wrapper, (void *) d, NULL);
}
@@ -4400,9 +4419,8 @@ check_connect(DESC *d, const char *msg)
}
if (!options.create_allow) {
fcache_dump(d, fcache.register_fcache, NULL, NULL);
do_rawlog(LT_CONN,
"Refused registration (creation disabled) for %s from "
"%s on descriptor %d.\n",
do_rawlog(LT_CONN, "Refused registration (creation disabled) for %s from "
"%s on descriptor %d.\n",
user, d->addr, d->descriptor);
queue_event(SYSEVENT, "SOCKET`CREATEFAIL", "%d,%s,%d,%s,%s",
d->descriptor, d->ip, mark_failed(d->ip),
@@ -7657,9 +7675,8 @@ file_watch_event_in(int fd)
do_rawlog(LT_TRACE, "Reindexing help file %s.", file);
WATCH(file);
} else {
do_rawlog(LT_ERR,
"Got status change for file '%s' but I don't "
"know what to do with it! Mask 0x%x",
do_rawlog(LT_ERR, "Got status change for file '%s' but I don't "
"know what to do with it! Mask 0x%x",
file, ev->mask);
}
lastwd = ev->wd;
Oops, something went wrong.

0 comments on commit 0a0a9ad

Please sign in to comment.