Quick Navigator

Search Site

Unix VPS
A - Starter
B - Basic
C - Preferred
D - Commercial
MPS - Dedicated
Previous VPSs
* Sign Up! *

Contact Us
Online Help
Domain Status
Man Pages

Virtual Servers

Topology Map

Server Agreement
Year 2038

USA Flag



Man Pages

Manual Reference Pages  -  VCP::MAINTENANCE (3)

.ds Aq ’


VCP::Maintenance - VCP code maintenance tips & tricks





 vcp revml: --dtd <dtd file name> --save_dtd <how>


    The distribution hierarchy

As untarred, the distribution hierarchy looks like (some files not shown for brevity):

   +--- Makefile.PL     ## Generates the Makefile
   +--- MANIFEST        ## what files to ship, built with `make manifest`
   +--- MANIFEST.SKIP   ## what filenames `make manifest` should ignore
   +--- CHANGES         ## A detailed summary of all edits
   +--- TODO            ## Things we cant get to quite yet
   +--- LICENSE
   +--- README
   +--- revml.dtd       ## Defines legal RevML
   +--+ bin/            ## Executable files
   |  +---- vcp         ## The command line interface
   |  +---- gentrevml   ## builds RevML files for the test suite
   |  +----  ## dumps files in hex, a debugging aid
   +--+ lib/            ## All modules that comprise VCP itself
   |  +---       ## Drives the VCP process
   |  +--- *.pod        ## Supplemental documentation
   |  +---    ## Base class for all sources & destinations
   |  |
   |  +---    ## Base class for all sources
   |  +--+ Source/
   |  |  +---    ## A backend to read from repo. type "foo"
   |  |
   |  +---      ## Base class for all destinations
   |  +--+ Dest/
   |  |  +---    ## A backend to write to repo. type "foo"
   |  |
   |  +--+ Utils/
   |  |  +---    ## Routines shared by Source/ and Dest/ foo.pms
   |  |
   |  +---       ## VCPs concept of a revision
   |  +---      ## A collection of VCP::Rev instances
   |  |
   |  +--- RevML/       ## Files defining RevML
   +--+ t/              ## The test suite
      +--- *.t          ## Test scripts
      +--- test-*.revml ## Fodder for test scripts

In addition, the following files are created:

   +--- vcp_html        ## By running the `vcp html` command
   +--- pod2htm*        ## Gunk left over from `vcp html`
   +--- blib/           ## By running `make`

    Useful command line idioms

perl -Ilib -cw % (in your editor’s key mapping).

Useful to map an editor key to this. Use whatever path for -I works given your cwd usage habit, and replace the % with whatever macro your editor replaces with the path to the current file.

make test TEST_FILES=t/90foo.t TEST_VERBOSE=1 Runs just the listed test files (space separated list; use quotes) and shows STDOUT.
perl -Ilib bin/vcp ... Run vcp manually without setting PERL5LIB or installing it.
export PERL5LIB=lib Allows vcp and gentrevml to be run from command line
make test Runs all tests, generating t/test-*.revml if need be.

    Environment Variables

Some environment variables that are useful in debugging:
VCPDEBUG Set this to a TRUE value to force VCP::* modules emit debugging messages.

See also VCP::Debug for more details.

VCPNODELETE Set this to yes to tell vcp not to delete it’s working directories. This allows you to take a look at them and see what the source and dest command lines saw.
IPCRUN3DEBUG Set this to some number from 0..10 to see how vcp (via IPC::Run3) is treating it’s subprocesses.
VCPP4LICENSE If this is present and pointing to a readable file when a p4 daemon is started via vcp, a symlink will be created in the (possibly newly created) p4root directory to point to the p4 license file pointed to by VCPP4LICENSE. The ’make’ target test_all_p4_versions will cycle through each version of p4 and p4d contained in the ’p4versions’ directory, in both unlicensed and (if VCPP4LICENSE present) licensed mode.
In addition, both CVS and Perforce backends pay attention to the relevant environment variables.

bin/ is useful for debugging issues involving line endings, embedded control code (esp. ^Z on Win32 and NULL on every platform, since most C programs die when encountering NULL in a text file).

    The tests

