[libsecret] Makefile.am: Use a single Makefile.am and parallel tests



commit b72048c920f50df85cb398f4309e68a575d8879e
Author: Stef Walter <stefw gnome org>
Date:   Tue Mar 4 08:20:53 2014 +0100

    Makefile.am: Use a single Makefile.am and parallel tests
    
    Allow parallel building and testing by using a single Makefile.am
    
    Implement parallel testing using TAP, with various drivers and
    compilers living in the build/ directory.
    
    Fix all sorts of issues that this caused, including builddir != srcdir,
    leaks in tests and so on.
    
    It would have been nice to break out all the above into separate
    commits ... blush.

 Makefile.am                                        |  120 +++++++-
 Makefile.decl                                      |   28 --
 build/Makefile.am                                  |   29 +-
 build/tap-compiler                                 |  174 ++++++++++
 build/tap-driver                                   |  287 ++++++++++++++++
 build/tap-unittest                                 |   84 +++++
 build/test-driver                                  |  127 +++++++
 configure.ac                                       |   10 +-
 docs/Makefile.am                                   |    6 -
 docs/man/Makefile.am                               |   10 +-
 docs/reference/Makefile.am                         |    2 -
 docs/reference/libsecret/Makefile.am               |    4 +-
 egg/Makefile.am                                    |   57 ++--
 egg/{tests => }/test-dh.c                          |    0
 egg/{tests => }/test-hex.c                         |    0
 egg/{tests => }/test-hkdf.c                        |    0
 egg/{tests => }/test-secmem.c                      |    0
 egg/tests/Makefile.am                              |   31 --
 libsecret/Makefile.am                              |  358 ++++++++++++++------
 libsecret/{tests => }/mock-service-delete.py       |    0
 libsecret/{tests => }/mock-service-empty.py        |    0
 libsecret/{tests => }/mock-service-lock.py         |    0
 libsecret/{tests => }/mock-service-normal.py       |    0
 libsecret/{tests => }/mock-service-only-plain.py   |    0
 libsecret/{tests => }/mock-service-prompt.py       |    0
 libsecret/{tests => }/mock-service.c               |   44 +++-
 libsecret/{tests => }/mock-service.h               |    0
 libsecret/{tests => }/mock/__init__.py             |    0
 libsecret/{tests => }/mock/aes.py                  |    0
 libsecret/{tests => }/mock/dh.py                   |    0
 libsecret/{tests => }/mock/hkdf.py                 |    0
 libsecret/{tests => }/mock/service.py              |    0
 libsecret/secret-collection.c                      |    3 +-
 libsecret/secret-item.c                            |   35 ++-
 libsecret/secret-schema.c                          |    5 +-
 libsecret/secret-service.c                         |    5 +-
 libsecret/secret-util.c                            |    2 +
 libsecret/{tests => }/test-attributes.c            |    0
 libsecret/{tests => }/test-collection.c            |    0
 libsecret/{tests => }/test-item.c                  |    9 +
 .../test-clear-password.js => test-js-clear.js}    |    9 +-
 .../test-lookup-password.js => test-js-lookup.js}  |    1 +
 .../test-store-password.js => test-js-store.js}    |    1 +
 libsecret/{tests => }/test-methods.c               |    0
 libsecret/{tests => }/test-password.c              |    0
 libsecret/{tests => }/test-paths.c                 |    0
 libsecret/{tests => }/test-prompt.c                |    0
 .../test-clear-password.py => test-py-clear.py}    |    0
 .../test-lookup-password.py => test-py-lookup.py}  |    0
 .../test-store-password.py => test-py-store.py}    |    0
 libsecret/{tests => }/test-service.c               |   20 +-
 libsecret/{tests => }/test-session.c               |    0
 libsecret/{tests => }/test-vala-lang.vala          |    0
 libsecret/{tests => }/test-vala-unstable.vala      |    0
 libsecret/{tests => }/test-value.c                 |    0
 libsecret/tests/Makefile.am                        |  210 ------------
 tool/Makefile.am                                   |   15 +-
 tool/secret-tool.c                                 |    8 +-
 58 files changed, 1205 insertions(+), 489 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index f5d56e9..53976a9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,9 +1,12 @@
 ## Process this file with automake to produce Makefile.in
-include $(top_srcdir)/Makefile.decl
+NULL =
 
 ACLOCAL_AMFLAGS = -I build/m4 ${ACLOCAL_FLAGS}
 
-SUBDIRS = build egg libsecret tool po docs .
+SUBDIRS = \
+       . \
+       po \
+       docs/reference/libsecret
 
 DISTCHECK_CONFIGURE_FLAGS = \
        --enable-debug=yes \
@@ -13,9 +16,6 @@ DISTCHECK_CONFIGURE_FLAGS = \
        --enable-gtk-doc \
        --enable-vala
 
-EXTRA_DIST = \
-       COPYING.TESTS
-
 dist-hook:
        @if test -d "$(srcdir)/.git"; \
        then \
@@ -55,3 +55,113 @@ dist-hook: dist-check-valac
 
 distcleancheck_listfiles =  \
        find . -name '*.gc[dn][oa]' -prune -o -type f -print
+
+TEST_SUPPRESSIONS = $(top_builddir)/build/valgrind-suppressions
+
+perform-memcheck: $(TEST_PROGS) $(TEST_SUPPRESSIONS)
+       @make -C $(top_builddir)/build all
+       @for test in $(TEST_PROGS); do \
+               G_SLICE=always-malloc libtool --mode=execute \
+                       valgrind --trace-children=no --gen-suppressions=all \
+                       --suppressions=$(TEST_SUPPRESSIONS) \
+                       --leak-check=full --show-reachable=yes --num-callers=16 \
+                       --quiet --error-exitcode=33 \
+                       $(builddir)/$$test; \
+       done
+
+if WITH_COVERAGE
+coverage:
+       mkdir -p $(top_builddir)/build/coverage
+       $(LCOV) --directory . --capture --output-file $(top_builddir)/build/coverage.info
+       $(GENHTML) --output-directory $(top_builddir)/build/coverage $(top_builddir)/build/coverage.info
+       $(LCOV) --directory . --zerocounters
+       @echo "file://$(abs_top_builddir)/build/coverage/index.html"
+
+clear-coverage:
+       $(LCOV) --directory . --zerocounters
+
+endif
+
+AM_CPPFLAGS = \
+       -I$(top_srcdir) \
+       -I$(top_srcdir)/build \
+       -DSRCDIR="\"@abs_srcdir \"" \
+       -DLOCALEDIR=\""$(datadir)/locale"\" \
+       -DWITH_VALGRIND \
+       -DSECRET_COMPILATION \
+       $(LIBGCRYPT_CFLAGS) \
+       $(GLIB_CFLAGS)
+
+bin_PROGRAMS =
+BUILT_SOURCES =
+check_PROGRAMS =
+DISTCLEANFILES =
+lib_LTLIBRARIES =
+man_MANS =
+nodist_noinst_DATA =
+noinst_DATA =
+noinst_LTLIBRARIES =
+TESTS =
+
+noinst_PROGRAMS = $(check_PROGRAMS)
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA =
+
+if HAVE_INTROSPECTION
+
+include $(INTROSPECTION_MAKEFILE)
+
+INTROSPECTION_GIRS = 
+INTROSPECTION_SCANNER_ARGS = $(INTROSPECTION_FLAGS) --warn-all \
+       --add-include-path=$(srcdir) --add-include-path=$(builddir)
+INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) --includedir=$(builddir)
+
+girdir = $(datadir)/gir-1.0
+gir_DATA =
+
+typelibsdir = $(libdir)/girepository-1.0
+typelibs_DATA = $(gir_DATA:.gir=.typelib)
+
+if ENABLE_VAPIGEN
+
+include $(VAPIGEN_MAKEFILE)
+
+VAPIGEN_VAPIS =
+
+vapidir = $(datadir)/vala/vapi
+vapi_DATA =
+
+endif
+
+endif
+
+CLEANFILES = \
+       $(pkgconfig_DATA) \
+       $(gir_DATA) \
+       $(typelibs_DATA) \
+       $(BUILT_SOURCES) \
+       $(vapi_DATA) \
+       $(man_MANS)
+
+EXTRA_DIST = \
+       COPYING.TESTS
+
+LOG_DRIVER = $(srcdir)/build/tap-driver
+LOG_COMPILER = $(srcdir)/build/tap-compiler
+
+TESTS_ENVIRONMENT = LD_LIBRARY_PATH=$(builddir)/.libs GI_TYPELIB_PATH=$(builddir)
+TEST_EXTENSIONS = .py .js
+PY_LOG_DRIVER = $(srcdir)/build/tap-driver
+PY_LOG_COMPILER = $(srcdir)/build/tap-unittest
+JS_LOG_DRIVER = $(srcdir)/build/test-driver
+JS_LOG_COMPILER = gjs
+
+include build/Makefile.am
+include egg/Makefile.am
+include libsecret/Makefile.am
+include tool/Makefile.am
+
+if WITH_MANPAGES
+include docs/man/Makefile.am
+endif
diff --git a/build/Makefile.am b/build/Makefile.am
index 73a8b1b..b73bf65 100644
--- a/build/Makefile.am
+++ b/build/Makefile.am
@@ -1,26 +1,23 @@
-include $(top_srcdir)/Makefile.decl
-
-VALGRIND_CONTRIB = \
-       valgrind.h \
-       memcheck.h \
-       $(NULL)
-
 SUPPRESSIONS = \
-       $(srcdir)/gcrypt.supp \
-       $(srcdir)/glib.supp \
-       $(srcdir)/pthread.supp \
-       $(srcdir)/unknown.supp \
+       build/gcrypt.supp \
+       build/glib.supp \
+       build/pthread.supp \
+       build/unknown.supp \
        $(NULL)
 
 valgrind-suppressions: $(SUPPRESSIONS)
-       $(AM_V_GEN) cat $(SUPPRESSIONS) > $@
+       $(AM_V_GEN) cat $^ > $@
 
-EXTRA_DIST = \
-       valgrind \
+EXTRA_DIST += \
+       build/valgrind \
+       build/tap-compiler \
+       build/tap-driver \
+       build/tap-unittest \
+       build/test-driver \
        $(SUPPRESSIONS)
 
