001package org.apache.maven.scm.provider.accurev.command.changelog;
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 static org.hamcrest.Matchers.is;
023import static org.hamcrest.Matchers.isOneOf;
024import static org.hamcrest.Matchers.not;
025import static org.hamcrest.Matchers.notNullValue;
026import static org.hamcrest.Matchers.nullValue;
027import static org.junit.Assert.assertThat;
028import static org.mockito.Matchers.any;
029import static org.mockito.Matchers.eq;
030import static org.mockito.Mockito.when;
031import static org.apache.maven.scm.ChangeFileMatcher.changeFile;
032
033import java.io.File;
034import java.util.Arrays;
035import java.util.Collections;
036import java.util.Date;
037import java.util.List;
038
039import org.apache.maven.scm.ChangeFile;
040import org.apache.maven.scm.ChangeSet;
041import org.apache.maven.scm.CommandParameter;
042import org.apache.maven.scm.CommandParameters;
043import org.apache.maven.scm.ScmException;
044import org.apache.maven.scm.ScmFileSet;
045import org.apache.maven.scm.ScmRevision;
046import org.apache.maven.scm.command.changelog.ChangeLogScmResult;
047import org.apache.maven.scm.command.changelog.ChangeLogSet;
048import org.apache.maven.scm.provider.accurev.FileDifference;
049import org.apache.maven.scm.provider.accurev.Stream;
050import org.apache.maven.scm.provider.accurev.Transaction;
051import org.apache.maven.scm.provider.accurev.command.AbstractAccuRevCommandTest;
052import org.junit.Test;
053
054public class AccuRevChangeLogCommandTest
055    extends AbstractAccuRevCommandTest
056{
057    @Test
058    public void testChangeLogBetweenStreamsUnsupported()
059        throws Exception
060    {
061        final ScmFileSet testFileSet = new ScmFileSet( new File( basedir, "project/dir" ) );
062
063        AccuRevChangeLogCommand command = new AccuRevChangeLogCommand( getLogger() );
064
065        CommandParameters params = new CommandParameters();
066        params.setScmVersion( CommandParameter.START_SCM_VERSION, new ScmRevision( "aStream/12" ) );
067        params.setScmVersion( CommandParameter.END_SCM_VERSION, new ScmRevision( "anotherStream/20" ) );
068
069        try
070        {
071            command.changelog( repo, testFileSet, params );
072            fail( "Expected accurev exception" );
073        }
074        catch ( ScmException e )
075        {
076            // Expected
077        }
078    }
079
080    @Test
081    public void testChangeLogToNow()
082        throws Exception
083    {
084        final ScmFileSet testFileSet = new ScmFileSet( new File( basedir, "project/dir" ) );
085
086        // start tran (35)
087        List<Transaction> startTransaction = Collections.singletonList( new Transaction( 35L, new Date(), "sometran",
088                                                                                         "anyone" ) );
089        when( accurev.history( "aStream", "12", null, 1, true, true ) ).thenReturn( startTransaction );
090
091        // end tran (42)
092        List<Transaction> endTransaction = Collections.singletonList( new Transaction( 42L, new Date(), "sometran",
093                                                                                       "anyone" ) );
094        when( accurev.history( "aStream", "now", null, 1, true, true ) ).thenReturn( endTransaction );
095
096        Stream basisStream = new Stream( "aStream", 10, "myDepot", 1, "myDepot", getDate( 2008, 1, 1 ), "normal" );
097        when( accurev.showStream( "aStream" ) ).thenReturn( basisStream );
098
099        List<FileDifference> emptyList = Collections.emptyList();
100        when( accurev.diff( "myStream", "12", "42" ) ).thenReturn( emptyList );
101
102        List<Transaction> noTransactions = Collections.emptyList();
103        when( accurev.history( "aStream", "13", "42", 0, false, false ) ).thenReturn( noTransactions );
104
105        AccuRevChangeLogCommand command = new AccuRevChangeLogCommand( getLogger() );
106        CommandParameters params = new CommandParameters();
107        params.setScmVersion( CommandParameter.START_SCM_VERSION, new ScmRevision( "aStream/12" ) );
108
109        assertThat( command.changelog( repo, testFileSet, params ), not( nullValue() ) );
110
111    }
112
113    @Test
114    public void testStandardCase()
115        throws Exception
116    {
117        // Workspace to root stream, keeps and promotes
118
119        // Setup test data so that the checkin area is the repo's project path.
120        final ScmFileSet testFileSet = new ScmFileSet( new File( basedir, "project/dir" ) );
121
122        // stream 1 only => not found
123        // stream 2 only => created
124        // stream 1 and 2 => version or moved
125        // comment to contain all the changes eg file moved from to
126        // files to contain all the referenced files
127        // NOTE: The version specs, and stream numbers used in this test are
128        // important!!
129
130        // start tran (35)
131        List<Transaction> startTransaction = Collections.singletonList( new Transaction( 35L, new Date(), "sometran",
132                                                                                         "anyone" ) );
133        when( accurev.history( "myStream", "2009/01/01 10:00:00", null, 1, true, true ) ).thenReturn( startTransaction );
134
135        // end tran (42)
136        List<Transaction> endTransaction = Collections.singletonList( new Transaction( 42L, new Date(), "sometran",
137                                                                                       "anyone" ) );
138
139        Stream basisStream = new Stream( "myStream", 10, "myDepot", 1, "myDepot", getDate( 2008, 1, 1 ), "normal" );
140        when( accurev.showStream( "myStream" ) ).thenReturn( basisStream );
141
142        when( accurev.history( "myStream", "2009/01/12 13:00:00", null, 1, true, true ) ).thenReturn( endTransaction );
143
144        // now we call diff between the tran ids - 35 to 42
145        FileDifference promoted = new FileDifference( 10L, "/promoted/file", "4/2", "/promoted/file", "6/1" );
146        FileDifference removed = new FileDifference( 20L, null, null, "/removed/file", "6/1" );
147        FileDifference created = new FileDifference( 30L, "/created/file", "6/1", null, null );
148        FileDifference moved = new FileDifference( 40L, "/moved/to", "4/2", "/moved/from", "6/1" );
149
150        when( accurev.diff( "myStream", "35", "42" ) ).thenReturn( Arrays.asList( promoted, removed, created, moved ) );
151
152        // and we call hist for tranid + 1 to end trand id
153
154        // getDate uses calendar's zero indexed months
155        final Date dateFrom = getDate( 2009, 0, 1, 10, 0, 0, null );
156        final Date dateTo = getDate( 2009, 0, 12, 13, 0, 0, null );
157        final Date keepWhen = getDate( 2009, 0, 2, 9, 0, 0, null );
158        final Date promoteWhen = getDate( 2009, 0, 4, 23, 0, 0, null );
159
160        final Transaction promoteOne = new Transaction( 10L, keepWhen, "promote", "aUser" );
161        promoteOne.addVersion( 5L, "/./kept/file", "10/5", "5/5", "3/2" );
162        promoteOne.setComment( "a Comment" );
163
164        final Transaction promoteTwo = new Transaction( 12L, promoteWhen, "promote", "anOther" );
165        promoteTwo.addVersion( 10L, "/./promoted/file", "10/5", "4/2", null );
166        promoteTwo.setComment( "my Promotion" );
167
168        when( accurev.history( "myStream", "36", "42", 0, false, false ) ).thenReturn( Arrays.asList( promoteOne,
169                                                                                                      promoteTwo ) );
170
171        AccuRevChangeLogCommand command = new AccuRevChangeLogCommand( getLogger() );
172
173        CommandParameters commandParameters = new CommandParameters();
174        commandParameters.setString( CommandParameter.MESSAGE, "A commit message" );
175        commandParameters.setDate( CommandParameter.START_DATE, dateFrom );
176        commandParameters.setDate( CommandParameter.END_DATE, dateTo );
177        ChangeLogScmResult result = command.changelog( repo, testFileSet, commandParameters );
178
179        assertThat( result.isSuccess(), is( true ) );
180        List<ChangeSet> changeSets = result.getChangeLog().getChangeSets();
181        assertThat( changeSets.size(), is( 3 ) );
182        ChangeSet cs = (ChangeSet) changeSets.get( 0 );
183        assertThat( cs.getAuthor(), is( "aUser" ) );
184        assertThat( cs.getComment(), is( "a Comment" ) );
185        assertThat( cs.getDate(), is( keepWhen ) );
186        assertThat( cs.getFiles().size(), is( 1 ) );
187        ChangeFile cf = (ChangeFile) cs.getFiles().get( 0 );
188
189        assertThat( cf.getName(), is( "/./kept/file" ) );
190        assertThat( cf.getRevision(), is( "10/5 (5/5)" ) );
191
192        cs = (ChangeSet) changeSets.get( 2 );
193        assertThat( cs.getAuthor(), is( "various" ) );
194        // created/removed/moved but not the file that was in the promoted
195        // set...
196        assertThat( cs.getComment(), is( "Upstream changes" ) );
197        assertThat( cs.getFiles().size(), is( 3 ) );
198        assertThat( cs.containsFilename( "created/file" ), is( true ) );
199    }
200
201    @Test
202    public void testWorkspaceChangelog()
203        throws Exception
204    {
205
206        final ScmFileSet testFileSet = new ScmFileSet( new File( basedir, "project/dir" ) );
207        final Date keepWhen = getDate( 2009, 0, 2, 9, 0, 0, null );
208        final Date promoteWhen = getDate( 2009, 0, 4, 23, 0, 0, null );
209        final Date fromDate = getDate( 2009, 0, 1, 0, 0, 0, null );
210        final Date toDate = getDate( 2009, 0, 5, 1, 0, 0, null );
211
212        // start tran (35)
213        List<Transaction> startTransaction = Collections.singletonList( new Transaction( 35L, fromDate, "sometran",
214                                                                                         "anyone" ) );
215        when( accurev.history( "workspace5", "35", null, 1, true, true ) ).thenReturn( startTransaction );
216
217        // end tran (42)
218        List<Transaction> endTransaction = Collections.singletonList( new Transaction( 42L, toDate, "sometran",
219                                                                                       "anyone" ) );
220
221        when( accurev.history( "workspace5", "42", null, 1, true, true ) ).thenReturn( endTransaction );
222
223        // Stream hierarchy
224        // S2 < S4, S2 < WS3, S4 < WS5, S4 << WS7
225        // 
226        // Changelog(WS5,35,42) involves
227        // -- diff(S4,35,42)
228        // -- hist(WS5,36-42)
229        // -- hist(S4,36-42)
230        //
231        // Promote S4 to S2 - not in diffS4, not in histS4, not in hist WS5 -
232        // not in changeset
233        // Promote WS3 to S2 - in diffS4, not hist histS4, not in hist WS5 - in
234        // "upstream changes"
235        // Promote WS5 to S4 - in diffS4, in histS4, not in hist WS5 - not in
236        // changeset (real version from WS5)
237        // Promote WS7 to S4 - in diffS4, in histS4, not in hist WS5 - in
238        // changeset as a promote transaction
239        // Keep WS5 - not in diffS4, not in histS4, in histWS5 - in changeset as
240        // a keep transaction
241
242        // This workspace is stream 5, attached to basis mystream 5
243        Stream workspaceStream = new Stream( "workspace5", 5, "stream4", 4, "myDepot", getDate( 2008, 10, 1, 10, 0, 0,
244                                                                                                null ), "workspace" );
245        when( accurev.showStream( "workspace5" ) ).thenReturn( workspaceStream );
246
247        Stream basisStream = new Stream( "stream4", 4, "myDepot", 1, "myDepot", getDate( 2008, 1, 1 ), "normal" );
248        when( accurev.showStream( "stream4" ) ).thenReturn( basisStream );
249
250        // now we call diff between the tran ids - 35 to 42
251        FileDifference diffWS3toS2 = new FileDifference( 32L, "/promoted/WS3toS2", "3/2", "/promoted/WS3toS2", "6/1" );
252        FileDifference diffWS5toS4 = new FileDifference( 54L, "/promoted/WS5toS4", "5/3", "/promoted/WS5toS4", "8/1" );
253        FileDifference diffWS7toS4 = new FileDifference( 74L, "/promoted/WS7toS4", "7/12", "/promoted/WS7toS4", "3/13" );
254
255        when( accurev.diff( "stream4", "35", "42" ) )
256            .thenReturn( Arrays.asList( diffWS3toS2, diffWS5toS4, diffWS7toS4 ) );
257
258        // and we call hist for tranid + 1 to end trand ii
259
260        Transaction promoteWS5toS4 = new Transaction( 37L, promoteWhen, "promote", "aUser" );
261        promoteWS5toS4.setComment( "WS5toS4" );
262        promoteWS5toS4.addVersion( 54L, "/./promoted/WS5toS4", "4/5", "5/3", "3/2" );
263
264        Transaction promoteWS7toS4 = new Transaction( 38L, promoteWhen, "promote", "aUser" );
265        promoteWS7toS4.setComment( "WS7toS4" );
266        promoteWS7toS4.addVersion( 74L, "/./promoted/WS7toS4", "4/11", "7/12", "3/2" );
267
268        when( accurev.history( "stream4", "36", "42", 0, false, false ) ).thenReturn( Arrays.asList( promoteWS5toS4,
269                                                                                                     promoteWS7toS4 ) );
270
271        Transaction keepWS5 = new Transaction( 39L, keepWhen, "keep", "anOther" );
272        keepWS5.addVersion( 5L, "/./kept/WS5", "5/7", "5/7", "7/21" );
273        keepWS5.setComment( "keepWS5" );
274
275        when( accurev.history( "workspace5", "36", "42", 0, false, false ) ).thenReturn( Collections
276                                                                                             .singletonList( keepWS5 ) );
277
278        AccuRevChangeLogCommand command = new AccuRevChangeLogCommand( getLogger() );
279
280        CommandParameters commandParameters = new CommandParameters();
281        commandParameters.setScmVersion( CommandParameter.START_SCM_VERSION, new ScmRevision( "workspace5/35" ) );
282        commandParameters.setScmVersion( CommandParameter.END_SCM_VERSION, new ScmRevision( "workspace5/42" ) );
283        ChangeLogScmResult result = command.changelog( repo, testFileSet, commandParameters );
284
285        assertThat( result.isSuccess(), is( true ) );
286        ChangeLogSet changelog = result.getChangeLog();
287        assertThat( changelog.getStartVersion().getName(), is( "workspace5/35" ) );
288        assertThat( changelog.getEndVersion().getName(), is( "workspace5/42" ) );
289        List<ChangeSet> changesets = changelog.getChangeSets();
290        assertThat( changesets.size(), is( 3 ) );
291
292        for ( ChangeSet changeSet : changesets )
293        {
294            assertThat( changeSet.getComment(), isOneOf( "Upstream changes", "WS7toS4", "keepWS5" ) );
295
296            if ( "Upstream changes".equals( changeSet.getComment() ) )
297            {
298                assertThat( changeSet.getFiles().size(), is( 1 ) );
299                ChangeFile changeFile = (ChangeFile) changeSet.getFiles().get( 0 );
300                assertThat( changeFile, is( changeFile( "/promoted/WS3toS2" ) ) );
301            }
302        }
303    }
304
305    @Test
306    public void testChangeLogFailed()
307        throws Exception
308    {
309        // Workspace to root stream, keeps and promotes
310
311        // Setup test data so that the checkin area is the repo's project path.
312        final ScmFileSet testFileSet = new ScmFileSet( new File( basedir, "project/dir" ) );
313
314        final Date dateFrom = getDate( 2009, 0, 01, 10, 00, 00, null );
315        final Date dateTo = getDate( 2009, 0, 12, 13, 00, 00, null );
316
317        // start tran (35)
318        List<Transaction> startTransaction = Collections.singletonList( new Transaction( 35L, new Date(), "sometran",
319                                                                                         "anyone" ) );
320        when( accurev.history( "myStream", "2009/01/01 10:00:00", null, 1, true, true ) ).thenReturn( startTransaction );
321
322        // end tran (42)
323        List<Transaction> endTransaction = Collections.singletonList( new Transaction( 42L, new Date(), "sometran",
324                                                                                       "anyone" ) );
325
326        when( accurev.history( "myStream", "2009/01/12 13:00:00", null, 1, true, true ) ).thenReturn( endTransaction );
327
328        when(
329              accurev.history( eq( "myStream" ), any( String.class ), any( String.class ), eq( 0 ), eq( false ),
330                               eq( false ) ) ).thenReturn( null );
331
332        AccuRevChangeLogCommand command = new AccuRevChangeLogCommand( getLogger() );
333
334        CommandParameters commandParameters = new CommandParameters();
335        commandParameters.setString( CommandParameter.MESSAGE, "A commit message" );
336        commandParameters.setDate( CommandParameter.START_DATE, dateFrom );
337        commandParameters.setDate( CommandParameter.END_DATE, dateTo );
338        ChangeLogScmResult result = command.changelog( repo, testFileSet, commandParameters );
339
340        assertThat( result.isSuccess(), is( false ) );
341        assertThat( result.getProviderMessage(), notNullValue() );
342    }
343}