001package org.apache.maven.scm.provider.jazz.command;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import org.apache.maven.scm.CommandParameters;
023import org.apache.maven.scm.ScmException;
024import org.apache.maven.scm.ScmFileSet;
025import org.apache.maven.scm.ScmResult;
026import org.apache.maven.scm.command.AbstractCommand;
027import org.apache.maven.scm.log.DefaultLog;
028import org.apache.maven.scm.provider.ScmProviderRepository;
029import org.apache.maven.scm.provider.jazz.command.consumer.DebugLoggerConsumer;
030import org.apache.maven.scm.provider.jazz.command.consumer.ErrorConsumer;
031import org.apache.maven.scm.provider.jazz.repository.JazzScmProviderRepository;
032import org.apache.maven.scm.repository.ScmRepository;
033import org.codehaus.plexus.util.FileUtils;
034import org.codehaus.plexus.util.StringUtils;
035import org.codehaus.plexus.util.cli.StreamConsumer;
036import org.junit.Assert;
037
038import java.io.File;
039
040/**
041 * Common utilities for Jazz TCK tests.
042 *
043 * @author <a href="mailto:ChrisGWarp@gmail.com">Chris Graham</a>
044 */
045public class JazzTckUtil
046    extends AbstractCommand
047{
048    private long currentSystemTimeMillis = System.currentTimeMillis();
049
050    private String tckBaseDir;
051
052    private String scmUrl;
053
054    private String snapshotName;
055
056    /**
057     * Get the specified system property. Borrowed from AccuRevTckUtil.
058     * TODO: Refactor to a common usage.
059     *
060     * @param name         The name of the property to get.
061     * @param defaultValue A default value if not found.
062     * @return
063     */
064    public String getSystemProperty( String name, String defaultValue )
065    {
066        String mavenProperty = "${" + name + "}";
067        String result = System.getProperty( name, mavenProperty );
068        if ( mavenProperty.equals( result ) )
069        {
070            result = defaultValue;
071        }
072        return result;
073    }
074
075    /* (non-Javadoc)
076    * @see org.apache.maven.scm.command.AbstractCommand#executeCommand(org.apache.maven.scm.provider.ScmProviderRepository, org.apache.maven.scm.ScmFileSet, org.apache.maven.scm.CommandParameters)
077    */
078    @Override
079    protected ScmResult executeCommand( ScmProviderRepository repository, ScmFileSet fileSet,
080                                        CommandParameters parameters )
081        throws ScmException
082    {
083        JazzScmProviderRepository jazzRepo = (JazzScmProviderRepository) repository;
084
085        StreamConsumer tckConsumer =
086            new DebugLoggerConsumer( getLogger() );      // No need for a dedicated consumer for this
087        ErrorConsumer errConsumer = new ErrorConsumer( getLogger() );
088        String nameWorkspace = jazzRepo.getRepositoryWorkspace();
089        //String nameSnapshot = "MavenSCMTestSnapshot";
090        String nameSnapshot = getSnapshotName();
091        JazzScmCommand tckCreateWorkspaceFromSnapshotCmd =
092            createCreateWorkspaceFromSnapshotCommand( jazzRepo, fileSet, nameWorkspace, nameSnapshot );
093        int status = tckCreateWorkspaceFromSnapshotCmd.execute( tckConsumer, errConsumer );
094
095        if ( status != 0 || errConsumer.hasBeenFed() )
096        {
097            return new ScmResult( tckCreateWorkspaceFromSnapshotCmd.getCommandString(),
098                                  "Error code for Jazz SCM (create workspace --snapshot) command - " + status,
099                                  errConsumer.getOutput(), false );
100        }
101
102        return new ScmResult( tckCreateWorkspaceFromSnapshotCmd.getCommandString(), "All ok",
103                              ( (DebugLoggerConsumer) tckConsumer ).getOutput(), true );
104    }
105
106    // Create the JazzScmCommand to execute the "scm create workspace ..." command
107    // This will create a workspace of the same name as the tag.
108    private JazzScmCommand createCreateWorkspaceFromSnapshotCommand( JazzScmProviderRepository repo, ScmFileSet fileSet,
109                                                                     String nameWorkspace, String nameSnapshot )
110    {
111        JazzScmCommand command =
112            new JazzScmCommand( JazzConstants.CMD_CREATE, JazzConstants.CMD_SUB_WORKSPACE, repo, fileSet, getLogger() );
113
114        command.addArgument( nameWorkspace );
115        command.addArgument( JazzConstants.ARG_WORKSPACE_SNAPSHOT );
116        command.addArgument( nameSnapshot );
117
118        return command;
119    }
120
121    /**
122     * If a TCK test case has more than one test case, it will need
123     * to generate a new workspace for each test. Use this method
124     * to provide uniqueness again.
125     */
126    public void generateNewSystemTime()
127    {
128        currentSystemTimeMillis = System.currentTimeMillis();
129    }
130
131    /**
132     * Create a unique repository workspace using the system time, based
133     * upon a supplied snapshot. The creation of this initial snapshot
134     * currently can not be scripted, so it needs to be done manually first.
135     *
136     * @see org.apache.maven.scm.ScmTckTestCase#initRepo()
137     */
138    public void initRepo( ScmRepository repository )
139        throws Exception
140    {
141        // Set a default logger. because I cann't get to the ones later on...
142        setLogger( new DefaultLog() );
143        // Create the unique workspace based upon a snapshot
144        executeCommand( repository.getProviderRepository(), new ScmFileSet( getWorkingCopy() ), null );
145    }
146
147    /**
148     * This method is available to those SCM clients that need to perform
149     * a cleanup at the end of the tests. It is needed when server side
150     * operations are performed, or the check out dirs are outside
151     * of the normal target directory.
152     */
153    public void removeRepo()
154        throws Exception
155    {
156        FileUtils.deleteDirectory( new File( getTckBaseDir() ) );
157    }
158
159    /**
160     * Return the URL used for this specific TCK test execution.
161     * It generates a unique workspace name, based on the system time.
162     *
163     * @see org.apache.maven.scm.ScmTckTestCase#getScmUrl()
164     */
165    public String getScmUrl()
166        throws Exception
167    {
168        if ( scmUrl == null )
169        {
170            // tckUrlPrefix is the system property that is used to seed the SCM URL.
171            // EG:
172            // "scm:jazz:Deb;Deb@https://rtc:9444/jazz:MavenSCMTestWorkspace"
173            //
174            String tckUrlPrefix = getSystemProperty( "tckUrlPrefix", "" );
175            if ( StringUtils.isBlank( tckUrlPrefix ) )
176            {
177                Assert.fail( "Property \"tckUrlPrefix\" is not set." );
178            }
179
180            scmUrl = tckUrlPrefix + "_" + currentSystemTimeMillis;
181        }
182
183        return scmUrl;
184    }
185
186    /**
187     * Get the snapshot name, getting it from the system properties if necessary.
188     *
189     * @return The name of the snapshot used to create a repository workspace,
190     *         which is then loaded into the tckBaseDir.
191     */
192    private String getSnapshotName()
193    {
194        if ( snapshotName == null )
195        {
196            snapshotName = getSystemProperty( "tckSnapshotName", "" );
197            if ( StringUtils.isBlank( snapshotName ) )
198            {
199                Assert.fail( "Property \"tckSnapshotName\" is not set." );
200            }
201        }
202
203        return snapshotName;
204    }
205
206    /**
207     * Get the base directory used for the tck tests.
208     *
209     * @return The base directory used for the tck tests, the sandbox.
210     */
211    private String getTckBaseDir()
212    {
213        if ( tckBaseDir == null )
214        {
215            tckBaseDir = getSystemProperty( "tckBaseDir", "" );
216            if ( StringUtils.isBlank( tckBaseDir ) )
217            {
218                Assert.fail( "Property \"tckBaseDir\" is not set." );
219            }
220        }
221
222        return tckBaseDir;
223    }
224
225    /**
226     * @see org.apache.maven.scm.ScmTestCase#getWorkingCopy()
227     */
228    public File getWorkingCopy()
229    {
230        return new File( getTckBaseDir() + "/wc" );
231    }
232
233    /**
234     * @see org.apache.maven.scm.ScmTestCase#getAssertionCopy()
235     */
236    public File getAssertionCopy()
237    {
238        return new File( getTckBaseDir() + "/ac" );
239    }
240
241    /**
242     * @see org.apache.maven.scm.ScmTestCase#getUpdatingCopy()
243     */
244    public File getUpdatingCopy()
245    {
246        return new File( getTckBaseDir() + "/uc" );
247    }
248}