-CLEANFILES = \
+CLEANFILES += \
        valgrind-suppressions \
        $(NULL)
 
-all-local: valgrind-suppressions
+nodist_noinst_DATA += valgrind-suppressions
diff --git a/build/tap-compiler b/build/tap-compiler
new file mode 100755
index 0000000..76b3171
--- /dev/null
+++ b/build/tap-compiler
@@ -0,0 +1,174 @@
+#!/usr/bin/python
+
+# Copyright (C) 2014 Red Hat, Inc.
+#
+# Cockpit is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# Cockpit is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
+
+#
+# This is a test output compiler which produces TAP from GTest output
+# if GTest output is detected.
+#
+# Versions of glib later than 2.38.x output TAP natively when tests are
+# run with the --tap option. However we can't depend on such a recent
+# version of glib for our purposes.
+#
+# This implements the Test Anything Protocol (ie: TAP)
+# https://metacpan.org/pod/release/PETDANCE/Test-Harness-2.64/lib/Test/Harness/TAP.pod
+#
+
+import argparse
+import os
+import select
+import subprocess
+import sys
+
+class NullCompiler:
+    def __init__(self, command):
+        self.command = command
+
+    def input(self, line):
+        sys.stdout.write(line)
+
+    def process(self, proc):
+        while True:
+            line = proc.stdout.readline()
+            if not line:
+                break
+            self.input(line)
+        proc.wait()
+        return proc.returncode
+
+    def run(self, proc, line=None):
+        if line:
+            self.input(line)
+        return self.process(proc)
+
+
+class GTestCompiler(NullCompiler):
+    def __init__(self, filename):
+        NullCompiler.__init__(self, filename)
+        self.test_num = 0
+        self.test_name = None
+        self.test_remaining = []
+
+    def input(self, line):
+        line = line.strip()
+        if line.startswith("GTest: "):
+           (cmd, unused, data) = line[7:].partition(": ")
+           cmd = cmd.strip()
+           data = data.strip()
+           if cmd == "run":
+               self.test_name = data
+               assert self.test_name in self.test_remaining, "%s %s" % (self.test_name, 
repr(self.test_remaining))
+               self.test_remaining.remove(self.test_name)
+               self.test_num += 1
+           elif cmd == "result":
+               if data == "OK":
+                   print "ok %d %s" % (self.test_num, self.test_name)
+               if data == "FAIL":
+                   print "not ok %d %s", (self.test_num, self.test_name)
+               self.test_name = None
+           elif cmd == "skipping":
+               print "ok %d # skip -- %s" % (self.test_num, self.test_name)
+               self.test_name = None
+           elif data:
+               print "# %s: %s" % (cmd, data)
+           else:
+               print "# %s" % cmd
+        elif line.startswith("(MSG: "):
+            print "# %s" % line[6:-1]
+        elif line:
+            print "# %s" % line
+        sys.stdout.flush()
+
+    def run(self, proc, output=""):
+        # Complete retrieval of the list of tests
+        output += proc.stdout.read()
+        proc.wait()
+        if proc.returncode:
+            raise subprocess.CalledProcessError(proc.returncode, self.command)
+        self.test_remaining = []
+        for line in output.split("\n"):
+            if line.startswith("/"):
+                self.test_remaining.append(line.strip())
+        if not self.test_remaining:
+            print "Bail out! No tests found in GTest: %s" % self.command[0]
+            return 0
+
+        print "1..%d" % len(self.test_remaining)
+
+        # First try to run all the tests in a batch
+        proc = subprocess.Popen(self.command + ["--verbose" ], close_fds=True, stdout=subprocess.PIPE)
+        result = self.process(proc)
+        if result == 0:
+            return 0
+
+        # Now pick up any stragglers due to failures
+        while True:
+            # Assume that the last test failed
+            if self.test_name:
+                print "not ok %d %s" % (self.test_num, self.test_name)
+                self.test_name = None
+
+            # Run any tests which didn't get run
+            if not self.test_remaining:
+                break
+
+            proc = subprocess.Popen(self.command + ["--verbose", "-p", self.test_remaining[0]],
+                                    close_fds=True, stdout=subprocess.PIPE)
+            result = self.process(proc)
+
+            # The various exit codes and signals we continue for
+            if result not in [ 0, 1, -4, -5, -6, -7, -8, -11 ]:
+                break
+
+        return result
+
+def main(argv):
+    parser = argparse.ArgumentParser(description='Automake TAP compiler')
+    parser.add_argument('--format', metavar='FORMAT', choices=[ "auto", "GTest", "TAP" ],
+                        default="auto", help='The input format to compile')
+    parser.add_argument('--verbose', action='store_true',
+                        default=True, help='Verbose mode (ignored)')
+    parser.add_argument('command', nargs='+', help="A test command to run")
+    args = parser.parse_args(argv[1:])
+
+    output = None
+    format = args.format
+    cmd = args.command
+    proc = None
+
+    if format in ["auto", "GTest"]:
+        list_cmd = cmd + ["-l", "--verbose"]
+        proc = subprocess.Popen(list_cmd, close_fds=True, stdout=subprocess.PIPE)
+        output = proc.stdout.readline()
+        # Smell whether we're dealing with GTest list output from first line
+        if "random seed" in output or "GTest" in output or output.startswith("/"):
+            format = "GTest"
+        else:
+            format = "TAP"
+    else:
+        proc = subprocess.Popen(cmd, close_fds=True, stdout=subprocess.PIPE)
+
+    if format == "GTest":
+        compiler = GTestCompiler(cmd)
+    elif format == "TAP":
+        compiler = NullCompiler(cmd)
+    else:
+        assert False, "not reached"
+
+    return compiler.run(proc, output)
+
+if __name__ == "__main__":
+    sys.exit(main(sys.argv))
diff --git a/build/tap-driver b/build/tap-driver
new file mode 100755
index 0000000..1c5af40
--- /dev/null
+++ b/build/tap-driver
@@ -0,0 +1,287 @@
+#!/usr/bin/python
+
+# Copyright (C) 2013 Red Hat, Inc.
+#
+# Cockpit is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+#
+# Cockpit is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with Cockpit; If not, see <http://www.gnu.org/licenses/>.
+
+#
+# This is a TAP driver for automake
+#
+# In particular it leaves stderr untouched, and is cleaner than the
+# one implemented in shell that is making the rounds.
+#
+# This implements the automake "Custom Test Driver" protocol:
+# https://www.gnu.org/software/automake/manual/html_node/Custom-Test-Drivers.html
+#
+# This consumes the Test Anything Protocol (ie: TAP)
+# https://metacpan.org/pod/release/PETDANCE/Test-Harness-2.64/lib/Test/Harness/TAP.pod
+#
+
+import argparse
+import os
+import select
+import subprocess
+import sys
+
+class Driver:
+    def __init__(self, command, args):
+        self.argv = command
+        self.output = ""
+        self.test_name = args.test_name
+        self.log = open(args.log_file, "w")
+        self.trs = open(args.trs_file, "w")
+        self.color_tests = args.color_tests
+        self.expect_failure = args.expect_failure
+        self.reported = { }
+        self.test_plan = None
+        self.late_plan = False
+        self.errored = False
+        self.bail_out = False
+
+    def report(self, code, num, *args):
+        CODES = {
+            "XPASS": '\x1b[0;31m', # red
+            "FAIL": '\x1b[0;31m', # red
+            "PASS": '\x1b[0;32m', # grn
+            "XFAIL": '\x1b[1;32m', # lgn
+            "SKIP": '\x1b[1;34m', # blu
+            "ERROR": '\x1b[0;35m', # mgn
+        }
+
+        # Print out to console
+        if self.color_tests:
+            if code in CODES:
+                sys.stdout.write(CODES[code])
+        sys.stdout.write(code)
+        if self.color_tests:
+            sys.stdout.write('\x1b[m')
+        sys.stdout.write(": ")
+        sys.stdout.write(self.test_name)
+        sys.stdout.write(" ")
+        if num:
+            sys.stdout.write(str(num))
+            sys.stdout.write(" ")
+        for arg in args:
+            sys.stdout.write(str(arg))
+        sys.stdout.write("\n")
+        sys.stdout.flush()
+
+        # Book keeping
+        if code in CODES:
+            if num != None:
+                self.reported[num] = code
+            self.trs.write(":test-result: %s\n" % code)
+        if code == "ERROR":
+            self.errored = True
+
+    def result_pass(self, num, description):
+        if self.expect_failure:
+            self.report("XPASS", num, description)
+        else:
+            self.report("PASS", num, description)
+
+    def result_fail(self, num, description):
+        if self.expect_failure:
+            self.report("XFAIL", num, description)
+        else:
+            self.report("FAIL", num, description)
+
+    def result_skip(self, num, description, ok):
+        if self.expect_failure:
+            self.report("XFAIL", num, description)
+        else:
+            self.report("SKIP", num, description)
+
+    def report_error(self, problem):
+        self.report("ERROR", None, problem)
+
+    def consume_test_line(self, ok, data):
+        # It's an error if the caller sends a test plan in the middle of tests
+        if self.late_plan:
+            self.report_error("Got tests after late TAP test plan")
+            self.late_plan = False
+
+        # Parse out a number and then description
+        (num, unused, description) = data.partition(" ")
+        try:
+            num = int(num)
+        except ValueError:
+            self.report_error("Invalid test number: %s" %  data)
+            return
+        description = description.lstrip()
+
+        # Special case if description starts with this, then skip
+        if description.lower().startswith("# skip"):
+            self.result_skip(num, description, ok)
+        elif ok:
+            self.result_pass(num, description)
+        else:
+            self.result_fail(num, description)
+
+    def consume_test_plan(self, first, last):
+        # Only one test plan is supported
+        if self.test_plan:
+            self.report_error("Get a second TAP test plan")
+            return
+
+        try:
+            first = int(first)
+            last = int(last)
+        except ValueError:
+            self.report_error("Invalid test plan: %s..%s" % (first, last))
+            return
+
+        self.test_plan = (first, last)
+        self.late_plan = self.reported and True or False
+
+    def consume_bail_out(self, line):
+        self.bail_out = True
+        self.report("SKIP", 0, line)
+
+    def drain(self):
+        (ready, unused, self.output) = self.output.rpartition("\n")
+        for line in ready.split("\n"):
+            self.log.write(line)
+            self.log.write("\n")
+
+            if line.startswith("ok "):
+                self.consume_test_line(True, line[3:])
+            elif line.startswith("not ok "):
+                self.consume_test_line(False, line[7:])
+            elif line and line[0].isdigit() and ".." in line:
+                (first, unused, last) = line.partition("..")
+                self.consume_test_plan(first, last)
+            elif line.lower().startswith("bail out!"):
+                self.consume_bail_out(line)
+
+    def execute(self):
+        try:
+            proc = subprocess.Popen(self.argv, close_fds=True,
+                                    stdout=subprocess.PIPE,
+                                    stderr=subprocess.PIPE)
+        except OSError, ex:
+            self.report_error("Couldn't run %s: %s" % (self.argv[0], str(ex)))
+            return
+
+        outf = proc.stdout.fileno()
+        errf = proc.stderr.fileno()
+        rset = [outf, errf]
+        while len(rset) > 0:
+            ret = select.select(rset, [], [], 10)
+            if outf in ret[0]:
+                data = os.read(outf, 1024)
+                if data == "":
+                    if self.output:
+                        self.output += "\n"
+                    rset.remove(outf)
+                else:
+                    self.output += data
+                self.drain()
+            if errf in ret[0]:
+                data = os.read(errf, 1024)
+                if data == "":
+                    rset.remove(errf)
+                self.log.write(data)
+                sys.stderr.write(data)
+
+        proc.wait()
+        self.returncode = proc.returncode
+
+    def run(self):
+        self.execute()
+
+        failed = False
+        skipped = True
+
+        # Basic collation of results
+        for (num, code) in self.reported.items():
+            if code == "ERROR":
+                self.errored = True
+            elif code == "FAIL" or code == "XPASS":
+                failed = True
+            if code != "SKIP":
+                skipped = False
+
+        # Check the plan
+        if not self.errored:
+            if not self.test_plan:
+                if not self.bail_out:
+                    if self.returncode:
+                        self.report_error("Test process failed: %d" % self.returncode)
+                    else:
+                        self.report_error("Didn't receive a TAP test plan")
+            else:
+                for i in range(self.test_plan[0], self.test_plan[1] + 1):
+                    if i not in self.reported:
+                        if self.bail_out:
+                            self.report("SKIP", i, "- bailed out")
+                        else:
+                            self.report("ERROR", i, "- missing test")
+                            skipped = False
+                            self.errored = True
+
+        if self.errored:
+            self.trs.write(":global-test-result: ERROR\n")
+            self.trs.write(":test-global-result: ERROR\n")
+            self.trs.write(":recheck: no\n")
+        elif failed:
+            self.trs.write(":global-test-result: FAIL\n")
+            self.trs.write(":test-global-result: FAIL\n")
+            self.trs.write(":recheck: yes\n")
+        elif skipped:
+            self.trs.write(":global-test-result: SKIP\n")
+            self.trs.write(":test-global-result: SKIP\n")
+            self.trs.write(":recheck: no\n")
+        if self.errored or failed:
+            self.trs.write(":copy-in-global-log: yes\n")
+
+        # Process result code
+        return self.errored and 1 or 0
+
+class YesNoAction(argparse.Action):
+    def __init__(self, option_strings, dest, **kwargs):
+        argparse.Action.__init__(self, option_strings, dest, **kwargs)
+        self.metavar = "[yes|no]"
+    def __call__(self, parser, namespace, values, option_string=None):
+        if not values or "yes" in values:
+            setattr(namespace, self.dest, True)
+        else:
+            setattr(namespace, self.dest, False)
+
+def main(argv):
+    parser = argparse.ArgumentParser(description='Automake TAP driver')
+    parser.add_argument('--test-name', metavar='NAME',
+                        help='The name of the test')
+    parser.add_argument('--log-file', metavar='PATH.log', required=True,
+                        help='The .log file the driver creates')
+    parser.add_argument('--trs-file', metavar='PATH.trs', required=True,
+                        help='The .trs file the driver creates')
+    parser.add_argument('--color-tests', default=True, action=YesNoAction,
+                        help='Whether the console output should be colorized or not')
+    parser.add_argument('--expect-failure', default=False, action=YesNoAction,
+                        help="Whether the tested program is expected to fail")
+    parser.add_argument('--enable-hard-errors', default=False, action=YesNoAction,
+                        help="Whether hard errors in the tested program are treated differently")
+    parser.add_argument('command', nargs='+',
+                        help="A test command line to run")
+    args = parser.parse_args(argv[1:])
+
+    if not args.test_name:
+        args.test_name = os.path.basename(args.command[0])
+
+    driver = Driver(args.command, args)
+    return driver.run()
+
+if __name__ == "__main__":
+    sys.exit(main(sys.argv))
diff --git a/build/tap-unittest b/build/tap-unittest
new file mode 100755
index 0000000..915ec7d
--- /dev/null
+++ b/build/tap-unittest
@@ -0,0 +1,84 @@
+#!/usr/bin/python
+
+#
+# This is a TAP compiler for python unittest
+#
+# It hooks into python's standard unittest module, and produces TAP output.
+#
+# This produces the Test Anything Protocol (ie: TAP)
+# https://metacpan.org/pod/release/PETDANCE/Test-Harness-2.64/lib/Test/Harness/TAP.pod
+#
+# Based on code from here:
+# https://github.com/vit1251/unittest-tap-reporting
+# 
+
+import argparse
+import imp
+import os
+import sys
+import time
+import traceback
+import unittest
+
+def write_line(format, *args):
+    sys.stdout.write(format % args)
+    sys.stdout.write("\n")
+    sys.stdout.flush()
+
+class TAPTestResult(unittest.result.TestResult):
+    def __init__(self):
+        unittest.result.TestResult.__init__(self)
+        self.number = 0
+
+    def addSuccess(self, test):
+        self.number += 1
+        write_line("ok %d %s", self.number, test.id())
+
+    def addSkip(self, test, reason):
+        self.number += 1
+        write_line("not ok %d # skip %s", self.number, test.id())
+        write_line("# %s", reason)
+
+    def addError(self, test, exc):
+        (etype, evalue, etraceback) = exc
+        traceback.print_exception(etype, evalue, etraceback, file=sys.stderr)
+        self.number += 1
+        write_line("not ok %d %s", self.number, test.id())
+
+    def addFailure(self, test, err):
+        (etype, evalue, etraceback) = exc
+        traceback.print_exception(etype, evalue, etraceback, limit=1, file=sys.stderr)
+        self.number += 1
+        write_line("not ok %d %s", self.number, test.id())
+
+class TAPTestRunner(object):
+    def __init__(self):
+        pass
+
+    def run(self, test):
+        write_line("1..%d", test.countTestCases())
+        result = TAPTestResult()
+        startTestRun = getattr(result, 'startTestRun', lambda : None)
+        startTestRun()
+        try:
+            test(result)
+        finally:
+            stopTestRun = getattr(result, 'stopTestRun', lambda : None)
+            stopTestRun()
+        return result
+
+def main(argv):
+    parser = argparse.ArgumentParser(description='Python unittest TAP driver')
+    parser.add_argument('module', nargs=1,
+                        help="A unittest test module to run")
+    args = parser.parse_args(argv[1:])
+
+    (name, ext) = os.path.splitext(os.path.basename(args.module[0]))
+    module = imp.load_source(name, args.module[0])
+    loader = unittest.TestLoader()
+    tests = loader.loadTestsFromModule(module)
+    runner = TAPTestRunner()
+    runner.run(tests)
+
+if __name__ == "__main__":
+    sys.exit(main(sys.argv))
diff --git a/build/test-driver b/build/test-driver
new file mode 100755
index 0000000..32bf39e
--- /dev/null
+++ b/build/test-driver
@@ -0,0 +1,127 @@
+#! /bin/sh
+# test-driver - basic testsuite driver script.
+
+scriptversion=2012-06-27.10; # UTC
+
+# Copyright (C) 2011-2013 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This file is maintained in Automake, please report
+# bugs to <bug-automake gnu org> or send patches to
+# <automake-patches gnu org>.
+
+# Make unconditional expansion of undefined variables an error.  This
+# helps a lot in preventing typo-related bugs.
+set -u
+
+usage_error ()
+{
+  echo "$0: $*" >&2
+  print_usage >&2
+  exit 2
+}
+
+print_usage ()
+{
+  cat <<END
+Usage:
+  test-driver --test-name=NAME --log-file=PATH --trs-file=PATH
+              [--expect-failure={yes|no}] [--color-tests={yes|no}]
+              [--enable-hard-errors={yes|no}] [--] TEST-SCRIPT
+The '--test-name', '--log-file' and '--trs-file' options are mandatory.
+END
+}
+
+# TODO: better error handling in option parsing (in particular, ensure
+# TODO: $log_file, $trs_file and $test_name are defined).
+test_name= # Used for reporting.
+log_file=  # Where to save the output of the test script.
+trs_file=  # Where to save the metadata of the test run.
+expect_failure=no
+color_tests=no
+enable_hard_errors=yes
+while test $# -gt 0; do
+  case $1 in
+  --help) print_usage; exit $?;;
+  --version) echo "test-driver $scriptversion"; exit $?;;
+  --test-name) test_name=$2; shift;;
+  --log-file) log_file=$2; shift;;
+  --trs-file) trs_file=$2; shift;;
+  --color-tests) color_tests=$2; shift;;
+  --expect-failure) expect_failure=$2; shift;;
+  --enable-hard-errors) enable_hard_errors=$2; shift;;
+  --) shift; break;;
+  -*) usage_error "invalid option: '$1'";;
+  esac
+  shift
+done
+
+if test $color_tests = yes; then
+  # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.
+  red='' # Red.
+  grn='' # Green.
+  lgn='' # Light green.
+  blu='' # Blue.
+  mgn='' # Magenta.
+  std=''     # No color.
+else
+  red= grn= lgn= blu= mgn= std=
+fi
+
+do_exit='rm -f $log_file $trs_file; (exit $st); exit $st'
+trap "st=129; $do_exit" 1
+trap "st=130; $do_exit" 2
+trap "st=141; $do_exit" 13
+trap "st=143; $do_exit" 15
+
+# Test script is run here.
+"$@" >$log_file 2>&1
+estatus=$?
+if test $enable_hard_errors = no && test $estatus -eq 99; then
+  estatus=1
+fi
+
+case $estatus:$expect_failure in
+  0:yes) col=$red res=XPASS recheck=yes gcopy=yes;;
+  0:*)   col=$grn res=PASS  recheck=no  gcopy=no;;
+  77:*)  col=$blu res=SKIP  recheck=no  gcopy=yes;;
+  99:*)  col=$mgn res=ERROR recheck=yes gcopy=yes;;
+  *:yes) col=$lgn res=XFAIL recheck=no  gcopy=yes;;
+  *:*)   col=$red res=FAIL  recheck=yes gcopy=yes;;
+esac
+
+# Report outcome to console.
+echo "${col}${res}${std}: $test_name"
+
+# Register the test result, and other relevant metadata.
+echo ":test-result: $res" > $trs_file
+echo ":global-test-result: $res" >> $trs_file
+echo ":recheck: $recheck" >> $trs_file
+echo ":copy-in-global-log: $gcopy" >> $trs_file
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/configure.ac b/configure.ac
index 595be0e..caa89f5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -45,6 +45,7 @@ SECRET_AGE=0
 # -----------------------------------------------------------------------------
 
 AC_CONFIG_MACRO_DIR([build/m4])
