From faa9ef0cd3de27d31064f88cd74140516b3569a3 Mon Sep 17 00:00:00 2001 From: Sylwester Lachiewicz Date: Wed, 7 Mar 2018 23:39:56 +0100 Subject: [PATCH] [MNG-6370] ConcurrencyDependencyGraph#getNumberOfBuilds() does not remove finished projects from unfinished ones This closes #161 --- .../ConcurrencyDependencyGraph.java | 6 +- .../ConcurrencyDependencyGraphTest.java | 83 +++++++++++++++++++ 2 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 maven-core/src/test/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ConcurrencyDependencyGraphTest.java diff --git a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ConcurrencyDependencyGraph.java b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ConcurrencyDependencyGraph.java index d7d764e4bc..190e0f7345 100644 --- a/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ConcurrencyDependencyGraph.java +++ b/maven-core/src/main/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ConcurrencyDependencyGraph.java @@ -45,7 +45,7 @@ public class ConcurrencyDependencyGraph private final ProjectDependencyGraph projectDependencyGraph; - private final HashSet finishedProjects = new HashSet<>(); + private final Set finishedProjects = new HashSet<>(); public ConcurrencyDependencyGraph( ProjectBuildList projectBuilds, ProjectDependencyGraph projectDependencyGraph ) { @@ -69,7 +69,7 @@ public class ConcurrencyDependencyGraph List result = new ArrayList<>(); for ( ProjectSegment projectBuild : projectBuilds ) { - if ( projectDependencyGraph.getUpstreamProjects( projectBuild.getProject(), false ).size() == 0 ) + if ( projectDependencyGraph.getUpstreamProjects( projectBuild.getProject(), false ).isEmpty() ) { result.add( projectBuild.getProject() ); } @@ -111,7 +111,7 @@ public class ConcurrencyDependencyGraph public Set getUnfinishedProjects() { Set unfinished = new HashSet<>( projectBuilds.getProjects() ); - unfinished.remove( finishedProjects ); + unfinished.removeAll( finishedProjects ); return unfinished; } diff --git a/maven-core/src/test/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ConcurrencyDependencyGraphTest.java b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ConcurrencyDependencyGraphTest.java new file mode 100644 index 0000000000..b909fb066b --- /dev/null +++ b/maven-core/src/test/java/org/apache/maven/lifecycle/internal/builder/multithreaded/ConcurrencyDependencyGraphTest.java @@ -0,0 +1,83 @@ +package org.apache.maven.lifecycle.internal.builder.multithreaded; +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +import junit.framework.TestCase; +import org.apache.maven.execution.ProjectDependencyGraph; +import org.apache.maven.lifecycle.internal.ProjectBuildList; +import org.apache.maven.lifecycle.internal.stub.ProjectDependencyGraphStub; +import org.apache.maven.project.MavenProject; + +import java.util.List; +import java.util.Set; + +public class ConcurrencyDependencyGraphTest extends TestCase { + + public void testGraph() throws Exception { + + ProjectBuildList projectBuildList = ProjectDependencyGraphStub.getProjectBuildList( + ProjectDependencyGraphStub.getMavenSession() ); + + ProjectDependencyGraph projectDependencyGraph = new ProjectDependencyGraphStub(); + + ConcurrencyDependencyGraph graph = new ConcurrencyDependencyGraph( projectBuildList, projectDependencyGraph ); + + // start + assertEquals( 0, graph.getFinishedProjects().size() ); + assertEquals( 6, graph.getNumberOfBuilds() ); + + List rootSchedulableBuilds = graph.getRootSchedulableBuilds(); + // only Project.A has no dependences + assertEquals( 1, rootSchedulableBuilds.size() ); + assertEquals( ProjectDependencyGraphStub.A, rootSchedulableBuilds.iterator().next() ); + // double check A deps + List dependenciesA = graph.getDependencies( ProjectDependencyGraphStub.A ); + assertEquals( 0, dependenciesA.size() ); + + assertEquals( 6, graph.getUnfinishedProjects().size() ); + + List schedulableNewProcesses = graph.markAsFinished( ProjectDependencyGraphStub.A ); + // expect Project B, C + assertEquals( 2, schedulableNewProcesses.size() ); + assertEquals( 1, graph.getFinishedProjects().size() ); + + graph.markAsFinished( ProjectDependencyGraphStub.A ); + // still only A + assertEquals( 1, graph.getFinishedProjects().size() ); + + Set unfinishedProjects = graph.getUnfinishedProjects(); + assertEquals( 5, unfinishedProjects.size() ); + + graph.markAsFinished( schedulableNewProcesses.get( 0 ) ); + assertEquals( 2, graph.getFinishedProjects().size() ); + assertEquals( 4, graph.getUnfinishedProjects().size() ); + + List dependenciesC = graph.getDependencies( ProjectDependencyGraphStub.C ); + // C depends only on A + assertEquals( 1, dependenciesC.size() ); + + List dependenciesX = graph.getDependencies( ProjectDependencyGraphStub.X ); + // X depends only on B and C + assertEquals( 2, dependenciesX.size() ); + + List activeDependenciesC = graph.getActiveDependencies( ProjectDependencyGraphStub.C ); + // A already finished + assertEquals( 0, activeDependenciesC.size() ); + + List activeDependenciesX = graph.getActiveDependencies( ProjectDependencyGraphStub.X ); + // waiting for C + assertEquals( 1, activeDependenciesX.size() ); + } +}