View Javadoc

1   package org.apache.maven.archiva.dependency.graph.walk;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.commons.lang.StringUtils;
23  import org.apache.maven.archiva.dependency.graph.DependencyGraph;
24  import org.apache.maven.archiva.dependency.graph.DependencyGraphEdge;
25  import org.apache.maven.archiva.dependency.graph.DependencyGraphKeys;
26  import org.apache.maven.archiva.dependency.graph.DependencyGraphNode;
27  import org.apache.maven.archiva.dependency.graph.tasks.FlagCyclicEdgesTask;
28  import org.apache.maven.archiva.model.ArtifactReference;
29  
30  import java.util.List;
31  
32  import junit.framework.TestCase;
33  
34  /**
35   * DependencyGraphWalkerTest 
36   *
37   * @version $Id: DependencyGraphWalkerTest.java 755277 2009-03-17 15:18:35Z brett $
38   */
39  public class DependencyGraphWalkerTest
40      extends TestCase
41  {
42      /**
43       * <pre>
44       *  [foo-util] ---&gt; [foo-common]
45       *      \
46       *       ---------&gt; [foo-xml] ---&gt; [xercesImpl] ---&gt; [xmlParserAPIs]
47       *                        \  \
48       *                         \  ---&gt; [jdom] ----+
49       *                          \                 |
50       *                           ----&gt; [jaxen] &lt;--+
51       * </pre>
52       */
53      public void testModerateWalk()
54      {
55          DependencyGraph graph = new DependencyGraph( "org.foo", "foo-util", "1.0" );
56          String rootKey = DependencyGraphKeys.toKey( graph.getRootNode().getArtifact() );
57          addEdgeAndNodes( graph, toEdge( rootKey, "org.foo:foo-common:1.0::jar" ) );
58          addEdgeAndNodes( graph, toEdge( rootKey, "org.foo:foo-xml:1.0::jar" ) );
59  
60          addEdgeAndNodes( graph, toEdge( "org.foo:foo-xml:1.0::jar", "xerces:xercesImpl:2.2.1::jar" ) );
61          addEdgeAndNodes( graph, toEdge( "xerces:xercesImpl:2.2.1::jar", "xerces:xmlParserAPIs:2.2.1::jar" ) );
62          addEdgeAndNodes( graph, toEdge( "org.foo:foo-xml:1.0::jar", "jdom:jdom:1.0::jar" ) );
63          addEdgeAndNodes( graph, toEdge( "org.foo:foo-xml:1.0::jar", "jaxen:jaxen:1.0::jar" ) );
64          addEdgeAndNodes( graph, toEdge( "jdom:jdom:1.0::jar", "jaxen:jaxen:1.0::jar" ) );
65  
66          DependencyGraphWalker walker = new WalkDepthFirstSearch();
67          WalkCollector walkCollector = new WalkCollector();
68          walker.visit( graph, walkCollector );
69  
70          String expectedPath[] = new String[] {
71              rootKey,
72              "org.foo:foo-common:1.0::jar",
73              "org.foo:foo-xml:1.0::jar",
74              "jaxen:jaxen:1.0::jar",
75              "xerces:xercesImpl:2.2.1::jar",
76              "xerces:xmlParserAPIs:2.2.1::jar",
77              "jdom:jdom:1.0::jar" };
78  
79          assertVisitor( walkCollector, 1, 7, 7 );
80          assertPath( expectedPath, walkCollector.getCollectedPath() );
81      }
82  
83      /**
84       * <pre>
85       *  [foo-util] ---&gt; [foo-common]
86       *      \
87       *       ---------&gt; [foo-xml] ---&gt; [xercesImpl] ---&gt; [xmlParserAPIs]
88       * </pre>
89       */
90      public void testSimpleWalk()
91      {
92          DependencyGraph graph = new DependencyGraph( "org.foo", "foo-util", "1.0" );
93          String rootKey = DependencyGraphKeys.toKey( graph.getRootNode().getArtifact() );
94          addEdgeAndNodes( graph, toEdge( rootKey, "org.foo:foo-common:1.0::jar" ) );
95          addEdgeAndNodes( graph, toEdge( rootKey, "org.foo:foo-xml:1.0::jar" ) );
96          addEdgeAndNodes( graph, toEdge( "org.foo:foo-xml:1.0::jar", "xerces:xercesImpl:2.2.1::jar" ) );
97          addEdgeAndNodes( graph, toEdge( "xerces:xercesImpl:2.2.1::jar", "xerces:xmlParserAPIs:2.2.1::jar" ) );
98  
99          DependencyGraphWalker walker = new WalkDepthFirstSearch();
100         WalkCollector walkCollector = new WalkCollector();
101         walker.visit( graph, walkCollector );
102 
103         String expectedPath[] = new String[] {
104             rootKey,
105             "org.foo:foo-common:1.0::jar",
106             "org.foo:foo-xml:1.0::jar",
107             "xerces:xercesImpl:2.2.1::jar",
108             "xerces:xmlParserAPIs:2.2.1::jar" };
109 
110         assertVisitor( walkCollector, 1, 5, 4 );
111         assertPath( expectedPath, walkCollector.getCollectedPath() );
112     }
113 
114     /**
115      * <pre>
116      *  [foo-util] ---&gt; [foo-common]
117      *      \
118      *       \              +----------------------------------------+
119      *        \             v                                        |
120      *         -------&gt; [foo-xml] ---&gt; [xercesImpl] ---&gt; [xmlParserAPIs]
121      *                        \  \
122      *                         \  ---&gt; [jdom] ----+
123      *                          \                 |
124      *                           ----&gt; [jaxen] &lt;--+
125      * </pre>
126      */
127     public void testDeepNodeWalk()
128     {
129         DependencyGraph graph = new DependencyGraph( "org.foo", "foo-util", "1.0" );
130         String rootKey = DependencyGraphKeys.toKey( graph.getRootNode().getArtifact() );
131         addEdgeAndNodes( graph, toEdge( rootKey, "org.foo:foo-common:1.0::jar" ) );
132         addEdgeAndNodes( graph, toEdge( rootKey, "org.foo:foo-xml:1.0::jar" ) );
133 
134         addEdgeAndNodes( graph, toEdge( "org.foo:foo-xml:1.0::jar", "xerces:xercesImpl:2.2.1::jar" ) );
135         addEdgeAndNodes( graph, toEdge( "xerces:xercesImpl:2.2.1::jar", "xerces:xmlParserAPIs:2.2.1::jar" ) );
136         addEdgeAndNodes( graph, toEdge( "org.foo:foo-xml:1.0::jar", "jdom:jdom:1.0::jar" ) );
137         addEdgeAndNodes( graph, toEdge( "org.foo:foo-xml:1.0::jar", "jaxen:jaxen:1.0::jar" ) );
138         addEdgeAndNodes( graph, toEdge( "jdom:jdom:1.0::jar", "jaxen:jaxen:1.0::jar" ) );
139         // introduce cyclic dep. intentional. should only result in walking to foo-xml once. 
140         addEdgeAndNodes( graph, toEdge( "xerces:xmlParserAPIs:2.2.1::jar", "org.foo:foo-xml:1.0::jar" ) );
141 
142         new FlagCyclicEdgesTask().executeTask( graph );
143 
144         DependencyGraphWalker walker = new WalkDepthFirstSearch();
145         WalkCollector walkCollector = new WalkCollector();
146         ArtifactReference startRef = toArtifactReference( "org.foo:foo-xml:1.0::jar" );
147         DependencyGraphNode startNode = new DependencyGraphNode( startRef );
148         walker.visit( graph, startNode, walkCollector );
149 
150         String expectedPath[] = new String[] {
151             "org.foo:foo-xml:1.0::jar",
152             "jaxen:jaxen:1.0::jar",
153             "xerces:xercesImpl:2.2.1::jar",
154             "xerces:xmlParserAPIs:2.2.1::jar",
155             "jdom:jdom:1.0::jar" };
156 
157         assertVisitor( walkCollector, 1, 5, 6 );
158         assertPath( expectedPath, walkCollector.getCollectedPath() );
159     }
160 
161     private void addEdgeAndNodes( DependencyGraph graph, DependencyGraphEdge edge )
162     {
163         ensureNodeExists( graph, edge.getNodeFrom() );
164         ensureNodeExists( graph, edge.getNodeTo() );
165         graph.addEdge( edge );
166     }
167 
168     private void ensureNodeExists( DependencyGraph graph, ArtifactReference artifact )
169     {
170         DependencyGraphNode node = graph.getNode( artifact );
171         if ( node == null )
172         {
173             node = new DependencyGraphNode( artifact );
174             graph.addNode( node );
175         }
176     }
177 
178     private void assertPath( String[] expectedPath, List<String> collectedPath )
179     {
180         assertEquals( "Path.length", expectedPath.length, collectedPath.size() );
181 
182         for ( int i = 0; i < expectedPath.length; i++ )
183         {
184             assertEquals( "Walk path[" + i + "]", expectedPath[i], collectedPath.get( i ) );
185         }
186     }
187 
188     private void assertVisitor( WalkCollector walkCollector, int countGraphs, int countNodes, int countEdges )
189     {
190         assertEquals( "Count of graph discovery.", countGraphs, walkCollector.getCountDiscoverGraph() );
191         assertEquals( "Count of graph finished.", countGraphs, walkCollector.getCountFinishGraph() );
192         assertEquals( "Discover - Finish = 0 (on graph counts)", 0,
193                       ( walkCollector.getCountDiscoverGraph() - walkCollector.getCountFinishGraph() ) );
194 
195         assertEquals( "Count of node discovery.", countNodes, walkCollector.getCountDiscoverNode() );
196         assertEquals( "Count of node finished.", countNodes, walkCollector.getCountFinishNode() );
197         assertEquals( "Discover - Finish = 0 (on node counts)", 0,
198                       ( walkCollector.getCountDiscoverNode() - walkCollector.getCountFinishNode() ) );
199 
200         assertEquals( "Count of edge discovery.", countEdges, walkCollector.getCountDiscoverEdge() );
201         assertEquals( "Count of edge finished.", countEdges, walkCollector.getCountFinishEdge() );
202         assertEquals( "Discover - Finish = 0 (on edge counts)", 0,
203                       ( walkCollector.getCountDiscoverEdge() - walkCollector.getCountFinishEdge() ) );
204     }
205 
206     private DependencyGraphEdge toEdge( String fromKey, String toKey )
207     {
208         ArtifactReference nodeFrom = toArtifactReference( fromKey );
209         ArtifactReference nodeTo = toArtifactReference( toKey );
210 
211         return new DependencyGraphEdge( nodeFrom, nodeTo );
212     }
213 
214     private ArtifactReference toArtifactReference( String key )
215     {
216         String parts[] = StringUtils.splitPreserveAllTokens( key, ':' );
217         assertEquals( "ArtifactReference [" + key + "] parts should equal 5", 5, parts.length );
218 
219         ArtifactReference artifact = new ArtifactReference();
220         artifact.setGroupId( parts[0] );
221         artifact.setArtifactId( parts[1] );
222         artifact.setVersion( parts[2] );
223         artifact.setClassifier( parts[3] );
224         artifact.setType( parts[4] );
225 
226         return artifact;
227     }
228 }