001package org.apache.maven.repository.legacy.resolver; 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.artifact.Artifact; 023import org.apache.maven.artifact.factory.ArtifactFactory; 024import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException; 025import org.apache.maven.artifact.metadata.ArtifactMetadataSource; 026import org.apache.maven.artifact.metadata.ResolutionGroup; 027import org.apache.maven.artifact.repository.ArtifactRepository; 028import org.apache.maven.artifact.resolver.ArtifactResolutionException; 029import org.apache.maven.artifact.resolver.ArtifactResolutionResult; 030import org.apache.maven.artifact.resolver.CyclicDependencyException; 031import org.apache.maven.artifact.resolver.ResolutionListener; 032import org.apache.maven.artifact.resolver.filter.ArtifactFilter; 033import org.apache.maven.artifact.resolver.filter.ExclusionSetFilter; 034import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter; 035import org.apache.maven.artifact.versioning.ArtifactVersion; 036import org.apache.maven.artifact.versioning.DefaultArtifactVersion; 037import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; 038import org.apache.maven.artifact.versioning.OverConstrainedVersionException; 039import org.apache.maven.artifact.versioning.VersionRange; 040import org.apache.maven.repository.legacy.metadata.MetadataResolutionRequest; 041import org.codehaus.plexus.PlexusTestCase; 042 043import java.util.ArrayList; 044import java.util.Arrays; 045import java.util.Collections; 046import java.util.HashMap; 047import java.util.HashSet; 048import java.util.LinkedHashSet; 049import java.util.List; 050import java.util.Map; 051import java.util.Set; 052 053/** 054 * Test the default artifact collector. 055 * 056 * @author <a href="mailto:brett@apache.org">Brett Porter</a> 057 */ 058public class DefaultArtifactCollectorTest 059 extends PlexusTestCase 060{ 061 private LegacyArtifactCollector artifactCollector; 062 063 private ArtifactFactory artifactFactory; 064 065 private ArtifactSpec projectArtifact; 066 067 private Source source; 068 069 private static final String GROUP_ID = "test"; 070 071 @Override 072 protected void setUp() 073 throws Exception 074 { 075 super.setUp(); 076 077 source = new Source(); 078 artifactFactory = (ArtifactFactory) lookup( ArtifactFactory.ROLE ); 079 artifactCollector = lookup( LegacyArtifactCollector.class ); 080 081 projectArtifact = createArtifactSpec( "project", "1.0", null ); 082 } 083 084 @Override 085 protected void tearDown() 086 throws Exception 087 { 088 artifactCollector = null; 089 artifactFactory = null; 090 super.tearDown(); 091 } 092 093 // works, but we don't fail on cycles presently 094 public void disabledtestCircularDependencyNotIncludingCurrentProject() 095 throws ArtifactResolutionException, InvalidVersionSpecificationException 096 { 097 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 098 ArtifactSpec b = a.addDependency( "b", "1.0" ); 099 b.addDependency( "a", "1.0" ); 100 try 101 { 102 collect( a ); 103 fail( "Should have failed on cyclic dependency not involving project" ); 104 } 105 catch ( CyclicDependencyException expected ) 106 { 107 assertTrue( true ); 108 } 109 } 110 111 // works, but we don't fail on cycles presently 112 public void disabledtestCircularDependencyIncludingCurrentProject() 113 throws ArtifactResolutionException, InvalidVersionSpecificationException 114 { 115 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 116 ArtifactSpec b = a.addDependency( "b", "1.0" ); 117 b.addDependency( "project", "1.0" ); 118 try 119 { 120 collect( a ); 121 fail( "Should have failed on cyclic dependency involving project" ); 122 } 123 catch ( CyclicDependencyException expected ) 124 { 125 assertTrue( true ); 126 } 127 } 128 129 public void testResolveWithFilter() 130 throws ArtifactResolutionException, InvalidVersionSpecificationException 131 { 132 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 133 ArtifactSpec b = a.addDependency( "b", "1.0" ); 134 ArtifactSpec c = a.addDependency( "c", "3.0" ); 135 136 b.addDependency( "c", "2.0" ); 137 ArtifactSpec d = b.addDependency( "d", "4.0" ); 138 139 ArtifactResolutionResult res = collect( a ); 140 assertEquals( "Check artifact list", 141 createSet( new Object[] { a.artifact, b.artifact, c.artifact, d.artifact } ), res.getArtifacts() ); 142 143 ArtifactFilter filter = new ExclusionSetFilter( new String[] { "b" } ); 144 res = collect( a, filter ); 145 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, c.artifact } ), res.getArtifacts() ); 146 } 147 148 public void testResolveCorrectDependenciesWhenDifferentDependenciesOnNearest() 149 throws ArtifactResolutionException, InvalidVersionSpecificationException 150 { 151 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 152 ArtifactSpec b = a.addDependency( "b", "1.0" ); 153 ArtifactSpec c2 = b.addDependency( "c", "2.0" ); 154 c2.addDependency( "d", "1.0" ); 155 156 ArtifactSpec e = createArtifactSpec( "e", "1.0" ); 157 ArtifactSpec c1 = e.addDependency( "c", "1.0" ); 158 ArtifactSpec f = c1.addDependency( "f", "1.0" ); 159 160 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, e.artifact } ) ); 161 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact, e.artifact, c1.artifact, 162 f.artifact } ), res.getArtifacts() ); 163 assertEquals( "Check version", "1.0", getArtifact( "c", res.getArtifacts() ).getVersion() ); 164 } 165 166 public void disabledtestResolveCorrectDependenciesWhenDifferentDependenciesOnNewest() 167 throws ArtifactResolutionException, InvalidVersionSpecificationException 168 { 169 // TODO: use newest conflict resolver 170 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 171 ArtifactSpec b = a.addDependency( "b", "1.0" ); 172 ArtifactSpec c2 = b.addDependency( "c", "2.0" ); 173 ArtifactSpec d = c2.addDependency( "d", "1.0" ); 174 175 ArtifactSpec e = createArtifactSpec( "e", "1.0" ); 176 ArtifactSpec c1 = e.addDependency( "c", "1.0" ); 177 c1.addDependency( "f", "1.0" ); 178 179 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, e.artifact } ) ); 180 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact, e.artifact, c2.artifact, 181 d.artifact } ), res.getArtifacts() ); 182 assertEquals( "Check version", "2.0", getArtifact( "c", res.getArtifacts() ).getVersion() ); 183 } 184 185 public void disabledtestResolveCorrectDependenciesWhenDifferentDependenciesOnNewestVersionReplaced() 186 throws ArtifactResolutionException, InvalidVersionSpecificationException 187 { 188 // TODO: use newest conflict resolver 189 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 190 ArtifactSpec b1 = a.addDependency( "b", "1.0" ); 191 ArtifactSpec c = a.addDependency( "c", "1.0" ); 192 ArtifactSpec d2 = b1.addDependency( "d", "2.0" ); 193 d2.addDependency( "h", "1.0" ); 194 ArtifactSpec d1 = c.addDependency( "d", "1.0" ); 195 ArtifactSpec b2 = c.addDependency( "b", "2.0" ); 196 ArtifactSpec e = b2.addDependency( "e", "1.0" ); 197 ArtifactSpec g = d1.addDependency( "g", "1.0" ); 198 199 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact } ) ); 200 Object[] artifacts = new Object[] { a.artifact, c.artifact, d1.artifact, b2.artifact, e.artifact, g.artifact }; 201 assertEquals( "Check artifact list", createSet( artifacts ), res.getArtifacts() ); 202 assertEquals( "Check version", "1.0", getArtifact( "d", res.getArtifacts() ).getVersion() ); 203 assertEquals( "Check version", "2.0", getArtifact( "b", res.getArtifacts() ).getVersion() ); 204 } 205 206 public void testResolveNearestNewestIsNearest() 207 throws ArtifactResolutionException, InvalidVersionSpecificationException 208 { 209 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 210 ArtifactSpec b = a.addDependency( "b", "1.0" ); 211 ArtifactSpec c = a.addDependency( "c", "3.0" ); 212 213 b.addDependency( "c", "2.0" ); 214 215 ArtifactResolutionResult res = collect( a ); 216 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact, c.artifact } ), 217 res.getArtifacts() ); 218 assertEquals( "Check version", "3.0", getArtifact( "c", res.getArtifacts() ).getVersion() ); 219 } 220 221 public void testResolveNearestOldestIsNearest() 222 throws ArtifactResolutionException, InvalidVersionSpecificationException 223 { 224 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 225 ArtifactSpec b = a.addDependency( "b", "1.0" ); 226 ArtifactSpec c = a.addDependency( "c", "2.0" ); 227 228 b.addDependency( "c", "3.0" ); 229 230 ArtifactResolutionResult res = collect( a ); 231 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact, c.artifact } ), 232 res.getArtifacts() ); 233 assertEquals( "Check version", "2.0", getArtifact( "c", res.getArtifacts() ).getVersion() ); 234 } 235 236 public void testResolveLocalNewestIsLocal() 237 throws ArtifactResolutionException, InvalidVersionSpecificationException 238 { 239 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 240 a.addDependency( "b", "2.0" ); 241 ArtifactSpec b = createArtifactSpec( "b", "3.0" ); 242 243 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) ); 244 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() ); 245 assertEquals( "Check version", "3.0", getArtifact( "b", res.getArtifacts() ).getVersion() ); 246 } 247 248 public void testResolveLocalOldestIsLocal() 249 throws ArtifactResolutionException, InvalidVersionSpecificationException 250 { 251 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 252 a.addDependency( "b", "3.0" ); 253 ArtifactSpec b = createArtifactSpec( "b", "2.0" ); 254 255 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) ); 256 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() ); 257 assertEquals( "Check version", "2.0", getArtifact( "b", res.getArtifacts() ).getVersion() ); 258 } 259 260 public void testResolveLocalWithNewerVersionButLesserScope() 261 throws ArtifactResolutionException, InvalidVersionSpecificationException 262 { 263 ArtifactSpec a = createArtifactSpec( "commons-logging", "1.0" ); 264 a.addDependency( "junit", "3.7" ); 265 ArtifactSpec b = createArtifactSpec( "junit", "3.8.1", Artifact.SCOPE_TEST ); 266 267 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) ); 268 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() ); 269 assertEquals( "Check version", "3.8.1", getArtifact( "junit", res.getArtifacts() ).getVersion() ); 270 assertEquals( "Check artifactScope", Artifact.SCOPE_TEST, getArtifact( "junit", res.getArtifacts() ).getScope() ); 271 } 272 273 public void testResolveLocalWithNewerVersionButLesserScopeResolvedFirst() 274 throws ArtifactResolutionException, InvalidVersionSpecificationException 275 { 276 ArtifactSpec b = createArtifactSpec( "junit", "3.8.1", Artifact.SCOPE_TEST ); 277 ArtifactSpec a = createArtifactSpec( "commons-logging", "1.0" ); 278 a.addDependency( "junit", "3.7" ); 279 280 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) ); 281 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() ); 282 assertEquals( "Check version", "3.8.1", getArtifact( "junit", res.getArtifacts() ).getVersion() ); 283 assertEquals( "Check artifactScope", Artifact.SCOPE_TEST, getArtifact( "junit", res.getArtifacts() ).getScope() ); 284 } 285 286 public void testResolveNearestWithRanges() 287 throws ArtifactResolutionException, InvalidVersionSpecificationException 288 { 289 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 290 ArtifactSpec b = a.addDependency( "b", "1.0" ); 291 ArtifactSpec c = a.addDependency( "c", "2.0" ); 292 293 b.addDependency( "c", "[1.0,3.0]" ); 294 295 ArtifactResolutionResult res = collect( a ); 296 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact, c.artifact } ), 297 res.getArtifacts() ); 298 assertEquals( "Check version", "2.0", getArtifact( "c", res.getArtifacts() ).getVersion() ); 299 } 300 301 public void testResolveRangeWithManagedVersion() 302 throws ArtifactResolutionException, InvalidVersionSpecificationException 303 { 304 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 305 ArtifactSpec b = a.addDependency( "b", "[1.0,3.0]" ); 306 307 ArtifactSpec managedB = createArtifactSpec( "b", "5.0" ); 308 309 ArtifactResolutionResult res = collect( a, managedB.artifact ); 310 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, managedB.artifact } ), 311 res.getArtifacts() ); 312 assertEquals( "Check version", "5.0", getArtifact( "b", res.getArtifacts() ).getVersion() ); 313 } 314 315 public void testCompatibleRanges() 316 throws ArtifactResolutionException, InvalidVersionSpecificationException 317 { 318 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 319 ArtifactSpec b = a.addDependency( "b", "1.0" ); 320 a.addDependency( "c", "[2.0,2.5]" ); 321 b.addDependency( "c", "[1.0,3.0]" ); 322 ArtifactSpec c = createArtifactSpec( "c", "2.5" ); 323 324 ArtifactResolutionResult res = collect( a ); 325 326 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact, c.artifact } ), 327 res.getArtifacts() ); 328 assertEquals( "Check version", "2.5", getArtifact( "c", res.getArtifacts() ).getVersion() ); 329 } 330 331 public void testIncompatibleRanges() 332 throws ArtifactResolutionException, InvalidVersionSpecificationException 333 { 334 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 335 ArtifactSpec b = a.addDependency( "b", "1.0" ); 336 a.addDependency( "c", "[2.4,3.0]" ); 337 338 b.addDependency( "c", "[1.0,2.0]" ); 339 340 ArtifactResolutionResult res = collect( a ); 341 342 assertTrue( res.hasVersionRangeViolations() ); 343 } 344 345 public void testUnboundedRangeWhenVersionUnavailable() 346 throws ArtifactResolutionException, InvalidVersionSpecificationException 347 { 348 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 349 ArtifactSpec b = a.addDependency( "b", "1.0" ); 350 a.addDependency( "c", "[2.0,]" ); 351 b.addDependency( "c", "[1.0,]" ); 352 353 ArtifactResolutionResult res = collect( a ); 354 355 assertTrue( res.hasVersionRangeViolations() ); 356 } 357 358 public void testUnboundedRangeBelowLastRelease() 359 throws ArtifactResolutionException, InvalidVersionSpecificationException 360 { 361 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 362 createArtifactSpec( "c", "1.5" ); 363 ArtifactSpec c = createArtifactSpec( "c", "2.0" ); 364 createArtifactSpec( "c", "1.1" ); 365 a.addDependency( "c", "[1.0,)" ); 366 367 ArtifactResolutionResult res = collect( a ); 368 369 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, c.artifact } ), res.getArtifacts() ); 370 assertEquals( "Check version", "2.0", getArtifact( "c", res.getArtifacts() ).getVersion() ); 371 } 372 373 public void testUnboundedRangeAboveLastRelease() 374 throws ArtifactResolutionException, InvalidVersionSpecificationException 375 { 376 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 377 createArtifactSpec( "c", "2.0" ); 378 a.addDependency( "c", "[10.0,)" ); 379 380 ArtifactResolutionResult res = collect( a ); 381 382 assertTrue( res.hasVersionRangeViolations() ); 383 } 384 385 public void testResolveManagedVersion() 386 throws ArtifactResolutionException, InvalidVersionSpecificationException 387 { 388 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 389 a.addDependency( "b", "3.0", Artifact.SCOPE_RUNTIME ); 390 391 Artifact managedVersion = createArtifactSpec( "b", "5.0" ).artifact; 392 Artifact modifiedB = createArtifactSpec( "b", "5.0", Artifact.SCOPE_RUNTIME ).artifact; 393 394 ArtifactResolutionResult res = collect( a, managedVersion ); 395 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, modifiedB } ), res.getArtifacts() ); 396 } 397 398 public void testCollectChangesVersionOfOriginatingArtifactIfInDependencyManagementHasDifferentVersion() 399 throws ArtifactResolutionException, InvalidVersionSpecificationException 400 { 401 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 402 403 Artifact artifact = projectArtifact.artifact; 404 Artifact managedVersion = createArtifactSpec( artifact.getArtifactId(), "2.0" ).artifact; 405 406 ArtifactResolutionResult result = collect( a, managedVersion ); 407 408 assertEquals( "collect has modified version in originating artifact", "1.0", artifact.getVersion() ); 409 410 Artifact resolvedArtifact = result.getArtifacts().iterator().next(); 411 412 assertEquals( "Resolved version don't match original artifact version", "1.0", resolvedArtifact.getVersion() ); 413 } 414 415 public void testResolveCompileScopeOverTestScope() 416 throws ArtifactResolutionException, InvalidVersionSpecificationException 417 { 418 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 419 ArtifactSpec c = createArtifactSpec( "c", "3.0", Artifact.SCOPE_TEST ); 420 421 a.addDependency( "c", "2.0", Artifact.SCOPE_COMPILE ); 422 423 Artifact modifiedC = createArtifactSpec( "c", "3.0", Artifact.SCOPE_COMPILE ).artifact; 424 425 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, c.artifact } ) ); 426 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, modifiedC } ), res.getArtifacts() ); 427 Artifact artifact = getArtifact( "c", res.getArtifacts() ); 428 // local wins now, and irrelevant if not local as test/provided aren't transitive 429 // assertEquals( "Check artifactScope", Artifact.SCOPE_COMPILE, artifact.getArtifactScope() ); 430 assertEquals( "Check artifactScope", Artifact.SCOPE_TEST, artifact.getScope() ); 431 } 432 433 public void testResolveRuntimeScopeOverTestScope() 434 throws ArtifactResolutionException, InvalidVersionSpecificationException 435 { 436 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 437 ArtifactSpec c = createArtifactSpec( "c", "3.0", Artifact.SCOPE_TEST ); 438 439 a.addDependency( "c", "2.0", Artifact.SCOPE_RUNTIME ); 440 441 Artifact modifiedC = createArtifactSpec( "c", "3.0", Artifact.SCOPE_RUNTIME ).artifact; 442 443 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, c.artifact } ) ); 444 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, modifiedC } ), res.getArtifacts() ); 445 Artifact artifact = getArtifact( "c", res.getArtifacts() ); 446 // local wins now, and irrelevant if not local as test/provided aren't transitive 447 // assertEquals( "Check artifactScope", Artifact.SCOPE_RUNTIME, artifact.getArtifactScope() ); 448 assertEquals( "Check artifactScope", Artifact.SCOPE_TEST, artifact.getScope() ); 449 } 450 451 public void testResolveCompileScopeOverRuntimeScope() 452 throws ArtifactResolutionException, InvalidVersionSpecificationException 453 { 454 ArtifactSpec root = createArtifactSpec( "root", "1.0" ); 455 ArtifactSpec a = root.addDependency( "a", "1.0" ); 456 root.addDependency( "c", "3.0", Artifact.SCOPE_RUNTIME ); 457 458 a.addDependency( "c", "2.0", Artifact.SCOPE_COMPILE ); 459 460 Artifact modifiedC = createArtifactSpec( "c", "3.0", Artifact.SCOPE_COMPILE ).artifact; 461 462 ArtifactResolutionResult res = collect( createSet( new Object[] { root.artifact } ) ); 463 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, root.artifact, modifiedC } ), 464 res.getArtifacts() ); 465 Artifact artifact = getArtifact( "c", res.getArtifacts() ); 466 assertEquals( "Check artifactScope", Artifact.SCOPE_COMPILE, artifact.getScope() ); 467 } 468 469 public void testResolveCompileScopeOverProvidedScope() 470 throws ArtifactResolutionException, InvalidVersionSpecificationException 471 { 472 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 473 ArtifactSpec c = createArtifactSpec( "c", "3.0", Artifact.SCOPE_PROVIDED ); 474 475 a.addDependency( "c", "2.0", Artifact.SCOPE_COMPILE ); 476 477 Artifact modifiedC = createArtifactSpec( "c", "3.0", Artifact.SCOPE_COMPILE ).artifact; 478 479 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, c.artifact } ) ); 480 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, modifiedC } ), res.getArtifacts() ); 481 Artifact artifact = getArtifact( "c", res.getArtifacts() ); 482 // local wins now, and irrelevant if not local as test/provided aren't transitive 483 // assertEquals( "Check artifactScope", Artifact.SCOPE_COMPILE, artifact.getArtifactScope() ); 484 assertEquals( "Check artifactScope", Artifact.SCOPE_PROVIDED, artifact.getScope() ); 485 } 486 487 public void testResolveRuntimeScopeOverProvidedScope() 488 throws ArtifactResolutionException, InvalidVersionSpecificationException 489 { 490 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 491 ArtifactSpec c = createArtifactSpec( "c", "3.0", Artifact.SCOPE_PROVIDED ); 492 493 a.addDependency( "c", "2.0", Artifact.SCOPE_RUNTIME ); 494 495 Artifact modifiedC = createArtifactSpec( "c", "3.0", Artifact.SCOPE_RUNTIME ).artifact; 496 497 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, c.artifact } ) ); 498 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, modifiedC } ), res.getArtifacts() ); 499 Artifact artifact = getArtifact( "c", res.getArtifacts() ); 500 // local wins now, and irrelevant if not local as test/provided aren't transitive 501 // assertEquals( "Check artifactScope", Artifact.SCOPE_RUNTIME, artifact.getArtifactScope() ); 502 assertEquals( "Check artifactScope", Artifact.SCOPE_PROVIDED, artifact.getScope() ); 503 } 504 505 public void testProvidedScopeNotTransitive() 506 throws ArtifactResolutionException, InvalidVersionSpecificationException 507 { 508 ArtifactSpec a = createArtifactSpec( "a", "1.0", Artifact.SCOPE_PROVIDED ); 509 ArtifactSpec b = createArtifactSpec( "b", "1.0" ); 510 b.addDependency( "c", "3.0", Artifact.SCOPE_PROVIDED ); 511 512 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) ); 513 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() ); 514 } 515 516 public void testOptionalNotTransitive() 517 throws ArtifactResolutionException, InvalidVersionSpecificationException 518 { 519 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 520 ArtifactSpec b = createArtifactSpec( "b", "1.0" ); 521 b.addDependency( "c", "3.0", true ); 522 523 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) ); 524 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() ); 525 } 526 527 public void testOptionalIncludedAtRoot() 528 throws ArtifactResolutionException, InvalidVersionSpecificationException 529 { 530 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 531 532 ArtifactSpec b = createArtifactSpec( "b", "1.0", true ); 533 534 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) ); 535 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() ); 536 } 537 538 public void testScopeUpdate() 539 throws InvalidVersionSpecificationException, ArtifactResolutionException 540 { 541 /* farthest = compile */ 542 checkScopeUpdate( Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE ); 543 checkScopeUpdate( Artifact.SCOPE_COMPILE, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_COMPILE ); 544 checkScopeUpdate( Artifact.SCOPE_COMPILE, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_COMPILE ); 545 checkScopeUpdate( Artifact.SCOPE_COMPILE, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_COMPILE ); 546 checkScopeUpdate( Artifact.SCOPE_COMPILE, Artifact.SCOPE_TEST, Artifact.SCOPE_COMPILE ); 547 548 /* farthest = provided */ 549 checkScopeUpdate( Artifact.SCOPE_PROVIDED, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE ); 550 checkScopeUpdate( Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED ); 551 checkScopeUpdate( Artifact.SCOPE_PROVIDED, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME ); 552 checkScopeUpdate( Artifact.SCOPE_PROVIDED, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM ); 553 checkScopeUpdate( Artifact.SCOPE_PROVIDED, Artifact.SCOPE_TEST, Artifact.SCOPE_TEST ); 554 555 /* farthest = runtime */ 556 checkScopeUpdate( Artifact.SCOPE_RUNTIME, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE ); 557 checkScopeUpdate( Artifact.SCOPE_RUNTIME, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_RUNTIME ); 558 checkScopeUpdate( Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME ); 559 checkScopeUpdate( Artifact.SCOPE_RUNTIME, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM ); 560 checkScopeUpdate( Artifact.SCOPE_RUNTIME, Artifact.SCOPE_TEST, Artifact.SCOPE_RUNTIME ); 561 562 /* farthest = system */ 563 checkScopeUpdate( Artifact.SCOPE_SYSTEM, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE ); 564 checkScopeUpdate( Artifact.SCOPE_SYSTEM, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED ); 565 checkScopeUpdate( Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME ); 566 checkScopeUpdate( Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM ); 567 checkScopeUpdate( Artifact.SCOPE_SYSTEM, Artifact.SCOPE_TEST, Artifact.SCOPE_TEST ); 568 569 /* farthest = test */ 570 checkScopeUpdate( Artifact.SCOPE_TEST, Artifact.SCOPE_COMPILE, Artifact.SCOPE_COMPILE ); 571 checkScopeUpdate( Artifact.SCOPE_TEST, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_PROVIDED ); 572 checkScopeUpdate( Artifact.SCOPE_TEST, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_RUNTIME ); 573 checkScopeUpdate( Artifact.SCOPE_TEST, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_SYSTEM ); 574 checkScopeUpdate( Artifact.SCOPE_TEST, Artifact.SCOPE_TEST, Artifact.SCOPE_TEST ); 575 } 576 577 private void checkScopeUpdate( String farthestScope, String nearestScope, String expectedScope ) 578 throws ArtifactResolutionException, InvalidVersionSpecificationException 579 { 580 checkScopeUpdateDirect( farthestScope, nearestScope, expectedScope ); 581 checkScopeUpdateTransitively( farthestScope, nearestScope, expectedScope ); 582 } 583 584 private void checkScopeUpdateTransitively( String farthestScope, String nearestScope, String expectedScope ) 585 throws ArtifactResolutionException, InvalidVersionSpecificationException 586 { 587 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 588 ArtifactSpec b = createArtifactSpec( "b", "1.0", nearestScope ); 589 ArtifactSpec c = createArtifactSpec( "c", "1.0" ); 590 a.addDependency( c ); 591 ArtifactSpec dNearest = createArtifactSpec( "d", "2.0" ); 592 b.addDependency( dNearest ); 593 ArtifactSpec dFarthest = createArtifactSpec( "d", "3.0", farthestScope ); 594 c.addDependency( dFarthest ); 595 596 /* system and provided dependencies are not transitive */ 597 if ( !Artifact.SCOPE_SYSTEM.equals( nearestScope ) && !Artifact.SCOPE_PROVIDED.equals( nearestScope ) ) 598 { 599 checkScopeUpdate( a, b, expectedScope, "2.0" ); 600 } 601 } 602 603 private void checkScopeUpdateDirect( String farthestScope, String nearestScope, String expectedScope ) 604 throws ArtifactResolutionException, InvalidVersionSpecificationException 605 { 606 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 607 ArtifactSpec b = createArtifactSpec( "b", "1.0" ); 608 ArtifactSpec c = createArtifactSpec( "c", "1.0" ); 609 a.addDependency( c ); 610 ArtifactSpec dNearest = createArtifactSpec( "d", "2.0", nearestScope ); 611 b.addDependency( dNearest ); 612 ArtifactSpec dFarthest = createArtifactSpec( "d", "3.0", farthestScope ); 613 c.addDependency( dFarthest ); 614 615 checkScopeUpdate( a, b, expectedScope, "2.0" ); 616 } 617 618 private void checkScopeUpdate( ArtifactSpec a, ArtifactSpec b, String expectedScope, String expectedVersion ) 619 throws ArtifactResolutionException, InvalidVersionSpecificationException 620 { 621 ScopeArtifactFilter filter; 622 if ( Artifact.SCOPE_PROVIDED.equals( expectedScope ) ) 623 { 624 filter = new ScopeArtifactFilter( Artifact.SCOPE_COMPILE ); 625 } 626 else if ( Artifact.SCOPE_SYSTEM.equals( expectedScope ) ) 627 { 628 filter = new ScopeArtifactFilter( Artifact.SCOPE_COMPILE ); 629 } 630 else 631 { 632 filter = new ScopeArtifactFilter( expectedScope ); 633 } 634 635 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ), filter ); 636 Artifact artifact = getArtifact( "d", res.getArtifacts() ); 637 assertNotNull( "MNG-1895 Dependency was not added to resolution", artifact ); 638 assertEquals( "Check artifactScope", expectedScope, artifact.getScope() ); 639 assertEquals( "Check version", expectedVersion, artifact.getVersion() ); 640 641 ArtifactSpec d = createArtifactSpec( "d", "1.0" ); 642 res = collect( createSet( new Object[] { a.artifact, b.artifact, d.artifact } ), filter ); 643 artifact = getArtifact( "d", res.getArtifacts() ); 644 assertNotNull( "MNG-1895 Dependency was not added to resolution", artifact ); 645 assertEquals( "Check artifactScope", d.artifact.getScope(), artifact.getScope() ); 646 assertEquals( "Check version", "1.0", artifact.getVersion() ); 647 } 648 649 public void disabledtestOptionalNotTransitiveButVersionIsInfluential() 650 throws ArtifactResolutionException, InvalidVersionSpecificationException 651 { 652 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 653 ArtifactSpec b = createArtifactSpec( "b", "1.0" ); 654 b.addDependency( "c", "3.0", true ); 655 ArtifactSpec d = a.addDependency( "d", "1.0" ); 656 ArtifactSpec e = d.addDependency( "e", "1.0" ); 657 e.addDependency( "c", "2.0" ); 658 659 ArtifactSpec c = createArtifactSpec( "c", "3.0" ); 660 661 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) ); 662 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact, c.artifact, d.artifact, 663 e.artifact } ), res.getArtifacts() ); 664 Artifact artifact = getArtifact( "c", res.getArtifacts() ); 665 assertEquals( "Check version", "3.0", artifact.getVersion() ); 666 } 667 668 public void testTestScopeNotTransitive() 669 throws ArtifactResolutionException, InvalidVersionSpecificationException 670 { 671 ArtifactSpec a = createArtifactSpec( "a", "1.0", Artifact.SCOPE_TEST ); 672 ArtifactSpec b = createArtifactSpec( "b", "1.0" ); 673 b.addDependency( "c", "3.0", Artifact.SCOPE_TEST ); 674 675 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact, b.artifact } ) ); 676 assertEquals( "Check artifact list", createSet( new Object[] { a.artifact, b.artifact } ), res.getArtifacts() ); 677 } 678 679 public void testSnapshotNotIncluded() 680 throws ArtifactResolutionException, InvalidVersionSpecificationException 681 { 682 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 683 a.addDependency( "b", "[1.0,)" ); 684 createArtifactSpec( "b", "1.0-SNAPSHOT" ); 685 686 ArtifactResolutionResult res = collect( a ); 687 688 assertTrue( res.hasVersionRangeViolations() ); 689 690 /* 691 * try { ArtifactResolutionResult res = collect( a ); fail( "Expected b not to resolve: " + res ); } catch ( 692 * OverConstrainedVersionException e ) { assertTrue( e.getMessage().indexOf( "[1.0-SNAPSHOT]" ) < 693 * e.getMessage().indexOf( "[1.0,)" ) ); } 694 */ 695 } 696 697 public void testOverConstrainedVersionException() 698 throws ArtifactResolutionException, InvalidVersionSpecificationException 699 { 700 ArtifactSpec a = createArtifactSpec( "a", "1.0" ); 701 a.addDependency( "b", "[1.0, 2.0)" ); 702 a.addDependency( "c", "[3.3.0,4.0.0)" ); 703 704 ArtifactSpec b = createArtifactSpec( "b", "1.0.0" ); 705 b.addDependency( "c", "3.3.0-v3346" ); 706 707 ArtifactSpec c = createArtifactSpec( "c", "3.2.1-v3235e" ); 708 709 try 710 { 711 ArtifactResolutionResult res = collect( createSet( new Object[] { a.artifact } ) ); 712 } 713 catch ( OverConstrainedVersionException e ) 714 { 715 assertTrue( "Versions unordered", e.getMessage().contains( "[3.2.1-v3235e, 3.3.0-v3346]" ) ); 716 assertTrue( "DependencyTrail unresolved", e.getMessage().contains( "Path to dependency:" ) ); 717 } 718 } 719 720 private Artifact getArtifact( String id, Set artifacts ) 721 { 722 for ( Object artifact : artifacts ) 723 { 724 Artifact a = (Artifact) artifact; 725 if ( a.getArtifactId().equals( id ) && a.getGroupId().equals( GROUP_ID ) ) 726 { 727 return a; 728 } 729 } 730 return null; 731 } 732 733 private ArtifactResolutionResult collect( Set<Artifact> artifacts ) 734 throws ArtifactResolutionException 735 { 736 return collect( artifacts, null ); 737 } 738 739 private ArtifactResolutionResult collect( Set<Artifact> artifacts, ArtifactFilter filter ) 740 throws ArtifactResolutionException 741 { 742 return artifactCollector.collect( artifacts, projectArtifact.artifact, null, null, null, source, filter, 743 Collections.<ResolutionListener>emptyList(), null ); 744 } 745 746 private ArtifactResolutionResult collect( ArtifactSpec a ) 747 throws ArtifactResolutionException 748 { 749 return artifactCollector.collect( Collections.singleton( a.artifact ), projectArtifact.artifact, null, null, 750 null, source, null, Collections.<ResolutionListener>emptyList(), null ); 751 } 752 753 private ArtifactResolutionResult collect( ArtifactSpec a, ArtifactFilter filter ) 754 throws ArtifactResolutionException 755 { 756 return artifactCollector.collect( Collections.singleton( a.artifact ), projectArtifact.artifact, null, null, 757 null, source, filter, Collections.<ResolutionListener>emptyList(), null ); 758 } 759 760 private ArtifactResolutionResult collect( ArtifactSpec a, Artifact managedVersion ) 761 throws ArtifactResolutionException 762 { 763 Map managedVersions = Collections.singletonMap( managedVersion.getDependencyConflictId(), managedVersion ); 764 return artifactCollector.collect( Collections.singleton( a.artifact ), projectArtifact.artifact, 765 managedVersions, null, null, source, null, Collections.<ResolutionListener>emptyList(), null ); 766 } 767 768 private ArtifactSpec createArtifactSpec( String id, String version ) 769 throws InvalidVersionSpecificationException 770 { 771 return createArtifactSpec( id, version, Artifact.SCOPE_COMPILE ); 772 } 773 774 private ArtifactSpec createArtifactSpec( String id, String version, boolean optional ) 775 throws InvalidVersionSpecificationException 776 { 777 return createArtifactSpec( id, version, Artifact.SCOPE_COMPILE, null, optional ); 778 } 779 780 private ArtifactSpec createArtifactSpec( String id, String version, String scope ) 781 throws InvalidVersionSpecificationException 782 { 783 return createArtifactSpec( id, version, scope, null, false ); 784 } 785 786 private ArtifactSpec createArtifactSpec( String id, String version, String scope, String inheritedScope, 787 boolean optional ) 788 throws InvalidVersionSpecificationException 789 { 790 VersionRange versionRange = VersionRange.createFromVersionSpec( version ); 791 Artifact artifact = 792 artifactFactory.createDependencyArtifact( GROUP_ID, id, versionRange, "jar", null, scope, inheritedScope, 793 optional ); 794 ArtifactSpec spec = null; 795 if ( artifact != null ) 796 { 797 spec = new ArtifactSpec(); 798 spec.artifact = artifact; 799 source.addArtifact( spec ); 800 } 801 return spec; 802 } 803 804 @SuppressWarnings( "unchecked" ) 805 private static Set<Artifact> createSet( Object[] x ) 806 { 807 return new LinkedHashSet( Arrays.asList( x ) ); 808 } 809 810 private class ArtifactSpec 811 { 812 private Artifact artifact; 813 814 private Set<Artifact> dependencies = new HashSet<>(); 815 816 public ArtifactSpec addDependency( String id, String version ) 817 throws InvalidVersionSpecificationException 818 { 819 return addDependency( id, version, Artifact.SCOPE_COMPILE ); 820 } 821 822 public ArtifactSpec addDependency( String id, String version, String scope ) 823 throws InvalidVersionSpecificationException 824 { 825 return addDependency( id, version, scope, false ); 826 } 827 828 private ArtifactSpec addDependency( ArtifactSpec dep ) 829 throws InvalidVersionSpecificationException 830 { 831 if ( dep != null ) 832 { 833 dependencies.add( dep.artifact ); 834 } 835 return dep; 836 } 837 838 private ArtifactSpec addDependency( String id, String version, String scope, boolean optional ) 839 throws InvalidVersionSpecificationException 840 { 841 ArtifactSpec dep = createArtifactSpec( id, version, scope, artifact.getScope(), optional ); 842 return addDependency( dep ); 843 } 844 845 public ArtifactSpec addDependency( String id, String version, boolean optional ) 846 throws InvalidVersionSpecificationException 847 { 848 return addDependency( id, version, Artifact.SCOPE_COMPILE, optional ); 849 } 850 } 851 852 private class Source 853 implements ArtifactMetadataSource 854 { 855 private Map<String, ArtifactSpec> artifacts = new HashMap<>(); 856 857 private Map<String, List<ArtifactVersion>> versions = new HashMap<>(); 858 859 public ResolutionGroup retrieve( Artifact artifact, ArtifactRepository localRepository, 860 List<ArtifactRepository> remoteRepositories ) 861 throws ArtifactMetadataRetrievalException 862 { 863 String key = getKey( artifact ); 864 865 ArtifactSpec a = (ArtifactSpec) artifacts.get( key ); 866 try 867 { 868 return new ResolutionGroup( artifact, createArtifacts( artifactFactory, a.dependencies, 869 artifact.getScope(), 870 artifact.getDependencyFilter() ), 871 Collections.EMPTY_LIST ); 872 } 873 catch ( InvalidVersionSpecificationException e ) 874 { 875 throw new ArtifactMetadataRetrievalException( "Invalid version creating artifacts", e, artifact ); 876 } 877 } 878 879 private String getKey( Artifact artifact ) 880 { 881 return artifact.getDependencyConflictId(); 882 } 883 884 private Set<Artifact> createArtifacts( ArtifactFactory artifactFactory, Set<Artifact> dependencies, String inheritedScope, 885 ArtifactFilter dependencyFilter ) 886 throws InvalidVersionSpecificationException 887 { 888 Set<Artifact> projectArtifacts = new HashSet<>(); 889 890 for ( Artifact d : dependencies ) 891 { 892 VersionRange versionRange; 893 if ( d.getVersionRange() != null ) 894 { 895 versionRange = d.getVersionRange(); 896 } 897 else 898 { 899 versionRange = VersionRange.createFromVersionSpec( d.getVersion() ); 900 } 901 Artifact artifact; 902 if ( d.getScope().equals( Artifact.SCOPE_TEST ) || d.getScope().equals( Artifact.SCOPE_PROVIDED ) ) 903 { 904 /* don't call createDependencyArtifact as it'll ignore test and provided scopes */ 905 artifact = 906 artifactFactory.createArtifact( d.getGroupId(), d.getArtifactId(), d.getVersion(), d.getScope(), 907 d.getType() ); 908 } 909 else 910 { 911 artifact = 912 artifactFactory.createDependencyArtifact( d.getGroupId(), d.getArtifactId(), versionRange, 913 d.getType(), d.getClassifier(), d.getScope(), 914 inheritedScope, d.isOptional() ); 915 } 916 917 if ( artifact != null && ( dependencyFilter == null || dependencyFilter.include( artifact ) ) ) 918 { 919 artifact.setDependencyFilter( dependencyFilter ); 920 921 projectArtifacts.add( artifact ); 922 } 923 } 924 925 return projectArtifacts; 926 } 927 928 public void addArtifact( ArtifactSpec spec ) 929 { 930 artifacts.put( getKey( spec.artifact ), spec ); 931 932 String key = spec.artifact.getDependencyConflictId(); 933 List<ArtifactVersion> artifactVersions = versions.get( key ); 934 if ( artifactVersions == null ) 935 { 936 artifactVersions = new ArrayList<>(); 937 versions.put( key, artifactVersions ); 938 } 939 if ( spec.artifact.getVersion() != null ) 940 { 941 artifactVersions.add( new DefaultArtifactVersion( spec.artifact.getVersion() ) ); 942 } 943 } 944 945 public List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact, ArtifactRepository localRepository, 946 List<ArtifactRepository> remoteRepositories ) 947 throws ArtifactMetadataRetrievalException 948 { 949 return retrieveAvailableVersions( artifact ); 950 } 951 952 public List<ArtifactVersion> retrieveAvailableVersionsFromDeploymentRepository( 953 Artifact artifact, 954 ArtifactRepository localRepository, 955 ArtifactRepository remoteRepository ) 956 throws ArtifactMetadataRetrievalException 957 { 958 return retrieveAvailableVersions( artifact ); 959 } 960 961 private List<ArtifactVersion> retrieveAvailableVersions( Artifact artifact ) 962 { 963 List<ArtifactVersion> artifactVersions = versions.get( artifact.getDependencyConflictId() ); 964 if ( artifactVersions == null ) 965 { 966 artifactVersions = Collections.emptyList(); 967 } 968 return artifactVersions; 969 } 970 971 public ResolutionGroup retrieve( MetadataResolutionRequest request ) 972 throws ArtifactMetadataRetrievalException 973 { 974 return retrieve( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() ); 975 } 976 977 public List<ArtifactVersion> retrieveAvailableVersions( MetadataResolutionRequest request ) 978 throws ArtifactMetadataRetrievalException 979 { 980 return retrieveAvailableVersions( request.getArtifact(), request.getLocalRepository(), request.getRemoteRepositories() ); 981 } 982 } 983}