blob: 6ae5d2cd3a39f434bbf228e3f84f2eaee04fd420 [file] [log] [blame]
/*
* 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.
*/
package org.apache.maven.toolchain.building;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamException;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.maven.api.services.xml.XmlReaderException;
import org.apache.maven.api.services.xml.XmlReaderRequest;
import org.apache.maven.building.Source;
import org.apache.maven.building.StringSource;
import org.apache.maven.internal.impl.DefaultToolchainsXmlFactory;
import org.apache.maven.toolchain.model.PersistedToolchains;
import org.apache.maven.toolchain.model.ToolchainModel;
import org.codehaus.plexus.interpolation.os.OperatingSystemUtils;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.apache.maven.internal.impl.StaxLocation.getLocation;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class DefaultToolchainsBuilderTest {
private static final String LS = System.lineSeparator();
@Spy
private DefaultToolchainsXmlFactory toolchainsXmlFactory;
@InjectMocks
private DefaultToolchainsBuilder toolchainBuilder;
@BeforeEach
void onSetup() {
// MockitoAnnotations.openMocks(this);
Map<String, String> envVarMap = new HashMap<>();
envVarMap.put("testKey", "testValue");
envVarMap.put("testSpecialCharactersKey", "<test&Value>");
OperatingSystemUtils.setEnvVarSource(new TestEnvVarSource(envVarMap));
toolchainBuilder = new DefaultToolchainsBuilder(
new org.apache.maven.internal.impl.DefaultToolchainsBuilder(), toolchainsXmlFactory);
}
@Test
void testBuildEmptyRequest() throws Exception {
ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
ToolchainsBuildingResult result = toolchainBuilder.build(request);
assertNotNull(result.getEffectiveToolchains());
assertNotNull(result.getProblems());
assertEquals(0, result.getProblems().size());
}
@Test
void testBuildRequestWithUserToolchains() throws Exception {
Properties props = new Properties();
props.put("key", "user_value");
ToolchainModel toolchain = new ToolchainModel();
toolchain.setType("TYPE");
toolchain.setProvides(props);
PersistedToolchains persistedToolchains = new PersistedToolchains();
persistedToolchains.setToolchains(Collections.singletonList(toolchain));
String xml = new DefaultToolchainsXmlFactory().toXmlString(persistedToolchains.getDelegate());
ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
request.setUserToolchainsSource(new StringSource(xml));
ToolchainsBuildingResult result = toolchainBuilder.build(request);
assertNotNull(result.getEffectiveToolchains());
assertEquals(1, result.getEffectiveToolchains().getToolchains().size());
assertEquals(
"TYPE", result.getEffectiveToolchains().getToolchains().get(0).getType());
assertEquals(
"user_value",
result.getEffectiveToolchains()
.getToolchains()
.get(0)
.getProvides()
.get("key"));
assertNotNull(result.getProblems());
assertEquals(0, result.getProblems().size());
}
@Test
void testBuildRequestWithGlobalToolchains() throws Exception {
Properties props = new Properties();
props.put("key", "global_value");
ToolchainModel toolchain = new ToolchainModel();
toolchain.setType("TYPE");
toolchain.setProvides(props);
PersistedToolchains persistedToolchains = new PersistedToolchains();
persistedToolchains.setToolchains(Collections.singletonList(toolchain));
String xml = new DefaultToolchainsXmlFactory().toXmlString(persistedToolchains.getDelegate());
ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
request.setGlobalToolchainsSource(new StringSource(xml));
ToolchainsBuildingResult result = toolchainBuilder.build(request);
assertNotNull(result.getEffectiveToolchains());
assertEquals(1, result.getEffectiveToolchains().getToolchains().size());
assertEquals(
"TYPE", result.getEffectiveToolchains().getToolchains().get(0).getType());
assertEquals(
"global_value",
result.getEffectiveToolchains()
.getToolchains()
.get(0)
.getProvides()
.get("key"));
assertNotNull(result.getProblems());
assertEquals(0, result.getProblems().size());
}
@Test
void testBuildRequestWithBothToolchains() throws Exception {
Properties props = new Properties();
props.put("key", "user_value");
ToolchainModel toolchain = new ToolchainModel();
toolchain.setType("TYPE");
toolchain.setProvides(props);
PersistedToolchains userResult = new PersistedToolchains();
userResult.setToolchains(Collections.singletonList(toolchain));
props = new Properties();
props.put("key", "global_value");
toolchain = new ToolchainModel();
toolchain.setType("TYPE");
toolchain.setProvides(props);
PersistedToolchains globalResult = new PersistedToolchains();
globalResult.setToolchains(Collections.singletonList(toolchain));
ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
request.setUserToolchainsSource(
new StringSource(new DefaultToolchainsXmlFactory().toXmlString(userResult.getDelegate())));
request.setGlobalToolchainsSource(
new StringSource(new DefaultToolchainsXmlFactory().toXmlString(globalResult.getDelegate())));
ToolchainsBuildingResult result = toolchainBuilder.build(request);
assertNotNull(result.getEffectiveToolchains());
assertEquals(2, result.getEffectiveToolchains().getToolchains().size());
assertEquals(
"TYPE", result.getEffectiveToolchains().getToolchains().get(0).getType());
assertEquals(
"user_value",
result.getEffectiveToolchains()
.getToolchains()
.get(0)
.getProvides()
.get("key"));
assertEquals(
"TYPE", result.getEffectiveToolchains().getToolchains().get(1).getType());
assertEquals(
"global_value",
result.getEffectiveToolchains()
.getToolchains()
.get(1)
.getProvides()
.get("key"));
assertNotNull(result.getProblems());
assertEquals(0, result.getProblems().size());
}
@Test
void testStrictToolchainsParseException() throws Exception {
Location loc = mock(Location.class);
when(loc.getLineNumber()).thenReturn(4);
when(loc.getColumnNumber()).thenReturn(2);
XMLStreamException parseException = new XMLStreamException("MESSAGE", loc);
doThrow(new XmlReaderException("MESSAGE", getLocation(parseException), parseException))
.when(toolchainsXmlFactory)
.read(any(XmlReaderRequest.class));
ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
request.setGlobalToolchainsSource(new StringSource(""));
try {
toolchainBuilder.build(request);
} catch (ToolchainsBuildingException e) {
assertEquals(
"1 problem was encountered while building the effective toolchains" + LS
+ "[FATAL] Non-parseable toolchains (memory): MESSAGE @ line 4, column 2" + LS,
e.getMessage());
}
}
@Test
void testIOException() throws Exception {
Source src = mock(Source.class);
IOException ioException = new IOException("MESSAGE");
doThrow(ioException).when(src).getInputStream();
doReturn("LOCATION").when(src).getLocation();
ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
request.setGlobalToolchainsSource(src);
try {
toolchainBuilder.build(request);
} catch (ToolchainsBuildingException e) {
assertEquals(
"1 problem was encountered while building the effective toolchains" + LS
+ "[FATAL] Non-readable toolchains LOCATION: MESSAGE" + LS,
e.getMessage());
}
}
@Test
void testEnvironmentVariablesAreInterpolated() throws Exception {
Properties props = new Properties();
props.put("key", "${env.testKey}");
Xpp3Dom configurationChild = new Xpp3Dom("jdkHome");
configurationChild.setValue("${env.testKey}");
Xpp3Dom configuration = new Xpp3Dom("configuration");
configuration.addChild(configurationChild);
ToolchainModel toolchain = new ToolchainModel();
toolchain.setType("TYPE");
toolchain.setProvides(props);
toolchain.setConfiguration(configuration);
PersistedToolchains persistedToolchains = new PersistedToolchains();
persistedToolchains.setToolchains(Collections.singletonList(toolchain));
String xml = new DefaultToolchainsXmlFactory().toXmlString(persistedToolchains.getDelegate());
ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
request.setUserToolchainsSource(new StringSource(xml));
ToolchainsBuildingResult result = toolchainBuilder.build(request);
String interpolatedValue = "testValue";
assertEquals(
interpolatedValue,
result.getEffectiveToolchains()
.getToolchains()
.get(0)
.getProvides()
.get("key"));
org.codehaus.plexus.util.xml.Xpp3Dom toolchainConfiguration = (org.codehaus.plexus.util.xml.Xpp3Dom)
result.getEffectiveToolchains().getToolchains().get(0).getConfiguration();
assertEquals(
interpolatedValue, toolchainConfiguration.getChild("jdkHome").getValue());
assertNotNull(result.getProblems());
assertEquals(0, result.getProblems().size());
}
@Test
void testNonExistingEnvironmentVariablesAreNotInterpolated() throws Exception {
Properties props = new Properties();
props.put("key", "${env.testNonExistingKey}");
ToolchainModel toolchain = new ToolchainModel();
toolchain.setType("TYPE");
toolchain.setProvides(props);
PersistedToolchains persistedToolchains = new PersistedToolchains();
persistedToolchains.setToolchains(Collections.singletonList(toolchain));
String xml = new DefaultToolchainsXmlFactory().toXmlString(persistedToolchains.getDelegate());
ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
request.setUserToolchainsSource(new StringSource(xml));
ToolchainsBuildingResult result = toolchainBuilder.build(request);
assertEquals(
"${env.testNonExistingKey}",
result.getEffectiveToolchains()
.getToolchains()
.get(0)
.getProvides()
.get("key"));
assertNotNull(result.getProblems());
assertEquals(0, result.getProblems().size());
}
@Test
void testEnvironmentVariablesWithSpecialCharactersAreInterpolated() throws Exception {
Properties props = new Properties();
props.put("key", "${env.testSpecialCharactersKey}");
ToolchainModel toolchain = new ToolchainModel();
toolchain.setType("TYPE");
toolchain.setProvides(props);
PersistedToolchains persistedToolchains = new PersistedToolchains();
persistedToolchains.setToolchains(Collections.singletonList(toolchain));
String xml = new DefaultToolchainsXmlFactory().toXmlString(persistedToolchains.getDelegate());
ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
request.setUserToolchainsSource(new StringSource(xml));
ToolchainsBuildingResult result = toolchainBuilder.build(request);
String interpolatedValue = "<test&Value>";
assertEquals(
interpolatedValue,
result.getEffectiveToolchains()
.getToolchains()
.get(0)
.getProvides()
.get("key"));
assertNotNull(result.getProblems());
assertEquals(0, result.getProblems().size());
}
static class TestEnvVarSource implements OperatingSystemUtils.EnvVarSource {
private final Map<String, String> envVarMap;
TestEnvVarSource(Map<String, String> envVarMap) {
this.envVarMap = envVarMap;
}
public Map<String, String> getEnvMap() {
return envVarMap;
}
}
}