+AC_CONFIG_AUX_DIR([build])
 AM_INIT_AUTOMAKE([1.11 tar-ustar foreign -Wno-portability])
 AM_SANITY_CHECK
 AC_CONFIG_HEADERS(config.h)
@@ -272,22 +273,13 @@ AC_SUBST(SECRET_MINOR)
 
 AC_CONFIG_FILES([
        Makefile
-       build/Makefile
-       docs/Makefile
-       docs/man/Makefile
-       docs/reference/Makefile
        docs/reference/libsecret/Makefile
        docs/reference/libsecret/version.xml
        docs/reference/libsecret/version-major.xml
-       egg/Makefile
-       egg/tests/Makefile
        po/Makefile.in
        po/Makefile
-       libsecret/Makefile
        libsecret/libsecret.pc
        libsecret/libsecret-unstable.pc
-       libsecret/tests/Makefile
-       tool/Makefile
 ])
 AC_OUTPUT
 
diff --git a/docs/man/Makefile.am b/docs/man/Makefile.am
index 66bcfd5..07bfd55 100644
--- a/docs/man/Makefile.am
+++ b/docs/man/Makefile.am
@@ -6,14 +6,10 @@ XSLTPROC_FLAGS = \
         --stringparam man.authors.section.enabled 0 \
         --stringparam man.copyright.section.enabled 0
 
