qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Michael Roth <mdroth@linux.vnet.ibm.com>
To: qemu-devel@nongnu.org
Cc: aliguori@us.ibm.com, quintela@redhat.com, owasserm@redhat.com,
	yamahata@valinux.co.jp, pbonzini@redhat.com, akong@redhat.com,
	afaerber@suse.de
Subject: [Qemu-devel] [PATCH 19/22] qidl: unit tests
Date: Tue, 24 Jul 2012 12:20:51 -0500	[thread overview]
Message-ID: <1343150454-4677-20-git-send-email-mdroth@linux.vnet.ibm.com> (raw)
In-Reply-To: <1343150454-4677-1-git-send-email-mdroth@linux.vnet.ibm.com>


Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
---
 Makefile                   |    2 +
 rules.mak                  |   15 +++-
 tests/Makefile             |    8 +-
 tests/test-qidl-included.h |   31 ++++++++
 tests/test-qidl-linked.c   |   91 +++++++++++++++++++++++
 tests/test-qidl-linked.h   |   18 +++++
 tests/test-qidl.c          |  177 ++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 339 insertions(+), 3 deletions(-)
 create mode 100644 tests/test-qidl-included.h
 create mode 100644 tests/test-qidl-linked.c
 create mode 100644 tests/test-qidl-linked.h
 create mode 100644 tests/test-qidl.c

diff --git a/Makefile b/Makefile
index 82fc9f0..0711f14 100644
--- a/Makefile
+++ b/Makefile
@@ -232,6 +232,7 @@ clean:
 	if test -d $$d; then $(MAKE) -C $$d $@ || exit 1; fi; \
 	rm -f $$d/qemu-options.def; \
         done
+	find -depth -name qidl-generated -type d -exec rm -rf {} \;
 
 VERSION ?= $(shell cat VERSION)
 
@@ -402,6 +403,7 @@ qemu-doc.dvi qemu-doc.html qemu-doc.info qemu-doc.pdf: \
 # rebuilt before other object files
 Makefile: $(GENERATED_HEADERS)
 
+
 # Include automatically generated dependency files
 # All subdir dependencies come automatically from our recursive subdir rules
 -include $(wildcard *.d)
diff --git a/rules.mak b/rules.mak
index 60f3e96..3c46599 100644
--- a/rules.mak
+++ b/rules.mak
@@ -15,7 +15,20 @@ MAKEFLAGS += -rR
 QEMU_DGFLAGS += -MMD -MP -MT $@ -MF $(*D)/$(*F).d
 
 %.o: %.c
