001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *   http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied.  See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019package org.apache.maven.scm;
020
021import java.io.File;
022import java.io.InputStream;
023import java.util.Map;
024
025import com.google.inject.Module;
026import org.codehaus.plexus.ContainerConfiguration;
027import org.codehaus.plexus.DefaultContainerConfiguration;
028import org.codehaus.plexus.DefaultPlexusContainer;
029import org.codehaus.plexus.PlexusConstants;
030import org.codehaus.plexus.PlexusContainer;
031import org.codehaus.plexus.PlexusContainerException;
032import org.codehaus.plexus.configuration.PlexusConfiguration;
033import org.codehaus.plexus.context.Context;
034import org.codehaus.plexus.context.DefaultContext;
035import org.junit.After;
036import org.junit.Before;
037import org.junit.Rule;
038import org.junit.rules.TestName;
039
040import static org.junit.Assert.fail;
041
042/**
043 * Based on PlexusTestCase from org.sonatype.sisu:sisu-inject-plexus.
044 * Note: this class is copied from maven-release.
045 *
046 * @author Robert Scholte
047 */
048public class PlexusJUnit4TestCase {
049    private PlexusContainer container;
050
051    private static String basedir;
052
053    @Rule
054    public TestName testName = new TestName();
055
056    @Before
057    public void setUp() throws Exception {
058        basedir = getBasedir();
059    }
060
061    public String getName() {
062        return testName.getMethodName();
063    }
064
065    protected void setupContainer() {
066        // ----------------------------------------------------------------------------
067        // Context Setup
068        // ----------------------------------------------------------------------------
069
070        final DefaultContext context = new DefaultContext();
071
072        context.put("basedir", getBasedir());
073
074        customizeContext(context);
075
076        final boolean hasPlexusHome = context.contains("plexus.home");
077
078        if (!hasPlexusHome) {
079            final File f = getTestFile("target/plexus-home");
080
081            if (!f.isDirectory()) {
082                f.mkdir();
083            }
084
085            context.put("plexus.home", f.getAbsolutePath());
086        }
087
088        // ----------------------------------------------------------------------------
089        // Configuration
090        // ----------------------------------------------------------------------------
091
092        final String config = getCustomConfigurationName();
093
094        final ContainerConfiguration containerConfiguration = new DefaultContainerConfiguration()
095                .setName("test")
096                .setContext(context.getContextData())
097                .setAutoWiring(true)
098                .setClassPathScanning(PlexusConstants.SCANNING_CACHE);
099
100        if (config != null) {
101            containerConfiguration.setContainerConfiguration(config);
102        } else {
103            final String resource = getConfigurationName(null);
104
105            containerConfiguration.setContainerConfiguration(resource);
106        }
107
108        customizeContainerConfiguration(containerConfiguration);
109
110        try {
111            container = new DefaultPlexusContainer(containerConfiguration, getCustomModules());
112        } catch (final PlexusContainerException e) {
113            e.printStackTrace();
114            fail("Failed to create plexus container.");
115        }
116    }
117
118    /**
119     * Allows test to define custom modules.
120     */
121    public Module[] getCustomModules() {
122        return new Module[0];
123    }
124
125    /**
126     * Allow custom test case implementations do augment the default container configuration before executing tests.
127     *
128     * @param containerConfiguration
129     */
130    protected void customizeContainerConfiguration(final ContainerConfiguration containerConfiguration) {}
131
132    protected void customizeContext(final Context context) {}
133
134    protected PlexusConfiguration customizeComponentConfiguration() {
135        return null;
136    }
137
138    @After
139    public void tearDown() throws Exception {
140        if (container != null) {
141            container.dispose();
142
143            container = null;
144        }
145    }
146
147    protected PlexusContainer getContainer() {
148        if (container == null) {
149            setupContainer();
150        }
151
152        return container;
153    }
154
155    protected InputStream getConfiguration() throws Exception {
156        return getConfiguration(null);
157    }
158
159    @SuppressWarnings("unused")
160    protected InputStream getConfiguration(final String subname) throws Exception {
161        return getResourceAsStream(getConfigurationName(subname));
162    }
163
164    protected String getCustomConfigurationName() {
165        return null;
166    }
167
168    /**
169     * Allow the retrieval of a container configuration that is based on the name of the test class being run. So if you
170     * have a test class called org.foo.FunTest, then this will produce a resource name of org/foo/FunTest.xml which
171     * would be used to configure the Plexus container before running your test.
172     *
173     * @param subname
174     * @return
175     */
176    protected String getConfigurationName(final String subname) {
177        return getClass().getName().replace('.', '/') + ".xml";
178    }
179
180    protected InputStream getResourceAsStream(final String resource) {
181        return getClass().getResourceAsStream(resource);
182    }
183
184    protected ClassLoader getClassLoader() {
185        return getClass().getClassLoader();
186    }
187
188    // ----------------------------------------------------------------------
189    // Container access
190    // ----------------------------------------------------------------------
191
192    protected Object lookup(final String componentKey) throws Exception {
193        return getContainer().lookup(componentKey);
194    }
195
196    protected Object lookup(final String role, final String roleHint) throws Exception {
197        return getContainer().lookup(role, roleHint);
198    }
199
200    protected <T> T lookup(final Class<T> componentClass) throws Exception {
201        return getContainer().lookup(componentClass);
202    }
203
204    protected <T> T lookup(final Class<T> componentClass, final String roleHint) throws Exception {
205        return getContainer().lookup(componentClass, roleHint);
206    }
207
208    protected <T> Map<String, T> lookupMap(final Class<T> componentClass) throws Exception {
209        return getContainer().lookupMap(componentClass);
210    }
211
212    protected void release(final Object component) throws Exception {
213        getContainer().release(component);
214    }
215
216    // ----------------------------------------------------------------------
217    // Helper methods for sub classes
218    // ----------------------------------------------------------------------
219
220    public static File getTestFile(final String path) {
221        return new File(getBasedir(), path);
222    }
223
224    @SuppressWarnings("hiding")
225    public static File getTestFile(final String basedir, final String path) {
226        File basedirFile = new File(basedir);
227
228        if (!basedirFile.isAbsolute()) {
229            basedirFile = getTestFile(basedir);
230        }
231
232        return new File(basedirFile, path);
233    }
234
235    public static String getTestPath(final String path) {
236        return getTestFile(path).getAbsolutePath();
237    }
238
239    @SuppressWarnings("hiding")
240    public static String getTestPath(final String basedir, final String path) {
241        return getTestFile(basedir, path).getAbsolutePath();
242    }
243
244    public static String getBasedir() {
245        if (basedir != null) {
246            return basedir;
247        }
248
249        basedir = System.getProperty("basedir");
250
251        if (basedir == null) {
252            basedir = new File("").getAbsolutePath();
253        }
254
255        return basedir;
256    }
257
258    public String getTestConfiguration() {
259        return getTestConfiguration(getClass());
260    }
261
262    public static String getTestConfiguration(final Class<?> clazz) {
263        final String s = clazz.getName().replace('.', '/');
264
265        return s.substring(0, s.indexOf("$")) + ".xml";
266    }
267}