-.xml.1:
+secret-tool.1: docs/man/secret-tool.xml
        $(AM_V_GEN) $(XSLTPROC) $(XSLTPROC_FLAGS) 
http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
 
-man_MANS = \
+man_MANS += \
        secret-tool.1
 
-xml_files = $(man_MANS:.1=.xml)
-
-EXTRA_DIST = $(xml_files)
-
-DISTCLEANFILES = $(man_MANS)
+EXTRA_DIST += docs/man/secret-tool.xml
diff --git a/docs/reference/libsecret/Makefile.am b/docs/reference/libsecret/Makefile.am
index 137be73..410a23e 100644
--- a/docs/reference/libsecret/Makefile.am
+++ b/docs/reference/libsecret/Makefile.am
@@ -21,7 +21,7 @@ DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml
 # gtk-doc will search all .c & .h files beneath here for inline comments
 # documenting the functions and macros.
 # e.g. DOC_SOURCE_DIR=../../../gtk
-DOC_SOURCE_DIR=$(top_srcdir)/libsecret
+DOC_SOURCE_DIR=$(top_srcdir)/libsecret $(top_builddir)/libsecret
 
 # Extra options to pass to gtkdoc-scangobj. Not normally needed.
 SCANGOBJ_OPTIONS=
@@ -89,7 +89,7 @@ GTKDOC_CFLAGS= -I$(top_srcdir) -I$(top_builddir) $(GLIB_CFLAGS) -Wno-error \
        -Wno-deprecated-declarations
 
 GTKDOC_LIBS= $(GLIB_LIBS) $(GOBJECT_LIBS) \
-       $(top_builddir)/libsecret/libsecret- SECRET_MAJOR@.la
+       $(top_builddir)/libsecret- SECRET_MAJOR@.la
 
 # This includes the standard gtk-doc make rules, copied by gtkdocize.
 include $(top_srcdir)/gtk-doc.make
diff --git a/egg/Makefile.am b/egg/Makefile.am
index 9b8e2fa..dc136a8 100644
--- a/egg/Makefile.am
+++ b/egg/Makefile.am
@@ -1,29 +1,46 @@
-SUBDIRS = . tests
-
-noinst_LTLIBRARIES = \
+noinst_LTLIBRARIES += \
        libegg.la
 
-EXTRA_DIST = egg-testing.h
-
-AM_CPPFLAGS = \
-       -I$(top_srcdir) \
-       -I$(top_srcdir)/build \
-       -DWITH_VALGRIND
+EXTRA_DIST += egg/egg-testing.h
 
 if WITH_GCRYPT
-ENCRYPTION_SRCS = egg-dh.c egg-dh.h
-ENCRYPTION_SRCS += egg-hkdf.c egg-hkdf.h
-ENCRYPTION_SRCS += egg-libgcrypt.c egg-libgcrypt.h
+ENCRYPTION_SRCS = egg/egg-dh.c egg/egg-dh.h
+ENCRYPTION_SRCS += egg/egg-hkdf.c egg/egg-hkdf.h
+ENCRYPTION_SRCS += egg/egg-libgcrypt.c egg/egg-libgcrypt.h
 else
 ENCRYPTION_SRCS =
 endif
 
 libegg_la_SOURCES = \
-       egg-hex.c egg-hex.h \
-       egg-secure-memory.c egg-secure-memory.h \
-       egg-testing.c egg-testing.h \
-       $(ENCRYPTION_SRCS) \
-       $(BUILT_SOURCES)
-
-check-memory:
-       make -C tests check-memory
\ No newline at end of file
+       egg/egg-hex.c egg/egg-hex.h \
+       egg/egg-secure-memory.c egg/egg-secure-memory.h \
+       egg/egg-testing.c egg/egg-testing.h \
+       $(ENCRYPTION_SRCS)
+
+egg_LIBS =  \
+       libegg.la \
+       $(LIBGCRYPT_LIBS) \
+       $(GLIB_LIBS)
+
+egg_TESTS = \
+       test-hex \
+       test-secmem
+
+test_hex_SOURCES = egg/test-hex.c
+test_hex_LDADD = $(egg_LIBS)
+
+test_secmem_SOURCES = egg/test-secmem.c
+test_secmem_LDADD = $(egg_LIBS)
+
+if WITH_GCRYPT
+egg_TESTS += test-hkdf test-dh
+
+test_hkdf_SOURCES = egg/test-hkdf.c
+test_hkdf_LDADD = $(egg_LIBS)
+
+test_dh_SOURCES = egg/test-dh.c
+test_dh_LDADD = $(egg_LIBS)
+endif
+
+check_PROGRAMS += $(egg_TESTS)
+TESTS += $(egg_TESTS)
diff --git a/egg/tests/test-dh.c b/egg/test-dh.c
similarity index 100%
rename from egg/tests/test-dh.c
rename to egg/test-dh.c
diff --git a/egg/tests/test-hex.c b/egg/test-hex.c
similarity index 100%
rename from egg/tests/test-hex.c
rename to egg/test-hex.c
diff --git a/egg/tests/test-hkdf.c b/egg/test-hkdf.c
similarity index 100%
rename from egg/tests/test-hkdf.c
rename to egg/test-hkdf.c
diff --git a/egg/tests/test-secmem.c b/egg/test-secmem.c
similarity index 100%
rename from egg/tests/test-secmem.c
rename to egg/test-secmem.c
diff --git a/libsecret/Makefile.am b/libsecret/Makefile.am
index 47d0969..f23109a 100644
--- a/libsecret/Makefile.am
+++ b/libsecret/Makefile.am
@@ -1,70 +1,63 @@
-include $(top_srcdir)/Makefile.decl
 
-SUBDIRS = . tests
-
-AM_CPPFLAGS = \
-       -I$(top_srcdir) \
-       -DSECRET_COMPILATION \
-       $(NULL)
-
-lib_LTLIBRARIES = libsecret- SECRET_MAJOR@.la
+lib_LTLIBRARIES += libsecret- SECRET_MAJOR@.la
 
 
 incdir = $(includedir)/libsecret- SECRET_MAJOR@/libsecret
 
-HEADER_FILES = \
-       secret.h \
-       secret-attributes.h \
-       secret-collection.h \
-       secret-item.h \
-       secret-password.h \
-       secret-paths.h \
-       secret-prompt.h \
-       secret-schema.h \
-       secret-schemas.h \
-       secret-service.h \
-       secret-types.h \
-       secret-value.h \
+libsecret_HEADS = \
+       libsecret/secret.h \
+       libsecret/secret-attributes.h \
+       libsecret/secret-collection.h \
+       libsecret/secret-item.h \
+       libsecret/secret-password.h \
+       libsecret/secret-paths.h \
+       libsecret/secret-prompt.h \
+       libsecret/secret-schema.h \
+       libsecret/secret-schemas.h \
+       libsecret/secret-service.h \
+       libsecret/secret-types.h \
+       libsecret/secret-value.h \
        $(NULL)
 
 inc_HEADERS = \
-       $(HEADER_FILES) \
-       secret-enum-types.h \
+       $(libsecret_HEADS) \
+       libsecret/secret-enum-types.h \
        $(NULL)
 
