[MNG-5977] Improve output readability of our MavenTransferListener implementations

* Applied a general decimal formatter which automatically scales file sizes between [0,10) (one decimal digit) and [10,1000) (whole numbers) along with proper size and time units
* The progress meter will now properly
** tell the amount of transfers along with file names (in debug mode) and absolute progress by size
** visually seperate parallel transfers with " | "
* Optimized and reduced padding to the cases where it actually is necessary
* Padding has to be applied to every event which can succeed with progress update
* Synchronize all calls to console to avoid race conditions where output is terminated by a carriage return only. If no sync is done, SLF4J or INIT/SUCCEEDED update can interleave and overwrite the progress while being shorter as the progress itself.
* Replaced the concurrent hash map with a synchronized linked hash map to retain order of the progress meter. It will behave now like a queue.
* Work around a rounding bug existed upto Java 7
  See http://stackoverflow.com/q/22797964/696632 and Oracle's bugfix
  Announcement: http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html

Race conditions cannot be avoided if -T is employed since one does not have access to the output stream of a SLF4J backend to synchronize on.
This commit is contained in:
Michael Osipov 2016-02-18 00:28:50 +01:00 committed by Michael Osipov
parent deefd9342b
commit 149cce7a86
5 changed files with 597 additions and 89 deletions

View File

