View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.toolchain.building;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.util.HashMap;
24  import java.util.Map;
25  
26  import org.apache.maven.building.StringSource;
27  import org.apache.maven.toolchain.io.DefaultToolchainsReader;
28  import org.apache.maven.toolchain.io.DefaultToolchainsWriter;
29  import org.apache.maven.toolchain.io.ToolchainsParseException;
30  import org.apache.maven.toolchain.model.PersistedToolchains;
31  import org.apache.maven.toolchain.model.ToolchainModel;
32  import org.codehaus.plexus.interpolation.os.OperatingSystemUtils;
33  import org.codehaus.plexus.util.xml.Xpp3Dom;
34  import org.junit.Before;
35  import org.junit.Test;
36  import org.mockito.ArgumentMatchers;
37  import org.mockito.InjectMocks;
38  import org.mockito.MockitoAnnotations;
39  import org.mockito.Spy;
40  
41  import static org.junit.Assert.assertEquals;
42  import static org.junit.Assert.assertNotNull;
43  import static org.mockito.ArgumentMatchers.any;
44  import static org.mockito.Mockito.doReturn;
45  import static org.mockito.Mockito.doThrow;
46  
47  public class DefaultToolchainsBuilderTest {
48      private static final String LS = System.lineSeparator();
49  
50      @Spy
51      private DefaultToolchainsReader toolchainsReader;
52  
53      @Spy
54      private DefaultToolchainsWriter toolchainsWriter;
55  
56      @InjectMocks
57      private DefaultToolchainsBuilder toolchainBuilder;
58  
59      @Before
60      public void onSetup() {
61          MockitoAnnotations.initMocks(this);
62  
63          Map<String, String> envVarMap = new HashMap<>();
64          envVarMap.put("testKey", "testValue");
65          envVarMap.put("testSpecialCharactersKey", "<test&Value>");
66          OperatingSystemUtils.setEnvVarSource(new TestEnvVarSource(envVarMap));
67      }
68  
69      @Test
70      public void testBuildEmptyRequest() throws Exception {
71          ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
72          ToolchainsBuildingResult result = toolchainBuilder.build(request);
73          assertNotNull(result.getEffectiveToolchains());
74          assertNotNull(result.getProblems());
75          assertEquals(0, result.getProblems().size());
76      }
77  
78      @Test
79      public void testBuildRequestWithUserToolchains() throws Exception {
80          ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
81          request.setUserToolchainsSource(new StringSource(""));
82  
83          PersistedToolchains userResult = new PersistedToolchains();
84          ToolchainModel toolchain = new ToolchainModel();
85          toolchain.setType("TYPE");
86          toolchain.addProvide("key", "user_value");
87          userResult.addToolchain(toolchain);
88          doReturn(userResult)
89                  .when(toolchainsReader)
90                  .read(any(InputStream.class), ArgumentMatchers.<String, Object>anyMap());
91  
92          ToolchainsBuildingResult result = toolchainBuilder.build(request);
93          assertNotNull(result.getEffectiveToolchains());
94          assertEquals(1, result.getEffectiveToolchains().getToolchains().size());
95          assertEquals(
96                  "TYPE", result.getEffectiveToolchains().getToolchains().get(0).getType());
97          assertEquals(
98                  "user_value",
99                  result.getEffectiveToolchains()
100                         .getToolchains()
101                         .get(0)
102                         .getProvides()
103                         .getProperty("key"));
104         assertNotNull(result.getProblems());
105         assertEquals(0, result.getProblems().size());
106     }
107 
108     @Test
109     public void testBuildRequestWithGlobalToolchains() throws Exception {
110         ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
111         request.setGlobalToolchainsSource(new StringSource(""));
112 
113         PersistedToolchains globalResult = new PersistedToolchains();
114         ToolchainModel toolchain = new ToolchainModel();
115         toolchain.setType("TYPE");
116         toolchain.addProvide("key", "global_value");
117         globalResult.addToolchain(toolchain);
118         doReturn(globalResult)
119                 .when(toolchainsReader)
120                 .read(any(InputStream.class), ArgumentMatchers.<String, Object>anyMap());
121 
122         ToolchainsBuildingResult result = toolchainBuilder.build(request);
123         assertNotNull(result.getEffectiveToolchains());
124         assertEquals(1, result.getEffectiveToolchains().getToolchains().size());
125         assertEquals(
126                 "TYPE", result.getEffectiveToolchains().getToolchains().get(0).getType());
127         assertEquals(
128                 "global_value",
129                 result.getEffectiveToolchains()
130                         .getToolchains()
131                         .get(0)
132                         .getProvides()
133                         .getProperty("key"));
134         assertNotNull(result.getProblems());
135         assertEquals(0, result.getProblems().size());
136     }
137 
138     @Test
139     public void testBuildRequestWithBothToolchains() throws Exception {
140         ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
141         request.setGlobalToolchainsSource(new StringSource(""));
142         request.setUserToolchainsSource(new StringSource(""));
143 
144         PersistedToolchains userResult = new PersistedToolchains();
145         ToolchainModel userToolchain = new ToolchainModel();
146         userToolchain.setType("TYPE");
147         userToolchain.addProvide("key", "user_value");
148         userResult.addToolchain(userToolchain);
149 
150         PersistedToolchains globalResult = new PersistedToolchains();
151         ToolchainModel globalToolchain = new ToolchainModel();
152         globalToolchain.setType("TYPE");
153         globalToolchain.addProvide("key", "global_value");
154         globalResult.addToolchain(globalToolchain);
155         doReturn(globalResult)
156                 .doReturn(userResult)
157                 .when(toolchainsReader)
158                 .read(any(InputStream.class), ArgumentMatchers.<String, Object>anyMap());
159 
160         ToolchainsBuildingResult result = toolchainBuilder.build(request);
161         assertNotNull(result.getEffectiveToolchains());
162         assertEquals(2, result.getEffectiveToolchains().getToolchains().size());
163         assertEquals(
164                 "TYPE", result.getEffectiveToolchains().getToolchains().get(0).getType());
165         assertEquals(
166                 "user_value",
167                 result.getEffectiveToolchains()
168                         .getToolchains()
169                         .get(0)
170                         .getProvides()
171                         .getProperty("key"));
172         assertEquals(
173                 "TYPE", result.getEffectiveToolchains().getToolchains().get(1).getType());
174         assertEquals(
175                 "global_value",
176                 result.getEffectiveToolchains()
177                         .getToolchains()
178                         .get(1)
179                         .getProvides()
180                         .getProperty("key"));
181         assertNotNull(result.getProblems());
182         assertEquals(0, result.getProblems().size());
183     }
184 
185     @Test
186     public void testStrictToolchainsParseException() throws Exception {
187         ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
188         request.setGlobalToolchainsSource(new StringSource(""));
189         ToolchainsParseException parseException = new ToolchainsParseException("MESSAGE", 4, 2);
190         doThrow(parseException)
191                 .when(toolchainsReader)
192                 .read(any(InputStream.class), ArgumentMatchers.<String, Object>anyMap());
193 
194         try {
195             toolchainBuilder.build(request);
196         } catch (ToolchainsBuildingException e) {
197             assertEquals(
198                     "1 problem was encountered while building the effective toolchains" + LS
199                             + "[FATAL] Non-parseable toolchains (memory): MESSAGE @ line 4, column 2" + LS,
200                     e.getMessage());
201         }
202     }
203 
204     @Test
205     public void testIOException() throws Exception {
206         ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
207         request.setGlobalToolchainsSource(new StringSource("", "LOCATION"));
208         IOException ioException = new IOException("MESSAGE");
209         doThrow(ioException)
210                 .when(toolchainsReader)
211                 .read(any(InputStream.class), ArgumentMatchers.<String, Object>anyMap());
212 
213         try {
214             toolchainBuilder.build(request);
215         } catch (ToolchainsBuildingException e) {
216             assertEquals(
217                     "1 problem was encountered while building the effective toolchains" + LS
218                             + "[FATAL] Non-readable toolchains LOCATION: MESSAGE" + LS,
219                     e.getMessage());
220         }
221     }
222 
223     @Test
224     public void testEnvironmentVariablesAreInterpolated() throws Exception {
225         ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
226         request.setUserToolchainsSource(new StringSource(""));
227 
228         PersistedToolchains persistedToolchains = new PersistedToolchains();
229         ToolchainModel toolchain = new ToolchainModel();
230         toolchain.setType("TYPE");
231         toolchain.addProvide("key", "${env.testKey}");
232 
233         Xpp3Dom configurationChild = new Xpp3Dom("jdkHome");
234         configurationChild.setValue("${env.testKey}");
235         Xpp3Dom configuration = new Xpp3Dom("configuration");
236         configuration.addChild(configurationChild);
237         toolchain.setConfiguration(configuration);
238         persistedToolchains.addToolchain(toolchain);
239         doReturn(persistedToolchains)
240                 .when(toolchainsReader)
241                 .read(any(InputStream.class), ArgumentMatchers.<String, Object>anyMap());
242 
243         ToolchainsBuildingResult result = toolchainBuilder.build(request);
244         String interpolatedValue = "testValue";
245         assertEquals(
246                 interpolatedValue,
247                 result.getEffectiveToolchains()
248                         .getToolchains()
249                         .get(0)
250                         .getProvides()
251                         .getProperty("key"));
252         Xpp3Dom toolchainConfiguration =
253                 (Xpp3Dom) result.getEffectiveToolchains().getToolchains().get(0).getConfiguration();
254         assertEquals(
255                 interpolatedValue, toolchainConfiguration.getChild("jdkHome").getValue());
256         assertNotNull(result.getProblems());
257         assertEquals(0, result.getProblems().size());
258     }
259 
260     @Test
261     public void testNonExistingEnvironmentVariablesAreNotInterpolated() throws Exception {
262         ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
263         request.setUserToolchainsSource(new StringSource(""));
264 
265         PersistedToolchains persistedToolchains = new PersistedToolchains();
266         ToolchainModel toolchain = new ToolchainModel();
267         toolchain.setType("TYPE");
268         toolchain.addProvide("key", "${env.testNonExistingKey}");
269 
270         persistedToolchains.addToolchain(toolchain);
271         doReturn(persistedToolchains)
272                 .when(toolchainsReader)
273                 .read(any(InputStream.class), ArgumentMatchers.<String, Object>anyMap());
274 
275         ToolchainsBuildingResult result = toolchainBuilder.build(request);
276         assertEquals(
277                 "${env.testNonExistingKey}",
278                 result.getEffectiveToolchains()
279                         .getToolchains()
280                         .get(0)
281                         .getProvides()
282                         .getProperty("key"));
283         assertNotNull(result.getProblems());
284         assertEquals(0, result.getProblems().size());
285     }
286 
287     @Test
288     public void testEnvironmentVariablesWithSpecialCharactersAreInterpolated() throws Exception {
289         ToolchainsBuildingRequest request = new DefaultToolchainsBuildingRequest();
290         request.setUserToolchainsSource(new StringSource(""));
291 
292         PersistedToolchains persistedToolchains = new PersistedToolchains();
293         ToolchainModel toolchain = new ToolchainModel();
294         toolchain.setType("TYPE");
295         toolchain.addProvide("key", "${env.testSpecialCharactersKey}");
296 
297         persistedToolchains.addToolchain(toolchain);
298         doReturn(persistedToolchains)
299                 .when(toolchainsReader)
300                 .read(any(InputStream.class), ArgumentMatchers.<String, Object>anyMap());
301 
302         ToolchainsBuildingResult result = toolchainBuilder.build(request);
303         String interpolatedValue = "<test&Value>";
304         assertEquals(
305                 interpolatedValue,
306                 result.getEffectiveToolchains()
307                         .getToolchains()
308                         .get(0)
309                         .getProvides()
310                         .getProperty("key"));
311         assertNotNull(result.getProblems());
312         assertEquals(0, result.getProblems().size());
313     }
314 
315     static class TestEnvVarSource implements OperatingSystemUtils.EnvVarSource {
316         private final Map<String, String> envVarMap;
317 
318         TestEnvVarSource(Map<String, String> envVarMap) {
319             this.envVarMap = envVarMap;
320         }
321 
322         public Map<String, String> getEnvMap() {
323             return envVarMap;
324         }
325     }
326 }