-BUILT_SOURCES = \
+libsecret_BUILT = \
        secret-dbus-generated.c secret-dbus-generated.h \
-       secret-enum-types.c secret-enum-types.h \
+       libsecret/secret-enum-types.c libsecret/secret-enum-types.h \
        $(NULL)
 
-PUBLIC_FILES = \
-       secret-attributes.h secret-attributes.c \
-       secret-collection.h secret-collection.c \
-       secret-item.h secret-item.c \
-       secret-methods.c \
-       secret-password.h secret-password.c \
-       secret-prompt.h secret-prompt.c \
-       secret-schema.h secret-schema.c \
-       secret-schemas.h secret-schemas.c \
-       secret-service.h secret-service.c \
-       secret-types.h \
-       secret-value.h secret-value.c \
-       secret-paths.h secret-paths.c \
+libsecret_PUBLIC = \
+       libsecret/secret-attributes.h libsecret/secret-attributes.c \
+       libsecret/secret-collection.h libsecret/secret-collection.c \
+       libsecret/secret-item.h libsecret/secret-item.c \
+       libsecret/secret-methods.c \
+       libsecret/secret-password.h libsecret/secret-password.c \
+       libsecret/secret-prompt.h libsecret/secret-prompt.c \
+       libsecret/secret-schema.h libsecret/secret-schema.c \
+       libsecret/secret-schemas.h libsecret/secret-schemas.c \
+       libsecret/secret-service.h libsecret/secret-service.c \
+       libsecret/secret-types.h \
+       libsecret/secret-value.h libsecret/secret-value.c \
+       libsecret/secret-paths.h libsecret/secret-paths.c \
        $(NULL)
 
-PRIVATE_FILES = \
-       secret-private.h \
-       secret-session.c \
-       secret-util.c \
+libsecret_PRIVATE = \
+       libsecret/secret-private.h \
+       libsecret/secret-session.c \
+       libsecret/secret-util.c \
        $(NULL)
 
 libsecret_ SECRET_MAJOR@_la_SOURCES = \
-       $(PUBLIC_FILES) \
-       $(PRIVATE_FILES) \
-       $(BUILT_SOURCES) \
+       $(libsecret_PUBLIC) \
+       $(libsecret_PRIVATE) \
+       $(libsecret_BUILT) \
        $(NULL)
 
 libsecret_ SECRET_MAJOR@_la_CFLAGS = \
+       -DSECRET_COMPILATION \
        $(LIBGCRYPT_CFLAGS)
 
 libsecret_ SECRET_MAJOR@_la_LDFLAGS = \
@@ -73,24 +66,25 @@ libsecret_ SECRET_MAJOR@_la_LDFLAGS = \
        -export-symbols-regex '^secret_|^SECRET_|^SECMEM_.*'
 
 libsecret_ SECRET_MAJOR@_la_LIBADD = \
-       $(top_builddir)/egg/libegg.la \
+       libegg.la \
        $(LIBGCRYPT_LIBS) \
        $(LIBS)
 
-noinst_LTLIBRARIES = libsecret-testable.la
+BUILT_SOURCES += $(libsecret_BUILT)
+
+noinst_LTLIBRARIES += libsecret-testable.la
 libsecret_testable_la_SOURCES =
 libsecret_testable_la_LIBADD = $(libsecret_ SECRET_MAJOR@_la_OBJECTS) \
        $(libsecret_ SECRET_MAJOR@_la_LIBADD)
-libsecret_testable_la_DEPENDENCIES = $(libsecret_ SECRET_MAJOR@_la_OBJECTS)
+EXTRA_libsecret_testable_la_DEPENDENCIES = $(libsecret_ SECRET_MAJOR@_la_OBJECTS)
 libsecret_testable_la_LDFLAGS = -rpath /force/shared
 
 DBUS_XML_DEFINITIONS = \
-       $(srcdir)/org.freedesktop.Secrets.xml
+       libsecret/org.freedesktop.Secrets.xml
 
 temp-dbus-generated.c: $(DBUS_XML_DEFINITIONS) Makefile.am
        $(AM_V_GEN) gdbus-codegen --interface-prefix org.freedesktop.Secret. \
-               --generate-c-code temp-dbus-generated --c-namespace SecretGen \
-               $(DBUS_XML_DEFINITIONS)
+               --generate-c-code temp-dbus-generated --c-namespace SecretGen $<
 secret-dbus-generated.c: temp-dbus-generated.c Makefile.am
        $(AM_V_GEN) sed -e '1i\
        #define GLIB_DISABLE_DEPRECATION_WARNINGS' \
@@ -101,24 +95,18 @@ secret-dbus-generated.h: temp-dbus-generated.c Makefile.am
        $(AM_V_GEN) sed -e 's/secret_gen_/_secret_gen_/g' -e 's/type-/type/g' \
                temp-dbus-generated.h > secret-dbus-generated.h
 
-secret-enum-types.h: secret-enum-types.h.template $(HEADER_FILES)
+libsecret/secret-enum-types.h: libsecret/secret-enum-types.h.template $(libsecret_HEADS)
        $(AM_V_GEN) $(GLIB_MKENUMS) --template $^ > $@
 
-secret-enum-types.c: secret-enum-types.c.template $(HEADER_FILES)
+libsecret/secret-enum-types.c: libsecret/secret-enum-types.c.template $(libsecret_HEADS)
        $(AM_V_GEN) $(GLIB_MKENUMS) --template $^ > $@
 
-CLEANFILES =
-
 # ------------------------------------------------------------------
 # INTROSPECTION
 
 if HAVE_INTROSPECTION
 
-include $(INTROSPECTION_MAKEFILE)
-
-INTROSPECTION_GIRS = Secret- SECRET_MAJOR@.gir
-INTROSPECTION_SCANNER_ARGS = $(INTROSPECTION_FLAGS) --warn-all --add-include-path=$(srcdir) 
--add-include-path=.
-INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir) --includedir=.
+INTROSPECTION_GIRS += Secret- SECRET_MAJOR@.gir
 
 Secret- SECRET_MAJOR@.gir: libsecret- SECRET_MAJOR@.la
 
@@ -126,79 +114,241 @@ Secret_ SECRET_MAJOR@_gir_NAMESPACE = Secret
 Secret_ SECRET_MAJOR@_gir_EXPORT_PACKAGES = libsecret- SECRET_MAJOR@
 Secret_ SECRET_MAJOR@_gir_INCLUDES = GObject-2.0 Gio-2.0
 Secret_ SECRET_MAJOR@_gir_LIBS = libsecret- SECRET_MAJOR@.la
-Secret_ SECRET_MAJOR@_gir_CFLAGS = -I$(top_srcdir) -I$(top_builddir) -DSECRET_COMPILATION
-Secret_ SECRET_MAJOR@_gir_FILES = $(PUBLIC_FILES)
+Secret_ SECRET_MAJOR@_gir_CFLAGS = -I$(srcdir) -I$(builddir) -DSECRET_COMPILATION
+Secret_ SECRET_MAJOR@_gir_FILES = $(libsecret_PUBLIC)
 Secret_ SECRET_MAJOR@_gir_SCANNERFLAGS = --c-include "libsecret/secret.h"
 
-girdir = $(datadir)/gir-1.0
-gir_DATA = Secret- SECRET_MAJOR@.gir
-
-typelibsdir = $(libdir)/girepository-1.0
-typelibs_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
+gir_DATA += Secret- SECRET_MAJOR@.gir
 
 if ENABLE_VAPIGEN
-include $(VAPIGEN_MAKEFILE)
 
-libsecret- SECRET_MAJOR@.vapi: Secret- SECRET_MAJOR@.gir Secret- SECRET_MAJOR@.metadata libsecret- 
SECRET_MAJOR@.deps
+libsecret- SECRET_MAJOR@.vapi: Secret- SECRET_MAJOR@.gir libsecret/Secret- SECRET_MAJOR@.metadata libsecret- 
SECRET_MAJOR@.deps
 
-VAPIGEN_VAPIS = \
-       libsecret- SECRET_MAJOR@.vapi
+VAPIGEN_VAPIS += libsecret- SECRET_MAJOR@.vapi
 
 libsecret_ SECRET_MAJOR@_vapi_DEPS = glib-2.0 gio-2.0
-libsecret_ SECRET_MAJOR@_vapi_METADATADIRS = $(srcdir)
+libsecret_ SECRET_MAJOR@_vapi_METADATADIRS = $(srcdir)/libsecret
 libsecret_ SECRET_MAJOR@_vapi_FILES = Secret- SECRET_MAJOR@.gir
 
-VAPI_DEPS = $(VAPIGEN_VAPIS:.vapi=.deps)
-
 libsecret-$(SECRET_MAJOR).deps: Makefile.am
        $(AM_V_GEN) echo $(libsecret_ SECRET_MAJOR@_vapi_DEPS) | tr ' ' '\n' > $@
 
-vapidir = $(datadir)/vala/vapi
-vapi_DATA = \
-       $(VAPIGEN_VAPIS) \
-       $(VAPI_DEPS)
-
-CLEANFILES += \
-       $(VAPIGEN_VAPIS) \
-       $(VAPI_DEPS)
-
+vapi_DATA += \
+       libsecret- SECRET_MAJOR@.vapi \
+       libsecret- SECRET_MAJOR@.deps
+       
 endif # ENABLE_VAPIGEN
 endif # HAVE_INTROSPECTION
 
 # ------------------------------------------------------------------
 # PKG CONFIG
 
-libsecret-$(SECRET_MAJOR).pc: libsecret.pc
-       cp libsecret.pc libsecret-$(SECRET_MAJOR).pc
+libsecret-$(SECRET_MAJOR).pc: libsecret/libsecret.pc
+       cp libsecret/libsecret.pc libsecret-$(SECRET_MAJOR).pc
 
-pkgconfigdir = $(libdir)/pkgconfig
-pkgconfig_DATA = \
+pkgconfig_DATA += \
        libsecret-$(SECRET_MAJOR).pc \
-       libsecret-unstable.pc
-
-# ------------------------------------------------------------------
-
+       libsecret/libsecret-unstable.pc
 
