Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
ea9f8ee
KAFKA-10401; Ensure `currentStateTimeStamp` is set correctly by group…
showuon Sep 21, 2020
ef0f2d9
KAFKA-9584: Fix Headers ConcurrentModificationException in Streams (#…
MicahRam Sep 28, 2020
a8e49ef
MINOR: add task ':streams:testAll' (#9073)
vvcephei Jul 24, 2020
8ac397b
KAFKA-10218: Stop reading config topic in every subsequent tick if ca…
C0urante Sep 28, 2020
f716986
Backport Jenkinsfile to 2.5 (#9327)
mumrah Oct 1, 2020
94fd8ff
KAFKA-10477: Fix JsonConverter regression to treat MISSING nodes as N…
shaikzakiriitm Oct 2, 2020
d2c332a
KAFKA-10531: Check for negative values to Thread.sleep call (#9347)
soondenana Oct 5, 2020
25a1ed4
MINOR: remove stream simple benchmark suite (#8353)
Apr 14, 2020
b926ccb
KAFKA-10439: Connect's Values to parse BigInteger as Decimal with zer…
avocader Oct 6, 2020
47c5179
KAFKA-10188: Prevent SinkTask::preCommit from being called after Sink…
C0urante Oct 6, 2020
673eaea
KAFKA-10574: Fix infinite loop in Values::parseString (#9375)
C0urante Oct 12, 2020
6688ea2
KAFKA-10600: Connect should not add error to connector validation val…
rhauch Oct 16, 2020
71f7ed3
KAFKA-10332: Update MM2 refreshTopicPartitions() logic (#9343)
mimaison Oct 19, 2020
28c8cc5
MINOR: Fix now that kafka.apache.org resolves to 3 IP addresses (#9305)
jolshan Oct 20, 2020
c820e3b
Merge remote-tracking branch 'apache-kafka/2.5' into ak-25-to-ccs-25-…
andrewegel Oct 20, 2020
fbe4053
Fix a Scala 2.11 compile error in GroupMetadataManagerTest
mumrah Oct 1, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ This is for `core`, `examples` and `clients`
./gradlew core:jar
./gradlew core:test

Streams has multiple sub-projects, but you can run all the tests:

./gradlew :streams:testAll

### Listing all gradle tasks ###
./gradlew tasks

Expand Down
38 changes: 31 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ subprojects {

test {
maxParallelForks = userMaxForks ?: Runtime.runtime.availableProcessors()
ignoreFailures = userIgnoreFailures

minHeapSize = "256m"
maxHeapSize = "2048m"
Expand All @@ -355,6 +356,10 @@ subprojects {
}
logTestStdout.rehydrate(delegate, owner, this)()

// The suites are for running sets of tests in IDEs.
// Gradle will run each test class, so we exclude the suites to avoid redundantly running the tests twice.
exclude '**/*Suite.class'

useJUnit {
includeCategories 'org.apache.kafka.test.IntegrationTest'
}
Expand All @@ -374,6 +379,10 @@ subprojects {
exceptionFormat = testExceptionFormat
}
logTestStdout.rehydrate(delegate, owner, this)()

// The suites are for running sets of tests in IDEs.
// Gradle will run each test class, so we exclude the suites to avoid redundantly running the tests twice.
exclude '**/*Suite.class'

if (it.project.name != 'generator') {
useJUnit {
Expand Down Expand Up @@ -499,8 +508,8 @@ subprojects {
scalaCompileOptions.additionalParameters += inlineFrom
}

// these options are valid for Scala versions < 2.13 only
// Scala 2.13 removes them, see https://github.com/scala/scala/pull/6502 and https://github.com/scala/scala/pull/5969
// these options are valid for Scala versions < 2.13 only
// Scala 2.13 removes them, see https://github.com/scala/scala/pull/6502 and https://github.com/scala/scala/pull/5969
if (versions.baseScala in ['2.11','2.12']) {
scalaCompileOptions.additionalParameters += [
"-Xlint:by-name-right-associative",
Expand Down Expand Up @@ -1317,11 +1326,26 @@ project(':streams') {
standardOutput = new File(generatedDocsDir, "streams_config.html").newOutputStream()
}

test {
// The suites are for running sets of tests in IDEs.
// Gradle will run each test class, so we exclude the suites to avoid redundantly running the tests twice.
exclude '**/*Suite.class'
}
task testAll(
dependsOn: [
':streams:test',
':streams:test-utils:test',
':streams:streams-scala:test',
':streams:upgrade-system-tests-0100:test',
':streams:upgrade-system-tests-0101:test',
':streams:upgrade-system-tests-0102:test',
':streams:upgrade-system-tests-0110:test',
':streams:upgrade-system-tests-10:test',
':streams:upgrade-system-tests-11:test',
':streams:upgrade-system-tests-20:test',
':streams:upgrade-system-tests-21:test',
':streams:upgrade-system-tests-22:test',
':streams:upgrade-system-tests-23:test',
':streams:upgrade-system-tests-24:test',
':streams:upgrade-system-tests-25:test',
':streams:examples:test'
]
)
}

project(':streams:streams-scala') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public void testResolveDnsLookup() throws UnknownHostException {

@Test
public void testResolveDnsLookupAllIps() throws UnknownHostException {
assertEquals(2, ClientUtils.resolve("kafka.apache.org", ClientDnsLookup.USE_ALL_DNS_IPS).size());
assertTrue(ClientUtils.resolve("kafka.apache.org", ClientDnsLookup.USE_ALL_DNS_IPS).size() > 1);
}

private List<InetSocketAddress> checkWithoutLookup(String... url) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ public void testSingleIPWithUseAll() throws UnknownHostException {

@Test
public void testMultipleIPsWithDefault() throws UnknownHostException {
assertEquals(2, ClientUtils.resolve(hostTwoIps, ClientDnsLookup.USE_ALL_DNS_IPS).size());
assertTrue(ClientUtils.resolve(hostTwoIps, ClientDnsLookup.USE_ALL_DNS_IPS).size() > 1);

connectionStates.connecting(nodeId1, time.milliseconds(), hostTwoIps, ClientDnsLookup.DEFAULT);
InetAddress currAddress = connectionStates.currentAddress(nodeId1);
Expand All @@ -266,22 +266,21 @@ public void testMultipleIPsWithDefault() throws UnknownHostException {

@Test
public void testMultipleIPsWithUseAll() throws UnknownHostException {
assertEquals(2, ClientUtils.resolve(hostTwoIps, ClientDnsLookup.USE_ALL_DNS_IPS).size());
assertTrue(ClientUtils.resolve(hostTwoIps, ClientDnsLookup.USE_ALL_DNS_IPS).size() > 1);

connectionStates.connecting(nodeId1, time.milliseconds(), hostTwoIps, ClientDnsLookup.USE_ALL_DNS_IPS);
InetAddress addr1 = connectionStates.currentAddress(nodeId1);
connectionStates.connecting(nodeId1, time.milliseconds(), hostTwoIps, ClientDnsLookup.USE_ALL_DNS_IPS);
InetAddress addr2 = connectionStates.currentAddress(nodeId1);
assertNotSame(addr1, addr2);

connectionStates.connecting(nodeId1, time.milliseconds(), hostTwoIps, ClientDnsLookup.USE_ALL_DNS_IPS);
InetAddress addr3 = connectionStates.currentAddress(nodeId1);
assertSame(addr1, addr3);
assertNotSame(addr1, addr3);
}

@Test
public void testHostResolveChange() throws UnknownHostException, ReflectiveOperationException {
assertEquals(2, ClientUtils.resolve(hostTwoIps, ClientDnsLookup.USE_ALL_DNS_IPS).size());
assertTrue(ClientUtils.resolve(hostTwoIps, ClientDnsLookup.USE_ALL_DNS_IPS).size() > 1);

connectionStates.connecting(nodeId1, time.milliseconds(), hostTwoIps, ClientDnsLookup.DEFAULT);
InetAddress addr1 = connectionStates.currentAddress(nodeId1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -943,8 +943,14 @@ protected static SchemaAndValue parse(Parser parser, boolean embedded) throws No
} catch (ArithmeticException e) {
// continue
}
float fValue = decimal.floatValue();
if (fValue != Float.NEGATIVE_INFINITY && fValue != Float.POSITIVE_INFINITY
&& decimal.scale() != 0) {
return new SchemaAndValue(Schema.FLOAT32_SCHEMA, fValue);
}
double dValue = decimal.doubleValue();
if (dValue != Double.NEGATIVE_INFINITY && dValue != Double.POSITIVE_INFINITY) {
if (dValue != Double.NEGATIVE_INFINITY && dValue != Double.POSITIVE_INFINITY
&& decimal.scale() != 0) {
return new SchemaAndValue(Schema.FLOAT64_SCHEMA, dValue);
}
Schema schema = Decimal.schema(decimal.scale());
Expand Down Expand Up @@ -1187,7 +1193,7 @@ private String consumeNextToken() throws NoSuchElementException {
boolean escaped = false;
int start = iter.getIndex();
char c = iter.current();
while (c != CharacterIterator.DONE) {
while (canConsumeNextToken()) {
switch (c) {
case '\\':
escaped = !escaped;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
import org.apache.kafka.connect.errors.DataException;
import org.junit.Test;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -73,6 +76,18 @@ public class ValuesTest {
INT_LIST.add(-987654321);
}

@Test(timeout = 5000)
public void shouldNotEncounterInfiniteLoop() {
// This byte sequence gets parsed as CharacterIterator.DONE and can cause issues if
// comparisons to that character are done to check if the end of a string has been reached.
// For more information, see https://issues.apache.org/jira/browse/KAFKA-10574
byte[] bytes = new byte[] {-17, -65, -65};
String str = new String(bytes, StandardCharsets.UTF_8);
SchemaAndValue schemaAndValue = Values.parseString(str);
assertEquals(Type.STRING, schemaAndValue.schema().type());
assertEquals(str, schemaAndValue.value());
}

@Test
public void shouldNotParseUnquotedEmbeddedMapKeysAsStrings() {
SchemaAndValue schemaAndValue = Values.parseString("{foo: 3}");
Expand Down Expand Up @@ -726,6 +741,132 @@ public void shouldConvertTimestampValues() {
public void canConsume() {
}

@Test
public void shouldParseBigIntegerAsDecimalWithZeroScale() {
BigInteger value = BigInteger.valueOf(Long.MAX_VALUE).add(new BigInteger("1"));
SchemaAndValue schemaAndValue = Values.parseString(
String.valueOf(value)
);
assertEquals(Decimal.schema(0), schemaAndValue.schema());
assertTrue(schemaAndValue.value() instanceof BigDecimal);
assertEquals(value, ((BigDecimal) schemaAndValue.value()).unscaledValue());
value = BigInteger.valueOf(Long.MIN_VALUE).subtract(new BigInteger("1"));
schemaAndValue = Values.parseString(
String.valueOf(value)
);
assertEquals(Decimal.schema(0), schemaAndValue.schema());
assertTrue(schemaAndValue.value() instanceof BigDecimal);
assertEquals(value, ((BigDecimal) schemaAndValue.value()).unscaledValue());
}

@Test
public void shouldParseByteAsInt8() {
Byte value = Byte.MAX_VALUE;
SchemaAndValue schemaAndValue = Values.parseString(
String.valueOf(value)
);
assertEquals(Schema.INT8_SCHEMA, schemaAndValue.schema());
assertTrue(schemaAndValue.value() instanceof Byte);
assertEquals(value.byteValue(), ((Byte) schemaAndValue.value()).byteValue());
value = Byte.MIN_VALUE;
schemaAndValue = Values.parseString(
String.valueOf(value)
);
assertEquals(Schema.INT8_SCHEMA, schemaAndValue.schema());
assertTrue(schemaAndValue.value() instanceof Byte);
assertEquals(value.byteValue(), ((Byte) schemaAndValue.value()).byteValue());
}

@Test
public void shouldParseShortAsInt16() {
Short value = Short.MAX_VALUE;
SchemaAndValue schemaAndValue = Values.parseString(
String.valueOf(value)
);
assertEquals(Schema.INT16_SCHEMA, schemaAndValue.schema());
assertTrue(schemaAndValue.value() instanceof Short);
assertEquals(value.shortValue(), ((Short) schemaAndValue.value()).shortValue());
value = Short.MIN_VALUE;
schemaAndValue = Values.parseString(
String.valueOf(value)
);
assertEquals(Schema.INT16_SCHEMA, schemaAndValue.schema());
assertTrue(schemaAndValue.value() instanceof Short);
assertEquals(value.shortValue(), ((Short) schemaAndValue.value()).shortValue());
}

@Test
public void shouldParseIntegerAsInt32() {
Integer value = Integer.MAX_VALUE;
SchemaAndValue schemaAndValue = Values.parseString(
String.valueOf(value)
);
assertEquals(Schema.INT32_SCHEMA, schemaAndValue.schema());
assertTrue(schemaAndValue.value() instanceof Integer);
assertEquals(value.intValue(), ((Integer) schemaAndValue.value()).intValue());
value = Integer.MIN_VALUE;
schemaAndValue = Values.parseString(
String.valueOf(value)
);
assertEquals(Schema.INT32_SCHEMA, schemaAndValue.schema());
assertTrue(schemaAndValue.value() instanceof Integer);
assertEquals(value.intValue(), ((Integer) schemaAndValue.value()).intValue());
}

@Test
public void shouldParseLongAsInt64() {
Long value = Long.MAX_VALUE;
SchemaAndValue schemaAndValue = Values.parseString(
String.valueOf(value)
);
assertEquals(Schema.INT64_SCHEMA, schemaAndValue.schema());
assertTrue(schemaAndValue.value() instanceof Long);
assertEquals(value.longValue(), ((Long) schemaAndValue.value()).longValue());
value = Long.MIN_VALUE;
schemaAndValue = Values.parseString(
String.valueOf(value)
);
assertEquals(Schema.INT64_SCHEMA, schemaAndValue.schema());
assertTrue(schemaAndValue.value() instanceof Long);
assertEquals(value.longValue(), ((Long) schemaAndValue.value()).longValue());
}

@Test
public void shouldParseFloatAsFloat32() {
Float value = Float.MAX_VALUE;
SchemaAndValue schemaAndValue = Values.parseString(
String.valueOf(value)
);
assertEquals(Schema.FLOAT32_SCHEMA, schemaAndValue.schema());
assertTrue(schemaAndValue.value() instanceof Float);
assertEquals(value.floatValue(), ((Float) schemaAndValue.value()).floatValue(), 0);
value = -Float.MAX_VALUE;
schemaAndValue = Values.parseString(
String.valueOf(value)
);
assertEquals(Schema.FLOAT32_SCHEMA, schemaAndValue.schema());
assertTrue(schemaAndValue.value() instanceof Float);
assertEquals(value.floatValue(), ((Float) schemaAndValue.value()).floatValue(), 0);
}

@Test
public void shouldParseDoubleAsFloat64() {
Double value = Double.MAX_VALUE;
SchemaAndValue schemaAndValue = Values.parseString(
String.valueOf(value)
);
assertEquals(Schema.FLOAT64_SCHEMA, schemaAndValue.schema());
assertTrue(schemaAndValue.value() instanceof Double);
assertEquals(value.doubleValue(), ((Double) schemaAndValue.value()).doubleValue(), 0);
value = -Double.MAX_VALUE;
schemaAndValue = Values.parseString(
String.valueOf(value)
);
assertEquals(Schema.FLOAT64_SCHEMA, schemaAndValue.schema());
assertTrue(schemaAndValue.value() instanceof Double);
assertEquals(value.doubleValue(), ((Double) schemaAndValue.value()).doubleValue(), 0);
}

protected void assertParsed(String input) {
assertParsed(input, input);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,7 @@ private static Object convertToConnect(Schema schema, JsonNode jsonValue) {
} else {
switch (jsonValue.getNodeType()) {
case NULL:
case MISSING:
// Special case. With no schema
return null;
case BOOLEAN:
Expand All @@ -751,7 +752,6 @@ private static Object convertToConnect(Schema schema, JsonNode jsonValue) {
break;

case BINARY:
case MISSING:
case POJO:
default:
schemaType = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,36 @@ public void nullToConnect() {
assertEquals(SchemaAndValue.NULL, converted);
}

/**
* When schemas are disabled, empty data should be decoded to an empty envelope.
* This test verifies the case where `schemas.enable` configuration is set to false, and
* {@link JsonConverter} converts empty bytes to {@link SchemaAndValue#NULL}.
*/
@Test
public void emptyBytesToConnect() {
// This characterizes the messages with empty data when Json schemas is disabled
Map<String, Boolean> props = Collections.singletonMap("schemas.enable", false);
converter.configure(props, true);
SchemaAndValue converted = converter.toConnectData(TOPIC, "".getBytes());
assertEquals(SchemaAndValue.NULL, converted);
}

/**
* When schemas are disabled, fields are mapped to Connect maps.
*/
@Test
public void schemalessWithEmptyFieldValueToConnect() {
// This characterizes the messages with empty data when Json schemas is disabled
Map<String, Boolean> props = Collections.singletonMap("schemas.enable", false);
converter.configure(props, true);
String input = "{ \"a\": \"\", \"b\": null}";
SchemaAndValue converted = converter.toConnectData(TOPIC, input.getBytes());
Map<String, String> expected = new HashMap<>();
expected.put("a", "");
expected.put("b", null);
assertEquals(new SchemaAndValue(null, expected), converted);
}

@Test
public void nullSchemaPrimitiveToConnect() {
SchemaAndValue converted = converter.toConnectData(TOPIC, "{ \"schema\": null, \"payload\": null }".getBytes());
Expand Down
Loading