/**
* Copyright (c) 2008-2011 Sonatype, Inc.
* All rights reserved. Includes the third-party code listed at http://www.sonatype.com/products/nexus/attributions.
*
* This program is free software: you can redistribute it and/or modify it only under the terms of the GNU Affero General
* Public License Version 3 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License Version 3
* for more details.
*
* You should have received a copy of the GNU Affero General Public License Version 3 along with this program. If not, see
* http://www.gnu.org/licenses.
*
* Sonatype Nexus (TM) Open Source Version is available from Sonatype, Inc. Sonatype and Sonatype Nexus are trademarks of
* Sonatype, Inc. Apache Maven is a trademark of the Apache Foundation. M2Eclipse is a trademark of the Eclipse Foundation.
* All other trademarks are the property of their respective owners.
*/
package org.sonatype.nexus.error.reporting;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import junit.framework.Assert;
import org.codehaus.plexus.swizzle.IssueSubmissionRequest;
import org.codehaus.plexus.util.ExceptionUtils;
import org.codehaus.swizzle.jira.Issue;
import org.sonatype.configuration.ConfigurationException;
import org.sonatype.nexus.AbstractNexusTestCase;
import org.sonatype.nexus.configuration.application.NexusConfiguration;
import org.sonatype.nexus.proxy.repository.RemoteProxySettings;
import org.sonatype.nexus.proxy.repository.UsernamePasswordRemoteAuthenticationSettings;
import org.sonatype.nexus.scheduling.NexusTask;
import org.sonatype.nexus.util.StringDigester;
import org.sonatype.scheduling.SchedulerTask;
public class DefaultErrorReportingManagerTest
extends AbstractNexusTestCase
{
private DefaultErrorReportingManager manager;
private NexusConfiguration nexusConfig;
private File unzipHomeDir = null;
@Override
protected void setUp()
throws Exception
{
super.setUp();
unzipHomeDir = new File( getPlexusHomeDir(), "unzip" );
unzipHomeDir.mkdirs();
nexusConfig = lookup( NexusConfiguration.class );
manager = (DefaultErrorReportingManager) lookup( ErrorReportingManager.class );
}
@Override
protected void tearDown()
throws Exception
{
super.tearDown();
cleanDir( unzipHomeDir );
}
private void enableErrorReports( boolean useProxy )
throws ConfigurationException, IOException
{
manager.setEnabled( true );
manager.setJIRAUrl( "https://issues.sonatype.org" );
manager.setJIRAProject( "SBOX" );
// manager.setJIRAUsername( "********" );
// manager.setJIRAPassword( "********" );
manager.setUseGlobalProxy( useProxy );
nexusConfig.saveConfiguration();
}
private void enableProxy()
throws ConfigurationException, IOException
{
RemoteProxySettings proxy = nexusConfig.getGlobalRemoteStorageContext().getRemoteProxySettings();
proxy.setHostname( "localhost" );
proxy.setPort( 8111 );
proxy.setProxyAuthentication( new UsernamePasswordRemoteAuthenticationSettings( "*****", "*****" ) );
nexusConfig.saveConfiguration();
}
public void testJiraAccess()
throws Exception
{
// enableProxy();
enableErrorReports( false );
ErrorReportRequest request = new ErrorReportRequest();
try
{
throw new Exception( "Test exception " + Long.toHexString( System.currentTimeMillis() ) );
}
catch ( Exception e )
{
request.setThrowable( e );
}
// First make sure item doesn't already exist
List<Issue> issues =
manager.retrieveIssues( "APR: " + request.getThrowable().getMessage(), manager.getValidJIRAUsername(),
manager.getValidJIRAPassword() );
Assert.assertNull( issues );
manager.handleError( request );
issues =
manager.retrieveIssues( "APR: " + request.getThrowable().getMessage(), manager.getValidJIRAUsername(),
manager.getValidJIRAPassword() );
Assert.assertEquals( 1, issues.size() );
manager.handleError( request );
issues =
manager.retrieveIssues( "APR: " + request.getThrowable().getMessage(), manager.getValidJIRAUsername(),
manager.getValidJIRAPassword() );
Assert.assertEquals( 1, issues.size() );
}
public void testPackageFiles()
throws Exception
{
addBackupFiles( getConfHomeDir() );
addDirectory( "test-directory", new String[] {"filename1.file", "filename2.file", "filename3.file"} );
addDirectory( "nested-test-directory/more-nested-test-directory", new String[] { "filename1.file", "filename2.file", "filename3.file" } );
Exception exception;
try
{
throw new Exception( "Test exception" );
}
catch ( Exception e )
{
exception = e;
}
manager.setEnabled( true );
manager.setJIRAProject( "NEXUS" );
nexusConfiguration.saveConfiguration();
ErrorReportRequest request = new ErrorReportRequest();
request.setThrowable( exception );
IssueSubmissionRequest subRequest =
manager.buildRequest( request, manager.getValidJIRAUsername(), manager.isUseGlobalProxy() );
assertEquals( "NEXUS", subRequest.getProjectId() );
assertEquals( "APR: Test exception", subRequest.getSummary() );
assertEquals( "The following exception occurred: " + StringDigester.LINE_SEPERATOR
+ ExceptionUtils.getFullStackTrace( exception ), subRequest.getDescription() );
assertNotNull( subRequest.getProblemReportBundle() );
extractZipFile( subRequest.getProblemReportBundle(), unzipHomeDir );
assertTrue( unzipHomeDir.exists() );
File[] files = unzipHomeDir.listFiles();
assertNotNull( files );
assertEquals( 6, files.length ); // TODO: was seven with the directory listing, but that was removed, as it OOM'd
files = unzipHomeDir.listFiles( new FileFilter(){
public boolean accept( File pathname )
{
if ( pathname.isDirectory()
&& pathname.getName().equals( "test-directory" ) )
{
return true;
}
return false;
}
});
assertEquals( 1, files.length );
files = files[0].listFiles();
boolean file1found = false;
boolean file2found = false;
boolean file3found = false;
for ( File file : files )
{
if ( file.getName().equals( "filename1.file" ) )
{
file1found = true;
}
else if ( file.getName().equals( "filename2.file" ) )
{
file2found = true;
}
else if ( file.getName().equals( "filename3.file" ) )
{
file3found = true;
}
}
assertTrue( file1found && file2found && file3found );
files = unzipHomeDir.listFiles( new FileFilter(){
public boolean accept( File pathname )
{
if ( pathname.isDirectory()
&& pathname.getName().equals( "nested-test-directory" ) )
{
return true;
}
return false;
}
});
files = files[0].listFiles( new FileFilter(){
public boolean accept( File pathname )
{
if ( pathname.isDirectory()
&& pathname.getName().equals( "more-nested-test-directory" ) )
{
return true;
}
return false;
}
});
files = files[0].listFiles();
file1found = false;
file2found = false;
file3found = false;
for ( File file : files )
{
if ( file.getName().equals( "filename1.file" ) )
{
file1found = true;
}
else if ( file.getName().equals( "filename2.file" ) )
{
file2found = true;
}
else if ( file.getName().equals( "filename3.file" ) )
{
file3found = true;
}
}
assertTrue( file1found && file2found && file3found );
}
private void addBackupFiles( File dir )
throws Exception
{
new File( dir, "nexus.xml.bak" ).createNewFile();
new File( dir, "security.xml.bak" ).createNewFile();
}
private void addDirectory( String path, String[] filenames )
throws Exception
{
File confDir = new File( getConfHomeDir(), path );
File unzipDir = new File( unzipHomeDir, path );
confDir.mkdirs();
unzipDir.mkdirs();
for ( String filename : filenames ){
new File( confDir, filename ).createNewFile();
}
}
private void extractZipFile( File zipFile, File outputDirectory )
throws Exception
{
FileInputStream fis = new FileInputStream( zipFile );
ZipInputStream zin = null;
try
{
zin = new ZipInputStream( new BufferedInputStream( fis ) );
ZipEntry entry;
while ( ( entry = zin.getNextEntry() ) != null )
{
FileOutputStream fos = new FileOutputStream( new File( outputDirectory, entry.getName() ) );
BufferedOutputStream bos = null;
try
{
byte[] buffer = new byte[2048];
bos = new BufferedOutputStream( fos, 2048 );
int count;
while ( ( count = zin.read( buffer, 0, buffer.length ) ) != -1 )
{
bos.write( buffer, 0, count );
}
}
finally
{
if ( bos != null )
{
bos.close();
}
}
}
}
finally
{
if ( zin != null )
{
zin.close();
}
}
}
public void testTaskFailure()
throws Exception
{
enableErrorReports( false );
String msg = "Runtime exception " + Long.toHexString( System.currentTimeMillis() );
ExceptionTask task = (ExceptionTask) lookup( SchedulerTask.class, "ExceptionTask" );
task.setMessage( msg );
// First make sure item doesn't already exist
List<Issue> issues =
manager.retrieveIssues( "APR: " + new RuntimeException( msg ).getMessage(), manager.getValidJIRAUsername(),
manager.getValidJIRAPassword() );
Assert.assertNull( issues );
doCall( task );
issues =
manager.retrieveIssues( "APR: " + new RuntimeException( msg ).getMessage(), manager.getValidJIRAUsername(),
manager.getValidJIRAPassword() );
Assert.assertEquals( 1, issues.size() );
doCall( task );
issues =
manager.retrieveIssues( "APR: " + new RuntimeException( msg ).getMessage(), manager.getValidJIRAUsername(),
manager.getValidJIRAPassword() );
Assert.assertEquals( 1, issues.size() );
}
private void doCall( NexusTask<?> task )
{
try
{
task.call();
Thread.sleep( 100 );
}
catch ( Throwable t )
{
}
}
}