Commit ee4a263c authored by Rusty Russell's avatar Rusty Russell

Turned libtap into a proper ccan package.

Fixed up ccan_tools dir, not other package's tests.
parent 36ef9b2c
ccan_tools/run_tests: ccan_tools/run_tests.o ccan_tools/libtap/src/tap.o ccan_tools/talloc/talloc.o
ccan_tools/run_tests: ccan_tools/run_tests.o tap/tap.o ccan_tools/talloc/talloc.o
ccan_tools/doc_extract: ccan_tools/doc_extract.c ccan_tools/talloc/talloc.o
ccan_tools/libtap/src/tap.o:
cd ccan_tools/libtap && ./configure && make
ccan_tools/talloc/talloc.o:
cd ccan_tools/talloc && ./configure && make
......@@ -12,5 +9,4 @@ ccan_tools/namespacize: ccan_tools/namespacize.c ccan_tools/talloc/talloc.o
ccan_tools-clean:
rm -f run_tests doc_extract
@cd ccan_tools/libtap && make clean
@cd ccan_tools/talloc && make clean
......@@ -4,11 +4,11 @@
#include <dirent.h>
#include <assert.h>
#include <unistd.h>
#include "libtap/src/tap.h"
#include "tap/tap.h"
#include "talloc/talloc.h"
#include "../string/string.h"
#define CFLAGS "-O3 -Wall -Wundef -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Werror -I. -Iccan_tools/libtap/src/"
#define CFLAGS "-O3 -Wall -Wundef -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Werror -I."
/* FIXME: Use build bug later. */
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
......@@ -56,7 +56,7 @@ static char *obj_list(void)
list = talloc_asprintf_append(list, "%s ", i->name);
/* FIXME */
list = talloc_asprintf_append(list, "ccan_tools/libtap/src/tap.o");
list = talloc_asprintf_append(list, "tap/tap.o");
return list;
}
......
#include <stdio.h>
#include <string.h>
#include "config.h"
/**
* tap - Test Anything Protocol
*
* The tap package produces simple-to-parse mainly-human-readable test
* output to assist in the writing of test cases. It is based on the
* (now-defunct) libtap, which is based on Perl's CPAN TAP module. Its
* output can be parsed by a harness such as CPAN's Prove.
*
* CCAN testcases are expected to output the TAP format, usually using
* this package.
*
* For more information about TAP, see:
* http://en.wikipedia.org/wiki/Test_Anything_Protocol
*
* Based on the original libtap, Copyright (c) 2004 Nik Clayton.
*
* Example:
* #include <string.h>
* #include "tap/tap.h"
*
* // Run some simple (but overly chatty) tests on strcmp().
* int main(int argc, char *argv[])
* {
* const char a[] = "a", another_a[] = "a";
* const char b[] = "b";
* const char ab[] = "ab";
*
* plan_tests(4);
* diag("Testing different pointers (%p/%p) with same contents",
* a, another_a);
* ok1(strcmp(a, another_a) == 0);
*
* diag("'a' comes before 'b'");
* ok1(strcmp(a, b) < 0);
* ok1(strcmp(b, a) > 0);
*
* diag("'ab' comes after 'a'");
* ok1(strcmp(ab, a) > 0);
* return exit_status();
* }
*/
int main(int argc, char *argv[])
{
if (argc != 2)
return 1;
if (strcmp(argv[1], "depends") == 0)
return 0;
if (strcmp(argv[1], "license") == 0)
return "BSD";
return 1;
}
......@@ -357,7 +357,7 @@ skip(unsigned int n, char *fmt, ...)
LOCK;
va_start(ap, fmt);
asprintf(&skip_msg, fmt, ap);
vasprintf(&skip_msg, fmt, ap);
va_end(ap);
while(n-- > 0) {
......
......@@ -24,23 +24,85 @@
* SUCH DAMAGE.
*/
/**
* plan_tests - announce the number of tests you plan to run
* @tests: the number of tests
*
* This should be the first call in your test program: it allows tracing
* of failures which mean that not all tests are run.
*
* If you don't know how many tests will actually be run, assume all of them
* and use skip() if you don't actually run some tests.
*
* Example:
* plan_tests(13);
*/
void plan_tests(unsigned int tests);
#if (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) && !defined(__GNUC__)
# error "Needs gcc or C99 compiler for variadic macros."
#else
/**
* ok1 - Simple conditional test
* @e: the expression which we expect to be true.
*
* This is the simplest kind of test: if the expression is true, the
* test passes. The name of the test which is printed will simply be
* file name, line number, and the expression itself.
*
* Example:
* ok1(init_subsystem() == 1);
*/
# define ok1(e) ((e) ? \
_gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : \
_gen_result(0, __func__, __FILE__, __LINE__, "%s", #e))
/**
* ok - Conditional test with a name
* @e: the expression which we expect to be true.
* @...: the printf-style name of the test.
*
* If the expression is true, the test passes. The name of the test will be
* the filename, line number, and the printf-style string. This can be clearer
* than simply the expression itself.
*
* Example:
* ok1(init_subsystem() == 1);
* ok(init_subsystem() == 0, "Second initialization should fail");
*/
# define ok(e, ...) ((e) ? \
_gen_result(1, __func__, __FILE__, __LINE__, \
__VA_ARGS__) : \
_gen_result(0, __func__, __FILE__, __LINE__, \
__VA_ARGS__))
# define ok1(e) ((e) ? \
_gen_result(1, __func__, __FILE__, __LINE__, "%s", #e) : \
_gen_result(0, __func__, __FILE__, __LINE__, "%s", #e))
/**
* pass - Note that a test passed
* @...: the printf-style name of the test.
*
* For complicated code paths, it can be easiest to simply call pass() in one
* branch and fail() in another.
*
* Example:
* x = do_something();
* if (!checkable(x) || check_value(x))
* pass("do_something() returned a valid value");
* else
* fail("do_something() returned an invalid value");
*/
# define pass(...) ok(1, __VA_ARGS__)
/**
* fail - Note that a test failed
* @...: the printf-style name of the test.
*
* For complicated code paths, it can be easiest to simply call pass() in one
* branch and fail() in another.
*/
# define fail(...) ok(0, __VA_ARGS__)
/* I don't find these to be useful. */
# define skip_if(cond, n, ...) \
if (cond) skip((n), __VA_ARGS__); \
else
......@@ -65,16 +127,120 @@
unsigned int _gen_result(int, const char *, char *, unsigned int, char *, ...)
PRINTF_ATTRIBUTE(5, 6);
void plan_no_plan(void);
void plan_skip_all(char *);
void plan_tests(unsigned int);
/**
* diag - print a diagnostic message (use instead of printf/fprintf)
* @fmt: the format of the printf-style message
*
* diag ensures that the output will not be considered to be a test
* result by the TAP test harness. It will append '\n' for you.
*
* Example:
* diag("Now running complex tests");
*/
void diag(char *fmt, ...) PRINTF_ATTRIBUTE(1, 2);
void diag(char *, ...) PRINTF_ATTRIBUTE(1, 2);
/**
* skip - print a diagnostic message (use instead of printf/fprintf)
* @n: number of tests you're skipping.
* @fmt: the format of the reason you're skipping the tests.
*
* Sometimes tests cannot be run because the test system lacks some feature:
* you should explicitly document that you're skipping tests using skip().
*
* From the Test::More documentation:
* If it's something the user might not be able to do, use SKIP. This
* includes optional modules that aren't installed, running under an OS that
* doesn't have some feature (like fork() or symlinks), or maybe you need an
* Internet connection and one isn't available.
*
* Example:
* #ifdef HAVE_SOME_FEATURE
* ok1(test_some_feature());
* #else
* skip(1, "Don't have SOME_FEATURE");
* #endif
*/
void skip(unsigned int n, char *fmt, ...) PRINTF_ATTRIBUTE(2, 3);
void skip(unsigned int, char *, ...) PRINTF_ATTRIBUTE(2, 3);
/**
* todo_start - mark tests that you expect to fail.
* @fmt: the reason they currently fail.
*
* It's extremely useful to write tests before you implement the matching fix
* or features: surround these tests by todo_start()/todo_end(). These tests
* will still be run, but with additional output that indicates that they are
* expected to fail.
*
* This way, should a test start to succeed unexpectedly, tools like prove(1)
* will indicate this and you can move the test out of the todo block. This
* is much more useful than simply commenting out (or '#if 0') the tests.
*
* From the Test::More documentation:
* If it's something the programmer hasn't done yet, use TODO. This is for
* any code you haven't written yet, or bugs you have yet to fix, but want to
* put tests in your testing script (always a good idea).
*
* Example:
* todo_start("dwim() not returning true yet");
* ok(dwim(), "Did what the user wanted");
* todo_end();
*/
void todo_start(char *fmt, ...) PRINTF_ATTRIBUTE(1, 2);
void todo_start(char *, ...) PRINTF_ATTRIBUTE(1, 2);
/**
* todo_end - end of tests you expect to fail.
*
* See todo_start().
*/
void todo_end(void);
/**
* exit_status - the value that main should return.
*
* For maximum compatability your test program should return a particular exit
* code (ie. 0 if all tests were run, and every test which was expected to
* succeed succeeded).
*
* Example:
* exit(exit_status());
*/
int exit_status(void);
/**
* plan_no_plan - I have no idea how many tests I'm going to run.
*
* In some situations you may not know how many tests you will be running, or
* you are developing your test program, and do not want to update the
* plan_tests() call every time you make a change. For those situations use
* plan_no_plan() instead of plan_tests(). It indicates to the test harness
* that an indeterminate number of tests will be run.
*
* Remember, if you fail to plan, you plan to fail.
*
* Example:
* plan_no_plan();
* while (random() % 2)
* ok1(some_test());
* exit(exit_status());
*/
void plan_no_plan(void);
/**
* plan_skip_all - Indicate that you will skip all tests.
* @reason: the string indicating why you can't run any tests.
*
* If your test program detects at run time that some required functionality
* is missing (for example, it relies on a database connection which is not
* present, or a particular configuration option that has not been included
* in the running kernel) use plan_skip_all() instead of plan_tests().
*
* Example:
* if (!have_some_feature) {
* plan_skip_all("Need some_feature support");
* exit(exit_status());
* }
* plan_tests(13);
*/
void plan_skip_all(char *reason);
#endif /* C99 or gcc */
/* We use the fact that pipes have a buffer greater than the size of
* any output, and change stdout and stderr to use that.
*
* Since we don't use libtap for output, this looks like one big test. */
#include "tap/tap.h"
#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <err.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <stdbool.h>
/* We dup stderr to here. */
static int stderrfd;
/* Simple replacement for err() */
static void failmsg(const char *fmt, ...)
{
char buf[1024];
va_list ap;
/* Write into buffer. */
va_start(ap, fmt);
vsprintf(buf, fmt, ap);
va_end(ap);
write(stderrfd, "# ", 2);
write(stderrfd, buf, strlen(buf));
write(stderrfd, "\n", 1);
_exit(1);
}
static void expect(int fd, const char *str)
{
char buffer[PIPE_BUF];
int r;
r = read(fd, buffer, sizeof(buffer));
if (r < 0)
failmsg("reading from pipe");
if (strlen(str) != r || strncmp(str, buffer, r) != 0)
failmsg("Expected '%s' got '%.*s'",
str, r, buffer);
}
int main(int argc, char *argv[])
{
int p[2];
int stdoutfd;
printf("1..1\n");
stderrfd = dup(STDERR_FILENO);
if (stderrfd < 0)
err(1, "dup of stderr failed");
stdoutfd = dup(STDOUT_FILENO);
if (stdoutfd < 0)
err(1, "dup of stdout failed");
if (pipe(p) != 0)
failmsg("pipe failed");
if (dup2(p[1], STDERR_FILENO) < 0 || dup2(p[1], STDOUT_FILENO) < 0)
failmsg("Duplicating file descriptor");
plan_tests(10);
expect(p[0], "1..10\n");
ok(1, "msg1");
expect(p[0], "ok 1 - msg1\n");
ok(0, "msg2");
expect(p[0], "not ok 2 - msg2\n"
"# Failed test (tap/test/run.c:main() at line 75)\n");
ok1(true);
expect(p[0], "ok 3 - true\n");
ok1(false);
expect(p[0], "not ok 4 - false\n"
"# Failed test (tap/test/run.c:main() at line 82)\n");
pass("passed");
expect(p[0], "ok 5 - passed\n");
fail("failed");
expect(p[0], "not ok 6 - failed\n"
"# Failed test (tap/test/run.c:main() at line 89)\n");
skip(2, "skipping %s", "test");
expect(p[0], "ok 7 # skip skipping test\n"
"ok 8 # skip skipping test\n");
todo_start("todo");
ok1(false);
expect(p[0], "not ok 9 - false # TODO todo\n"
"# Failed (TODO) test (tap/test/run.c:main() at line 98)\n");
ok1(true);
expect(p[0], "ok 10 - true # TODO todo\n");
todo_end();
if (exit_status() != 3)
failmsg("Expected exit status 3, not %i", exit_status());
#if 0
/* Manually run the atexit command. */
_cleanup();
expect(p[0], "# Looks like you failed 2 tests of 9.\n");
#endif
write(stdoutfd, "ok 1 - All passed\n", strlen("ok 1 - All passed\n"));
_exit(0);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment