Skip to content

Commit

Permalink
Add limits overriding with system properties (#112)
Browse files Browse the repository at this point in the history
  • Loading branch information
Obolrom committed Apr 28, 2024
1 parent b648663 commit 8419a80
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 2 deletions.
36 changes: 34 additions & 2 deletions lib/src/main/java/de/siegmar/fastcsv/util/Limits.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

/**
* The {@code Limits} class defines the maximum limits for various fields and records in a CSV file.
* <p>
* Example use:
* <pre>{@code
* System.setProperty("fastcsv.max.field.size", "1024");
* }</pre>
* <p>
* Or using VM options:
* <pre>{@code
* -Dfastcsv.max.field.count=1024
* }</pre>
*/
public final class Limits {

Expand All @@ -10,13 +20,13 @@ public final class Limits {
* The value is set to 16,777,216 characters (16 to 64 MiB depending on the circumstance of multibyte character
* utilization).
*/
public static final int MAX_FIELD_SIZE = 16 * 1024 * 1024;
public static final int MAX_FIELD_SIZE = getIntProperty("fastcsv.max.field.size", 16 * 1024 * 1024);

/**
* The {@code MAX_FIELDS_SIZE} constant defines the maximum number of fields per record.
* The value is set to 16,384.
*/
public static final int MAX_FIELD_COUNT = 16 * 1024;
public static final int MAX_FIELD_COUNT = getIntProperty("fastcsv.max.field.count", 16 * 1024);

/**
* The {@code MAX_RECORD_SIZE} constant defines the maximum size for all fields combined in a CSV record.
Expand All @@ -27,4 +37,26 @@ public final class Limits {
private Limits() {
}

/**
* Retrieves the system property value if presented, otherwise default value is returned.
* If the property cannot be parsed as an integer, an {@code IllegalArgumentException} is thrown.
*
* @param key The system property key.
* @param defaultValue The default value to use if the system property is not set or is invalid.
* @return The system property value as an integer or the default value if the property is not set or is invalid.
* @throws IllegalArgumentException If the system property value cannot be parsed as an integer.
*/
static int getIntProperty(final String key, final int defaultValue) {
final String value = System.getProperty(key);

if (value == null) {
return defaultValue;
}

try {
return Integer.parseInt(value);
} catch (final NumberFormatException e) {
throw new IllegalArgumentException("Invalid format for system property " + key, e);
}
}
}
69 changes: 69 additions & 0 deletions lib/src/test/java/de/siegmar/fastcsv/util/LimitsTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package de.siegmar.fastcsv.util;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;

class LimitsTest {

public static final String FASTCSV_MAX_FIELD_SIZE = "fastcsv.max.field.size";
public static final String FASTCSV_MAX_FIELD_COUNT = "fastcsv.max.field.count";

@AfterEach
void cleanup() {
System.clearProperty(FASTCSV_MAX_FIELD_SIZE);
System.clearProperty(FASTCSV_MAX_FIELD_COUNT);
}

@Test
void defaultMaxFieldSize() {
assertThat(Limits.MAX_FIELD_SIZE)
.as("Default max field size should be correct")
.isEqualTo(16 * 1024 * 1024);
}

@Test
void customMaxFieldSize() {
System.setProperty(FASTCSV_MAX_FIELD_SIZE, "100000");

assertThat(Limits.getIntProperty(FASTCSV_MAX_FIELD_SIZE, 16 * 1024 * 1024))
.as("Custom max field size should be respected")
.isEqualTo(100000);
}

@Test
void defaultMaxFieldCount() {
assertThat(Limits.MAX_FIELD_COUNT)
.as("Default max field count should be correct")
.isEqualTo(16 * 1024);
}

@Test
void customMaxFieldCount() {
System.setProperty(FASTCSV_MAX_FIELD_COUNT, "200");

assertThat(Limits.getIntProperty(FASTCSV_MAX_FIELD_COUNT, 16 * 1024))
.as("Custom max field count should be respected")
.isEqualTo(200);
}

@Test
void invalidMaxFieldSizeThrowsException() {
System.setProperty(FASTCSV_MAX_FIELD_SIZE, "invalid");

assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> Limits.getIntProperty(FASTCSV_MAX_FIELD_SIZE, 16 * 1024 * 1024))
.withMessageContaining("Invalid format for system property " + FASTCSV_MAX_FIELD_SIZE);
}

@Test
void maxRecordSizeBasedOnMaxFieldSize() {
System.setProperty(FASTCSV_MAX_FIELD_SIZE, "4000000");

assertThat(4 * Limits.getIntProperty(FASTCSV_MAX_FIELD_SIZE, 16 * 1024 * 1024))
.as("MAX_RECORD_SIZE should be four times MAX_FIELD_SIZE")
.isEqualTo(4 * 4000000);
}
}

0 comments on commit 8419a80

Please sign in to comment.