The t/*.t files in the source distribution contain a large number of tests. The tests begin with a two digit number that orders them so that more primitive tests run first, followed by higher level end-to-end tests in t/90*.t.

The more primitive tests are pretty standard fare for Perl test suites. Where things get interesting is the t/90*.t tests. These tests use the command-line vcp interface to move reasonably sized chunks of RevML (up to about 65k currently; pretty small in comparison to real exports) in to, out of, and between various repositories.

The RevML extracted from the repositories is compared to the RevML that was fed in to them, after sanitizing both of data that is known to not make it through ok.

The module VCP::TestUtils contains support routines for initializing repositories and shutting them down (when a server is needed). Existing repositories are not used in the test suite; they’d be useless and in danger if we did.

The file bin/gentrevml is used to generate the RevML files (t/test*.revml) from scratch using hand written code instead of VCP::Dest::revml in order to reduce the chances of a bug in VCP::Dest::revml causing false positives in the test results.

It’s highly likely that new back ends will require new test RevML files. bin/gentrevml should be hacked up to generate these and new rules should be added to the Makefile by editing Makefile.PL.

The structure of a test script.

The t/*.t scripts generally all follow the same structure.

First, they import all necessary modules and init themselves.

Then they build a

   my @tests = (
   sub {

array that contain the actual tests. Each test is a single anonymous sub {...}, every once in a while a single sub {...} will contain two tests; it is preceded by an empty (or nearly empty) sub {} in these cases.

At the bottom, some final checks are run to see if all tests should be skipped, then

   plan tests => scalar @tests;

emits how many tests are to be run, and

   $_->() for @tests;

runs the tests.

This structure is used for several reasons:
1. No counting tests Tests are counted automatically for you this way, the scalar @tests does this. Otherwise you end up having to remember to manually fudge this every time a test is adding or removed.
2. Clear demarcation Tests tend to use local variables a lot; this structure keeps them from leaking from one test to another. Things that are shared between tests are usually declared right above the my @tests = line and are pretty obvious.
3. Commenting out tests In situations where you want to focus on one or a few tests, just put a line like:

    ); @tests = (

before the first test sub you want to run, and a line like

   sub { last },

after the last one. This is especially important.

4. Test line numbers Failing tests, when run with TEST_VERBOSE=1 as shown above, will report their line numbers. This is the fastest way to find out what’s failing. The list-of-subs approach is used even when @tests could actually contain just test vectors and the for @tests loop could check the vectors because we want line numbers to tell us where to look. If we used test vectors, then the call to ok() would report some line number in the for @tests loop, not the line number of the test.
5. If you want to enable vcp or IPC::Run3 debugging (see VCP::Debug, too), you can put a

   local $ENV{IPCRUN3DEBUG} = 1;  ## 1..10

in the appropriate sub {...} and it won’t cause all the other tests to spew a lot of noise.

    Developing a new backend

In general, backends are created in pairs so that a t/90foo.t can be written to import the RevML files in to the backend repository, extract new RevML from it, and compare the two.

A backend usually consists of 3 Perl classes: VCP::Source::foo, VCP::Dest::foo, and VCP::Utils::foo. The reason for the lowercase final name is so that the vcp command can translate from the scheme name (cvs:) to a source or destination module name trivially.

The VCP::Source::foo generally contains a parser to extract metadata from repository log reports and a routine to drive the copying process. The VCP module (/lib/

    Updating the RevML DTD

Run the command compile_dtd, which by default will look for the file ’revml.dtd’. This should be done each time the dtd changes. Optionally you may pass in a dtd file name as the argument to compile_dtd.

The generated file is placed in ./lib/RevML/Doctype/ or ./RevML/Doctype/ or ./, whichever is found first. No directories will be created.

This does not update the VCP::Source::revml or VCP::Dest::revml drivers to match the DTD, nor does it affect bin/gentrevml, which is used by the test suite to build the RevML files used for testing.


Barrie Slaymaker <>


Copyright (c) 2000, 2001, Perforce Software, Inc. All rights reserved.

See VCP::License (vcp help license) for the terms of use.


Hey! <B>The above document had some coding errors, which are explained below:B>
Around line 243: Expected text after =item, not a number
Search for    or go to Top of page |  Section 3 |  Main Index

perl v5.20.3 VCP::MAINTENANCE (3) 2004-11-04

Powered by GSP Visit the GSP FreeBSD Man Page Interface.
Output converted with manServer 1.07.