-EXTRA_DIST = \
-       secret-enum-types.h.template \
-       secret-enum-types.c.template \
-       org.freedesktop.Secrets.xml \
-       Secret- SECRET_MAJOR@.metadata \
+EXTRA_DIST += \
+       libsecret/secret-enum-types.h.template \
+       libsecret/secret-enum-types.c.template \
+       libsecret/org.freedesktop.Secrets.xml \
+       libsecret/Secret- SECRET_MAJOR@.metadata \
        $(NULL)
 
 CLEANFILES += \
-       $(pkgconfig_DATA) \
-       $(gir_DATA) \
-       $(typelibs_DATA) \
-       $(noinst_DATA) \
        temp-dbus-generated.c \
        temp-dbus-generated.h \
        $(NULL)
 
-DISTCLEANFILES = \
+DISTCLEANFILES += \
        secret-dbus-generated.c \
        secret-dbus-generated.h \
        $(NULL)
 
-check-memory:
-       make -C tests check-memory
+# ------------------------------------------------------------------
+# TESTS
+
+noinst_LTLIBRARIES += libmock_service.la
+
+libmock_service_la_SOURCES = \
+       libsecret/mock-service.c \
+       libsecret/mock-service.h \
+       $(NULL)
+
+libmock_service_la_LDFLAGS = \
+       -rpath /force/shared
+
+libmock_service_la_LIBADD = \
+       $(LIBGCRYPT_LIBS)
+
+libsecret_LIBS = \
+       libsecret-testable.la \
+       libmock_service.la \
+       $(NULL)
+
+C_TESTS = \
+       test-attributes \
+       test-value \
+       test-prompt \
+       test-service \
+       test-session \
+       test-paths \
+       test-methods \
+       test-password \
+       test-item \
+       test-collection \
+       $(NULL)
+
+test_attributes_SOURCES = libsecret/test-attributes.c
+test_attributes_LDADD = $(libsecret_LIBS)
+
+test_collection_SOURCES = libsecret/test-collection.c
+test_collection_LDADD = $(libsecret_LIBS)
+
+test_item_SOURCES = libsecret/test-item.c
+test_item_LDADD = $(libsecret_LIBS)
+
+test_methods_SOURCES = libsecret/test-methods.c
+test_methods_LDADD = $(libsecret_LIBS)
+
+test_password_SOURCES = libsecret/test-password.c
+test_password_LDADD = $(libsecret_LIBS)
+
+test_paths_SOURCES = libsecret/test-paths.c
+test_paths_LDADD = $(libsecret_LIBS)
+
+test_prompt_SOURCES = libsecret/test-prompt.c
+test_prompt_LDADD = $(libsecret_LIBS)
+
+test_service_SOURCES = libsecret/test-service.c
+test_service_LDADD = $(libsecret_LIBS)
+
+test_session_SOURCES = libsecret/test-session.c
+test_session_LDADD = $(libsecret_LIBS)
+
+test_value_SOURCES = libsecret/test-value.c
+test_value_LDADD = $(libsecret_LIBS)
+
+JS_TESTS = \
+       libsecret/test-js-lookup.js \
+       libsecret/test-js-clear.js \
+       libsecret/test-js-store.js \
+       $(NULL)
+
+PY_TESTS = \
+       libsecret/test-py-lookup.py \
+       libsecret/test-py-clear.py \
+       libsecret/test-py-store.py \
+       $(NULL)
+
+check_PROGRAMS += $(C_TESTS)
+TESTS += $(C_TESTS) $(PY_TESTS) $(JS_TESTS)
+
+# ------------------------------------------------------------------
+# VALA TESTS
+
+if HAVE_VALAC
+
+VALA_V = $(VALA_V_$(V))
+VALA_V_ = $(VALA_V_$(AM_DEFAULT_VERBOSITY))
+VALA_V_0 = @echo "  VALAC   ";
+
+VALA_TESTS_FLAGS = \
+       --vapidir=$(builddir) \
+       --pkg libsecret- SECRET_MAJOR@ \
+       --pkg mock-service-0 \
+       --pkg gio-2.0
+
+VALA_TESTS_VAPIS = \
+       libsecret- SECRET_MAJOR@.vapi \
+       mock-service-0.vapi
+
+VALA_TESTS = \
+       test-vala-lang \
+       test-vala-unstable \
+       $(NULL)
+
+%.c: libsecret/%.vala $(VALA_TESTS_VAPIS)
+       $(VALA_V) $(VALAC) -C $(VALA_TESTS_FLAGS) $<
+
+test_vala_lang_CFLAGS = -w
+test_vala_lang_LDADD = libsecret- SECRET_MAJOR@.la libmock_service.la
+
+test_vala_unstable_CFLAGS = -w
+test_vala_unstable_LDADD = libsecret- SECRET_MAJOR@.la libmock_service.la
+
+VALA_TESTS_SRCS = \
+       libsecret/test-vala-lang.vala \
+       libsecret/test-vala-unstable.vala
+
+CLEANFILES += \
+       test-vala-lang.c \
+       test-vala-unstable.c
+
+if HAVE_INTROSPECTION
+if ENABLE_VAPIGEN
+
+check_PROGRAMS += $(VALA_TESTS)
+TESTS += $(VALA_TESTS)
+
+endif # ENABLE_VAPIGEN
+endif # HAVE_INTROSPECTION
+
+endif # HAVE_VALAC
+
+# ------------------------------------------------------------------
+# TEST INTROSPECTION
+
+if HAVE_INTROSPECTION
+
+INTROSPECTION_GIRS += MockService-0.gir
+
+MockService-0.gir: libmock_service.la
+
+MockService_0_gir_PACKAGES = gobject-2.0 gio-2.0
+MockService_0_gir_EXPORT_PACKAGES = mock-service-0
+MockService_0_gir_INCLUDES = GObject-2.0 Gio-2.0
+MockService_0_gir_LIBS = libmock_service.la
+MockService_0_gir_CFLAGS = -I$(builddir) -I$(srcdir)
+MockService_0_gir_FILES = $(libmock_service_la_SOURCES)
+MockService_0_gir_SCANNERFLAGS = --c-include "libsecret/mock-service.h"
+
+noinst_DATA += MockService-0.gir MockService-0.typelib
+CLEANFILES += MockService-0.gir MockService-0.typelib
+
+if ENABLE_VAPIGEN
+
+mock-service-0.vapi: MockService-0.gir libsecret- SECRET_MAJOR@.vapi
+
+mock-service-0.deps:
+
+VAPIGEN_VAPIS += mock-service-0.vapi
+
+mock_service_0_vapi_DEPS = gio-2.0 libsecret- SECRET_MAJOR@
+mock_service_0_vapi_METADATADIRS = $(builddir)
+mock_service_0_vapi_VAPIDIRS = $(builddir)
+mock_service_0_vapi_FILES = MockService-0.gir
+
+noinst_DATA += mock-service-0.vapi
+
+CLEANFILES += mock-service-0.vapi
+
+endif # ENABLE_VAPIGEN
+endif # HAVE_INTROSPECTION
+
+#--------------------------------------------------------------------
+
+EXTRA_DIST += \
+       libsecret/mock \
+       libsecret/mock-service-delete.py \
+       libsecret/mock-service-empty.py \
+       libsecret/mock-service-lock.py \
+       libsecret/mock-service-normal.py \
+       libsecret/mock-service-only-plain.py \
+       libsecret/mock-service-prompt.py \
+       $(VALA_TESTS_SRCS) \
+       $(JS_TESTS) \
+       $(PY_TESTS) \
+       $(NULL)
diff --git a/libsecret/tests/mock-service-delete.py b/libsecret/mock-service-delete.py
similarity index 100%
rename from libsecret/tests/mock-service-delete.py
rename to libsecret/mock-service-delete.py
diff --git a/libsecret/tests/mock-service-empty.py b/libsecret/mock-service-empty.py
similarity index 100%
rename from libsecret/tests/mock-service-empty.py
rename to libsecret/mock-service-empty.py
diff --git a/libsecret/tests/mock-service-lock.py b/libsecret/mock-service-lock.py
similarity index 100%
rename from libsecret/tests/mock-service-lock.py
rename to libsecret/mock-service-lock.py
diff --git a/libsecret/tests/mock-service-normal.py b/libsecret/mock-service-normal.py
similarity index 100%
rename from libsecret/tests/mock-service-normal.py
rename to libsecret/mock-service-normal.py
diff --git a/libsecret/tests/mock-service-only-plain.py b/libsecret/mock-service-only-plain.py
similarity index 100%
rename from libsecret/tests/mock-service-only-plain.py
rename to libsecret/mock-service-only-plain.py
diff --git a/libsecret/tests/mock-service-prompt.py b/libsecret/mock-service-prompt.py
similarity index 100%
rename from libsecret/tests/mock-service-prompt.py
rename to libsecret/mock-service-prompt.py
diff --git a/libsecret/tests/mock-service.c b/libsecret/mock-service.c
similarity index 71%
rename from libsecret/tests/mock-service.c
rename to libsecret/mock-service.c
index 583e015..68baec4 100644
--- a/libsecret/tests/mock-service.c
+++ b/libsecret/mock-service.c
@@ -21,12 +21,14 @@
 
 #include <errno.h>
 #include <stdio.h>
+#include <string.h>
 
+static GTestDBus *test_bus = NULL;
 static GPid pid = 0;
 
