git-if-needed: read patches from a series file.

Change-Id: I29c87e8448f89deaab0c04678296b25013982486
diff --git a/tools/git-if-needed/tests/gifn-test.pl b/tools/git-if-needed/tests/gifn-test.pl
index 5de957d..989cbfa 100755
--- a/tools/git-if-needed/tests/gifn-test.pl
+++ b/tools/git-if-needed/tests/gifn-test.pl
@@ -346,6 +346,77 @@
 	}
 }
 
+sub setup_subdir_repos($)
+{
+	my ($cfg) = @_;
+
+	$cfg->{sub}->{full}->{base} = $cfg->{subrepo}->child('full');
+	$cfg->{sub}->{full}->{cinder} =
+	    $cfg->{sub}->{full}->{base}->
+	    child('openstack')->child('cinder');
+	$cfg->{sub}->{full}->{nova} =
+	    $cfg->{sub}->{full}->{base}->
+	    child('openstack')->child('nova');
+	$cfg->{sub}->{full}->{cinder}->mkpath({ mode => 0755 });
+	$cfg->{sub}->{full}->{nova}->mkpath({ mode => 0755 });
+
+	$cfg->{sub}->{short}->{base} = $cfg->{subrepo}->child('short');
+	$cfg->{sub}->{short}->{cinder} =
+	    $cfg->{sub}->{short}->{base}->child('cinder');
+	$cfg->{sub}->{short}->{nova} =
+	    $cfg->{sub}->{short}->{base}->child('nova');
+	$cfg->{sub}->{short}->{cinder}->mkpath({ mode => 0755 });
+	$cfg->{sub}->{short}->{nova}->mkpath({ mode => 0755 });
+
+	for my $part (qw(full short)) {
+		for my $comp (qw(cinder nova)) {
+			my $dir = $cfg->{sub}->{$part}->{$comp};
+			chdir($dir) or die "Could not change into $dir: $!\n";
+			run_command @{$cfg->{git}}, 'init';
+			git_status_ok $cfg;
+		}
+	}
+}
+
+sub test_subdir($ $ $ $)
+{
+	my ($cfg, $part, $expected, $opt) = @_;
+	my $run = $expected ? 'second' : 'first';
+	my $sub = $cfg->{sub}->{$part};
+
+	say "\ntest-subdir $part $run\n";
+
+	my $any = sub {
+	    $sub->{cinder}->child('README.txt')->exists ||
+	    $sub->{nova}->child('README.txt')->exists
+	};
+	my $all = sub {
+	    $sub->{cinder}->child('README.txt')->exists &&
+	    $sub->{nova}->child('README.txt')->exists
+	};
+
+	chdir $sub->{base} or die "Could not change into $sub->{base}: $!\n";
+	if ($expected && !$all->()) {
+		die "No $part files before the second run in $sub->{base}\n";
+	} elsif (!$expected && $any->()) {
+		die "Unexpected $part files in $sub->{base}\n";
+	}
+
+	run_command @{$cfg->{gifn}}, '-s', $cfg->{data}->child('series'),
+	    @{$opt}, 'am';
+
+	if (!$all->()) {
+		my $run = $expected ? 'second' : 'first';
+		die "No $part files after the $run run in $sub->{base}\n";
+	}
+
+	for my $comp (qw(cinder nova)) {
+		chdir $sub->{$comp} or
+		    die "Could not change into $sub->{comp}: $!\n";
+		git_status_ok $cfg;
+	}
+}
+
 MAIN:
 {
 	my %opts;
@@ -361,6 +432,9 @@
 	my $repodir = File::Temp->newdir(
 	    TEMPLATE => 'gifn-test.XXXXXX',
 	    TMPDIR => 1);
+	my $subrepodir = File::Temp->newdir(
+	    TEMPLATE => 'gifn-test.XXXXXX',
+	    TMPDIR => 1);
 
 	my $cfg = {
 		cwd => $cwd,
@@ -368,6 +442,7 @@
 		gifn => [@ARGV],
 		git => ['env', "LC_MESSAGES=$locale", 'git', '--no-pager'],
 		repo => path($repodir),
+		subrepo => path($subrepodir),
 	};
 
 	$cfg->{gifn}[0] = path($cfg->{gifn}[0])->absolute;
@@ -381,6 +456,13 @@
 		test_apply $cfg, @{PATCHFILES->{more}};
 		test_already_applied $cfg, (@{PATCHFILES->{initial}}, @{PATCHFILES->{more}});
 		test_fail_to_apply $cfg, @{PATCHFILES->{conflict}};
+
+		setup_subdir_repos $cfg;
+
+		test_subdir $cfg, 'full', 0, [];
+		test_subdir $cfg, 'short', 0, ['-S'];
+		test_subdir $cfg, 'full', 1, [];
+		test_subdir $cfg, 'short', 1, ['-S'];
 	};
 	my $err = $@;
 	chdir $cwd;