@ -1005,13 +1005,13 @@ private void configure( CliRequest cliRequest )
// present supplied by the user. The rule is that we only allow the execution of one ConfigurationProcessor.
// If there is more than one then we execute the one supplied by the user, otherwise we execute the
// the default SettingsXmlConfigurationProcessor.
//
//
int userSuppliedConfigurationProcessorCount = configurationProcessors.size() - 1;
if ( userSuppliedConfigurationProcessorCount == 0 )
{
//
// Our settings.xml source is historically how we have configured Maven from the CLI so we are going to
// Our settings.xml source is historically how we have configured Maven from the CLI so we are going to
// have to honour its existence forever. So let's run it.
//
configurationProcessors.get( SettingsXmlConfigurationProcessor.HINT ).process( cliRequest );
@ -1288,7 +1288,7 @@ else if ( request.isInteractiveMode() && !cliRequest.commandLine.hasOption( CLIM
// If we're logging to a file then we don't want the console transfer listener as it will spew
// download progress all over the place
//
transferListener = getConsoleTransferListener();
transferListener = getConsoleTransferListener( cliRequest.commandLine.hasOption( CLIManager.DEBUG ) );
}
else
{
@ -1588,9 +1588,9 @@ public ExitException( int exitCode )
// Customizations available via the CLI
//
protected TransferListener getConsoleTransferListener()
protected TransferListener getConsoleTransferListener( boolean printResourceNames )
{
return new ConsoleMavenTransferListener( System.out );
return new ConsoleMavenTransferListener( System.out, printResourceNames );
}
protected TransferListener getBatchTransferListener()

View File

@ -24,6 +24,7 @@
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import org.apache.commons.lang3.Validate;
import org.eclipse.aether.transfer.AbstractTransferListener;
import org.eclipse.aether.transfer.TransferCancelledException;
import org.eclipse.aether.transfer.TransferEvent;
@ -33,6 +34,178 @@ public abstract class AbstractMavenTransferListener
extends AbstractTransferListener
{
// CHECKSTYLE_OFF: LineLength
/**
* Formats file size with the associated <a href="https://en.wikipedia.org/wiki/Metric_prefix">SI</a> prefix
* (GB, MB, kB) and using the patterns <code>#0.0</code> for numbers between 1 and 10
* and <code>###0</code> for numbers between 10 and 1000+ by default.
*
* @see <a href="https://en.wikipedia.org/wiki/Metric_prefix">https://en.wikipedia.org/wiki/Metric_prefix</a>
* @see <a href="https://en.wikipedia.org/wiki/Binary_prefix">https://en.wikipedia.org/wiki/Binary_prefix</a>
* @see <a
* href="https://en.wikipedia.org/wiki/Octet_%28computing%29">https://en.wikipedia.org/wiki/Octet_(computing)</a>
*/
// CHECKSTYLE_ON: LineLength
// TODO Move me to Maven Shared Utils
static class FileSizeFormat
{
static enum ScaleUnit
{
BYTE
{
@Override
public long bytes()
{
return 1L;
}
@Override
public String symbol()
{
return "B";
}
},
KILOBYTE
{
@Override
public long bytes()
{
return 1000L;
}
@Override
public String symbol()
{
return "kB";
}
},
MEGABYTE
{
@Override
public long bytes()
{
return KILOBYTE.bytes() * KILOBYTE.bytes();
}
@Override
public String symbol()
{
return "MB";
}
},
GIGABYTE
{
@Override
public long bytes()
{
return MEGABYTE.bytes() * KILOBYTE.bytes();
};
@Override
public String symbol()
{
return "GB";
}
};
public abstract long bytes();
public abstract String symbol();
public static ScaleUnit getScaleUnit( long size )
{
Validate.isTrue( size >= 0L, "file size cannot be negative: %s", size );
if ( size >= GIGABYTE.bytes() )
{
return GIGABYTE;
}
else if ( size >= MEGABYTE.bytes() )
{
return MEGABYTE;
}
else if ( size >= KILOBYTE.bytes() )
{
return KILOBYTE;
}
else
{
return BYTE;
}
}
}
private DecimalFormat smallFormat;
private DecimalFormat largeFormat;
public FileSizeFormat( Locale locale )
{
smallFormat = new DecimalFormat( "#0.0", new DecimalFormatSymbols( locale ) );
largeFormat = new DecimalFormat( "###0", new DecimalFormatSymbols( locale ) );
}
public String format( long size )
{
return format( size, null );
}
public String format( long size, ScaleUnit unit )
{
return format( size, unit, false );
}
public String format( long size, ScaleUnit unit, boolean omitSymbol )
{
Validate.isTrue( size >= 0L, "file size cannot be negative: %s", size );
if ( unit == null )
{
unit = ScaleUnit.getScaleUnit( size );
}
double scaledSize = (double) size / unit.bytes();
String scaledSymbol = " " + unit.symbol();
if ( omitSymbol )
{
scaledSymbol = "";
}
if ( unit == ScaleUnit.BYTE )
{
return largeFormat.format( size ) + scaledSymbol;
}
if ( scaledSize < 0.05 || scaledSize >= 10.0 )
{
return largeFormat.format( scaledSize ) + scaledSymbol;
}
else
{
return smallFormat.format( scaledSize ) + scaledSymbol;
}
}
public String formatProgress( long progressedSize, long size )
{
Validate.isTrue( progressedSize >= 0L, "progressed file size cannot be negative: %s", progressedSize );
Validate.isTrue( size >= 0L && progressedSize <= size || size < 0L,
"progressed file size cannot be greater than size: %s > %s", progressedSize, size );
if ( size >= 0L && progressedSize != size )
{
ScaleUnit unit = ScaleUnit.getScaleUnit( size );
String formattedProgressedSize = format( progressedSize, unit, true );
String formattedSize = format( size, unit );
return formattedProgressedSize + "/" + formattedSize;
}
else
{
return format( progressedSize );
}
}
}
protected PrintStream out;
protected AbstractMavenTransferListener( PrintStream out )
@ -43,9 +216,10 @@ protected AbstractMavenTransferListener( PrintStream out )
@Override
public void transferInitiated( TransferEvent event )
{
String message = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading";
String action = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading";
out.println( message + ": " + event.getResource().getRepositoryUrl() + event.getResource().getResourceName() );
TransferResource resource = event.getResource();
out.println( action + ": " + resource.getRepositoryUrl() + resource.getResourceName() );
}
@Override
@ -53,7 +227,7 @@ public void transferCorrupted( TransferEvent event )
throws TransferCancelledException
{
TransferResource resource = event.getResource();
// TODO This needs to be colorized
out.println( "[WARNING] " + event.getException().getMessage() + " for " + resource.getRepositoryUrl()
+ resource.getResourceName() );
}
@ -63,28 +237,21 @@ public void transferSucceeded( TransferEvent event )
{
TransferResource resource = event.getResource();
long contentLength = event.getTransferredBytes();
if ( contentLength >= 0 )
FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
String result = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" );
String len = format.format( contentLength );
String throughput = "";
long duration = System.currentTimeMillis() - resource.getTransferStartTime();
if ( duration > 0L )
{
String type = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" );
String len = contentLength >= 1024 ? toKB( contentLength ) + " KB" : contentLength + " B";
String throughput = "";
long duration = System.currentTimeMillis() - resource.getTransferStartTime();
if ( duration > 0 )
{
DecimalFormat format = new DecimalFormat( "0.0", new DecimalFormatSymbols( Locale.ENGLISH ) );
double kbPerSec = ( contentLength / 1024.0 ) / ( duration / 1000.0 );
throughput = " at " + format.format( kbPerSec ) + " KB/sec";
}
out.println( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " (" + len
+ throughput + ")" );
double bytesPerSecond = contentLength / ( duration / 1000.0 );
throughput = " at " + format.format( (long) bytesPerSecond ) + "/s";
}
}
protected long toKB( long bytes )
{
return ( bytes + 1023 ) / 1024;
out.println( result + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " (" + len
+ throughput + ")" );
}
}

View File

@ -20,9 +20,13 @@
*/
import java.io.PrintStream;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.aether.transfer.TransferCancelledException;
import org.eclipse.aether.transfer.TransferEvent;
import org.eclipse.aether.transfer.TransferResource;
@ -36,32 +40,58 @@ public class ConsoleMavenTransferListener
extends AbstractMavenTransferListener
{
private Map<TransferResource, Long> downloads = new ConcurrentHashMap<>();
private Map<TransferResource, Long> transfers = Collections.synchronizedMap(
new LinkedHashMap<TransferResource, Long>() );
private boolean printResourceNames;
private int lastLength;
public ConsoleMavenTransferListener( PrintStream out )
public ConsoleMavenTransferListener( PrintStream out, boolean printResourceNames )
{
super( out );
this.printResourceNames = printResourceNames;
}
@Override
public void transferProgressed( TransferEvent event )
public synchronized void transferInitiated( TransferEvent event )
{
overridePreviousTransfer( event );
super.transferInitiated( event );
}
@Override
public synchronized void transferCorrupted( TransferEvent event )
throws TransferCancelledException
{
overridePreviousTransfer( event );
super.transferCorrupted( event );
}
@Override
public synchronized void transferProgressed( TransferEvent event )
throws TransferCancelledException
{
TransferResource resource = event.getResource();
downloads.put( resource, event.getTransferredBytes() );
transfers.put( resource, event.getTransferredBytes() );
StringBuilder buffer = new StringBuilder( 64 );
StringBuilder buffer = new StringBuilder( 128 );
buffer.append( "Progress (" ).append( transfers.size() ).append( "): " );
for ( Map.Entry<TransferResource, Long> entry : downloads.entrySet() )
synchronized ( transfers )
{
long total = entry.getKey().getContentLength();
Long complete = entry.getValue();
// NOTE: This null check guards against http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6312056
if ( complete != null )
Iterator<Map.Entry<TransferResource, Long>> entries = transfers.entrySet().iterator();
while ( entries.hasNext() )
{
buffer.append( getStatus( complete, total ) ).append( " " );
Map.Entry<TransferResource, Long> entry = entries.next();
long total = entry.getKey().getContentLength();
Long complete = entry.getValue();
buffer.append( getStatus( entry.getKey().getResourceName(), complete, total ) );
if ( entries.hasNext() )
{
buffer.append( " | " );
}
}
}
@ -69,28 +99,29 @@ public void transferProgressed( TransferEvent event )
lastLength = buffer.length();
pad( buffer, pad );
buffer.append( '\r' );
out.print( buffer.toString() );
out.print( buffer );
out.flush();
}
private String getStatus( long complete, long total )
private String getStatus( String resourceName, long complete, long total )
{
if ( total >= 1024 )
FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
StringBuilder status = new StringBuilder();
if ( printResourceNames )
{
return toKB( complete ) + "/" + toKB( total ) + " KB ";
status.append( StringUtils.substringAfterLast( resourceName, "/" ) );
status.append( " (" );
}
else if ( total >= 0 )
status.append( format.formatProgress( complete, total ) );
if ( printResourceNames )
{
return complete + "/" + total + " B ";
}
else if ( complete >= 1024 )
{
return toKB( complete ) + " KB ";
}
else
{
return complete + " B ";
status.append( ")" );
}
return status.toString();
}
private void pad( StringBuilder buffer, int spaces )
@ -105,29 +136,34 @@ private void pad( StringBuilder buffer, int spaces )
}
@Override
public void transferSucceeded( TransferEvent event )
public synchronized void transferSucceeded( TransferEvent event )
{
transferCompleted( event );
transfers.remove( event.getResource() );
overridePreviousTransfer( event );
super.transferSucceeded( event );
}
@Override
public void transferFailed( TransferEvent event )
public synchronized void transferFailed( TransferEvent event )
{
transferCompleted( event );
transfers.remove( event.getResource() );
overridePreviousTransfer( event );
super.transferFailed( event );
}
private void transferCompleted( TransferEvent event )
private void overridePreviousTransfer( TransferEvent event )
{
downloads.remove( event.getResource() );
StringBuilder buffer = new StringBuilder( 64 );
pad( buffer, lastLength );
buffer.append( '\r' );
out.print( buffer.toString() );
if ( lastLength > 0 )
{
StringBuilder buffer = new StringBuilder( 128 );
pad( buffer, lastLength );
buffer.append( '\r' );
out.print( buffer );
out.flush();
lastLength = 0;
}
}
}

View File

@ -19,10 +19,9 @@
* under the License.
*/
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import org.apache.maven.cli.transfer.AbstractMavenTransferListener.FileSizeFormat;
import org.eclipse.aether.transfer.AbstractTransferListener;
import org.eclipse.aether.transfer.TransferCancelledException;
import org.eclipse.aether.transfer.TransferEvent;
@ -50,9 +49,10 @@ public Slf4jMavenTransferListener( Logger out )
@Override
public void transferInitiated( TransferEvent event )
{
String message = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading";
String action = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading";
out.info( message + ": " + event.getResource().getRepositoryUrl() + event.getResource().getResourceName() );
TransferResource resource = event.getResource();
out.info( action + ": " + resource.getRepositoryUrl() + resource.getResourceName() );
}
@Override
@ -60,7 +60,6 @@ public void transferCorrupted( TransferEvent event )
throws TransferCancelledException
{
TransferResource resource = event.getResource();
out.warn( event.getException().getMessage() + " for " + resource.getRepositoryUrl()
+ resource.getResourceName() );
}
@ -70,28 +69,21 @@ public void transferSucceeded( TransferEvent event )
{
TransferResource resource = event.getResource();
long contentLength = event.getTransferredBytes();
if ( contentLength >= 0 )
FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
String result = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" );
String len = format.format( contentLength );
String throughput = "";
long duration = System.currentTimeMillis() - resource.getTransferStartTime();
if ( duration > 0L )
{
String type = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" );
String len = contentLength >= 1024 ? toKB( contentLength ) + " KB" : contentLength + " B";
String throughput = "";
long duration = System.currentTimeMillis() - resource.getTransferStartTime();
if ( duration > 0 )
{
DecimalFormat format = new DecimalFormat( "0.0", new DecimalFormatSymbols( Locale.ENGLISH ) );
double kbPerSec = ( contentLength / 1024.0 ) / ( duration / 1000.0 );
throughput = " at " + format.format( kbPerSec ) + " KB/sec";
}
out.info( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " (" + len
+ throughput + ")" );
double bytesPerSecond = contentLength / ( duration / 1000.0 );
throughput = " at " + format.format( (long) bytesPerSecond ) + "/s";
}
}
protected long toKB( long bytes )
{
return ( bytes + 1023 ) / 1024;
out.info( result + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " (" + len
+ throughput + ")" );
}
}

View File

@ -0,0 +1,313 @@
package org.apache.maven.cli.transfer;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import java.util.Locale;
import org.apache.commons.lang3.JavaVersion;
import org.apache.commons.lang3.SystemUtils;
import org.apache.maven.cli.transfer.AbstractMavenTransferListener.FileSizeFormat;
import org.apache.maven.cli.transfer.AbstractMavenTransferListener.FileSizeFormat.ScaleUnit;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class FileSizeFormatTest {
@Test( expected = IllegalArgumentException.class )
public void testNegativeSize()
{
FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
long negativeSize = -100L;
format.format( negativeSize );
}
@Test
public void testSize()
{
FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
long _0_bytes = 0L;
assertEquals( "0 B", format.format( _0_bytes ) );
long _5_bytes = 5L;
assertEquals( "5 B", format.format( _5_bytes ) );
long _10_bytes = 10L;
assertEquals( "10 B", format.format( _10_bytes ) );
long _15_bytes = 15L;
assertEquals( "15 B", format.format( _15_bytes ) );
long _999_bytes = 999L;
assertEquals( "999 B", format.format( _999_bytes ) );
long _1000_bytes = 1000L;
assertEquals( "1.0 kB", format.format( _1000_bytes ) );
long _5500_bytes = 5500L;
assertEquals( "5.5 kB", format.format( _5500_bytes ) );
long _10_kilobytes = 10L * 1000L;
assertEquals( "10 kB", format.format( _10_kilobytes ) );
long _15_kilobytes = 15L * 1000L;
assertEquals( "15 kB", format.format( _15_kilobytes ) );
long _999_kilobytes = 999L * 1000L;
assertEquals( "999 kB", format.format( _999_kilobytes ) );
long _1000_kilobytes = 1000L * 1000L;
assertEquals( "1.0 MB", format.format( _1000_kilobytes ) );
long _5500_kilobytes = 5500L * 1000L;
assertEquals( "5.5 MB", format.format( _5500_kilobytes ) );
long _10_megabytes = 10L * 1000L * 1000L;
assertEquals( "10 MB", format.format( _10_megabytes ) );
long _15_megabytes = 15L * 1000L * 1000L;
assertEquals( "15 MB", format.format( _15_megabytes ) );
long _999_megabytes = 999L * 1000L * 1000L;
assertEquals( "999 MB", format.format( _999_megabytes ) );
long _1000_megabytes = 1000L * 1000L * 1000L;
assertEquals( "1.0 GB", format.format( _1000_megabytes ) );
long _5500_megabytes = 5500L * 1000L * 1000L;
assertEquals( "5.5 GB", format.format( _5500_megabytes ) );
long _10_gigabytes = 10L * 1000L * 1000L * 1000L;
assertEquals( "10 GB", format.format( _10_gigabytes ) );
long _15_gigabytes = 15L * 1000L * 1000L * 1000L;
assertEquals( "15 GB", format.format( _15_gigabytes ) );
long _1000_gigabytes = 1000L * 1000L * 1000L * 1000L;
assertEquals( "1000 GB", format.format( _1000_gigabytes ) );
}
@Test
public void testSizeWithSelectedScaleUnit()
{
FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
long _0_bytes = 0L;
assertEquals( "0 B", format.format( _0_bytes ) );
assertEquals( "0 B", format.format( _0_bytes, ScaleUnit.BYTE ) );
assertEquals( "0 kB", format.format( _0_bytes, ScaleUnit.KILOBYTE ) );
assertEquals( "0 MB", format.format( _0_bytes, ScaleUnit.MEGABYTE ) );
assertEquals( "0 GB", format.format( _0_bytes, ScaleUnit.GIGABYTE ) );
long _5_bytes = 5L;
assertEquals( "5 B", format.format( _5_bytes ) );
assertEquals( "5 B", format.format( _5_bytes, ScaleUnit.BYTE ) );
assertEquals( "0 kB", format.format( _5_bytes, ScaleUnit.KILOBYTE ) );
assertEquals( "0 MB", format.format( _5_bytes, ScaleUnit.MEGABYTE ) );
assertEquals( "0 GB", format.format( _5_bytes, ScaleUnit.GIGABYTE ) );
long _49_bytes = 49L;
assertEquals( "49 B", format.format( _49_bytes ) );
assertEquals( "49 B", format.format( _49_bytes, ScaleUnit.BYTE ) );
assertEquals( "0 kB", format.format( _49_bytes, ScaleUnit.KILOBYTE ) );
assertEquals( "0 MB", format.format( _49_bytes, ScaleUnit.MEGABYTE ) );
assertEquals( "0 GB", format.format( _49_bytes, ScaleUnit.GIGABYTE ) );
long _50_bytes = 50L;
assertEquals( "50 B", format.format( _50_bytes ) );
assertEquals( "50 B", format.format( _50_bytes, ScaleUnit.BYTE ) );
if ( SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) )
{
assertEquals( "0.1 kB", format.format( _50_bytes, ScaleUnit.KILOBYTE ) );
}
assertEquals( "0 MB", format.format( _50_bytes, ScaleUnit.MEGABYTE ) );
assertEquals( "0 GB", format.format( _50_bytes, ScaleUnit.GIGABYTE ) );
long _999_bytes = 999L;
assertEquals( "999 B", format.format( _999_bytes ) );
assertEquals( "999 B", format.format( _999_bytes, ScaleUnit.BYTE ) );
assertEquals( "1.0 kB", format.format( _999_bytes, ScaleUnit.KILOBYTE ) );
assertEquals( "0 MB", format.format( _999_bytes, ScaleUnit.MEGABYTE ) );
assertEquals( "0 GB", format.format( _999_bytes, ScaleUnit.GIGABYTE ) );
long _1000_bytes = 1000L;
assertEquals( "1.0 kB", format.format( _1000_bytes ) );
assertEquals( "1000 B", format.format( _1000_bytes, ScaleUnit.BYTE ) );
assertEquals( "1.0 kB", format.format( _1000_bytes, ScaleUnit.KILOBYTE ) );
assertEquals( "0 MB", format.format( _1000_bytes, ScaleUnit.MEGABYTE ) );
assertEquals( "0 GB", format.format( _1000_bytes, ScaleUnit.GIGABYTE ) );
long _49_kilobytes = 49L * 1000L;
assertEquals( "49 kB", format.format( _49_kilobytes ) );
assertEquals( "49000 B", format.format( _49_kilobytes, ScaleUnit.BYTE ) );
assertEquals( "49 kB", format.format( _49_kilobytes, ScaleUnit.KILOBYTE ) );
assertEquals( "0 MB", format.format( _49_kilobytes, ScaleUnit.MEGABYTE ) );
assertEquals( "0 GB", format.format( _49_kilobytes, ScaleUnit.GIGABYTE ) );
long _50_kilobytes = 50L * 1000L;
assertEquals( "50 kB", format.format( _50_kilobytes ) );
assertEquals( "50000 B", format.format( _50_kilobytes, ScaleUnit.BYTE ) );
assertEquals( "50 kB", format.format( _50_kilobytes, ScaleUnit.KILOBYTE ) );
if ( SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) )
{
assertEquals( "0.1 MB", format.format( _50_kilobytes, ScaleUnit.MEGABYTE ) );
}
assertEquals( "0 GB", format.format( _50_kilobytes, ScaleUnit.GIGABYTE ) );
long _999_kilobytes = 999L * 1000L;
assertEquals( "999 kB", format.format( _999_kilobytes ) );
assertEquals( "999000 B", format.format( _999_kilobytes, ScaleUnit.BYTE ) );
assertEquals( "999 kB", format.format( _999_kilobytes, ScaleUnit.KILOBYTE ) );
assertEquals( "1.0 MB", format.format( _999_kilobytes, ScaleUnit.MEGABYTE ) );
assertEquals( "0 GB", format.format( _999_kilobytes, ScaleUnit.GIGABYTE ) );
long _1000_kilobytes = 1000L * 1000L;
assertEquals( "1.0 MB", format.format( _1000_kilobytes ) );
assertEquals( "1000000 B", format.format( _1000_kilobytes, ScaleUnit.BYTE ) );
assertEquals( "1000 kB", format.format( _1000_kilobytes, ScaleUnit.KILOBYTE ) );
assertEquals( "1.0 MB", format.format( _1000_kilobytes, ScaleUnit.MEGABYTE ) );
assertEquals( "0 GB", format.format( _1000_kilobytes, ScaleUnit.GIGABYTE ) );
long _49_megabytes = 49L * 1000L * 1000L;
assertEquals( "49 MB", format.format( _49_megabytes ) );
assertEquals( "49000000 B", format.format( _49_megabytes, ScaleUnit.BYTE ) );
assertEquals( "49000 kB", format.format( _49_megabytes, ScaleUnit.KILOBYTE ) );
assertEquals( "49 MB", format.format( _49_megabytes, ScaleUnit.MEGABYTE ) );
assertEquals( "0 GB", format.format( _49_megabytes, ScaleUnit.GIGABYTE ) );
long _50_megabytes = 50L * 1000L * 1000L;
assertEquals( "50 MB", format.format( _50_megabytes ) );
assertEquals( "50000000 B", format.format( _50_megabytes, ScaleUnit.BYTE ) );
assertEquals( "50000 kB", format.format( _50_megabytes, ScaleUnit.KILOBYTE ) );
assertEquals( "50 MB", format.format( _50_megabytes, ScaleUnit.MEGABYTE ) );
if ( SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) )
{
assertEquals( "0.1 GB", format.format( _50_megabytes, ScaleUnit.GIGABYTE ) );
}
long _999_megabytes = 999L * 1000L * 1000L;
assertEquals( "999 MB", format.format( _999_megabytes ) );
assertEquals( "999000000 B", format.format( _999_megabytes, ScaleUnit.BYTE ) );
assertEquals( "999000 kB", format.format( _999_megabytes, ScaleUnit.KILOBYTE ) );
assertEquals( "999 MB", format.format( _999_megabytes, ScaleUnit.MEGABYTE ) );
assertEquals( "1.0 GB", format.format( _999_megabytes, ScaleUnit.GIGABYTE ) );
long _1000_megabytes = 1000L * 1000L * 1000L;
assertEquals( "1.0 GB", format.format( _1000_megabytes ) );
assertEquals( "1000000000 B", format.format( _1000_megabytes, ScaleUnit.BYTE ) );
assertEquals( "1000000 kB", format.format( _1000_megabytes, ScaleUnit.KILOBYTE ) );
assertEquals( "1000 MB", format.format( _1000_megabytes, ScaleUnit.MEGABYTE ) );
assertEquals( "1.0 GB", format.format( _1000_megabytes, ScaleUnit.GIGABYTE ) );
}
@Test( expected = IllegalArgumentException.class )
public void testNegativeProgessedSize()
{
FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
long negativeProgessedSize = -100L;
format.formatProgress( negativeProgessedSize, 10L );
}
@Test( expected = IllegalArgumentException.class )
public void testNegativeProgessedSizeBiggerThanSize()
{
FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
format.formatProgress( 100L, 10L );
}
@Test
public void testProgressedSizeWithoutSize()
{
FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
long _0_bytes = 0L;
assertEquals( "0 B", format.formatProgress( _0_bytes, -1L ) );
long _1000_bytes = 1000L;
assertEquals( "1.0 kB", format.formatProgress( _1000_bytes, -1L ) );
long _1000_kilobytes = 1000L * 1000L;
assertEquals( "1.0 MB", format.formatProgress( _1000_kilobytes, -1L ) );
long _1000_megabytes = 1000L * 1000L * 1000L;
assertEquals( "1.0 GB", format.formatProgress( _1000_megabytes, -1L ) );
}
@Test
public void testProgressedBothZero()
{
FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
long _0_bytes = 0L;
assertEquals( "0 B", format.formatProgress( _0_bytes, _0_bytes ) );
}
@Test
public void testProgressedSizeWithSize()
{
FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH );
long _0_bytes = 0L;
long _400_bytes = 400L;
long _800_bytes = 2L * _400_bytes;
assertEquals( "0/800 B", format.formatProgress( _0_bytes, _800_bytes ) );
assertEquals( "400/800 B", format.formatProgress( _400_bytes, _800_bytes ) );
assertEquals( "800 B", format.formatProgress( _800_bytes, _800_bytes ) );
long _4000_bytes = 4000L;
long _8000_bytes = 2L * _4000_bytes;
long _50_kilobytes = 50000L;
assertEquals( "0/8.0 kB", format.formatProgress( _0_bytes, _8000_bytes ) );
assertEquals( "0.4/8.0 kB", format.formatProgress( _400_bytes, _8000_bytes ) );
assertEquals( "4.0/8.0 kB", format.formatProgress( _4000_bytes, _8000_bytes ) );
assertEquals( "8.0 kB", format.formatProgress( _8000_bytes, _8000_bytes ) );
assertEquals( "8.0/50 kB", format.formatProgress( _8000_bytes, _50_kilobytes ) );
assertEquals( "16/50 kB", format.formatProgress( 2L * _8000_bytes, _50_kilobytes ) );
assertEquals( "50 kB", format.formatProgress( _50_kilobytes, _50_kilobytes ) );
long _500_kilobytes = 500000L;
long _1000_kilobytes = 2L * _500_kilobytes;;
long _5000_kilobytes = 5L * _1000_kilobytes;
long _15_megabytes = 3L * _5000_kilobytes;
assertEquals( "0/5.0 MB", format.formatProgress( _0_bytes, _5000_kilobytes ) );
assertEquals( "0.5/5.0 MB", format.formatProgress( _500_kilobytes, _5000_kilobytes ) );
assertEquals( "1.0/5.0 MB", format.formatProgress( _1000_kilobytes, _5000_kilobytes ) );
assertEquals( "5.0 MB", format.formatProgress( _5000_kilobytes, _5000_kilobytes ) );
assertEquals( "5.0/15 MB", format.formatProgress( _5000_kilobytes, _15_megabytes ) );
assertEquals( "15 MB", format.formatProgress( _15_megabytes, _15_megabytes ) );
long _500_megabytes = 500000000L;
long _1000_megabytes = 2L * _500_megabytes;
long _5000_megabytes = 5L * _1000_megabytes;
long _15_gigabytes = 3L * _5000_megabytes;
assertEquals( "0/500 MB", format.formatProgress( _0_bytes, _500_megabytes ) );
assertEquals( "1.0/5.0 GB", format.formatProgress( _1000_megabytes, _5000_megabytes ) );
assertEquals( "5.0 GB", format.formatProgress( _5000_megabytes, _5000_megabytes ) );
assertEquals( "5.0/15 GB", format.formatProgress( _5000_megabytes, _15_gigabytes ) );
assertEquals( "15 GB", format.formatProgress( _15_gigabytes, _15_gigabytes ) );
}
}