-gboolean
-mock_service_start (const gchar *mock_script,
-                    GError **error)
+static gboolean
+service_start (const gchar *mock_script,
+               GError **error)
 {
        gchar ready[8] = { 0, };
        GSpawnFlags flags;
@@ -45,6 +47,9 @@ mock_service_start (const gchar *mock_script,
        g_return_val_if_fail (mock_script != NULL, FALSE);
        g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
 
+       test_bus = g_test_dbus_new (G_TEST_DBUS_NONE);
+       g_test_dbus_up (test_bus);
+
        g_setenv ("SECRET_SERVICE_BUS_NAME", MOCK_SERVICE_NAME, TRUE);
 
        if (pipe (wait_pipe) < 0) {
@@ -76,9 +81,25 @@ mock_service_start (const gchar *mock_script,
        return ret;
 }
 
+gboolean
+mock_service_start (const gchar *mock_script,
+                    GError **error)
+{
+       gchar *path;
+       gboolean ret;
+
+       path = g_build_filename (SRCDIR, "libsecret", mock_script, NULL);
+       ret = service_start (path, error);
+       g_free (path);
+
+       return ret;
+}
+
 void
 mock_service_stop (void)
 {
+       const gchar *prgname;
+
        if (!pid)
                return;
 
@@ -89,4 +110,21 @@ mock_service_stop (void)
 
        g_spawn_close_pid (pid);
        pid = 0;
+
+       while (g_main_context_iteration (NULL, FALSE));
+
+       /*
+        * HACK: Don't worry about leaking tests when running under gjs.
+        * Waiting for the connection to go away is hopeless due to
+        * the way gjs garbage collects.
+        */
+       prgname = g_get_prgname ();
+       if (prgname && strstr (prgname, "gjs")) {
+               g_test_dbus_stop (test_bus);
+
+       } else {
+               g_test_dbus_down (test_bus);
+               g_object_unref (test_bus);
+       }
+       test_bus = NULL;
 }
diff --git a/libsecret/tests/mock-service.h b/libsecret/mock-service.h
similarity index 100%
rename from libsecret/tests/mock-service.h
rename to libsecret/mock-service.h
diff --git a/libsecret/tests/mock/__init__.py b/libsecret/mock/__init__.py
similarity index 100%
rename from libsecret/tests/mock/__init__.py
rename to libsecret/mock/__init__.py
diff --git a/libsecret/tests/mock/aes.py b/libsecret/mock/aes.py
similarity index 100%
rename from libsecret/tests/mock/aes.py
rename to libsecret/mock/aes.py
diff --git a/libsecret/tests/mock/dh.py b/libsecret/mock/dh.py
similarity index 100%
rename from libsecret/tests/mock/dh.py
rename to libsecret/mock/dh.py
diff --git a/libsecret/tests/mock/hkdf.py b/libsecret/mock/hkdf.py
similarity index 100%
rename from libsecret/tests/mock/hkdf.py
rename to libsecret/mock/hkdf.py
diff --git a/libsecret/tests/mock/service.py b/libsecret/mock/service.py
similarity index 100%
rename from libsecret/tests/mock/service.py
rename to libsecret/mock/service.py
diff --git a/libsecret/secret-collection.c b/libsecret/secret-collection.c
index 3acdacd..0bef304 100644
--- a/libsecret/secret-collection.c
+++ b/libsecret/secret-collection.c
@@ -16,13 +16,14 @@
 
 #include "secret-collection.h"
 #include "secret-dbus-generated.h"
-#include "secret-enum-types.h"
 #include "secret-item.h"
 #include "secret-paths.h"
 #include "secret-private.h"
 #include "secret-service.h"
 #include "secret-types.h"
 
+#include "libsecret/secret-enum-types.h"
+
 #include <glib/gi18n-lib.h>
 
 /**
diff --git a/libsecret/secret-item.c b/libsecret/secret-item.c
index abcfa62..1e8c141 100644
--- a/libsecret/secret-item.c
+++ b/libsecret/secret-item.c
@@ -16,7 +16,6 @@
 
 #include "secret-collection.h"
 #include "secret-dbus-generated.h"
-#include "secret-enum-types.h"
 #include "secret-item.h"
 #include "secret-paths.h"
 #include "secret-private.h"
@@ -24,6 +23,8 @@
 #include "secret-types.h"
 #include "secret-value.h"
 
+#include "libsecret/secret-enum-types.h"
+
 #include <glib/gi18n-lib.h>
 
 /**
@@ -97,11 +98,11 @@ struct _SecretItemPrivate {
        /* No changes between construct and finalize */
        SecretService *service;
        SecretItemFlags init_flags;
-       GCancellable *cancellable;
 
        /* Locked by mutex */
        GMutex mutex;
        SecretValue *value;
+       gint disposed;
 };
 
 static GInitableIface *secret_item_initable_parent_iface = NULL;
@@ -121,7 +122,6 @@ static void
 secret_item_init (SecretItem *self)
 {
        self->pv = G_TYPE_INSTANCE_GET_PRIVATE (self, SECRET_TYPE_ITEM, SecretItemPrivate);
-       self->pv->cancellable = g_cancellable_new ();
        g_mutex_init (&self->pv->mutex);
 }
 
@@ -133,10 +133,12 @@ on_set_attributes (GObject *source,
        SecretItem *self = SECRET_ITEM (user_data);
        GError *error = NULL;
 
-       secret_item_set_attributes_finish (self, result, &error);
-       if (error != NULL) {
-               g_warning ("couldn't set SecretItem Attributes: %s", error->message);
-               g_error_free (error);
+       if (!g_atomic_int_get (&self->pv->disposed)) {
+               secret_item_set_attributes_finish (self, result, &error);
+               if (error != NULL) {
+                       g_warning ("couldn't set SecretItem Attributes: %s", error->message);
+                       g_error_free (error);
+               }
        }
 
        g_object_unref (self);
@@ -150,10 +152,12 @@ on_set_label (GObject *source,
        SecretItem *self = SECRET_ITEM (user_data);
        GError *error = NULL;
 
-       secret_item_set_label_finish (self, result, &error);
-       if (error != NULL) {
-               g_warning ("couldn't set SecretItem Label: %s", error->message);
-               g_error_free (error);
+       if (!g_atomic_int_get (&self->pv->disposed)) {
+               secret_item_set_label_finish (self, result, &error);
+               if (error != NULL) {
+                       g_warning ("couldn't set SecretItem Label: %s", error->message);
+                       g_error_free (error);
+               }
        }
 
        g_object_unref (self);
@@ -194,12 +198,12 @@ secret_item_set_property (GObject *obj,
                break;
        case PROP_ATTRIBUTES:
                secret_item_set_attributes (self, NULL, g_value_get_boxed (value),
-                                           self->pv->cancellable, on_set_attributes,
+                                           NULL, on_set_attributes,
                                            g_object_ref (self));
                break;
        case PROP_LABEL:
                secret_item_set_label (self, g_value_get_string (value),
-                                      self->pv->cancellable, on_set_label,
+                                      NULL, on_set_label,
                                       g_object_ref (self));
                break;
        default:
@@ -249,7 +253,7 @@ secret_item_dispose (GObject *obj)
 {
        SecretItem *self = SECRET_ITEM (obj);
 
-       g_cancellable_cancel (self->pv->cancellable);
+       g_atomic_int_inc (&self->pv->disposed);
 
        G_OBJECT_CLASS (secret_item_parent_class)->dispose (obj);
 }
@@ -263,7 +267,6 @@ secret_item_finalize (GObject *obj)
                g_object_remove_weak_pointer (G_OBJECT (self->pv->service),
                                              (gpointer *)&self->pv->service);
 
-       g_object_unref (self->pv->cancellable);
        g_mutex_clear (&self->pv->mutex);
 
        G_OBJECT_CLASS (secret_item_parent_class)->finalize (obj);
@@ -1170,6 +1173,7 @@ on_item_load_secret (GObject *source,
        }
 
        g_simple_async_result_complete (res);
+       g_object_unref (self);
        g_object_unref (res);
 }
 
@@ -1332,6 +1336,7 @@ loads_closure_free (gpointer data)
        if (loads->service)
                g_object_unref (loads->service);
        g_clear_object (&loads->cancellable);
+       g_hash_table_destroy (loads->items);
        g_slice_free (LoadsClosure, loads);
 }
 
diff --git a/libsecret/secret-schema.c b/libsecret/secret-schema.c
index 8cc5ac7..5cc47f9 100644
--- a/libsecret/secret-schema.c
+++ b/libsecret/secret-schema.c
@@ -14,12 +14,13 @@
 
 #include "config.h"
 
-#include "secret-enum-types.h"
 #include "secret-password.h"
 #include "secret-private.h"
 #include "secret-value.h"
 
-#include <egg/egg-secure-memory.h>
+#include "libsecret/secret-enum-types.h"
+
+#include "egg/egg-secure-memory.h"
 
 /**
  * SECTION:secret-schema
diff --git a/libsecret/secret-service.c b/libsecret/secret-service.c
index 0179f64..7bf58b5 100644
--- a/libsecret/secret-service.c
+++ b/libsecret/secret-service.c
@@ -17,7 +17,6 @@
 
 #include "secret-collection.h"
 #include "secret-dbus-generated.h"
-#include "secret-enum-types.h"
 #include "secret-item.h"
 #include "secret-paths.h"
 #include "secret-private.h"
@@ -25,6 +24,8 @@
 #include "secret-types.h"
 #include "secret-value.h"
 
+#include "libsecret/secret-enum-types.h"
+
 #include "egg/egg-secure-memory.h"
 
 /**
@@ -202,7 +203,7 @@ service_cache_instance (SecretService *instance)
        proxy = G_DBUS_PROXY (instance);
        watch = g_bus_watch_name_on_connection (g_dbus_proxy_get_connection (proxy),
                                                g_dbus_proxy_get_name (proxy),
-                                               G_BUS_NAME_WATCHER_FLAGS_AUTO_START,
+                                               G_BUS_NAME_WATCHER_FLAGS_NONE,
                                                NULL, on_service_instance_vanished,
                                                instance, NULL);
 
diff --git a/libsecret/secret-util.c b/libsecret/secret-util.c
index 2442d37..67ac081 100644
--- a/libsecret/secret-util.c
+++ b/libsecret/secret-util.c
@@ -448,6 +448,8 @@ _secret_sync_free (gpointer data)
 {
        SecretSync *sync = data;
 
+       while (g_main_context_iteration (sync->context, FALSE));
+
        g_clear_object (&sync->result);
        g_main_loop_unref (sync->loop);
        g_main_context_unref (sync->context);
diff --git a/libsecret/tests/test-attributes.c b/libsecret/test-attributes.c
similarity index 100%
rename from libsecret/tests/test-attributes.c
rename to libsecret/test-attributes.c
diff --git a/libsecret/tests/test-collection.c b/libsecret/test-collection.c
similarity index 100%
rename from libsecret/tests/test-collection.c
rename to libsecret/test-collection.c
diff --git a/libsecret/tests/test-item.c b/libsecret/test-item.c
similarity index 98%
rename from libsecret/tests/test-item.c
rename to libsecret/test-item.c
index a723f89..29219c8 100644
--- a/libsecret/tests/test-item.c
+++ b/libsecret/test-item.c
@@ -408,7 +408,11 @@ test_set_label_prop (Test *test,
        g_assert_cmpstr (label, ==, "Blah blah");
        g_free (label);
 
+       g_object_add_weak_pointer (G_OBJECT (item), (gpointer *)&item);
        g_object_unref (item);
+
+       while (item != NULL)
+               g_main_context_iteration (g_main_context_get_thread_default (), TRUE);
 }
 
 static void
@@ -555,7 +559,11 @@ test_set_attributes_prop (Test *test,
        g_assert_cmpuint (g_hash_table_size (attributes), ==, 2);
        g_hash_table_unref (attributes);
 
+       g_object_add_weak_pointer (G_OBJECT (item), (gpointer *)&item);
        g_object_unref (item);
+
+       while (item != NULL)
+               g_main_context_iteration (g_main_context_get_thread_default (), TRUE);
 }
 
 static void
@@ -831,6 +839,7 @@ test_delete_async (Test *test,
        g_assert_no_error (error);
        g_assert (ret == TRUE);
 
+       g_object_unref (result);
        g_object_unref (item);
 
        item = secret_item_new_for_dbus_path_sync (test->service, item_path, SECRET_ITEM_NONE, NULL, &error);
diff --git a/libsecret/tests/test-clear-password.js b/libsecret/test-js-clear.js
similarity index 93%
rename from libsecret/tests/test-clear-password.js
rename to libsecret/test-js-clear.js
index 357cb5c..db124da 100644
--- a/libsecret/tests/test-clear-password.js
+++ b/libsecret/test-js-clear.js
@@ -30,7 +30,7 @@ const STORE_SCHEMA = new Secret.Schema("org.mock.Schema",
 );
 
 /* Synchronous */
-
+/*
 var attributes = { "number": "1", "string": "one", "even": "false" };
 
 var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
@@ -44,8 +44,9 @@ assertEquals(null, password);
 
 var deleted = Secret.password_clear_sync (STORE_SCHEMA, attributes, null);
 assertEquals(false, deleted);
+*/
 
-/* Asynchronous */ 
+/* Asynchronous */
 
 var attributes = { "number": "2", "string": "two", "even": "true" };
 
@@ -75,4 +76,8 @@ Secret.password_clear (STORE_SCHEMA, attributes,
 
 loop.run();
 
+var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
+assertEquals(null, password);
+
+Secret.Service.disconnect();
 Mock.stop();
diff --git a/libsecret/tests/test-lookup-password.js b/libsecret/test-js-lookup.js
similarity index 98%
rename from libsecret/tests/test-lookup-password.js
rename to libsecret/test-js-lookup.js
index 90cb158..595fb22 100644
--- a/libsecret/tests/test-lookup-password.js
+++ b/libsecret/test-js-lookup.js
@@ -59,4 +59,5 @@ Secret.password_lookup (STORE_SCHEMA, { "number": "7", "string": "five" },
 
 loop.run();
 
+Secret.Service.disconnect();
 Mock.stop();
diff --git a/libsecret/tests/test-store-password.js b/libsecret/test-js-store.js
similarity index 98%
rename from libsecret/tests/test-store-password.js
rename to libsecret/test-js-store.js
index 13725c6..1675172 100644
--- a/libsecret/tests/test-store-password.js
+++ b/libsecret/test-js-store.js
@@ -65,4 +65,5 @@ loop.run();
 var password = Secret.password_lookup_sync (STORE_SCHEMA, attributes, null);
 assertEquals("888", password);
 
+Secret.Service.disconnect();
 Mock.stop();
diff --git a/libsecret/tests/test-methods.c b/libsecret/test-methods.c
similarity index 100%
rename from libsecret/tests/test-methods.c
rename to libsecret/test-methods.c
diff --git a/libsecret/tests/test-password.c b/libsecret/test-password.c
similarity index 100%
rename from libsecret/tests/test-password.c
rename to libsecret/test-password.c
diff --git a/libsecret/tests/test-paths.c b/libsecret/test-paths.c
similarity index 100%
rename from libsecret/tests/test-paths.c
rename to libsecret/test-paths.c
diff --git a/libsecret/tests/test-prompt.c b/libsecret/test-prompt.c
similarity index 100%
rename from libsecret/tests/test-prompt.c
rename to libsecret/test-prompt.c
diff --git a/libsecret/tests/test-clear-password.py b/libsecret/test-py-clear.py
similarity index 100%
rename from libsecret/tests/test-clear-password.py
rename to libsecret/test-py-clear.py
diff --git a/libsecret/tests/test-lookup-password.py b/libsecret/test-py-lookup.py
similarity index 100%
rename from libsecret/tests/test-lookup-password.py
rename to libsecret/test-py-lookup.py
diff --git a/libsecret/tests/test-store-password.py b/libsecret/test-py-store.py
similarity index 100%
rename from libsecret/tests/test-store-password.py
rename to libsecret/test-py-store.py
diff --git a/libsecret/tests/test-service.c b/libsecret/test-service.c
similarity index 96%
rename from libsecret/tests/test-service.c
rename to libsecret/test-service.c
index 284941e..aa1a395 100644
--- a/libsecret/tests/test-service.c
+++ b/libsecret/test-service.c
@@ -64,7 +64,8 @@ on_complete_get_result (GObject *source,
 }
 
 static void
-test_get_sync (void)
+test_get_sync (Test *test,
+               gconstpointer data)
 {
        SecretService *service1;
        SecretService *service2;
@@ -102,7 +103,8 @@ test_get_sync (void)
 }
 
 static void
-test_get_async (void)
+test_get_async (Test *test,
+                gconstpointer data)
 {
        SecretService *service1;
        SecretService *service2;
@@ -253,7 +255,8 @@ test_get_more_async (Test *test,
 }
 
 static void
-test_open_sync (void)
+test_open_sync (Test *test,
+                gconstpointer data)
 {
        SecretService *service1;
        SecretService *service2;
@@ -283,7 +286,8 @@ test_open_sync (void)
 }
 
 static void
-test_open_async (void)
+test_open_async (Test *test,
+                 gconstpointer data)
 {
        SecretService *service1;
        SecretService *service2;
@@ -587,13 +591,13 @@ main (int argc, char **argv)
        g_type_init ();
 #endif
 
-       g_test_add_func ("/service/get-sync", test_get_sync);
-       g_test_add_func ("/service/get-async", test_get_async);
+       g_test_add ("/service/get-sync", Test, "mock-service-normal.py", setup_mock, test_get_sync, 
teardown_mock);
+       g_test_add ("/service/get-async", Test, "mock-service-normal.py", setup_mock, test_get_async, 
teardown_mock);
        g_test_add ("/service/get-more-sync", Test, "mock-service-normal.py", setup_mock, test_get_more_sync, 
teardown_mock);
        g_test_add ("/service/get-more-async", Test, "mock-service-normal.py", setup_mock, 
test_get_more_async, teardown_mock);
 
-       g_test_add_func ("/service/open-sync", test_open_sync);
-       g_test_add_func ("/service/open-async", test_open_async);
+       g_test_add ("/service/open-sync", Test, "mock-service-normal.py", setup_mock, test_open_sync, 
teardown_mock);
+       g_test_add ("/service/open-async", Test, "mock-service-normal.py", setup_mock, test_open_async, 
teardown_mock);
        g_test_add ("/service/open-more-sync", Test, "mock-service-normal.py", setup_mock, 
test_open_more_sync, teardown_mock);
        g_test_add ("/service/open-more-async", Test, "mock-service-normal.py", setup_mock, 
test_open_more_async, teardown_mock);
 
diff --git a/libsecret/tests/test-session.c b/libsecret/test-session.c
similarity index 100%
rename from libsecret/tests/test-session.c
rename to libsecret/test-session.c
diff --git a/libsecret/tests/test-vala-lang.vala b/libsecret/test-vala-lang.vala
similarity index 100%
rename from libsecret/tests/test-vala-lang.vala
rename to libsecret/test-vala-lang.vala
diff --git a/libsecret/tests/test-vala-unstable.vala b/libsecret/test-vala-unstable.vala
similarity index 100%
rename from libsecret/tests/test-vala-unstable.vala
rename to libsecret/test-vala-unstable.vala
diff --git a/libsecret/tests/test-value.c b/libsecret/test-value.c
similarity index 100%
rename from libsecret/tests/test-value.c
rename to libsecret/test-value.c
diff --git a/tool/Makefile.am b/tool/Makefile.am
index 667c88c..422e0d3 100644
--- a/tool/Makefile.am
+++ b/tool/Makefile.am
@@ -1,16 +1,7 @@
-include $(top_srcdir)/Makefile.decl
-
-AM_CPPFLAGS = \
-       -I$(top_srcdir) \
-       -I$(top_srcdir)/libsecret \
-       -DSECRET_COMPILATION \
-       -DLOCALEDIR=\""$(datadir)/locale"\" \
-       $(NULL)
-
-bin_PROGRAMS = secret-tool
+bin_PROGRAMS += secret-tool
 
 secret_tool_SOURCES = \
-       secret-tool.c
+       tool/secret-tool.c
 
 secret_tool_LDADD = \
-       $(top_builddir)/libsecret/libsecret- SECRET_MAJOR@.la
+       libsecret- SECRET_MAJOR@.la
diff --git a/tool/secret-tool.c b/tool/secret-tool.c
index 0a1350f..14ce14b 100644
--- a/tool/secret-tool.c
+++ b/tool/secret-tool.c
@@ -14,10 +14,10 @@
 
 #include "config.h"
 
-#include "secret-item.h"
-#include "secret-password.h"
-#include "secret-service.h"
-#include "secret-value.h"
+#include "libsecret/secret-item.h"
+#include "libsecret/secret-password.h"
+#include "libsecret/secret-service.h"
+#include "libsecret/secret-value.h"
 
 #include <glib/gi18n.h>
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]