[MNG-8436] Fix wrong transfer rates displayed in console (#1985)

```
Downloaded from central: https://repo.maven.apache.org/maven2/org/graalvm/compiler/compiler/24.1.1/compiler-24.1.1.pom (1.7 kB at 9223372036854775807 GB/s)
```

---

https://issues.apache.org/jira/browse/MNG-8436
This commit is contained in:
Guillaume Nodet 2024-12-17 10:57:01 +01:00 committed by GitHub
parent 99777ace02
commit 698614e3cc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 70 additions and 17 deletions

View File

@ -20,6 +20,7 @@ package org.apache.maven.cling.transfer;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.time.Duration; import java.time.Duration;
import java.util.concurrent.TimeUnit;
import org.apache.maven.api.MonotonicClock; import org.apache.maven.api.MonotonicClock;
import org.apache.maven.api.services.MessageBuilder; import org.apache.maven.api.services.MessageBuilder;
@ -83,8 +84,10 @@ public abstract class AbstractMavenTransferListener extends AbstractTransferList
message.style(STYLE).append(" (").append(format.format(contentLength)); message.style(STYLE).append(" (").append(format.format(contentLength));
Duration duration = Duration.between(resource.getStartTime(), MonotonicClock.now()); Duration duration = Duration.between(resource.getStartTime(), MonotonicClock.now());
if ((duration.getSeconds() | duration.getNano()) > 0) { // duration.isPositive() long nanos = duration.toNanos();
double bytesPerSecond = contentLength / (double) duration.toSeconds(); if (nanos > 0) {
double seconds = nanos / (double) TimeUnit.SECONDS.toNanos(1); // Convert to fractional seconds
double bytesPerSecond = contentLength / seconds;
message.append(" at "); message.append(" at ");
format.formatRate(message, bytesPerSecond); format.formatRate(message, bytesPerSecond);
} }

View File

@ -153,19 +153,16 @@ public class FileSizeFormat {
} }
public void formatRate(MessageBuilder builder, double rate) { public void formatRate(MessageBuilder builder, double rate) {
// Handle invalid rates gracefully (including negative values)
if (Double.isNaN(rate) || Double.isInfinite(rate) || rate < 0) {
builder.append("? B/s");
return;
}
ScaleUnit unit = ScaleUnit.getScaleUnit(Math.round(rate)); ScaleUnit unit = ScaleUnit.getScaleUnit(Math.round(rate));
double scaledRate = rate / unit.bytes(); double scaledRate = rate / unit.bytes();
if (unit == ScaleUnit.BYTE || scaledRate < 0.05d || scaledRate >= 10.0d) { builder.append(String.format("%.1f", scaledRate));
builder.append(Long.toString(Math.round(scaledRate))); builder.append(" ").append(unit.symbol()).append("/s");
} else {
builder.append(Double.toString(Math.round(scaledRate * 10d) / 10d));
}
if (unit == ScaleUnit.BYTE) {
builder.append(" B");
} else {
builder.append(" ").append(unit.symbol());
}
builder.append("/s");
} }
private void format(MessageBuilder builder, long size, ScaleUnit unit, boolean omitSymbol) { private void format(MessageBuilder builder, long size, ScaleUnit unit, boolean omitSymbol) {

View File

@ -296,7 +296,7 @@ class FileSizeFormatTest {
// Test bytes per second // Test bytes per second
MessageBuilder builder = new DefaultMessageBuilder(); MessageBuilder builder = new DefaultMessageBuilder();
format.formatRate(builder, 5.0); format.formatRate(builder, 5.0);
assertEquals("5 B/s", builder.build()); assertEquals("5.0 B/s", builder.build());
// Test kilobytes per second // Test kilobytes per second
builder = new DefaultMessageBuilder(); builder = new DefaultMessageBuilder();
@ -319,19 +319,33 @@ class FileSizeFormatTest {
FileSizeFormat format = new FileSizeFormat(); FileSizeFormat format = new FileSizeFormat();
// Test value less than 0.05 // Test value less than 0.05
// Test exact unit thresholds
MessageBuilder builder = new DefaultMessageBuilder(); MessageBuilder builder = new DefaultMessageBuilder();
format.formatRate(builder, 45.0); // 45 B/s format.formatRate(builder, 45.0); // 45 B/s
assertEquals("45 B/s", builder.build()); assertEquals("45.0 B/s", builder.build());
// Test value greater than or equal to 10 // Test value greater than or equal to 10
builder = new DefaultMessageBuilder(); builder = new DefaultMessageBuilder();
format.formatRate(builder, 15000.0); // 15 kB/s format.formatRate(builder, 15000.0); // 15 kB/s
assertEquals("15 kB/s", builder.build()); assertEquals("15.0 kB/s", builder.build());
// Test value between 0.05 and 10 // Test value between 0.05 and 10
builder = new DefaultMessageBuilder(); builder = new DefaultMessageBuilder();
format.formatRate(builder, 5500.0); // 5.5 kB/s format.formatRate(builder, 5500.0); // 5.5 kB/s
assertEquals("5.5 kB/s", builder.build()); assertEquals("5.5 kB/s", builder.build());
// Test exact unit thresholds
builder = new DefaultMessageBuilder();
format.formatRate(builder, 1000.0); // 1 kB/s
assertEquals("1.0 kB/s", builder.build());
builder = new DefaultMessageBuilder();
format.formatRate(builder, 1000000.0); // 1 MB/s
assertEquals("1.0 MB/s", builder.build());
builder = new DefaultMessageBuilder();
format.formatRate(builder, 1000000000.0); // 1 GB/s
assertEquals("1.0 GB/s", builder.build());
} }
@Test @Test
@ -341,7 +355,7 @@ class FileSizeFormatTest {
// Test zero rate // Test zero rate
MessageBuilder builder = new DefaultMessageBuilder(); MessageBuilder builder = new DefaultMessageBuilder();
format.formatRate(builder, 0.0); format.formatRate(builder, 0.0);
assertEquals("0 B/s", builder.build()); assertEquals("0.0 B/s", builder.build());
// Test rate at exactly 1000 (1 kB/s) // Test rate at exactly 1000 (1 kB/s)
builder = new DefaultMessageBuilder(); builder = new DefaultMessageBuilder();
@ -353,4 +367,43 @@ class FileSizeFormatTest {
format.formatRate(builder, 1000000.0); format.formatRate(builder, 1000000.0);
assertEquals("1.0 MB/s", builder.build()); assertEquals("1.0 MB/s", builder.build());
} }
@Test
void testFormatRateLargeValues() {
FileSizeFormat format = new FileSizeFormat();
// Test large but valid rates
MessageBuilder builder = new DefaultMessageBuilder();
format.formatRate(builder, 5e12); // 5 TB/s
assertEquals("5000.0 GB/s", builder.build());
// Test very large rate
builder = new DefaultMessageBuilder();
format.formatRate(builder, 1e15); // 1 PB/s
assertEquals("1000000.0 GB/s", builder.build());
}
@Test
void testFormatRateInvalidValues() {
FileSizeFormat format = new FileSizeFormat();
// Test negative rate
MessageBuilder builder = new DefaultMessageBuilder();
format.formatRate(builder, -1.0);
assertEquals("? B/s", builder.build());
// Test NaN
builder = new DefaultMessageBuilder();
format.formatRate(builder, Double.NaN);
assertEquals("? B/s", builder.build());
// Test Infinity
builder = new DefaultMessageBuilder();
format.formatRate(builder, Double.POSITIVE_INFINITY);
assertEquals("? B/s", builder.build());
builder = new DefaultMessageBuilder();
format.formatRate(builder, Double.NEGATIVE_INFINITY);
assertEquals("? B/s", builder.build());
}
} }