# # # delete "debian/monotone-server.examples" # # add_file "contrib/dump-test-logs.sh" # content [e8c725862bb8e18a11c8b93155fea908251d3c17] # # add_file "debian/monotone-doc.doc-base" # content [8cca0bd4a32e4e65142af055fbd38f299eed8e84] # # add_file "unix/tester-check-net.c" # content [bb758c2b16c6a1978a5a96f4ddd204b6feac6e37] # # add_file "win32/tester-check-net.c" # content [939b4453fe11bc0e1883797f0052ca45f760ea1a] # # patch "Makefile.am" # from [4bd4212a2e021abffa9f0151375e47988fd0c7ce] # to [8fa723cf98f3f341801888e7f0dab6fcac38525c] # # patch "debian/changelog" # from [2679ba3563d26623e72ee5a61a47d048ff3c4826] # to [25d7bfcd00f317192f6b04327b98b2c4658c826e] # # patch "debian/control" # from [62318b78abab9543f3cbc183c190230e499bb5f9] # to [73ee7b2329440674ddd9cf8100c08676e91a3ed2] # # patch "debian/monotone-doc.dirs" # from [87882a2689244f9c7380a9c320c595e52c0f3b02] # to [f6173411af16a69abba3fe7572866591c6121b23] # # patch "debian/monotone-doc.docs" # from [234795010ef0166d4bba978034cc12b2f2459373] # to [befa0a5aa8814a3a456423e6fa384348e9660721] # # patch "debian/monotone-server.dirs" # from [03976bb511b4f98e04b46ba38be3cd756a4cfd00] # to [f375fd99eb1d2d4d378db7e40a9cf0fe97ee11b6] # # patch "debian/rules" # from [0bd97c7aaece3021a5522460346ad25a8abc8bb4] # to [718c858ea1aedd36fdb162524688cb90225a09a3] # # patch "lua-testsuite.lua" # from [8254404e53c3ad822023d7d80b059519e2694eba] # to [0e0e38f25d6d9e4d063352806d82f85d0f97380f] # # patch "tests/common/netsync.lua" # from [3e28b68bf122aefa0f55f5d3dfb80338f55bba2b] # to [3740674f76b3efe676df404047e219b604bc3be5] # ============================================================ --- contrib/dump-test-logs.sh e8c725862bb8e18a11c8b93155fea908251d3c17 +++ contrib/dump-test-logs.sh e8c725862bb8e18a11c8b93155fea908251d3c17 @@ -0,0 +1,43 @@ +#! /bin/sh + +# Dump the detailed logs for all tests with an unexpected outcome to +# stdout. This is intended for use in super-automated build +# environments, e.g. the Debian build daemons, where the easiest way +# to recover detailed test logs for a failed build is to embed them in +# the overall 'make' output. Run, with no arguments, from the top +# level of a monotone build tree. + +set -e +cd tester_dir + +dumped=0 +for log in */*/tester.log +do + label=${log%/tester.log} + status=${log%/tester.log}/STATUS + + if [ -f "$status" ]; then + shorttag=$(cat "$status") + case "$shorttag" in + ok | skipped* | expected\ failure* | partial\ skip ) + continue ;; + esac + else + shorttag="no status file" + fi + + if [ $dumped -eq 0 ]; then + echo "### Detailed test logs:" + dumped=1 + fi + echo "### $label $shorttag" + cat "$log" +done + +# Exit unsuccessfully if we dumped anything, so that a driver Makefile +# can do something like +# +# make check || sh dump-test-logs.sh +# +# and have that fail the build just like plain "make check" would. +exit $dumped ============================================================ --- debian/monotone-doc.doc-base 8cca0bd4a32e4e65142af055fbd38f299eed8e84 +++ debian/monotone-doc.doc-base 8cca0bd4a32e4e65142af055fbd38f299eed8e84 @@ -0,0 +1,20 @@ +Document: monotone-manual +Title: Monotone version control system manual +Author: Graydon Hoare et al +Abstract: This manual documents the Monotone distributed version control + system. It includes a basic tutorial, several use examples, and + a detailed reference. +Section: Programming + +Format: HTML +Index: /usr/share/doc/monotone/html/index.html +Files: /usr/share/doc/monotone/html/*.html + /usr/share/doc/monotone/html/*.css + /usr/share/doc/monotone/html/figures/*.png + +Format: PDF +Files: /usr/share/doc/monotone/monotone.pdf + +Format: Info +Index: /usr/share/info/monotone.info.gz +Files: /usr/share/info/monotone.info*.gz ============================================================ --- unix/tester-check-net.c bb758c2b16c6a1978a5a96f4ddd204b6feac6e37 +++ unix/tester-check-net.c bb758c2b16c6a1978a5a96f4ddd204b6feac6e37 @@ -0,0 +1,283 @@ +/* Copyright (C) 2008 Zack Weinberg + + This program is made available under the GNU GPL version 2.0 or + greater. See the accompanying file COPYING for details. + + This program is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. */ + +/* The test suite runs this program to decide whether or not to include + network tests. It determines whether it is possible to create a + listening socket on a randomly chosen port on the loopback interface, + connect to that socket from another process, and ping-pong a byte. + + Will exit successfully, with no output, if everything works; otherwise, + will exit unsuccessfully and produce diagnostics on stderr. */ + +#include "config.h" +#if defined HAVE_SOCKET && defined HAVE_NETINET_IN_H + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +static int synchronizer[2]; +static const char *who; +static unsigned short port; + +static void sigalrm(int unused) +{ + fprintf(stderr, "%s: timeout\n", who); + exit(1); +} + +static void prep_timeout(const char *w) +{ + who = w; + signal(SIGALRM, sigalrm); + alarm(5); +} + +/* "b_or_c" should be either "bind" or "connect". Conveniently, they have + the same signature. */ +static int get_socket(int (*b_or_c)(int, const struct sockaddr *, socklen_t)) +{ + int sfd; + + /* try IPv4 first */ + { + struct sockaddr_in sin; + memset(&sin, 0, sizeof sin); + sin.sin_family = AF_INET; + sin.sin_port = htons(port); + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + sfd = socket(PF_INET, SOCK_STREAM, 0); + if (sfd >= 0) + { + if (b_or_c(sfd, (struct sockaddr *)&sin, sizeof sin) == 0) + return sfd; + close(sfd); + } + } + + /* if that didn't work, and we have library support for it, try IPv6 too */ +#ifdef AF_INET6 + { + struct sockaddr_in6 sin6; + memset(&sin6, 0, sizeof sin6); + sin6.sin6_family = AF_INET6; + sin6.sin6_port = htons(port); + sin6.sin6_addr = in6addr_loopback; + + sfd = socket(PF_INET6, SOCK_STREAM, 0); + if (sfd >= 0) + { + if (b_or_c(sfd, (struct sockaddr *)&sin6, sizeof sin6) == 0) + return sfd; + close(sfd); + } + } +#endif + + fprintf(stderr, "socket/connect/bind: %s\n", strerror(errno)); + return -1; +} + +static int server(void) +{ + int sfd, cfd, n; + char buf; + + prep_timeout("server"); + + sfd = get_socket(bind); + if (sfd < 0) + return 1; + + if (listen(sfd, 1)) + { + fprintf(stderr, "server: listen: %s\n", strerror(errno)); + close(sfd); + return 1; + } + + /* Client process may proceed. */ + n = write(synchronizer[1], "x", 1); + if (n != 1) + { + fprintf(stderr, "server: semaphore write: %s\n", + n == 0 ? "unexpected EOF" : strerror(errno)); + close(sfd); + return 1; + } + + cfd = accept(sfd, 0, 0); /* don't care _who_ connects */ + if (cfd < 0) + { + fprintf(stderr, "server: accept: %s\n", strerror(errno)); + close(sfd); + return 1; + } + + n = read(cfd, &buf, 1); + if (n != 1) + { + fprintf(stderr, "server: socket read: %s\n", + n == 0 ? "unexpected EOF" : strerror(errno)); + close(cfd); + close(sfd); + return 1; + } + if (buf != 'x') + { + fprintf(stderr, "server: socket read: got '%c' exp 'x'\n", buf); + close(cfd); + close(sfd); + return 1; + } + n = write(cfd, "x", 1); + if (n != 1) + { + fprintf(stderr, "server: socket write: %s\n", + n == 0 ? "unexpected EOF" : strerror(errno)); + close(cfd); + close(sfd); + return 1; + } + + close(cfd); + close(sfd); + return 0; +} + +static int client(void) +{ + int sfd, n; + char buf; + + prep_timeout("client"); + + /* wait for server setup */ + n = read(synchronizer[0], &buf, 1); + if (n != 1) + { + fprintf(stderr, "client: semaphore read: %s\n", + n == 0 ? "unexpected EOF" : strerror(errno)); + return 1; + } + + sfd = get_socket(connect); + if (sfd < 0) + return 1; + + n = write(sfd, "x", 1); + if (n != 1) + { + fprintf(stderr, "client: socket write: %s\n", + n == 0 ? "unexpected EOF" : strerror(errno)); + close(sfd); + return 1; + } + + n = read(sfd, &buf, 1); + if (n != 1) + { + fprintf(stderr, "client: socket read: %s\n", + n == 0 ? "unexpected EOF" : strerror(errno)); + close(sfd); + return 1; + } + if (buf != 'x') + { + fprintf(stderr, "client: socket read: got '%c' exp 'x'\n", buf); + close(sfd); + return 1; + } + + close(sfd); + return 0; +} + +int main(void) +{ + pid_t child, p; + int status; + + /* Pick a random port in the high half of the range, thus + unlikely to be used for anything. */ + srand(time(0)); + do + { + port = rand(); + } + while (port < 32767); + + if (pipe(synchronizer)) + { + fprintf(stderr, "setup: pipe: %s\n", strerror(errno)); + return 2; + } + + child = fork(); + if (child < 0) + { + fprintf(stderr, "setup: fork: %s\n", strerror(errno)); + return 2; + } + + if (child == 0) + return client(); + + if (server()) + return 1; + + p = wait(&status); + if (p < 0) + { + fprintf(stderr, "teardown: wait: %s\n", strerror(errno)); + return 2; + } + if (p != child) + { + fprintf(stderr, "teardown: unexpected child %d != %d\n", p, child); + return 2; + } + if (!WIFEXITED(status)) + { + fprintf(stderr, "teardown: child crash, status %d\n", status); + return 2; + } + + return WEXITSTATUS(status); +} + +#else /* no socket, or no netinet/in.h */ + +int main(void) +{ + fprintf(stderr, "socket headers are missing, cannot test networking\n"); + return 1; +} + +#endif + +/* + Local Variables: + mode: C + fill-column: 76 + c-file-style: "gnu" + indent-tabs-mode: nil + End: + vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s: + */ ============================================================ --- win32/tester-check-net.c 939b4453fe11bc0e1883797f0052ca45f760ea1a +++ win32/tester-check-net.c 939b4453fe11bc0e1883797f0052ca45f760ea1a @@ -0,0 +1,6 @@ +/* Stub - needs implementing. See lua-testsuite.lua (very end) for rationale, + and unix/tester-check-net.c for behavior to emulate. */ +int main(void) +{ + return 0; +} ============================================================ --- Makefile.am 4bd4212a2e021abffa9f0151375e47988fd0c7ce +++ Makefile.am 8fa723cf98f3f341801888e7f0dab6fcac38525c @@ -452,11 +452,13 @@ if WIN32_PLATFORM lib3rdparty_a_CPPFLAGS += -DWIN32 lib3rdparty_a_SOURCES += botan/es_capi.cpp botan/es_win32.cpp tester_SOURCES += win32/tester-plaf.cc + check_net_SOURCES = win32/tester-check-net.c else libplatform_a_SOURCES += $(UNIX_PLATFORM_SOURCES) mtn_SOURCES += unix/main.cc lib3rdparty_a_SOURCES += botan/es_dev.cpp tester_SOURCES += unix/tester-plaf.cc + check_net_SOURCES = unix/tester-check-net.c endif if MISSING_INET_PTON @@ -646,9 +648,9 @@ run_%_tests: Makefile %_tests.status: run_%_tests %-testsuite.lua tester$(EXEEXT) FORCE +./run_$*_tests -unit_tests.status : unit_tester -lua_tests.status : mtn -check_PROGRAMS = unit_tester tester +unit_tests.status : unit_tester$(EXEEXT) +lua_tests.status : mtn$(EXEEXT) check_net$(EXEEXT) +check_PROGRAMS = unit_tester tester check_net # We want the tests re-run even if the .status files already exist. # .PHONY does not work for that (bad interaction with pattern rules), ============================================================ --- debian/changelog 2679ba3563d26623e72ee5a61a47d048ff3c4826 +++ debian/changelog 25d7bfcd00f317192f6b04327b98b2c4658c826e @@ -1,7 +1,25 @@ +monotone (0.40-2) unstable; urgency=low + + * Automatically skip all tests involving netsync if it is impossible + to use TCP on the loopback interface. (Closes: #474280) + * If the testsuite fails, dump the per-test logs for all failed + testcases into the main build log. + + * Install HTML documentation in /usr/share/doc/monotone/html, not + /usr/share/doc/html. (Closes: #480072) + * Make /usr/share/doc/monotone-server and /usr/share/doc/monotone-doc + symlinks to /usr/share/doc/monotone; do not ship any files in those + packages that are also in the main monotone package. This requires + adding a dependency of monotone-doc on monotone. + * Register monotone manual with doc-base. + * Improve description of monotone-doc package. + + -- Zack Weinberg Sun, 25 May 2008 00:10:11 -0400 + monotone (0.40-1) unstable; urgency=low [ Zack Weinberg ] - * New upstream release. + * New upstream release. (Closes: #482547) - Upstream "make distclean" now cleans up after "make html". (Closes: #473402) ============================================================ --- debian/control 62318b78abab9543f3cbc183c190230e499bb5f9 +++ debian/control 73ee7b2329440674ddd9cf8100c08676e91a3ed2 @@ -39,6 +39,14 @@ Architecture: all Package: monotone-doc Section: doc Architecture: all +Depends: monotone (>= ${source:Version}) Description: A distributed version (revision) control system - documentation + Monotone is a free, distributed version control system. It provides + fully disconnected operation, manages complete tree versions, keeps + its state in a local transactional database, supports overlapping + branches and extensible metadata, uses an efficient peer-to-peer + network protocol, performs history-sensitive merging, and delegates + trust functions to client-side RSA certificates. + . This package contains the documentation for monotone in Info, HTML, and PDF + formats. - formats. See the description of the package monotone for more details. ============================================================ --- debian/monotone-doc.dirs 87882a2689244f9c7380a9c320c595e52c0f3b02 +++ debian/monotone-doc.dirs f6173411af16a69abba3fe7572866591c6121b23 @@ -1 +1 @@ -usr/share/doc/html/figures +usr/share/doc/monotone/html/figures ============================================================ --- debian/monotone-doc.docs 234795010ef0166d4bba978034cc12b2f2459373 +++ debian/monotone-doc.docs befa0a5aa8814a3a456423e6fa384348e9660721 @@ -1,6 +1 @@ -AUTHORS -NEWS -README -README.changesets -UPGRADE monotone.pdf ============================================================ --- debian/monotone-server.dirs 03976bb511b4f98e04b46ba38be3cd756a4cfd00 +++ debian/monotone-server.dirs f375fd99eb1d2d4d378db7e40a9cf0fe97ee11b6 @@ -1,5 +1,6 @@ var/run/monotone var/lib/monotone var/lib/monotone/keys etc/monotone var/log/monotone var/run/monotone +usr/share/doc ============================================================ --- debian/rules 0bd97c7aaece3021a5522460346ad25a8abc8bb4 +++ debian/rules 718c858ea1aedd36fdb162524688cb90225a09a3 @@ -87,8 +87,8 @@ ifeq "$(findstring nocheck, $(DEB_BUILD_ make -j$(CPUS) -C po all make -j$(CPUS) mtn ifeq "$(findstring nocheck, $(DEB_BUILD_OPTIONS))" "" - make -j$(CPUS) unit_tester tester - make check-local + make -j$(CPUS) unit_tester tester check_net + make check-local || sh contrib/dump-test-logs.sh endif touch $@ @@ -107,24 +107,43 @@ clean: dh_clean # Build architecture-independent files here. -binary-indep: build-indep - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs -i +# +# Both monotone-server and monotone-doc are permitted to have their +# documentation directories be symlinks to the main package's +# documentation directory, per Policy 12.5. This means we should not +# run dh_installexamples or dh_installchangelogs for either, and should +# not run dh_installdocs for monotone-server. monotone-doc needs us +# to run dh_installdocs for monotone.pdf and doc-base support, but then +# needs a bunch of -X flags to avoid conflicting files. +# # The upstream makefiles' install targets do nothing useful for these # packages. (In particular, we do not want the monolithic # monotone.html installed.) Annoyingly, at present we cannot simply # dh_installdocs the entire html directory, because it contains a # bunch of unwanted junk; instead we dh_installdirs the directory -# hierarchy that is required and use cp -p to put all the files in place. - cp -p html/*.html html/*.css debian/monotone-doc/usr/share/doc/html - cp -p html/figures/*.png debian/monotone-doc/usr/share/doc/html/figures +# hierarchy that is required and use cp -p to put all the files in +# place. (Using globs in monotone-doc.docs would get everything dumped +# directly into /usr/share/doc/monotone, which doesn't work.) - dh_installchangelogs -i +binary-indep: build-indep + dh_testdir + dh_testroot + dh_clean -k + + dh_installdirs -i + cd debian/monotone-doc/usr/share/doc && \ + ln -s monotone monotone-doc + cd debian/monotone-server/usr/share/doc && \ + ln -s monotone monotone-server + + cp -p html/*.html html/*.css \ + debian/monotone-doc/usr/share/doc/monotone/html + cp -p html/figures/*.png \ + debian/monotone-doc/usr/share/doc/monotone/html/figures + dh_installdocs -p monotone-doc -X copyright -X NEWS + dh_installdebconf -i - dh_installdocs -i - dh_installexamples -i + # we should have logrotate support for monotone-server, but currently we don't # dh_installlogrotate -i --name=monotone dh_installinit -i --name=monotone ============================================================ --- lua-testsuite.lua 8254404e53c3ad822023d7d80b059519e2694eba +++ lua-testsuite.lua 0e0e38f25d6d9e4d063352806d82f85d0f97380f @@ -1,6 +1,7 @@ monotone_path = nil #!./tester monotone_path = nil +no_network_tests = false function safe_mtn(...) if monotone_path == nil then @@ -338,6 +339,36 @@ function prepare_to_run_tests (P) end unlogged_remove(d) + -- Several tests require the ability to run a network server on + -- the loopback interface, and connect to it from another process + -- on this computer. Unlike the above, we just skip those tests + -- (loudly) if we can't do that. Verifying that this is possible + -- requires a helper program. + + local checknet = getpathof("check_net") + if checknet ~= nil then + writefile_q("in", nil) + prepare_redirect("in", "out", "err") + local status = execute(checknet) + local out = readfile_q("out") + local err = readfile_q("err") + + if status == 0 and err == "" and out == "" then + logfile:write("check_net: Can use the loopback interface.\n") + else + logfile:write(string.format("check_net: failed with status %d\n".. + "stdout:\n%s\nstderr:\n%s\n", + status, out, err)) + P("warning: network unavailable, skipping network server tests\n") + no_network_tests = true + end + else + P("warning: check_net helper is missing, skipping network server tests\n") + no_network_tests = true + end + + -- Record the full version of monotone under test in the logfile. + monotone_path = getpathof("mtn") if monotone_path == nil then monotone_path = "mtn" end set_env("mtn", monotone_path) ============================================================ --- tests/common/netsync.lua 3e28b68bf122aefa0f55f5d3dfb80338f55bba2b +++ tests/common/netsync.lua 3740674f76b3efe676df404047e219b604bc3be5 @@ -1,3 +1,7 @@ +-- Conveniently, all network tests load this file, so this skip_if +-- suffices to skip all network tests if the network is unavailable +-- (see lua-testsuite.lua and [platform]/tester-check-net.c). +skip_if(no_network_tests) function mtn2(...) return mtn("--db=test2.db", "--keydir=keys2", unpack(arg))