#!/usr/local/bin/perl -w =head1 NAME p4.t - testing of vcp p4 i/o =cut use strict ; use Carp ; use File::Spec ; use POSIX ':sys_wait_h' ; use Test ; use VCP::TestUtils ; # use eq_or_diff from Test::Differences if available, # else just use ok. eval "use Test::Differences"; sub ok_or_diff { if( defined &eq_or_diff ) { # $_[3] = { context => 3 }; # arg to eq_or_diff goto &eq_or_diff; } goto &Test::ok; } my $t = -d 't' ? 't/' : '' ; my $p4_options ; my $p4_spec_base ; my $p4_rev_root ; my $p4_spec ; my $deepdir = "one/two/three/four/five"; # what change number to start incremental export at ## my $first_import_1_change; # was called $incr_change sub clean_p4_branch_spec { ## mutates ( $in, $out ) in place my $options = $_[2]; $_[0] =~ s{(<p4_branch_spec.*?>)(.*)(</p4_branch_spec>)}{ ## $in my ( $stag, $etag ) = ( $1, $3 ); local $_ = $2; s{//ignored/}{//depot/foo/}g; s{^Options:.*}{}m; "$stag$_$etag"; }sge; $_[1] =~ s{(<p4_branch_spec.*?>)(.*)(</p4_branch_spec>)}{ ## $out my ( $stag, $etag ) = ( $1, $3 ); local $_ = $2; s/^#.*\r?\n\r?\n?//mg; s/^Access:.*\r?\n\r?\n//mg; s{^Options:.*}{}m; s{(//depot/foo/)${deepdir}/}{$1}mg if $options->{reroot}; "$stag$_$etag"; }sge; } my @tests = ( ### # start p4d in existing p4root_0 sub { $ENV{P4USER} = "foobar_user" ; $ENV{P4PORT} = "foobar_port" ; $ENV{P4CLIENT} = "foobar_client" ; $ENV{P4PASSWD} = "foobar_passwd" ; $p4_options = launch_p4d "p4_", { repo_dir => "${t}p4root_0", } ; $p4_spec_base = "p4:$p4_options->{user}:\@$p4_options->{port}:" ; $p4_rev_root = "//depot/foo/" ; $p4_spec = "$p4_spec_base$p4_rev_root" ; ok 1 ; }, ## revml -> p4 -> revml, bootstrap export sub { my $infile = $t . "test-p4-in-0.revml" ; ## ## Idempotency test ## ## These depend on the "test-foo-in-0.revml" files built in the makefile. ## See MakeMaker.PL for how those are generated. ## ## We are also testing to see if we can re-root the files under foo/... ## my $state = "t/91p42revml_state_A"; rm_dir_tree $state; my $in = slurp $infile ; my $out = get_vcp_output "$p4_spec...", "--repo-id=p4:test_repository", { revml_out_spec => [ "--state-location=$state" ] } ; s_content qw( rep_desc time user_id p4_info ), \$in, \$out ; s_content qw( rev_root ), \$in, "depot/foo" ; # rm_elts qw( label ), qr/r_\w+|ch_\w+/, \$in, \$out ; $in =~ s{(id="|_id>)/+ignored}{$1//depot/foo}g; $in =~ s{(id="|_id>)ignored}{$1depot/foo}g; clean_p4_branch_spec $in, $out; # do this ok_or_diff $out, $in; }, ## Test a single file extraction from a p4 repo. This file exists in ## change 1. ## TODO: give these two explicit state files sub { ok( get_vcp_output( "${p4_spec}main/add/f1", "--repo-id=p4:test_repository" ), qr{<rev_root>depot/foo/main/add</.+<name>f1<.+<rev_id>1<.+<rev_id>2<.+</revml>}s ) ; }, ## Test a single file extraction from a p4 repo. This file does not exist ## in change 1. sub { ok( get_vcp_output( "${p4_spec}main/add/f2", "--repo-id=p4:test_repository" ), qr{<rev_root>depot/foo/main/add</.+<name>f2<.+<change_id>2<.+<change_id>3<.+</revml>}s ) ; }, ##------------------------- ## ## p4->revml, re-rooting a dir tree ## copies //depot/foo/main/a/deeply/ as if it was a whole repo ## into a target dir as if it were a complete repository. ## sub { ## Hide global $p4_spec for the nonce my $p4_spec = "$p4_spec_base//depot/foo/main/a/deeply/" ; my $state = "t/91p42revml_state_B"; rm_dir_tree $state; my $infile = $t . "test-p4-in-0.revml" ; my $in = slurp $infile ; my $out = get_vcp_output "${p4_spec}...", "--repo-id=p4:test_repository", { revml_out_spec => [ "--state-location=$state" ] } ; s_content qw( rep_desc time user_id ), \$in, \$out ; # s_content qw( source_repo_id ), \$in, "p4:" . $p4_options->{port} ; s_content qw( rev_root ), \$in, "depot/foo/main/a/deeply" ; rm_elts qw( mod_time change_id p4_info ), \$in, \$out ; # rm_elts qw( label ), qr/r_\w+|ch_\w+/, \$out ; ## Strip out all files from $in that shouldn't be there rm_elts qw( rev ), qr{(?:(?!a/deeply).)*?}s, \$in ; ## Adjust the $in paths to look like the result paths. $in is ## now the "expected" output. $in =~ s{<(name|source_name)>main/a/deeply/}{<$1>}g ; $in =~ s{(id="|_id>)/+ignored}{$1//depot/foo}g; $in =~ s{(id="|_id>)ignored}{$1depot/foo}g; rm_elts qw( branches ), \$in; ok_or_diff $out, $in; }, ##------------------------- ## # determine next change number that p4d will use this will become the ## # change number of the first change in t/test-p4-in-1.revml when it is ## # imported. ## sub { ## # get counter change ## run_p4 [ qw( counter change ) ], ## \undef, ## \$first_import_1_change, ## $p4_options ; ## ## chomp $first_import_1_change ; ## die "Invalid change counter value: '$first_import_1_change'" ## unless $first_import_1_change =~ /^\d+$/ ; ## ## ++$first_import_1_change ; ## ## ok 1; ## }, # shut down the p4root_0 p4d sub { $p4_options->{p4d_handle}->kill_kill; ok 1; }, ### # start p4d in existing p4root_1 sub { $ENV{P4USER} = "foobar_user" ; $ENV{P4PORT} = "foobar_port" ; $ENV{P4CLIENT} = "foobar_client" ; $ENV{P4PASSWD} = "foobar_passwd" ; $p4_options = launch_p4d "p4_", { repo_dir => "${t}p4root_1", } ; $p4_spec_base = "p4:$p4_options->{user}:\@$p4_options->{port}:" ; $p4_spec = "$p4_spec_base//depot/foo/" ; ok 1 ; }, ## ## revml -> p4 -> revml, incremental export ## sub { my $infile = $t . "test-p4-in-1.revml" ; my $state = "t/91p42revml_state_C"; rm_dir_tree $state; copy_dir_tree "t/91p42revml_state_B" => $state; #??? or A? # see if got the right # of files, changes # p42revml will do detailed checking (the following code) my $in = slurp $infile ; # my $out = get_vcp_output "${p4_spec}...\@$first_import_1_change,#head" ; my $out = get_vcp_output "${p4_spec}...", "--repo-id=p4:test_repository", "--continue", { revml_out_spec => [ "--state-location=$state" ] } ; $in =~ s{</rev_root>}{/foo</rev_root>} ; s_content qw( rep_desc time user_id p4_info ), \$in, \$out ; # s_content qw( source_repo_id ), \$in, "p4:" . $p4_options->{port} ; s_content qw( rev_root ), \$in, "depot/foo" ; # rm_elts qw( label ), qr/r_\w+|ch_\w+/, \$in, \$out ; rm_elts qw( branches ), \$in, \$out ; #!!! added \$out ??? ## TODO: This is an incremental export and perforce does not give us ## a trivial way to figure out what branch a file is on (since ## multiple branch views can cover the same file), so we bail ## on that for now. rm_elts qw( branch_id source_branch_id ), \$in ; $in =~ s{(id="|_id>)/+ignored}{$1//depot/foo}g; $in =~ s{(id="|_id>)ignored}{$1depot/foo}g; #$in =~ s{(<source_filebranch_id>)}{$1depot/foo}g; ok_or_diff $out, $in; # open IN, ">/tmp/91p42revml.in" or die; # open OUT, ">/tmp/91p42revml.out" or die; # print IN $in; # print OUT $out; # close IN; # close OUT; # ok 0; # die; }, ##------------------------- ## ## p4 -> revml, incremental export in bootstrap mode ## sub { my $infile = $t . "test-p4-in-1-bootstrap.revml" ; my $state = "t/91p42revml_state_D"; rm_dir_tree $state; copy_dir_tree "t/91p42revml_state_A" => $state; #??? or B? my $in = slurp $infile ; ## my $out = get_vcp_output ## "${p4_spec}...\@$first_import_1_change,#head", "--bootstrap=..." ; my $out = get_vcp_output "${p4_spec}...", "--repo-id=p4:test_repository", "--continue", "--bootstrap=...", { revml_out_spec => [ "--state-location=$state" ] } ; $in =~ s{</rev_root>}{/foo</rev_root>} ; s_content qw( rep_desc time user_id p4_info ), \$in, \$out ; # s_content qw( source_repo_id ), \$in, "p4:" . $p4_options->{port} ; s_content qw( rev_root ), \$in, "depot/foo" ; # rm_elts qw( label ), qr/r_\w+|ch_\w+/, \$in, \$out ; $in =~ s{(id="|_id>)/+ignored}{$1//depot/foo}g; $in =~ s{(id="|_id>)ignored}{$1depot/foo}g; rm_elts qw( branches ), \$in ; ## TODO: This is an incremental export and perforce does not give us ## a trivial way to figure out what branch a file is on (since ## multiple branch views can cover the same file), so we bail ## on that for now. rm_elts qw( branch_id source_branch_id ), \$in ; ok_or_diff $out, $in; }, # shut down the p4root_1 p4d sub { $p4_options->{p4d_handle}->kill_kill; ok 1; }, ### # start p4d in existing p4root_2 sub { $ENV{P4USER} = "foobar_user" ; $ENV{P4PORT} = "foobar_port" ; $ENV{P4CLIENT} = "foobar_client" ; $ENV{P4PASSWD} = "foobar_passwd" ; $p4_options = launch_p4d "p4_", { repo_dir => "${t}p4root_2", } ; $p4_spec_base = "p4:$p4_options->{user}:\@$p4_options->{port}:" ; $p4_spec = "$p4_spec_base//depot/foo/" ; ok 1 ; }, ## Check contents of t/p4root_2 ## extract p4 to revml ## build expected from revml ## ## p4->revml, re-rooting a dir tree ## sub { my $p4root_2 = "${t}p4root_2"; my $infile = $t . "test-p4-in-0.revml" ; my $in = slurp $infile; warn "p4_spec: '$p4_spec'\n"; my $out = get_vcp_output "${p4_spec}...", "--repo-id=p4:test_repository" ; s_content qw( rep_desc time user_id ), \$in, \$out ; # s_content qw( source_repo_id ), \$in, "p4:" . $p4_options->{port} ; rm_elts qw( p4_info ), \$in, \$out ; #rm_elts qw( mod_time change_id source_change_id p4_info ), \$in, \$out ; ## Adjust the $in paths to look like the result paths. $in is ## now the "expected" output. s_content qw( rev_root ), \$in, "depot/foo" ; $in =~ s{(<(?:source_)?name>)}{${1}${deepdir}/}g; $in =~ s{(id="|id>)/ignored}{$1//depot/foo/${deepdir}}g; $in =~ s{(_id>)ignored}{$1//depot/foo/${deepdir}}g; clean_p4_branch_spec $in, $out, { reroot => 1 }; ok_or_diff $out, $in; }, # shut down the p4root_2 p4d sub { $p4_options->{p4d_handle}->kill_kill; ok 1; }, ) ; plan tests => scalar @tests ; my $p4d_borken = p4d_borken ; my $why_skip ; $why_skip .= "p4 command not found\n" unless ( `p4 -V` || 0 ) =~ /^Perforce/ ; $why_skip .= "$p4d_borken\n" if $p4d_borken ; $why_skip ? skip( $why_skip, '' ) : $_->() for @tests ;
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#21 | 5403 | Barrie Slaymaker | - Misc logging, maintainability & debugging improvements | ||
#20 | 3800 | Barrie Slaymaker | - <branches> removed from all code | ||
#19 | 3719 | Barrie Slaymaker | - p4 username is now parsed correctly (but client is lost) | ||
#18 | 3717 | Barrie Slaymaker | - Minor docco cleanup | ||
#17 | 3428 | Barrie Slaymaker | - Test suite cleanup | ||
#16 | 2926 | John Fetkovich |
remove --state-location switch add --db-dir and --repo-id switches build state location from concatenation of those two. |
||
#15 | 2915 | Barrie Slaymaker |
Default to *not* changing the first rev of a branch, add --change-branch-rev-1 to enable the non-default behavior (which is what is used by most of the test suite). |
||
#14 | 2914 | Barrie Slaymaker | Remove need for launch_p4d and general cleanup. | ||
#13 | 2913 | Barrie Slaymaker | Put a user id on each change | ||
#12 | 2863 | Barrie Slaymaker |
Use the absolute path to a file's directory as its branch_id for SCMs that branch in file path space. |
||
#11 | 2854 | John Fetkovich | fixed hard-coded "t/" to be ${t} in state file locations. | ||
#10 | 2843 | John Fetkovich |
remove old comments, add --state-location switch to the tests that didn't have it. |
||
#9 | 2842 | Barrie Slaymaker | Get --continue working in VCP::Source::p4 | ||
#8 | 2840 | John Fetkovich | oops, left a debugging 'die' in the test suite. | ||
#7 | 2836 | John Fetkovich |
Make Source::p4 use --continue and --bootstrap options (partial) update test suite appropriately |
||
#6 | 2763 | John Fetkovich |
test a rerooted revml->p4 to someplace deep in the p4 tree, to make sure that VCP is configuring p4 to map the files to the right place. |
||
#5 | 2743 | John Fetkovich |
Add fields to vcp: source_name, source_filebranch_id, source_branch_id, source_rev_id, source_change_id 1. Alter revml.dtd to include the fields 2. Alter bin/gentrevml to emit legal RevML 3. Extend VCP::Rev to have the fields 4. Extend VCP::{Source,Dest}::revml to read/write the fields (VCP::Dest::revml should die() if VCP tries to emit illegal RevML) 5. Extend VCP::{Source,Dest}::{cvs,p4} to read the fields 7. Get all tests through t/91*.t to pass except those that rely on ch_4 labels |
||
#4 | 2714 | Barrie Slaymaker |
Simplify t/90*cvs.t tests, remove make_cvsroots for speed and simplicity. |
||
#3 | 2650 | John Fetkovich |
Change clean_p4_branch_spec to remove Options: lines. We can't always expect this to be the same. |
||
#2 | 2600 | John Fetkovich | Minor clean-ups. | ||
#1 | 2589 | John Fetkovich |
Split 90p4.t into 90revml2p4_0.t, 90revml2p4_1.t, 91p42revml.t, 95p42cvs.t. Added some utilities to the library files listed. |