-	$(call quiet-command,$(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c -o $@ $<,"  CC    $(TARGET_DIR)$@")
+
+%.qidl.c: %.c $(SRC_PATH)/qidl.h $(addprefix $(SRC_PATH)/scripts/,qidl.py qidl_parser.py qapi.py qapi_visit.py)
+	$(call rm -f $(*D)/qidl-generated/$(*F).qidl.c)
+	$(call quiet-command, $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(CFLAGS) -E -c -DQIDL_GEN $< | \
+	  $(PYTHON) $(SRC_PATH)/scripts/qidl.py --output-filepath=$(*D)/qidl-generated/$(*F).qidl.c || [ "$$?" -eq 2 ])
+
+%.o: %.c %.qidl.c
+	$(if $(strip $(shell test -f $(*D)/qidl-generated/$(*F).qidl.c && echo "true")), \
+	  $(call quiet-command, \
+	    $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c \
+	      -include $< -o $@ -c -x c - <$(*D)/qidl-generated/$(*F).qidl.c,"qidl CC $@"), \
+	  $(call quiet-command, \
+	    $(CC) $(QEMU_INCLUDES) $(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) -c \
+	      -o $@ $<,"  CC    $@"))
 
 ifeq ($(LIBTOOL),)
 %.lo: %.c
diff --git a/tests/Makefile b/tests/Makefile
index 7cfd3d8..7a82b53 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -15,6 +15,7 @@ check-unit-y += tests/test-string-output-visitor$(EXESUF)
 check-unit-y += tests/test-coroutine$(EXESUF)
 check-unit-y += tests/test-visitor-serialization$(EXESUF)
 check-unit-y += tests/test-iov$(EXESUF)
+check-unit-y += tests/test-qidl$(EXESUF)
 
 check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
 
@@ -34,11 +35,12 @@ test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \
 	tests/test-coroutine.o tests/test-string-output-visitor.o \
 	tests/test-string-input-visitor.o tests/test-qmp-output-visitor.o \
 	tests/test-qmp-input-visitor.o tests/test-qmp-input-strict.o \
-	tests/test-qmp-commands.o tests/test-visitor-serialization.o
+	tests/test-qmp-commands.o tests/test-visitor-serialization.o \
+	tests/test-qidl.o
 
 test-qapi-obj-y =  $(qobject-obj-y) $(qapi-obj-y) $(tools-obj-y)
 test-qapi-obj-y += tests/test-qapi-visit.o tests/test-qapi-types.o
-test-qapi-obj-y += module.o
+test-qapi-obj-y += module.o $(qom-obj-y)
 
 $(test-obj-y): QEMU_INCLUDES += -Itests
 
@@ -84,6 +86,8 @@ check-qtest-$(CONFIG_POSIX)=$(foreach TARGET,$(TARGETS), $(check-qtest-$(TARGET)
 qtest-obj-y = tests/libqtest.o $(oslib-obj-y)
 $(check-qtest-y): $(qtest-obj-y)
 
+tests/test-qidl$(EXESUF): tests/test-qidl.o tests/test-qidl-linked.o $(test-qapi-obj-y) qapi/misc-qapi-visit.o
+
 .PHONY: check-help
 check-help:
 	@echo "Regression testing targets:"
diff --git a/tests/test-qidl-included.h b/tests/test-qidl-included.h
new file mode 100644
index 0000000..2aae51e
--- /dev/null
+++ b/tests/test-qidl-included.h
@@ -0,0 +1,31 @@
+/*
+ * Unit-tests for QIDL-generated visitors/code
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Michael Roth <mdroth@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef TEST_QIDL_INCLUDED_H
+#define TEST_QIDL_INCLUDED_H
+
+#include "qidl.h"
+
+QIDL_START(TestStructIncluded, state, properties)
+typedef struct TestStructIncluded {
+    int32_t a QIDL(immutable);
+    int32_t b;
+    uint32_t c QIDL(immutable);
+    uint32_t d;
+    uint64_t e QIDL(immutable);
+    uint64_t f QIDL(property, "f", 42);
+    char *g QIDL(property, "g");
+    char *h QIDL(immutable) QIDL(property, "h");
+} TestStructIncluded;
+QIDL_END(TestStructIncluded)
+
+#endif
diff --git a/tests/test-qidl-linked.c b/tests/test-qidl-linked.c
new file mode 100644
index 0000000..b0d9896
--- /dev/null
+++ b/tests/test-qidl-linked.c
@@ -0,0 +1,91 @@
+/*
+ * Unit-tests for QIDL-generated visitors/code
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Michael Roth <mdroth@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include "qidl.h"
+#include "test-qidl-linked.h"
+#include "hw/qdev-properties.h"
+#include "qapi/qmp-input-visitor.h"
+#include "qapi/qmp-output-visitor.h"
+#include "qapi/qapi-dealloc-visitor.h"
+
+QIDL_START(TestStructLinked, state, properties)
+typedef struct TestStructLinked {
+    int32_t a QIDL(immutable);
+    int32_t b;
+    uint32_t c QIDL(immutable);
+    uint32_t d;
+    uint64_t e QIDL(immutable);
+    uint64_t f QIDL(property, "f", 42);
+    char *g QIDL(property, "g");
+    char *h QIDL(immutable) QIDL(property, "h");
+} TestStructLinked;
+QIDL_END(TestStructLinked)
+
+/* exercise generated code from annotations in objects we link against */
+void test_linked_object_annotations(gconstpointer opaque)
+{
+    TestStructLinked *s1, *s2 = NULL;
+    Property *props;
+    QmpInputVisitor *qiv;
+    QmpOutputVisitor *qov;
+    QObject *s1_obj;
+    Error *err = NULL;
+
+    s1 = g_malloc0(sizeof(TestStructLinked));
+    s1->a = 42;
+    s1->b = INT32_MAX;
+    s1->c = 43;
+    s1->d = UINT32_MAX;
+    s1->e = 44;
+    s1->f = UINT64_MAX;
+    s1->g = g_strdup("test string g");
+    s1->h = g_strdup("test string h");
+
+    qov = qmp_output_visitor_new();
+    QIDL_VISIT_TYPE(TestStructLinked, qmp_output_get_visitor(qov), &s1, NULL, &err);
+    g_assert(err == NULL);
+
+    s1_obj = qmp_output_get_qobject(qov);
+    qiv = qmp_input_visitor_new(s1_obj);
+
+    qobject_decref(s1_obj);
+    qmp_output_visitor_cleanup(qov);
+    g_free(s1->g);
+    g_free(s1->h);
+    g_free(s1);
+
+    s2 = g_malloc0(sizeof(TestStructLinked));
+    QIDL_VISIT_TYPE(TestStructLinked, qmp_input_get_visitor(qiv), &s2, NULL, &err);
+    g_assert(err == NULL);
+
+    g_assert_cmpint(s2->a, ==, 0);
+    g_assert_cmpint(s2->b, ==, INT32_MAX);
+    g_assert_cmpint(s2->c, ==, 0);
+    g_assert_cmpint(s2->d, ==, UINT32_MAX);
+    g_assert_cmpint(s2->e, ==, 0);
+    g_assert_cmpint(s2->f, ==, UINT64_MAX);
+    g_assert_cmpstr(s2->g, ==, "test string g");
+    g_assert(s2->h == NULL);
+
+    qmp_input_visitor_cleanup(qiv);
+    g_free(s2->g);
+    g_free(s2);
+
+    props = QIDL_PROPERTIES(TestStructLinked);
+    g_assert_cmpstr(props[0].name, ==, "f");
+    g_assert_cmpint(props[0].defval, ==, 42);
+    g_assert_cmpstr(props[1].name, ==, "g");
+    g_assert_cmpint(props[1].defval, ==, 0);
+    g_assert_cmpstr(props[2].name, ==, "h");
+    g_assert_cmpint(props[2].defval, ==, 0);
+    g_assert(props[3].name == NULL);
+}
diff --git a/tests/test-qidl-linked.h b/tests/test-qidl-linked.h
new file mode 100644
index 0000000..1b100a2
--- /dev/null
+++ b/tests/test-qidl-linked.h
@@ -0,0 +1,18 @@
+/*
+ * Unit-tests for QIDL-generated visitors/code
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Michael Roth <mdroth@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#ifndef TEST_QIDL_LINKED_H
+#define TEST_QIDL_LINKED_H
+
+void test_linked_object_annotations(gconstpointer opaque);
+
+#endif
diff --git a/tests/test-qidl.c b/tests/test-qidl.c
new file mode 100644
index 0000000..a1d27a2
--- /dev/null
+++ b/tests/test-qidl.c
@@ -0,0 +1,177 @@
+/*
+ * Unit-tests for QIDL-generated visitors/code
+ *
+ * Copyright IBM, Corp. 2012
+ *
+ * Authors:
+ *  Michael Roth <mdroth@linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <glib.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "qidl.h"
+#include "test-qidl-included.h"
+#include "test-qidl-linked.h"
+#include "hw/qdev-properties.h"
+#include "qapi/qmp-input-visitor.h"
+#include "qapi/qmp-output-visitor.h"
+#include "qapi/qapi-dealloc-visitor.h"
+
+PropertyInfo qdev_prop_uint64;
+PropertyInfo qdev_prop_string;
+
+QIDL_START(TestStructMain, state, properties)
+typedef struct TestStructMain {
+    int32_t a QIDL(immutable);
+    int32_t b;
+    uint32_t c QIDL(immutable);
+    uint32_t d;
+    uint64_t e QIDL(immutable);
+    uint64_t f QIDL(property, "f", 42);
+    char *g QIDL(property, "g");
+    char *h QIDL(immutable) QIDL(property, "h");
+} TestStructMain;
+QIDL_END(TestStructMain)
+
+/* exercise generated code from annotations in main() object file */
+static void test_main_object_annotations(gconstpointer opaque)
+{
+    TestStructMain *s1, *s2 = NULL;
+    Property *props;
+    QmpInputVisitor *qiv;
+    QmpOutputVisitor *qov;
+    QObject *s1_obj;
+    Error *err = NULL;
+
+    s1 = g_malloc0(sizeof(TestStructMain));
+    s1->a = 42;
+    s1->b = INT32_MAX;
+    s1->c = 43;
+    s1->d = UINT32_MAX;
+    s1->e = 44;
+    s1->f = UINT64_MAX;
+    s1->g = g_strdup("test string g");
+    s1->h = g_strdup("test string h");
+
+    qov = qmp_output_visitor_new();
+    QIDL_VISIT_TYPE(TestStructMain, qmp_output_get_visitor(qov), &s1, NULL, &err);
+    g_assert(err == NULL);
+
+    s1_obj = qmp_output_get_qobject(qov);
+    qiv = qmp_input_visitor_new(s1_obj);
+
+    qobject_decref(s1_obj);
+    qmp_output_visitor_cleanup(qov);
+    g_free(s1->g);
+    g_free(s1->h);
+    g_free(s1);
+
+    s2 = g_malloc0(sizeof(TestStructMain));
+    QIDL_VISIT_TYPE(TestStructMain, qmp_input_get_visitor(qiv), &s2, NULL, &err);
+    g_assert(err == NULL);
+
+    g_assert_cmpint(s2->a, ==, 0);
+    g_assert_cmpint(s2->b, ==, INT32_MAX);
+    g_assert_cmpint(s2->c, ==, 0);
+    g_assert_cmpint(s2->d, ==, UINT32_MAX);
+    g_assert_cmpint(s2->e, ==, 0);
+    g_assert_cmpint(s2->f, ==, UINT64_MAX);
+    g_assert_cmpstr(s2->g, ==, "test string g");
+    g_assert(s2->h == NULL);
+
+    qmp_input_visitor_cleanup(qiv);
+    g_free(s2->g);
+    g_free(s2);
+
+    props = QIDL_PROPERTIES(TestStructMain);
+    g_assert_cmpstr(props[0].name, ==, "f");
+    g_assert_cmpint(props[0].defval, ==, 42);
+    g_assert_cmpstr(props[1].name, ==, "g");
+    g_assert_cmpint(props[1].defval, ==, 0);
+    g_assert_cmpstr(props[2].name, ==, "h");
+    g_assert_cmpint(props[2].defval, ==, 0);
+    g_assert(props[3].name == NULL);
+}
+
+/* exercise generated code from annotations in included header files */
+static void test_header_file_annotations(gconstpointer opaque)
+{
+    TestStructIncluded *s1, *s2 = NULL;
+    Property *props;
+    QmpInputVisitor *qiv;
+    QmpOutputVisitor *qov;
+    QObject *s1_obj;
+    Error *err = NULL;
+
+    s1 = g_malloc0(sizeof(TestStructIncluded));
+    s1->a = 42;
+    s1->b = INT32_MAX;
+    s1->c = 43;
+    s1->d = UINT32_MAX;
+    s1->e = 44;
+    s1->f = UINT64_MAX;
+    s1->g = g_strdup("test string g");
+    s1->h = g_strdup("test string h");
+
+    qov = qmp_output_visitor_new();
+    QIDL_VISIT_TYPE(TestStructIncluded, qmp_output_get_visitor(qov), &s1, NULL, &err);
+    g_assert(err == NULL);
+
+    s1_obj = qmp_output_get_qobject(qov);
+    qiv = qmp_input_visitor_new(s1_obj);
+
+    qobject_decref(s1_obj);
+    qmp_output_visitor_cleanup(qov);
+    g_free(s1->g);
+    g_free(s1->h);
+    g_free(s1);
+
+    s2 = g_malloc0(sizeof(TestStructIncluded));
+    QIDL_VISIT_TYPE(TestStructIncluded, qmp_input_get_visitor(qiv), &s2, NULL, &err);
+    g_assert(err == NULL);
+
+    g_assert_cmpint(s2->a, ==, 0);
+    g_assert_cmpint(s2->b, ==, INT32_MAX);
+    g_assert_cmpint(s2->c, ==, 0);
+    g_assert_cmpint(s2->d, ==, UINT32_MAX);
+    g_assert_cmpint(s2->e, ==, 0);
+    g_assert_cmpint(s2->f, ==, UINT64_MAX);
+    g_assert_cmpstr(s2->g, ==, "test string g");
+    g_assert(s2->h == NULL);
+
+    qmp_input_visitor_cleanup(qiv);
+    g_free(s2->g);
+    g_free(s2);
+
+    props = QIDL_PROPERTIES(TestStructIncluded);
+    g_assert_cmpstr(props[0].name, ==, "f");
+    g_assert_cmpint(props[0].defval, ==, 42);
+    g_assert_cmpstr(props[1].name, ==, "g");
+    g_assert_cmpint(props[1].defval, ==, 0);
+    g_assert_cmpstr(props[2].name, ==, "h");
+    g_assert_cmpint(props[2].defval, ==, 0);
+    g_assert(props[3].name == NULL);
+}
+
+int main(int argc, char **argv)
+{
+    module_call_init(MODULE_INIT_QOM);
+    module_call_init(MODULE_INIT_QIDL);
+
+    g_test_init(&argc, &argv, NULL);
+
+    g_test_add_data_func("/qidl/build_test/main_object_annotations", NULL,
+                         test_main_object_annotations);
+    g_test_add_data_func("/qidl/build_test/linked_object_annotations", NULL,
+                         test_linked_object_annotations);
+    g_test_add_data_func("/qidl/build_test/header_file_annotations", NULL,
+                         test_header_file_annotations);
+
+    g_test_run();
+
+    return 0;
+}
-- 
1.7.9.5

  parent reply	other threads:[~2012-07-24 17:22 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-07-24 17:20 [Qemu-devel] [RFC v2] Use QEMU IDL for device serialization/introspection Michael Roth
2012-07-24 17:20 ` [Qemu-devel] [PATCH 01/22] qapi: qapi-visit.py -> qapi_visit.py so we can import Michael Roth
2012-07-24 22:12   ` Anthony Liguori
2012-07-24 17:20 ` [Qemu-devel] [PATCH 02/22] qapi: qapi-types.py -> qapi_types.py Michael Roth
2012-07-24 17:20 ` [Qemu-devel] [PATCH 03/22] qapi: qapi-commands.py -> qapi_commands.py Michael Roth
2012-07-24 17:20 ` [Qemu-devel] [PATCH 04/22] qapi: qapi_visit.py, make code useable as module Michael Roth
2012-07-24 22:13   ` Anthony Liguori
2012-07-24 17:20 ` [Qemu-devel] [PATCH 05/22] qapi: qapi_visit.py, support arrays and complex qapi definitions Michael Roth
2012-07-24 22:16   ` Anthony Liguori
2012-07-24 17:20 ` [Qemu-devel] [PATCH 06/22] qapi: add visitor interfaces for arrays Michael Roth
2012-07-24 22:18   ` Anthony Liguori
2012-07-24 17:20 ` [Qemu-devel] [PATCH 07/22] qapi: qapi_visit.py, support generating static functions Michael Roth
2012-07-24 22:19   ` Anthony Liguori
2012-07-24 17:20 ` [Qemu-devel] [PATCH 08/22] qapi: qapi_visit.py, support for visiting non-pointer/embedded structs Michael Roth
2012-07-24 22:21   ` Anthony Liguori
2012-07-24 17:20 ` [Qemu-devel] [PATCH 09/22] qapi: QmpOutputVisitor, implement array handling Michael Roth
2012-07-24 17:20 ` [Qemu-devel] [PATCH 10/22] qapi: qapi.py, make json parser more robust Michael Roth
2012-07-24 22:23   ` Anthony Liguori
2012-07-24 22:59     ` Michael Roth
2012-07-24 17:20 ` [Qemu-devel] [PATCH 11/22] qapi: add open-coded visitor for struct tm types Michael Roth
2012-07-24 22:24   ` Anthony Liguori
2012-07-24 17:20 ` [Qemu-devel] [PATCH 12/22] qom-fuse: workaround for truncated properties > 4096 Michael Roth
2012-07-24 22:26   ` Anthony Liguori
2012-07-24 17:20 ` [Qemu-devel] [PATCH 13/22] module additions for schema registration Michael Roth
2012-07-24 17:20 ` [Qemu-devel] [PATCH 14/22] qdev: move Property-related declarations to qdev-properties.h Michael Roth
2012-07-24 22:28   ` Anthony Liguori
2012-07-24 17:20 ` [Qemu-devel] [PATCH 15/22] qidl: Add documentation Michael Roth
2012-07-24 17:20 ` [Qemu-devel] [PATCH 16/22] qidl: parser, initial import from qc.git Michael Roth
2012-07-24 17:20 ` [Qemu-devel] [PATCH 17/22] qidl: codegen, initial commit Michael Roth
2012-07-24 17:20 ` [Qemu-devel] [PATCH 18/22] qidl: qidl.h Michael Roth
2012-07-24 20:47   ` Blue Swirl
2012-07-25  0:30     ` Michael Roth
2012-07-24 17:20 ` Michael Roth [this message]
2012-07-24 17:20 ` [Qemu-devel] [PATCH 20/22] qemu-timer: add visit_type_QEMUTimer Michael Roth
2012-07-24 17:20 ` [Qemu-devel] [PATCH 21/22] rtc: add QIDL annotations Michael Roth
2012-07-24 17:20 ` [Qemu-devel] [PATCH 22/22] cirrus_vga: " Michael Roth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1343150454-4677-20-git-send-email-mdroth@linux.vnet.ibm.com \
    --to=mdroth@linux.vnet.ibm.com \
    --cc=afaerber@suse.de \
    --cc=akong@redhat.com \
    --cc=aliguori@us.ibm.com \
    --cc=owasserm@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=yamahata@valinux.co.jp \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).