/*
* Copyright 2017 Red Hat, Inc. and/or its affiliates.
*
* Licensed 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.
*/
package org.kie.workbench.common.services.backend.builder.core;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import javax.enterprise.inject.Instance;
import com.google.common.base.Charsets;
import org.guvnor.common.services.project.builder.service.PostBuildHandler;
import org.guvnor.common.services.project.model.GAV;
import org.guvnor.common.services.project.model.MavenRepositoryMetadata;
import org.guvnor.common.services.project.model.POM;
import org.guvnor.common.services.project.model.ProjectRepositories;
import org.guvnor.common.services.project.service.DeploymentMode;
import org.guvnor.common.services.project.service.GAVAlreadyExistsException;
import org.guvnor.common.services.project.service.POMService;
import org.guvnor.common.services.project.service.ProjectRepositoriesService;
import org.guvnor.common.services.project.service.ProjectRepositoryResolver;
import org.guvnor.m2repo.backend.server.ExtendedM2RepoService;
import org.guvnor.test.TestFileSystem;
import org.jboss.errai.security.shared.api.identity.User;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.kie.api.builder.KieFileSystem;
import org.kie.workbench.common.services.shared.project.KieProject;
import org.kie.workbench.common.services.shared.project.KieProjectService;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.uberfire.backend.server.util.Paths;
import org.uberfire.backend.vfs.Path;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
@RunWith( MockitoJUnitRunner.class )
public class BuildHelperTest {
private static final String GROUP_ID = "org.kie.workbench.common.services.builder.tests";
private static final String ARTIFACT_ID = "build-helper-test";
private static final String VERSION = "1.0.0";
private static final String SNAPSHOT_VERSION = "1.0.0-SNAPSHOT";
private POMService pomService;
@Mock
private ExtendedM2RepoService m2RepoService;
@Mock
private ProjectRepositoryResolver repositoryResolver;
@Mock
private ProjectRepositoriesService projectRepositoriesService;
@Mock
private Instance< PostBuildHandler > handlers;
@Mock
protected Instance< User > identity;
@Mock
protected User user;
private LRUBuilderCache cache;
private TestFileSystem testFileSystem;
private KieProjectService projectService;
private BuildHelper buildHelper;
private DeploymentVerifier deploymentVerifier;
private Path rootPath;
private Path snapshotRootPath;
private KieProject project;
@Mock
private POM pom;
@Mock
private GAV gav;
@Mock
private Path repositoriesPath;
@Mock
private ProjectRepositories projectRepositories;
private Set< MavenRepositoryMetadata > repositories;
@Mock
private MavenRepositoryMetadata repositoryMetadata1;
@Mock
private MavenRepositoryMetadata repositoryMetadata2;
@BeforeClass
public static void setupSystemProperties( ) {
//These are not needed for the tests
System.setProperty( "org.uberfire.nio.git.daemon.enabled",
"false" );
System.setProperty( "org.uberfire.nio.git.ssh.enabled",
"false" );
System.setProperty( "org.uberfire.sys.repo.monitor.disabled",
"true" );
}
@Before
public void setUp( ) throws Exception {
testFileSystem = new TestFileSystem( );
projectService = testFileSystem.getReference( KieProjectService.class );
pomService = testFileSystem.getReference( POMService.class );
cache = testFileSystem.getReference( LRUBuilderCache.class );
deploymentVerifier = new DeploymentVerifier( repositoryResolver, projectRepositoriesService );
buildHelper = spy( new BuildHelper( pomService,
m2RepoService,
projectService,
deploymentVerifier,
cache,
handlers,
identity ) );
when( identity.get() ).thenReturn( user );
when( user.getIdentifier() ).thenReturn( "test-user" );
URL rootUrl = this.getClass( ).getResource( "/BuildHelperTest" );
rootPath = Paths.convert( testFileSystem.fileSystemProvider.getPath( rootUrl.toURI() ) );
rootUrl = this.getClass( ).getResource( "/BuildHelperTestSnapshot" );
snapshotRootPath = Paths.convert( testFileSystem.fileSystemProvider.getPath( rootUrl.toURI() ) );
Iterator<PostBuildHandler> mockIterator = mock( Iterator.class );
when( handlers.iterator() ).thenReturn( mockIterator );
when ( mockIterator.hasNext() ).thenReturn( false );
}
@After
public void tearDown( ) throws Exception {
testFileSystem.tearDown( );
}
@Test
public void testBuildAndDeployNonSnapshotNotDeployed( ) {
final GAV gav = new GAV( GROUP_ID, ARTIFACT_ID, VERSION );
prepareBuildAndDeploy( rootPath, gav, false );
buildHelper.buildAndDeploy( project );
verify( buildHelper,
times( 1 ) ).buildAndDeploy( eq( project ),
eq( DeploymentMode.VALIDATED ) );
verifyBuildAndDeploy( project, gav );
}
@Test
public void testBuildAndDeployNonSnapshotAlreadyDeployed( ) {
final GAV gav = new GAV( GROUP_ID, ARTIFACT_ID, VERSION );
prepareBuildAndDeploy( rootPath, gav, true );
Exception exception = null;
try {
buildHelper.buildAndDeploy( project );
} catch ( Exception e ) {
exception = e;
}
verify( buildHelper,
times( 1 ) ).buildAndDeploy( eq( project ),
eq( DeploymentMode.VALIDATED ) );
assertNotNull( exception );
assertTrue( exception instanceof GAVAlreadyExistsException );
assertEquals( gav, ( ( GAVAlreadyExistsException ) exception ).getGAV() );
}
@Test
public void testBuildAndDeploySnapshot( ) {
final GAV gav = new GAV( GROUP_ID, ARTIFACT_ID, SNAPSHOT_VERSION );
prepareBuildAndDeploy( snapshotRootPath, gav );
buildHelper.buildAndDeploy( project );
verify( buildHelper,
times( 1 ) ).buildAndDeploy( eq( project ),
eq( DeploymentMode.VALIDATED ) );
verifyBuildAndDeploySnapshot( project, gav );
}
@Test
public void testBuildAndDeploySuppressHandlersNonSnapshot( ) {
final GAV gav = new GAV( GROUP_ID, ARTIFACT_ID, VERSION );
prepareBuildAndDeploy( rootPath, gav );
buildHelper.buildAndDeploy( project, true );
verify( buildHelper,
times( 1 ) ).buildAndDeploy( eq( project ),
eq( true ),
eq( DeploymentMode.VALIDATED ) );
verifyBuildAndDeploy( project, gav );
}
@Test
public void testBuildAndDeploySuppressHandlersSnapshot( ) {
final GAV gav = new GAV( GROUP_ID, ARTIFACT_ID, SNAPSHOT_VERSION );
prepareBuildAndDeploy( snapshotRootPath, gav );
buildHelper.buildAndDeploy( project, true );
verify( buildHelper,
times( 1 ) ).buildAndDeploy( eq( project ),
eq( true ),
eq( DeploymentMode.VALIDATED ) );
verifyBuildAndDeploySnapshot( project, gav );
}
private void prepareBuildAndDeploy( Path rootPath, GAV gav ) {
prepareBuildAndDeploy( rootPath, gav, false );
}
private void prepareBuildAndDeploy( Path rootPath, GAV gav, boolean isDeployed ) {
project = projectService.resolveProject( rootPath );
repositories = new HashSet<>( );
if ( isDeployed ) {
repositories.add( repositoryMetadata1 );
repositories.add( repositoryMetadata2 );
}
when( projectRepositoriesService.load( project.getRepositoriesPath() ) ).thenReturn( projectRepositories );
when( repositoryResolver.getRepositoriesResolvingArtifact( eq( gav ), any( MavenRepositoryMetadata[].class ) ) ).thenReturn( repositories );
}
private void verifyBuildAndDeploy( KieProject project, GAV gav ) {
verify( projectRepositoriesService,
times( 1 ) ).load( any( Path.class ) );
verify( repositoryResolver, times( 1 ) ).getRepositoriesResolvingArtifact( eq( gav ), any( MavenRepositoryMetadata[].class ) );
verifyBuilder( project, gav );
}
private void verifyBuildAndDeploySnapshot( KieProject project, GAV gav ) {
verify( projectRepositoriesService,
never( ) ).load( any( Path.class ) );
verify( repositoryResolver,
never( ) ).getRepositoriesResolvingArtifact( eq( gav ) );
verifyBuilder( project, gav );
}
private void verifyBuilder( KieProject project, GAV gav ) {
Builder builder = cache.getBuilder( project );
assertNotNull( builder );
assertTrue( builder.isBuilt() );
verify( m2RepoService, times( 1 ) ).deployJar( any( InputStream.class ), eq( gav ) );
}
@Test
public void testBuildThatDoesNotUpdateTheCache( ) throws Exception {
final Path path = path( );
buildHelper.build( projectService.resolveProject( path ) );
assertTrue( cachedFileSystemDoesNotChange( ) );
}
@Test
public void testUpdatePackageResourceThatDoesNotUpdateTheCache( ) throws Exception {
final Path path = path( );
buildHelper.build( projectService.resolveProject( path ) );
buildHelper.updatePackageResource( path );
assertTrue( cachedFileSystemDoesNotChange( ) );
}
private Path path( ) throws URISyntaxException {
final URL urlToValidate = this.getClass( ).getResource( "/GuvnorM2RepoDependencyExample1/src/main/resources/rule2.drl" );
return Paths.convert( testFileSystem.fileSystemProvider.getPath( urlToValidate.toURI( ) ) );
}
private String content( ) {
return "package org.kie.workbench.common.services.builder.tests.test1\n" +
"\n" +
"rule R2\n" +
"when\n" +
"Ban()\n" +
"then\n" +
"end";
}
private boolean cachedFileSystemDoesNotChange( ) throws URISyntaxException {
final Builder builder = cache.assertBuilder( projectService.resolveProject( path( ) ) );
final KieFileSystem fileSystem = builder.getKieFileSystem( );
final String fileContent = new String( fileSystem.read( "src/main/resources/rule2.drl" ), Charsets.UTF_8 );
return fileContent.contains( "Bean" );
}
}