001package org.andromda.maven.plugin.bootstrap;
002
003import java.io.File;
004import java.net.URL;
005import java.util.List;
006import junit.framework.TestResult;
007import org.andromda.core.common.ExceptionUtils;
008import org.andromda.core.common.ResourceUtils;
009import org.andromda.maven.plugin.configuration.AbstractConfigurationMojo;
010import org.andromda.translation.ocl.testsuite.TranslationTestProcessor;
011import org.apache.maven.artifact.factory.ArtifactFactory;
012import org.apache.maven.artifact.repository.ArtifactRepository;
013import org.apache.maven.model.Plugin;
014import org.apache.maven.plugin.MojoExecutionException;
015import org.apache.maven.plugin.MojoFailureException;
016import org.apache.maven.project.MavenProject;
017import org.apache.maven.settings.Settings;
018
019/**
020 * The bootstrap version of the translation-library test.
021 *
022 * @phase test
023 * @goal test-translation-library
024 * @requiresDependencyResolution test
025 * @description runs AndroMDA Translation-Library tests
026 * @author Chad Brandon
027 */
028public class TranslationLibraryTestMojo
029    extends AbstractConfigurationMojo
030{
031    /**
032     * Base directory to which the cartridge test report is written
033     *
034     * @parameter expression="${project.build.directory}/translation-library-test/reports"
035     */
036    private String reportDirectory;
037
038    /**
039     * Whether or not the expression shall be 'traced' (i.e. the TraceTranslator will run instead of the specified translator).
040     * This is helpful, in allowing us to see which expressions are being parsed in what order, etc.
041     *
042     * @parameter expression="${trace.expression}"
043     */
044    protected boolean traceExpression;
045
046    /**
047     * When specified, only this translation will be tested (If more than one TestTranslation-* file is found).
048     *
049     * @parameter expression="${translation.name}"
050     */
051    protected String translationName;
052
053    /**
054     * The directory containing the test source.
055     *
056     * @parameter expression="${basedir}"
057     * @required
058     * @readonly
059     */
060    protected String testSourceDirectory;
061
062    /**
063     * This is the URI to the AndroMDA configuration file.
064     *
065     * @parameter expression="file:${basedir}/conf/test/andromda.xml"
066     * @required
067     */
068    protected String configurationUri;
069
070    /**
071     * @parameter expression="${project}"
072     * @required
073     * @readonly
074     */
075    private MavenProject project;
076
077    /**
078     * @parameter expression="${project.build.filters}"
079     */
080    private List<String> propertyFiles;
081
082    /**
083     * The current user system settings for use in Maven. (allows us to pass the user
084     * settings to the AndroMDA configuration).
085     *
086     * @parameter expression="${settings}"
087     * @required
088     * @readonly
089     */
090    private Settings settings;
091
092    /**
093     * @component role="org.apache.maven.artifact.factory.ArtifactFactory"
094     * @required
095     * @readonly
096     */
097    private ArtifactFactory factory;
098
099    /**
100     * The registered plugin implementations.
101     *
102     * @parameter expression="${project.build.plugins}"
103     * @required
104     * @readonly
105     */
106    protected List<Plugin> plugins;
107
108    /**
109     * @parameter expression="${localRepository}"
110     * @required
111     * @readonly
112     */
113    protected ArtifactRepository localRepository;
114
115    /**
116     * Set this to 'true' to bypass cartridge tests entirely. Its use is NOT RECOMMENDED, but quite convenient on occasion.
117     *
118     * @parameter expression="${maven.test.skip}"
119     */
120    protected boolean skip;
121
122    /**
123     *  Set this to 'true' to skip running tests, but still compile them. Its use is NOT RECOMMENDED, but quite convenient on occasion.
124     *
125     * @parameter expression="${skipTests}"
126     */
127    protected boolean skipTests;
128
129    /**
130     * Set this to true to ignore a failure during testing. Its use is NOT RECOMMENDED, but quite convenient on occasion.
131     *
132     * @parameter expression="${maven.test.failure.ignore}" default-value="false"
133     */
134    protected boolean testFailureIgnore;
135
136    /**
137     * @see org.apache.maven.plugin.Mojo#execute()
138     */
139    public void execute()
140        throws MojoExecutionException, MojoFailureException
141    {
142        if (!this.skip && !this.skipTests)
143        {
144            try
145            {
146                this.getLog().info("--------------------------------------------------------------------------------");
147                this.getLog().info("  A n d r o M D A   T r a n s l a t i o n - L i b r a r y  T e s t   S u i t e  ");
148                this.getLog().info("--------------------------------------------------------------------------------");
149
150                this.initializeClasspathFromClassPathElements(this.project.getTestClasspathElements());
151
152                final TranslationTestProcessor processor = TranslationTestProcessor.instance();
153                processor.setTranslationName(this.translationName);
154                processor.setUseTraceTranslator(this.traceExpression);
155                processor.setTestSourceDirectory(this.testSourceDirectory);
156                final URL configurationUri = ResourceUtils.toURL(this.configurationUri);
157                if (configurationUri == null)
158                {
159                    throw new MojoExecutionException("No configuration could be loaded from --> '" +
160                        this.configurationUri + '\'');
161                }
162                processor.setConfiguration(this.getConfiguration(configurationUri));
163
164                final TranslationLibraryTestFormatter formatter = new TranslationLibraryTestFormatter();
165
166                // - set the report location
167                final File report = new File(this.reportDirectory, this.getProject().getArtifactId() + ".txt");
168                formatter.setReportFile(report);
169                final TestResult result = new TestResult();
170                formatter.startTestSuite(this.getProject().getName());
171                result.addListener(formatter);
172                processor.setResult(result);
173                processor.runSuite();
174                this.getLog().info("");
175                this.getLog().info("Results:");
176                this.getLog().info(formatter.endTestSuite());
177                if (result.failureCount() > 0 || result.errorCount() > 0)
178                {
179                    throw new MojoExecutionException("There are some test failures");
180                }
181                processor.shutdown();
182            }
183            catch (final Throwable throwable)
184            {
185                if (throwable instanceof MojoExecutionException && !this.testFailureIgnore)
186                {
187                    throw (MojoExecutionException)throwable;
188                }
189                else if (this.testFailureIgnore)
190                {
191                    this.getLog().error("An error occurred while testing translation-library '" +
192                            this.translationName + '\'',
193                        ExceptionUtils.getRootCause(throwable));
194                }
195                else
196                {
197                    throw new MojoExecutionException("An error occurred while testing translation-library '" +
198                            this.translationName + '\'',
199                            ExceptionUtils.getRootCause(throwable));
200                }
201            }
202        }
203        else
204        {
205            this.getLog().info("Skipping translation-library tests");
206        }
207    }
208
209    /**
210     * @see org.andromda.maven.plugin.configuration.AbstractConfigurationMojo#getProject()
211     */
212    protected MavenProject getProject()
213    {
214        return this.project;
215    }
216
217    /**
218     * @see org.andromda.maven.plugin.configuration.AbstractConfigurationMojo#getPropertyFiles()
219     */
220    protected List<String> getPropertyFiles()
221    {
222        return this.propertyFiles;
223    }
224
225    /**
226     * @see org.andromda.maven.plugin.configuration.AbstractConfigurationMojo#getSettings()
227     */
228    protected Settings getSettings()
229    {
230        return this.settings;
231    }
232
233    /**
234     * @see org.andromda.maven.plugin.configuration.AbstractConfigurationMojo#getFactory()
235     */
236    protected ArtifactFactory getFactory()
237    {
238        return this.factory;
239    }
240
241    /**
242     * @see org.andromda.maven.plugin.configuration.AbstractConfigurationMojo#getPlugins()
243     */
244    protected List<Plugin> getPlugins()
245    {
246        return this.plugins;
247    }
248
249    /**
250     * @see org.andromda.maven.plugin.configuration.AbstractConfigurationMojo#getLocalRepository()
251     */
252    protected ArtifactRepository getLocalRepository()
253    {
254        return this.localRepository;
255    }
256}