EMMA Coverage Report (generated Sun Sep 18 11:34:27 PHT 2011)
[all classes][org.apache.maven.continuum.execution]

COVERAGE SUMMARY FOR SOURCE FILE [AbstractBuildExecutor.java]

nameclass, %method, %block, %line, %
AbstractBuildExecutor.java100% (1/1)66%  (19/29)61%  (354/580)66%  (80.7/122)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class AbstractBuildExecutor100% (1/1)66%  (19/29)61%  (354/580)66%  (80.7/122)
backupTestFiles (Project, int): void 0%   (0/1)0%   (0/1)0%   (0/1)
getDefaultExecutable (): String 0%   (0/1)0%   (0/3)0%   (0/1)
getDeployableArtifacts (Project, File, BuildDefinition): List 0%   (0/1)0%   (0/2)0%   (0/1)
getEnvironmentVariables (BuildDefinition): Map 0%   (0/1)0%   (0/39)0%   (0/10)
getJavaHomeValue (BuildDefinition): String 0%   (0/1)0%   (0/17)0%   (0/7)
isBuilding (Project): boolean 0%   (0/1)0%   (0/15)0%   (0/1)
isResolveExecutable (): boolean 0%   (0/1)0%   (0/3)0%   (0/1)
killProcess (Project): void 0%   (0/1)0%   (0/7)0%   (0/2)
setResolveExecutable (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
shouldBuild (List, Project, File, BuildDefinition): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
initialize (): void 100% (1/1)52%  (42/80)78%  (7/9)
getBuildFileForProject (Project, BuildDefinition): String 100% (1/1)54%  (13/24)80%  (4/5)
getRelativePath (File, File, String): String 100% (1/1)57%  (21/37)80%  (4/5)
findExecutable (String, String, boolean, File): String 100% (1/1)70%  (51/73)73%  (11.7/16)
executeShellCommand (Project, String, String, File, Map): ContinuumBuildExecu... 100% (1/1)71%  (114/160)79%  (22/28)
AbstractBuildExecutor (String, boolean): void 100% (1/1)100% (14/14)100% (5/5)
getChrootJailDirectory (): File 100% (1/1)100% (3/3)100% (1/1)
getContinuumSystemProperties (Project): Properties 100% (1/1)100% (55/55)100% (9/9)
getExecutableResolver (): ExecutableResolver 100% (1/1)100% (3/3)100% (1/1)
getInstallationService (): InstallationService 100% (1/1)100% (3/3)100% (1/1)
getShellCommandHelper (): ShellCommandHelper 100% (1/1)100% (3/3)100% (1/1)
getWorkingDirectory (Project): File 100% (1/1)100% (5/5)100% (1/1)
getWorkingDirectoryService (): WorkingDirectoryService 100% (1/1)100% (3/3)100% (1/1)
setChrootJailDirectory (File): void 100% (1/1)100% (4/4)100% (2/2)
setDefaultExecutable (String): void 100% (1/1)100% (4/4)100% (2/2)
setExecutableResolver (ExecutableResolver): void 100% (1/1)100% (4/4)100% (2/2)
setInstallationService (InstallationService): void 100% (1/1)100% (4/4)100% (2/2)
setShellCommandHelper (ShellCommandHelper): void 100% (1/1)100% (4/4)100% (2/2)
setWorkingDirectoryService (WorkingDirectoryService): void 100% (1/1)100% (4/4)100% (2/2)

1package org.apache.maven.continuum.execution;
2 
3/*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements.  See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership.  The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License.  You may obtain a copy of the License at
11 *
12 *   http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied.  See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21 
22import java.io.File;
23import java.util.Collections;
24import java.util.HashMap;
25import java.util.List;
26import java.util.Map;
27import java.util.Properties;
28 
29import org.apache.continuum.utils.shell.ExecutionResult;
30import org.apache.continuum.utils.shell.ShellCommandHelper;
31import org.apache.maven.artifact.Artifact;
32import org.apache.maven.continuum.installation.InstallationService;
33import org.apache.maven.continuum.model.project.BuildDefinition;
34import org.apache.maven.continuum.model.project.Project;
35import org.apache.maven.continuum.model.scm.ChangeSet;
36import org.apache.maven.continuum.model.system.Installation;
37import org.apache.maven.continuum.model.system.Profile;
38import org.apache.maven.continuum.project.ContinuumProjectState;
39import org.apache.maven.continuum.utils.WorkingDirectoryService;
40import org.codehaus.plexus.commandline.ExecutableResolver;
41import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
42import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
43import org.codehaus.plexus.util.StringUtils;
44import org.codehaus.plexus.util.cli.CommandLineException;
45import org.slf4j.Logger;
46import org.slf4j.LoggerFactory;
47 
48/**
49 * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
50 * @version $Id: AbstractBuildExecutor.java 764863 2009-04-14 16:28:12Z evenisse $
51 */
52public abstract class AbstractBuildExecutor
53    implements ContinuumBuildExecutor, Initializable
54{
55    protected final Logger log = LoggerFactory.getLogger( getClass() );
56 
57    private static final String SUDO_EXECUTABLE = "sudo";
58 
59    private static final String CHROOT_EXECUTABLE = "chroot";
60 
61    // ----------------------------------------------------------------------
62    //
63    // ----------------------------------------------------------------------
64 
65    /**
66     * @plexus.requirement
67     */
68    private ShellCommandHelper shellCommandHelper;
69 
70    /**
71     * @plexus.requirement
72     */
73    private ExecutableResolver executableResolver;
74 
75    /**
76     * @plexus.requirement
77     */
78    private WorkingDirectoryService workingDirectoryService;
79 
80    /**
81     * @plexus.requirement
82     */
83    private InstallationService installationService;
84 
85    /**
86     * @plexus.configuration
87     */
88    private File chrootJailDirectory;
89 
90    /**
91     * @plexus.configuration
92     */
93    private String defaultExecutable;
94 
95    // ----------------------------------------------------------------------
96    //
97    // ----------------------------------------------------------------------
98 
99    private final String id;
100 
101    private boolean resolveExecutable;
102 
103    // ----------------------------------------------------------------------
104    //
105    // ----------------------------------------------------------------------
106 
107    protected AbstractBuildExecutor( String id, boolean resolveExecutable )
108    {
109        this.id = id;
110 
111        this.resolveExecutable = resolveExecutable;
112    }
113 
114    public void setShellCommandHelper( ShellCommandHelper shellCommandHelper )
115    {
116        this.shellCommandHelper = shellCommandHelper;
117    }
118 
119    public ShellCommandHelper getShellCommandHelper()
120    {
121        return shellCommandHelper;
122    }
123 
124    public void setWorkingDirectoryService( WorkingDirectoryService workingDirectoryService )
125    {
126        this.workingDirectoryService = workingDirectoryService;
127    }
128 
129    public WorkingDirectoryService getWorkingDirectoryService()
130    {
131        return workingDirectoryService;
132    }
133 
134    public void setDefaultExecutable( String defaultExecutable )
135    {
136        this.defaultExecutable = defaultExecutable;
137    }
138 
139    // ----------------------------------------------------------------------
140    // Component Lifecycle
141    // ----------------------------------------------------------------------
142 
143    public String getDefaultExecutable()
144    {
145        return defaultExecutable;
146    }
147 
148    public void initialize()
149        throws InitializationException
150    {
151        List path = executableResolver.getDefaultPath();
152 
153        if ( resolveExecutable )
154        {
155            if ( StringUtils.isEmpty( defaultExecutable ) )
156            {
157                log.warn( "The default executable for build executor '" + id + "' is not set. " +
158                    "This will cause a problem unless the project has a executable configured." );
159            }
160            else
161            {
162                File resolvedExecutable = executableResolver.findExecutable( defaultExecutable, path );
163 
164                if ( resolvedExecutable == null )
165                {
166                    log.warn(
167                        "Could not find the executable '" + defaultExecutable + "' in the " + "path '" + path + "'." );
168                }
169                else
170                {
171                    log.info( "Resolved the executable '" + defaultExecutable + "' to " + "'" +
172                        resolvedExecutable.getAbsolutePath() + "'." );
173                }
174            }
175        }
176    }
177 
178    // ----------------------------------------------------------------------
179    //
180    // ----------------------------------------------------------------------
181 
182    /**
183     * Find the actual executable path to be used
184     *
185     * @param defaultExecutable
186     * @return The executable path
187     */
188    protected String findExecutable( String executable, String defaultExecutable, boolean resolveExecutable,
189                                   File workingDirectory )
190    {
191        // ----------------------------------------------------------------------
192        // If we're not searching the path for the executable, prefix the
193        // executable with the working directory to make sure the path is
194        // absolute and thus won't be tried resolved by using the PATH
195        // ----------------------------------------------------------------------
196 
197        String actualExecutable;
198 
199        if ( !resolveExecutable )
200        {
201            actualExecutable = new File( workingDirectory, executable ).getAbsolutePath();
202        }
203        else
204        {
205            List<String> path = executableResolver.getDefaultPath();
206 
207            if ( StringUtils.isEmpty( executable ) )
208            {
209                executable = defaultExecutable;
210            }
211 
212            File e = executableResolver.findExecutable( executable, path );
213 
214            if ( e == null )
215            {
216                log.warn( "Could not find the executable '" + executable + "' in this path: " );
217 
218                for ( String element : path )
219                {
220                    log.warn( element );
221                }
222 
223                actualExecutable = defaultExecutable;
224            }
225            else
226            {
227                actualExecutable = e.getAbsolutePath();
228            }
229        }
230 
231        //sometimes executable isn't found in path but it exit (CONTINUUM-365)
232        File actualExecutableFile = new File( actualExecutable );
233 
234        if ( !actualExecutableFile.exists() )
235        {
236            actualExecutable = executable;
237        }
238 
239        return actualExecutable;
240    }
241 
242    protected ContinuumBuildExecutionResult executeShellCommand( Project project, String executable, String arguments,
243                                                                 File output, Map<String, String> environments )
244        throws ContinuumBuildExecutorException
245    {
246 
247        File workingDirectory = getWorkingDirectory( project );
248 
249        String actualExecutable = findExecutable( executable, defaultExecutable, resolveExecutable, workingDirectory );
250 
251        // ----------------------------------------------------------------------
252        // Execute the build
253        // ----------------------------------------------------------------------
254 
255        try
256        {
257            File chrootJailDirectory = getChrootJailDirectory();
258            if ( chrootJailDirectory != null )
259            {
260                StringBuilder sb = new StringBuilder();
261                sb.append( CHROOT_EXECUTABLE );
262                sb.append( " " );
263                sb.append( new File( chrootJailDirectory, project.getGroupId() ) );
264                sb.append( " " );
265                sb.append( " /bin/sh -c 'cd " );
266                sb.append( getRelativePath( chrootJailDirectory, workingDirectory, project.getGroupId() ) );
267                sb.append( " && " );
268                sb.append( actualExecutable );
269                sb.append( " " );
270                sb.append( arguments );
271                sb.append( "'" );
272 
273                arguments = sb.toString();
274                actualExecutable = SUDO_EXECUTABLE;
275                workingDirectory = chrootJailDirectory; // not really used but must exist
276            }
277 
278            ExecutionResult result =
279                getShellCommandHelper().executeShellCommand( workingDirectory, actualExecutable, arguments, output,
280                                                             project.getId(), environments );
281 
282            log.info( "Exit code: " + result.getExitCode() );
283 
284            return new ContinuumBuildExecutionResult( output, result.getExitCode() );
285        }
286        catch ( CommandLineException e )
287        {
288            if ( e.getCause() instanceof InterruptedException )
289            {
290                throw new ContinuumBuildCancelledException( "The build was cancelled", e );
291            }
292            else
293            {
294                throw new ContinuumBuildExecutorException(
295                    "Error while executing shell command. The most common error is that '" + executable + "' " +
296                        "is not in your path.", e );
297            }
298        }
299        catch ( Exception e )
300        {
301            throw new ContinuumBuildExecutorException(
302                "Error while executing shell command. " + "The most common error is that '" + executable + "' " +
303                    "is not in your path.", e );
304        }
305    }
306 
307    private String getRelativePath( File chrootDir, File workingDirectory, String groupId )
308    {
309        String path = workingDirectory.getPath();
310        String chrootBase = new File( chrootDir, groupId ).getPath();
311        if ( path.startsWith( chrootBase ) )
312        {
313            return path.substring( chrootBase.length(), path.length() );
314        }
315        else
316        {
317            throw new IllegalArgumentException(
318                "Working directory is not inside the chroot jail " + chrootBase + " , " + path );
319        }
320    }
321 
322    protected abstract Map<String, String> getEnvironments( BuildDefinition buildDefinition );
323 
324    protected String getJavaHomeValue( BuildDefinition buildDefinition )
325    {
326        Profile profile = buildDefinition.getProfile();
327        if ( profile == null )
328        {
329            return null;
330        }
331        Installation jdk = profile.getJdk();
332        if ( jdk == null )
333        {
334            return null;
335        }
336        return jdk.getVarValue();
337    }
338 
339    public void backupTestFiles( Project project, int buildId )
340    {
341        //Nothing to do, by default
342    }
343 
344    /**
345     * By default, we return true because with a change, the project must be rebuilt.
346     */
347    public boolean shouldBuild( List<ChangeSet> changes, Project continuumProject, File workingDirectory,
348                                BuildDefinition buildDefinition )
349        throws ContinuumBuildExecutorException
350    {
351        return true;
352    }
353 
354    protected Map<String, String> getEnvironmentVariables( BuildDefinition buildDefinition )
355    {
356        Profile profile = buildDefinition.getProfile();
357        Map<String, String> envVars = new HashMap<String, String>();
358        if ( profile == null )
359        {
360            return envVars;
361        }
362        List<Installation> environmentVariables = profile.getEnvironmentVariables();
363        if ( environmentVariables.isEmpty() )
364        {
365            return envVars;
366        }
367        for ( Installation installation : environmentVariables )
368        {
369            envVars.put( installation.getVarName(), installation.getVarValue() );
370        }
371        return envVars;
372    }
373 
374    protected Properties getContinuumSystemProperties( Project project )
375    {
376        Properties properties = new Properties();
377        properties.setProperty( "continuum.project.group.name", project.getProjectGroup().getName() );
378        properties.setProperty( "continuum.project.lastBuild.state", String.valueOf( project.getOldState() ) );
379        properties.setProperty( "continuum.project.lastBuild.number", String.valueOf( project.getBuildNumber() ) );
380        properties.setProperty( "continuum.project.nextBuild.number", String.valueOf( project.getBuildNumber() + 1 ) );
381        properties.setProperty( "continuum.project.id", String.valueOf( project.getId() ) );
382        properties.setProperty( "continuum.project.name", project.getName() );
383        properties.setProperty( "continuum.project.version", project.getVersion() );
384        return properties;
385    }
386 
387    protected String getBuildFileForProject( Project project, BuildDefinition buildDefinition )
388    {
389        String buildFile = StringUtils.clean( buildDefinition.getBuildFile() );
390        String relPath = StringUtils.clean( project.getRelativePath() );
391 
392        if ( StringUtils.isEmpty( relPath ) )
393        {
394            return buildFile;
395        }
396 
397        return relPath + File.separator + buildFile;
398    }
399 
400    public boolean isBuilding( Project project )
401    {
402        return project.getState() == ContinuumProjectState.BUILDING ||
403            getShellCommandHelper().isRunning( project.getId() );
404    }
405 
406    public void killProcess( Project project )
407    {
408        getShellCommandHelper().killProcess( project.getId() );
409    }
410 
411    public List<Artifact> getDeployableArtifacts( Project project, File workingDirectory,
412                                                  BuildDefinition buildDefinition )
413        throws ContinuumBuildExecutorException
414    {
415        // Not supported by this builder
416        return Collections.EMPTY_LIST;
417    }
418 
419    public File getWorkingDirectory( Project project )
420    {
421        return getWorkingDirectoryService().getWorkingDirectory( project );
422    }
423 
424    public InstallationService getInstallationService()
425    {
426        return installationService;
427    }
428 
429    public void setInstallationService( InstallationService installationService )
430    {
431        this.installationService = installationService;
432    }
433 
434    public boolean isResolveExecutable()
435    {
436        return resolveExecutable;
437    }
438 
439    public void setResolveExecutable( boolean resolveExecutable )
440    {
441        this.resolveExecutable = resolveExecutable;
442    }
443 
444    public void setExecutableResolver( ExecutableResolver executableResolver )
445    {
446        this.executableResolver = executableResolver;
447    }
448 
449    public ExecutableResolver getExecutableResolver()
450    {
451        return executableResolver;
452    }
453 
454    public void setChrootJailDirectory( File chrootJailDirectory )
455    {
456        this.chrootJailDirectory = chrootJailDirectory;
457    }
458 
459    public File getChrootJailDirectory()
460    {
461        return chrootJailDirectory;
462    }
463}

[all classes][org.apache.maven.continuum.execution]
EMMA 2.0.5312 (C) Vladimir Roubtsov