001/*
002 * Copyright 2017-2022 original authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package io.micronaut.maven.testresources;
017
018import io.micronaut.maven.MojoUtils;
019import io.micronaut.maven.services.DependencyResolutionService;
020import org.apache.maven.execution.MavenSession;
021import org.apache.maven.plugin.MojoExecutionException;
022import org.apache.maven.plugin.MojoExecution;
023import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
024import org.apache.maven.plugins.annotations.Mojo;
025import org.apache.maven.plugins.annotations.ResolutionScope;
026import org.apache.maven.project.MavenProject;
027import org.apache.maven.toolchain.ToolchainManager;
028import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
029
030import javax.inject.Inject;
031
032/**
033 * Starts the Micronaut test resources server.
034 */
035@Mojo(name = StartTestResourcesServerMojo.NAME, requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
036public class StartTestResourcesServerMojo extends AbstractTestResourcesMojo {
037    public static final String NAME = "start-testresources-service";
038
039    private final MavenProject mavenProject;
040
041    private final MavenSession mavenSession;
042
043    private final DependencyResolutionService dependencyResolutionService;
044
045    private final ToolchainManager toolchainManager;
046
047    @Inject
048    @SuppressWarnings("CdiInjectionPointsInspection")
049    public StartTestResourcesServerMojo(MavenProject mavenProject,
050                                        MavenSession mavenSession,
051                                        DependencyResolutionService dependencyResolutionService,
052                                        ToolchainManager toolchainManager) {
053        this.mavenProject = mavenProject;
054        this.mavenSession = mavenSession;
055        this.dependencyResolutionService = dependencyResolutionService;
056        this.toolchainManager = toolchainManager;
057    }
058
059    @Override
060    public final void execute() throws MojoExecutionException {
061        // Skip starting test resources if tests are being skipped
062        if (isTestExecutionSkipped()) {
063            getLog().warn("Skipping Test Resources service start because integration test execution is disabled with skipITs");
064            return;
065        }
066        
067        var helper = new TestResourcesHelper(testResourcesEnabled, shared, buildDirectory, explicitPort, clientTimeout,
068                serverIdleTimeoutMinutes, mavenProject, mavenSession, dependencyResolutionService, toolchainManager,
069                testResourcesVersion, classpathInference, testResourcesDependencies, sharedServerNamespace, debugServer,
070                foreground, testResourcesSystemProperties);
071        helper.start();
072
073    }
074
075    /**
076     * Checks whether integration test execution is skipped using skipITs properties.
077     *
078     * @return true if tests are being skipped, false otherwise
079     */
080    boolean isTestExecutionSkipped() {
081        try {
082            var execution = new MojoExecution(mavenProject.getPlugin(MojoUtils.THIS_PLUGIN), null, null);
083            var evaluator = new PluginParameterExpressionEvaluator(mavenSession, execution);
084            
085            // Check skip properties (from maven-surefire-plugin, maven-compiler-plugin, and maven-failsafe-plugin)
086            return isPropertyTrue(evaluator, "skipITs");
087            
088        } catch (ExpressionEvaluationException e) {
089            getLog().debug("Could not evaluate test skip properties: " + e.getMessage());
090        }
091        return false;
092    }
093
094    /**
095     * Checks if a property evaluates to true.
096     *
097     * @param evaluator the expression evaluator
098     * @param propertyName the property name to check
099     * @return true if the property is set to true, false otherwise
100     * @throws ExpressionEvaluationException if the property cannot be evaluated
101     */
102    private boolean isPropertyTrue(PluginParameterExpressionEvaluator evaluator, String propertyName) throws ExpressionEvaluationException {
103        Object propertyValue = evaluator.evaluate("${" + propertyName + "}");
104        if (propertyValue instanceof Boolean) {
105            return (Boolean) propertyValue;
106        }
107        if (propertyValue instanceof String) {
108            return Boolean.parseBoolean((String) propertyValue);
109        }
110        return false;
111    }
112
113}