summaryrefslogtreecommitdiff
path: root/t
diff options
context:
space:
mode:
Diffstat (limited to 't')
-rw-r--r--t/Test/DH.pm4
-rwxr-xr-xt/debhelper-compat/syntax.t2
-rwxr-xr-xt/dh-sequencer.t173
-rw-r--r--t/dh_installgsettings/debian/changelog5
-rw-r--r--t/dh_installgsettings/debian/control17
-rwxr-xr-xt/dh_installgsettings/dh_installgsettings.t49
-rw-r--r--t/dh_installinit/debian/bar.other.init4
-rwxr-xr-xt/dh_installinit/dh_installinit.t2
-rwxr-xr-xt/dh_installman/01-basics.t71
-rw-r--r--t/dh_installman/manpage-compressed.pod17
-rw-r--r--t/dh_installman/manpage-uncompressed.pod17
-rwxr-xr-xt/dh_installsystemd/dh_installsystemd.t22
-rw-r--r--t/dh_installsystemduser/debian/baz.user.service8
-rw-r--r--t/dh_installsystemduser/debian/changelog5
-rw-r--r--t/dh_installsystemduser/debian/control10
-rw-r--r--t/dh_installsystemduser/debian/foo.user.service8
-rw-r--r--t/dh_installsystemduser/dh_installsystemduser.t75
-rwxr-xr-xt/dh_missing/02-fail-on-missing.t2
18 files changed, 453 insertions, 38 deletions
diff --git a/t/Test/DH.pm b/t/Test/DH.pm
index 20e6e9f6..5ca9515d 100644
--- a/t/Test/DH.pm
+++ b/t/Test/DH.pm
@@ -5,7 +5,7 @@ use warnings;
use Test::More;
-use Cwd qw(cwd realpath);
+use Cwd qw(getcwd realpath);
use Errno qw(EEXIST);
use Exporter qw(import);
@@ -44,7 +44,7 @@ our @EXPORT = qw(
our ($TEST_DH_COMPAT, $ROOT_OK, $ROOT_CMD);
-my $START_DIR = cwd();
+my $START_DIR = getcwd();
my $TEST_DIR;
sub run_dh_tool {
diff --git a/t/debhelper-compat/syntax.t b/t/debhelper-compat/syntax.t
index 9c0987d6..7fe0307a 100755
--- a/t/debhelper-compat/syntax.t
+++ b/t/debhelper-compat/syntax.t
@@ -31,7 +31,7 @@ sub test_build_depends {
error("close $dir/debian/control failed: $!");
close($in);
- my $start_dir = Test::DH::cwd();
+ my $start_dir = Test::DH::getcwd();
chdir($dir) or error("chdir($dir): $!");
plan(tests => 5);
diff --git a/t/dh-sequencer.t b/t/dh-sequencer.t
index dd5c264a..f8643866 100755
--- a/t/dh-sequencer.t
+++ b/t/dh-sequencer.t
@@ -4,6 +4,7 @@ use strict;
use warnings;
use Test::More;
+use Debian::Debhelper::Sequence;
use Debian::Debhelper::SequencerUtil;
# Shorten variants of the sequences.
@@ -21,46 +22,85 @@ my @i = (qw{
dh_install
dh_missing
});
-my @ba=qw{
- dh_strip
- dh_makeshlibs
- dh_shlibdeps
-};
+my @ba = (
+ {
+ 'command' => 'dh_strip',
+ 'command-options' => [],
+ 'sequence-limitation' => SEQUENCE_TYPE_ARCH_ONLY,
+ },
+ {
+ 'command' => 'dh_makeshlibs',
+ 'command-options' => [],
+ 'sequence-limitation' => SEQUENCE_TYPE_ARCH_ONLY,
+ },
+ {
+ 'command' => 'dh_shlibdeps',
+ 'command-options' => [],
+ 'sequence-limitation' => SEQUENCE_TYPE_ARCH_ONLY,
+ }
+);
my @b=qw{
dh_installdeb
dh_gencontrol
dh_builddeb
};
+my @c=qw{
+ dh_testdir
+ dh_auto_clean
+ dh_clean
+};
-my %sequences = (
- 'build-indep' => [@bd],
- 'build-arch' => [@bd],
- 'build' => [to_rules_target("build-arch"), to_rules_target("build-indep")],
-
- 'install-indep' => [to_rules_target("build-indep"), @i],
- 'install-arch' => [to_rules_target("build-arch"), @i],
- 'install' => [to_rules_target("build"), to_rules_target("install-arch"), to_rules_target("install-indep")],
+my %sequences;
+
+sub _add_sequence {
+ my @args = @_;
+ my $seq = Debian::Debhelper::Sequence->new(@args);
+ my $name = $seq->name;
+ $sequences{$name} = $seq;
+ if ($seq->allowed_subsequences eq SEQUENCE_ARCH_INDEP_SUBSEQUENCES) {
+ for my $subseq ((SEQUENCE_TYPE_ARCH_ONLY, SEQUENCE_TYPE_INDEP_ONLY)) {
+ my $subname = "${name}-${subseq}";
+ $sequences{$subname} = $seq;
+ }
+ }
+ return;
+}
- 'binary-indep' => [to_rules_target("install-indep"), @b],
- 'binary-arch' => [to_rules_target("install-arch"), @ba, @b],
- 'binary' => [to_rules_target("install"), to_rules_target("binary-arch"), to_rules_target("binary-indep")],
-);
+_add_sequence('build', SEQUENCE_ARCH_INDEP_SUBSEQUENCES, @bd);
+_add_sequence('install', SEQUENCE_ARCH_INDEP_SUBSEQUENCES, to_rules_target("build"), @i);
+_add_sequence('binary', SEQUENCE_ARCH_INDEP_SUBSEQUENCES, to_rules_target("install"), @ba, @b);
+_add_sequence('clean', SEQUENCE_NO_SUBSEQUENCES, @c);
+
+sub _cmd_names {
+ my (@input) = @_;
+ my @cmds;
+ for my $cmd (@input) {
+ if (ref($cmd) eq 'HASH') {
+ push(@cmds, $cmd->{'command'});
+ } else {
+ push(@cmds, $cmd);
+ }
+ }
+ return \@cmds;
+}
my %sequences_unpacked = (
- 'build-indep' => [@bd],
- 'build-arch' => [@bd],
- 'build' => [@bd],
+ 'build-indep' => _cmd_names(@bd),
+ 'build-arch' => _cmd_names(@bd),
+ 'build' => _cmd_names(@bd),
+
+ 'install-indep' => _cmd_names(@bd, @i),
+ 'install-arch' => _cmd_names(@bd, @i),
+ 'install' => _cmd_names(@bd, @i),
- 'install-indep' => [@bd, @i],
- 'install-arch' => [@bd, @i],
- 'install' => [@bd, @i],
+ 'binary-indep' => _cmd_names(@bd, @i, @b),
+ 'binary-arch' => _cmd_names(@bd, @i, @ba, @b),
+ 'binary' => _cmd_names(@bd, @i, @ba, @b),
- 'binary-indep' => [@bd, @i, @b],
- 'binary-arch' => [@bd, @i, @ba, @b],
- 'binary' => [@bd, @i, @ba, @b],
+ 'clean' => _cmd_names(@c),
);
-plan tests => 11 + 3 * scalar(keys(%sequences));
+plan tests => 21 + 3 * scalar(keys(%sequences));
# We will horse around with %EXPLICIT_TARGETS in this test; it should
# definitely not attempt to read d/rules or the test will be break.
@@ -95,20 +135,89 @@ is_deeply(
is_deeply(
[unpack_sequence(\%sequences, 'binary', 0, { 'build' => 1, 'build-arch' => 1, 'build-indep' => 1})],
- [[], [@i, @ba, @b]],
+ [[], _cmd_names(@i, @ba, @b)],
'Inlined binary sequence with build-* done has @i, @ba and @b');
+
+is_deeply(
+ [unpack_sequence(\%sequences, 'binary', 0, { 'build-arch' => 1, 'build-indep' => 1})],
+ [[], _cmd_names(@i, @ba, @b)],
+ 'Inlined binary sequence with build-* done has @i, @ba and @b');
+
+is_deeply(
+ [unpack_sequence(\%sequences, 'binary', 0, {}, 0)],
+ [[], _cmd_names(@bd, @i, @ba, @b)],
+ 'Inlined binary sequence and arch:all + arch:any is reduced to @bd, @i, @ba and @b');
+
+is_deeply(
+ [unpack_sequence(\%sequences, 'binary', 0, {}, FLAG_OPT_SOURCE_BUILDS_NO_ARCH_PACKAGES)],
+ [[], _cmd_names(@bd, @i, @b)],
+ 'Inlined binary sequence and not arch:any is reduced to @bd, @i and @b');
+
+is_deeply(
+ [unpack_sequence(\%sequences, 'binary', 0, {}, FLAG_OPT_SOURCE_BUILDS_NO_INDEP_PACKAGES)],
+ [[], _cmd_names(@bd, @i, @ba, @b)],
+ 'Inlined binary sequence and not arch:all is reduced to @bd, @i, @ba and @b');
+
+
+{
+ local $Debian::Debhelper::SequencerUtil::EXPLICIT_TARGETS{'build-arch'} = 1;
+ local $Debian::Debhelper::SequencerUtil::EXPLICIT_TARGETS{'build-indep'} = 1;
+
+ is_deeply(
+ [unpack_sequence(\%sequences, 'binary', 0, { 'build-arch' => 1, 'build-indep' => 1})],
+ [[], _cmd_names(@i, @ba, @b)],
+ 'Inlined binary sequence with build-* done has @i, @ba and @b');
+ my $actual = [unpack_sequence(\%sequences, 'binary')];
+ # @i should be "-i"-only, @ba + @b should be both.
+ # Unfortunately, unpack_sequence cannot show that.
+ my $expected = [[to_rules_target('build-arch'), to_rules_target('build-indep')], _cmd_names(@i, @ba, @b)];
+ # Permit some fuzz on the order between build-arch and build-arch
+ if ($actual->[0][0] eq to_rules_target('build-indep')) {
+ $expected->[0][0] = to_rules_target('build-indep');
+ $expected->[0][1] = to_rules_target('build-arch');
+ }
+ is_deeply(
+ $actual,
+ $expected,
+ 'Inlined binary sequence with explicit build-* has explicit d/rules build-{arch,indep} + @i, @ba, @b');
+
+ is_deeply(
+ [unpack_sequence(\%sequences, 'binary', 0, { 'build' => 1})],
+ [[], _cmd_names(@i, @ba, @b)],
+ 'Inlined binary sequence with explicit build-* but done build has only @i, @ba and @b');
+}
+
+{
+ local $Debian::Debhelper::SequencerUtil::EXPLICIT_TARGETS{'build-indep'} = 1;
+ is_deeply(
+ [ unpack_sequence(\%sequences, 'binary', 0, { 'build-arch' => 1 }) ],
+ [ [to_rules_target('build-indep')], _cmd_names(@i, @ba, @b) ],
+ 'Inlined binary sequence with build-arch done and build-indep explicit has d/rules build-indep + @i, @ba and @b');
+
+ is_deeply(
+ [ unpack_sequence(\%sequences, 'binary-arch', 0, { 'build-arch' => 1 }) ],
+ [ [], _cmd_names(@i, @ba, @b) ],
+ 'Inlined binary-arch sequence with build-arch done and build-indep explicit has @i, @ba and @b');
+
+
+ is_deeply(
+ [ unpack_sequence(\%sequences, 'binary-indep', 0, { 'build-arch' => 1 }) ],
+ [ [to_rules_target('build-indep')], _cmd_names(@i, @b) ],
+ 'Inlined binary-indep sequence with build-arch done and build-indep explicit has d/rules build-indep + @i and @b');
+}
+
{
local $Debian::Debhelper::SequencerUtil::EXPLICIT_TARGETS{'build'} = 1;
is_deeply(
[unpack_sequence(\%sequences, 'binary')],
- [[to_rules_target('build')], [@i, @ba, @b]],
+ [[to_rules_target('build')], _cmd_names(@i, @ba, @b)],
'Inlined binary sequence has all the commands but build target is opaque');
is_deeply(
[unpack_sequence(\%sequences, 'binary', 0, { 'build' => 1, 'build-arch' => 1, 'build-indep' => 1})],
- [[], [@i, @ba, @b]],
+ [[], _cmd_names(@i, @ba, @b)],
'Inlined binary sequence has all the commands with build-* done and not build-target');
is_deeply(
@@ -133,7 +242,7 @@ is_deeply(
[unpack_sequence(\%sequences, 'binary')],
# @bd_minimal, @bd and @i should be "-i"-only, @ba + @b should be both.
# Unfortunately, unpack_sequence cannot show that.
- [[to_rules_target('install-arch')], [@bd, @i, @ba, @b]],
+ [[to_rules_target('install-arch')], _cmd_names(@bd, @i, @ba, @b)],
'Inlined binary sequence has all the commands');
# Compat <= 8 ignores explicit targets!
@@ -152,7 +261,7 @@ is_deeply(
my $actual = [unpack_sequence(\%sequences, 'binary')];
# @i should be "-i"-only, @ba + @b should be both.
# Unfortunately, unpack_sequence cannot show that.
- my $expected = [[to_rules_target('build'), to_rules_target('install-arch')], [@i, @ba, @b]];
+ my $expected = [[to_rules_target('build'), to_rules_target('install-arch')], _cmd_names(@i, @ba, @b)];
# Permit some fuzz on the order between build and install-arch
if ($actual->[0][0] eq to_rules_target('install-arch')) {
$expected->[0][0] = to_rules_target('install-arch');
diff --git a/t/dh_installgsettings/debian/changelog b/t/dh_installgsettings/debian/changelog
new file mode 100644
index 00000000..5850f0e2
--- /dev/null
+++ b/t/dh_installgsettings/debian/changelog
@@ -0,0 +1,5 @@
+foo (1.0-1) unstable; urgency=low
+
+ * Initial release. (Closes: #XXXXXX)
+
+ -- Test <testing@nowhere> Mon, 11 Jul 2016 18:10:59 +0200
diff --git a/t/dh_installgsettings/debian/control b/t/dh_installgsettings/debian/control
new file mode 100644
index 00000000..c3cb827c
--- /dev/null
+++ b/t/dh_installgsettings/debian/control
@@ -0,0 +1,17 @@
+Source: foo
+Section: misc
+Priority: optional
+Maintainer: Test <testing@nowhere>
+Standards-Version: 3.9.8
+
+Package: has-settings
+Architecture: all
+Depends: ${misc:Depends}
+Description: package has-settings
+ This package has a GSettings schema.
+
+Package: no-settings
+Architecture: all
+Depends: ${misc:Depends}
+Description: package no-settings
+ This package doesn't have a GSettings schema.
diff --git a/t/dh_installgsettings/dh_installgsettings.t b/t/dh_installgsettings/dh_installgsettings.t
new file mode 100755
index 00000000..fe76e8dc
--- /dev/null
+++ b/t/dh_installgsettings/dh_installgsettings.t
@@ -0,0 +1,49 @@
+#!/usr/bin/perl
+use strict;
+use Test::More tests => 1;
+
+use autodie;
+use File::Basename qw(dirname);
+use lib dirname(dirname(__FILE__));
+use Test::DH;
+use File::Path qw(remove_tree make_path);
+use Debian::Debhelper::Dh_Lib qw(!dirname);
+
+our @TEST_DH_EXTRA_TEMPLATE_FILES = (qw(
+ debian/changelog
+ debian/control
+));
+
+my $SCHEMAS = 'usr/share/glib-2.0/schemas';
+
+sub touch {
+ my $path = shift;
+ open(my $fh, '>>', $path);
+ close $fh;
+}
+
+sub slurp {
+ my $path = shift;
+ local $/ = undef;
+ open(my $fh, '<', $path);
+ my $contents = <$fh>;
+ close $fh;
+ return $contents;
+}
+
+each_compat_subtest {
+ make_path("debian/has-settings/$SCHEMAS");
+ touch("debian/has-settings/$SCHEMAS/com.example.HasSettings.xml");
+ make_path("debian/has-unimportant-settings/$SCHEMAS");
+ touch("debian/no-settings.substvars");
+ ok(run_dh_tool('dh_installgsettings', '-phas-settings'), 'run for has-settings');
+ ok(run_dh_tool('dh_installgsettings', '-pno-settings'), 'run for no-settings');
+ remove_tree(qw(debian/has-settings debian/has-unimportant-settings));
+ like(slurp('debian/has-settings.substvars'),
+ qr{^misc:Depends=dconf-gsettings-backend \| gsettings-backend$}m,
+ 'has-settings should depend on a backend');
+ unlike(slurp('debian/no-settings.substvars'),
+ qr{^misc:Depends=dconf-gsettings-backend \| gsettings-backend$}m,
+ 'no-settings should not depend on a backend');
+};
+
diff --git a/t/dh_installinit/debian/bar.other.init b/t/dh_installinit/debian/bar.other.init
new file mode 100644
index 00000000..ea948c58
--- /dev/null
+++ b/t/dh_installinit/debian/bar.other.init
@@ -0,0 +1,4 @@
+#!/bin/sh
+cat << 'EOF'
+I am init script to be installed into package "bar" into /etc/init.d/other path.
+EOF \ No newline at end of file
diff --git a/t/dh_installinit/dh_installinit.t b/t/dh_installinit/dh_installinit.t
index b20caa58..d290df21 100755
--- a/t/dh_installinit/dh_installinit.t
+++ b/t/dh_installinit/dh_installinit.t
@@ -12,6 +12,7 @@ our @TEST_DH_EXTRA_TEMPLATE_FILES = (qw(
debian/changelog
debian/control
debian/foo.service
+ debian/bar.other.init
));
plan(tests => 2);
@@ -29,6 +30,7 @@ each_compat_from_and_above_subtest(11, sub {
make_path(qw(debian/foo debian/bar debian/baz));
ok(run_dh_tool('dh_installinit'));
+ ok(run_dh_tool({'quiet' => 1}, 'dh_installinit', '--name=other'));
ok(! -e "debian/foo/lib/systemd/system/foo.service");
ok(!find_script('foo', 'postinst'));
ok(run_dh_tool('dh_clean'));
diff --git a/t/dh_installman/01-basics.t b/t/dh_installman/01-basics.t
new file mode 100755
index 00000000..6e90cc94
--- /dev/null
+++ b/t/dh_installman/01-basics.t
@@ -0,0 +1,71 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use Test::More;
+
+use File::Basename qw(dirname);
+use lib dirname(dirname(__FILE__));
+use Test::DH;
+use File::Path qw(remove_tree make_path);
+use Debian::Debhelper::Dh_Lib qw(!dirname);
+
+sub has_man_db_tool {
+ my ($tool) = @_;
+ open(my $old_stderr, '>&', *STDERR) or error("dup(STDERR, tmp_fd): $!");
+ open(*STDERR, '>', '/dev/null') or error("re-open stderr as /dev/null: $!");
+
+ my $res = defined(`$tool --version`);
+ open(*STDERR, '>&', $old_stderr) or error("dup(tmp_fd, STDERR): $!");
+ close($old_stderr);
+ return $res;
+}
+
+if (has_man_db_tool('man') || has_man_db_tool('man-recode')) {
+ plan(tests => 2);
+} else {
+ plan(skip_all => 'Test requires man or man-recode');
+}
+
+our @TEST_DH_EXTRA_TEMPLATE_FILES = (qw(
+ manpage-uncompressed.pod
+ manpage-compressed.pod
+));
+
+each_compat_subtest {
+ my ($compat) = @_;
+ if (! -d 'generated-manpages') {
+ # Static data that can be reused. Generate only in the first test
+ make_path('generated-manpages');
+ for my $basename (qw(manpage-uncompressed manpage-compressed)) {
+ doit('pod2man', '--utf8', '-c', 'Debhelper', '-r', '1.0', "${basename}.pod",
+ "generated-manpages/${basename}.1");
+ }
+ doit('gzip', '-9n', 'generated-manpages/manpage-compressed.1');
+ }
+ ok(run_dh_tool('dh_installman', 'generated-manpages/manpage-uncompressed.1',
+ 'generated-manpages/manpage-compressed.1.gz'));
+ ok(-e 'debian/debhelper/usr/share/man/man1/manpage-uncompressed.1');
+ ok(-e 'debian/debhelper/usr/share/man/man1/manpage-compressed.1');
+ remove_tree('debian/debhelper', 'debian/tmp', 'debian/.debhelper');
+};
+
+each_compat_subtest {
+ my ($compat) = @_;
+ if (! -d 'generated-manpages') {
+ # Static data that can be reused. Generate only in the first test
+ make_path('generated-manpages');
+ for my $basename (qw(manpage-uncompressed manpage-compressed)) {
+ doit('pod2man', '--utf8', '-c', 'Debhelper', '-r', '1.0', "${basename}.pod",
+ "generated-manpages/${basename}.1");
+ }
+ doit('gzip', '-9n', 'generated-manpages/manpage-compressed.1');
+ }
+ install_dir('debian/debhelper/usr/share/man/man1');
+ install_file('generated-manpages/manpage-uncompressed.1', 'debian/debhelper/usr/share/man/man1/manpage-uncompressed.1');
+ install_file('generated-manpages/manpage-compressed.1.gz', 'debian/debhelper/usr/share/man/man1/manpage-compressed.1.gz');
+ ok(run_dh_tool('dh_installman'));
+ ok(-e 'debian/debhelper/usr/share/man/man1/manpage-uncompressed.1');
+ ok(-e 'debian/debhelper/usr/share/man/man1/manpage-compressed.1');
+ remove_tree('debian/debhelper', 'debian/tmp', 'debian/.debhelper');
+};
+
diff --git a/t/dh_installman/manpage-compressed.pod b/t/dh_installman/manpage-compressed.pod
new file mode 100644
index 00000000..d2c05968
--- /dev/null
+++ b/t/dh_installman/manpage-compressed.pod
@@ -0,0 +1,17 @@
+=head1 NAME
+
+manpage - Something very exciting
+
+=head1 SYNOPSIS
+
+This tool does not exist but would be awesome.
+
+=head1 SEE ALSO
+
+L<debhelper(7)>
+
+=head1 AUTHORS
+
+Niels Thykier <niels@thykier.net>
+
+=cut
diff --git a/t/dh_installman/manpage-uncompressed.pod b/t/dh_installman/manpage-uncompressed.pod
new file mode 100644
index 00000000..c95037cf
--- /dev/null
+++ b/t/dh_installman/manpage-uncompressed.pod
@@ -0,0 +1,17 @@
+=head1 NAME
+
+manpage-uncompressed - Something very exciting
+
+=head1 SYNOPSIS
+
+This tool does not exist but would be awesome.
+
+=head1 SEE ALSO
+
+L<debhelper(7)>
+
+=head1 AUTHORS
+
+Niels Thykier <niels@thykier.net>
+
+=cut
diff --git a/t/dh_installsystemd/dh_installsystemd.t b/t/dh_installsystemd/dh_installsystemd.t
index 7029c615..1faa1868 100755
--- a/t/dh_installsystemd/dh_installsystemd.t
+++ b/t/dh_installsystemd/dh_installsystemd.t
@@ -8,7 +8,7 @@ use Test::DH;
use File::Path qw(remove_tree make_path);
use Debian::Debhelper::Dh_Lib qw(!dirname);
-plan(tests => 2);
+plan(tests => 4);
sub write_file {
my ($path, $content) = @_;
@@ -196,7 +196,9 @@ each_compat_subtest {
unit_is_enabled('foo', 'source', 0);
unit_is_enabled('foo', 'target', 1);
ok(run_dh_tool('dh_clean'));
+};
+each_compat_up_to_and_incl_subtest(11, sub {
make_path('debian/foo/lib/systemd/system/');
make_path('debian/foo/etc/init.d/');
install_file('debian/foo.service', 'debian/foo/lib/systemd/system/target.service');
@@ -211,4 +213,20 @@ each_compat_subtest {
unit_is_started('foo', 'source', 0);
unit_is_started('foo', 'target', 0);
ok(run_dh_tool('dh_clean'));
-};
+});
+
+each_compat_from_and_above_subtest(12, sub {
+ make_path('debian/foo/lib/systemd/system/');
+ make_path('debian/foo/etc/init.d/');
+ install_file('debian/foo.service', 'debian/foo/lib/systemd/system/target.service');
+ make_symlink_raw_target('target.service', 'debian/foo/lib/systemd/system/source.service');
+ write_file('debian/foo/etc/init.d/source', '# something');
+ ok(run_dh_tool('dh_installsystemd'));
+ unit_is_enabled('foo', 'foo', 1);
+ # Alias= realized by symlinks are not enabled in maintaner scripts
+ unit_is_enabled('foo', 'source', 0);
+ unit_is_enabled('foo', 'target', 1);
+ unit_is_started('foo', 'source', 0);
+ unit_is_started('foo', 'target', 1);
+ ok(run_dh_tool('dh_clean'));
+});
diff --git a/t/dh_installsystemduser/debian/baz.user.service b/t/dh_installsystemduser/debian/baz.user.service
new file mode 100644
index 00000000..3af041de
--- /dev/null
+++ b/t/dh_installsystemduser/debian/baz.user.service
@@ -0,0 +1,8 @@
+[Unit]
+Description=Baz User Unit
+
+[Service]
+ExecStart=/bin/true
+
+[Install]
+WantedBy=default.target
diff --git a/t/dh_installsystemduser/debian/changelog b/t/dh_installsystemduser/debian/changelog
new file mode 100644
index 00000000..5850f0e2
--- /dev/null
+++ b/t/dh_installsystemduser/debian/changelog
@@ -0,0 +1,5 @@
+foo (1.0-1) unstable; urgency=low
+
+ * Initial release. (Closes: #XXXXXX)
+
+ -- Test <testing@nowhere> Mon, 11 Jul 2016 18:10:59 +0200
diff --git a/t/dh_installsystemduser/debian/control b/t/dh_installsystemduser/debian/control
new file mode 100644
index 00000000..adccbc63
--- /dev/null
+++ b/t/dh_installsystemduser/debian/control
@@ -0,0 +1,10 @@
+Source: foo
+Section: misc
+Priority: optional
+Maintainer: Test <testing@exampe.org>
+Standards-Version: 3.9.8
+
+Package: foo
+Architecture: all
+Description: package foo
+ Package foo
diff --git a/t/dh_installsystemduser/debian/foo.user.service b/t/dh_installsystemduser/debian/foo.user.service
new file mode 100644
index 00000000..7ef597d4
--- /dev/null
+++ b/t/dh_installsystemduser/debian/foo.user.service
@@ -0,0 +1,8 @@
+[Unit]
+Description=Foo User Unit
+
+[Service]
+ExecStart=/bin/true
+
+[Install]
+WantedBy=default.target
diff --git a/t/dh_installsystemduser/dh_installsystemduser.t b/t/dh_installsystemduser/dh_installsystemduser.t
new file mode 100644
index 00000000..894eeb7a
--- /dev/null
+++ b/t/dh_installsystemduser/dh_installsystemduser.t
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+use strict;
+use Test::More;
+use File::Path qw(make_path);
+use File::Basename qw(dirname);
+use lib dirname(dirname(__FILE__));
+use Test::DH;
+use Debian::Debhelper::Dh_Lib qw(!dirname);
+
+plan(tests => 1);
+
+our @TEST_DH_EXTRA_TEMPLATE_FILES = (qw(
+ debian/changelog
+ debian/control
+ debian/foo.user.service
+ debian/baz.user.service
+));
+
+
+sub read_script {
+ my ($package, $name) = @_;
+ my @lines;
+
+ foreach my $script (find_script($package, $name)) {
+ open(my $fh, '<', $script) or die("open($script): $!");
+ push @lines, $_ for <$fh>;
+ close($fh);
+ }
+
+ return @lines;
+}
+
+sub _unit_check_user_enabled {
+ my ($package, $unit, $enabled) = @_;
+ my $verb = $enabled ? "is" : "isnt";
+ my $matches;
+
+ my @postinst = read_script($package, 'postinst');
+ # Match exactly one tab character. The "dont-enable" script has
+ # an "enable" line for re-enabling the service if the admin had it
+ # enabled, but we do not want to include that in our count.
+ $matches = grep { m{^\tif deb-systemd-helper( --\w+)* --user was-enabled.*'\Q$unit'} } @postinst;
+ is($matches, $enabled, "$unit $verb enabled");
+
+ my @postrm = read_script($package, 'postrm');
+ $matches = grep { m{deb-systemd-helper( --\w+)* --user mask.*'\Q$unit'} } @postrm;
+ is($matches, $enabled, "$unit $verb masked");
+}
+
+sub is_enabled { _unit_check_user_enabled(@_, 1); }
+sub isnt_enabled { _unit_check_user_enabled(@_, 0); }
+
+each_compat_subtest {
+ make_path('debian/foo/usr/lib/systemd/user/');
+ install_file('debian/foo.user.service', 'debian/foo/usr/lib/systemd/user/bar.service');
+ ok(run_dh_tool('dh_installsystemduser'));
+ ok(-e 'debian/foo/usr/lib/systemd/user/foo.service');
+ is_enabled('foo', 'foo.service');
+ is_enabled('foo', 'bar.service');
+ ok(run_dh_tool('dh_clean'));
+
+ ok(run_dh_tool('dh_installsystemduser'));
+ ok(-e 'debian/foo/usr/lib/systemd/user/foo.service');
+ ok(! -e 'debian/foo/usr/lib/systemd/user/baz.service');
+ is_enabled('foo', 'foo.service');
+ isnt_enabled('foo', 'baz.service');
+ ok(run_dh_tool('dh_clean'));
+
+ ok(run_dh_tool('dh_installsystemduser', '--name', 'baz'));
+ ok(! -e 'debian/foo/usr/lib/systemd/user/foo.service');
+ ok(-e 'debian/foo/usr/lib/systemd/user/baz.service');
+ isnt_enabled('foo', 'foo.service');
+ is_enabled('foo', 'baz.service');
+ ok(run_dh_tool('dh_clean'));
+};
diff --git a/t/dh_missing/02-fail-on-missing.t b/t/dh_missing/02-fail-on-missing.t
index 711ed984..e97b6eba 100755
--- a/t/dh_missing/02-fail-on-missing.t
+++ b/t/dh_missing/02-fail-on-missing.t
@@ -28,6 +28,6 @@ each_compat_subtest {
isnt($?, -1, 'dh_missing was executed');
ok(! ($? & 127), 'dh_missing did not die due to a signal');
my $exitcode = ($? >> 8);
- is($exitcode, 2, 'dh_missing exited with exit code 2');
+ is($exitcode, 255, 'dh_missing exited with exit code 255');
};