From 85b36263a28faae0c20e6c92f653642098b26e5e Mon Sep 17 00:00:00 2001 From: Sarah Chen Date: Fri, 13 Mar 2026 16:32:17 -0400 Subject: [PATCH 1/2] Use TableTest in dd-trace-api --- dd-trace-api/build.gradle.kts | 1 + .../java/datadog/trace/api/DDSpanIdTest.java | 163 ++++------ .../java/datadog/trace/api/DDTraceIdTest.java | 300 +++++++----------- .../trace/api/IdGenerationStrategyTest.java | 27 +- .../api/internal/util/HexStringUtilsTest.java | 37 +-- 5 files changed, 213 insertions(+), 315 deletions(-) diff --git a/dd-trace-api/build.gradle.kts b/dd-trace-api/build.gradle.kts index bc05a8753a4..c715fb62bdd 100644 --- a/dd-trace-api/build.gradle.kts +++ b/dd-trace-api/build.gradle.kts @@ -75,5 +75,6 @@ dependencies { api(libs.slf4j) testImplementation(libs.guava) testImplementation(libs.bundles.mockito) + testImplementation(libs.tabletest) testImplementation(project(":utils:test-utils")) } diff --git a/dd-trace-api/src/test/java/datadog/trace/api/DDSpanIdTest.java b/dd-trace-api/src/test/java/datadog/trace/api/DDSpanIdTest.java index e6cc4719b88..39f2ccbd160 100644 --- a/dd-trace-api/src/test/java/datadog/trace/api/DDSpanIdTest.java +++ b/dd-trace-api/src/test/java/datadog/trace/api/DDSpanIdTest.java @@ -7,58 +7,57 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertThrows; -import java.math.BigInteger; import java.util.HashSet; import java.util.Set; -import java.util.stream.Stream; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; -import org.junit.jupiter.params.provider.ValueSource; +import org.tabletest.junit.TableTest; class DDSpanIdTest { - @ParameterizedTest(name = "convert ids from/to String {0}") - @MethodSource("convertIdsFromToStringArguments") - void convertIdsFromToString(String displayName, String stringId, long expectedId) { + @TableTest({ + "scenario | stringId | expectedId ", + "zero | '0' | 0 ", + "one | '1' | 1 ", + "max | '18446744073709551615' | -1 ", + "long max | '9223372036854775807' | 9223372036854775807 ", + "long max plus one | '9223372036854775808' | -9223372036854775808" + }) + @ParameterizedTest + void convertIdsFromToString(String stringId, long expectedId) { long ddid = DDSpanId.from(stringId); assertEquals(expectedId, ddid); assertEquals(stringId, DDSpanId.toString(ddid)); } - static Stream convertIdsFromToStringArguments() { - return Stream.of( - Arguments.of("zero", "0", 0L), - Arguments.of("one", "1", 1L), - Arguments.of("max", "18446744073709551615", DDSpanId.MAX), - Arguments.of("long max", String.valueOf(Long.MAX_VALUE), Long.MAX_VALUE), - Arguments.of( - "long max plus one", - BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE).toString(), - Long.MIN_VALUE)); - } - - @ParameterizedTest(name = "fail on illegal String {0}") - @MethodSource("failOnIllegalStringArguments") + @TableTest({ + "scenario | stringId ", + "null | ", + "empty | '' ", + "negative one | '-1' ", + "too large | '18446744073709551616'", + "too large variant | '18446744073709551625'", + "too large long | '184467440737095516150'", + "contains alpha first | '18446744073709551a1' ", + "contains alpha last | '184467440737095511a' " + }) + @ParameterizedTest void failOnIllegalString(String stringId) { assertThrows(NumberFormatException.class, () -> DDSpanId.from(stringId)); } - static Stream failOnIllegalStringArguments() { - return Stream.of( - Arguments.of((Object) null), - Arguments.of(""), - Arguments.of("-1"), - Arguments.of("18446744073709551616"), - Arguments.of("18446744073709551625"), - Arguments.of("184467440737095516150"), - Arguments.of("18446744073709551a1"), - Arguments.of("184467440737095511a")); - } - - @ParameterizedTest(name = "convert ids from/to hex String {0}") - @MethodSource("convertIdsFromToHexStringArguments") + @TableTest({ + "scenario | hexId | expectedId ", + "zero | '0' | 0 ", + "one | '1' | 1 ", + "max | 'ffffffffffffffff' | -1 ", + "long max | '7fffffffffffffff' | 9223372036854775807 ", + "long min | '8000000000000000' | -9223372036854775808", + "long min with leading zeros | '00008000000000000000' | -9223372036854775808", + "cafebabe | 'cafebabe' | 3405691582 ", + "fifteen hex digits | '123456789abcdef' | 81985529216486895 " + }) + @ParameterizedTest void convertIdsFromToHexString(String hexId, long expectedId) { long ddid = DDSpanId.fromHex(hexId); String padded16 = @@ -73,27 +72,22 @@ void convertIdsFromToHexString(String hexId, long expectedId) { assertEquals(padded16, DDSpanId.toHexStringPadded(ddid)); } - static Stream convertIdsFromToHexStringArguments() { - return Stream.of( - Arguments.of("0", 0L), - Arguments.of("1", 1L), - Arguments.of(repeat("f", 16), DDSpanId.MAX), - Arguments.of("7" + repeat("f", 15), Long.MAX_VALUE), - Arguments.of("8" + repeat("0", 15), Long.MIN_VALUE), - Arguments.of(repeat("0", 4) + "8" + repeat("0", 15), Long.MIN_VALUE), - Arguments.of("cafebabe", 3405691582L), - Arguments.of("123456789abcdef", 81985529216486895L)); - } - - @ParameterizedTest(name = "convert ids from part of hex String {0}") - @MethodSource("convertIdsFromPartOfHexStringArguments") + @TableTest({ + "scenario | hexId | start | length | lowerCaseOnly | expectedId", + "null input | | 1 | 1 | false | ", + "empty input | '' | 1 | 1 | false | ", + "negative start | '00' | -1 | 1 | false | ", + "zero length | '00' | 0 | 0 | false | ", + "single zero at index 0 | '00' | 0 | 1 | false | 0 ", + "single zero at index 1 | '00' | 1 | 1 | false | 0 ", + "single zero at index 1 duplicate | '00' | 1 | 1 | false | 0 ", + "max lower-case | 'ffffffffffffffff' | 0 | 16 | true | -1 ", + "upper-case rejected when lower-case only| 'ffffffffffffFfff' | 0 | 16 | true | ", + "upper-case accepted when lower disabled | 'ffffffffffffFfff' | 0 | 16 | false | -1 " + }) + @ParameterizedTest void convertIdsFromPartOfHexString( - String displayName, - String hexId, - int start, - int length, - boolean lowerCaseOnly, - Long expectedId) { + String hexId, int start, int length, boolean lowerCaseOnly, Long expectedId) { Long parsedId = null; try { parsedId = DDSpanId.fromHex(hexId, start, length, lowerCaseOnly); @@ -108,50 +102,27 @@ void convertIdsFromPartOfHexString( } } - static Stream convertIdsFromPartOfHexStringArguments() { - return Stream.of( - Arguments.of("null input", null, 1, 1, false, null), - Arguments.of("empty input", "", 1, 1, false, null), - Arguments.of("negative start", "00", -1, 1, false, null), - Arguments.of("zero length", "00", 0, 0, false, null), - Arguments.of("single zero at index 0", "00", 0, 1, false, DDSpanId.ZERO), - Arguments.of("single zero at index 1", "00", 1, 1, false, DDSpanId.ZERO), - Arguments.of("single zero at index 1 duplicate", "00", 1, 1, false, DDSpanId.ZERO), - Arguments.of("max lower-case", repeat("f", 16), 0, 16, true, DDSpanId.MAX), - Arguments.of( - "upper-case rejected when lower-case only", - repeat("f", 12) + "Ffff", - 0, - 16, - true, - null), - Arguments.of( - "upper-case accepted when lower-case disabled", - repeat("f", 12) + "Ffff", - 0, - 16, - false, - DDSpanId.MAX)); - } - - @ParameterizedTest(name = "fail on illegal hex String {0}") - @MethodSource("failOnIllegalHexStringArguments") + @TableTest({ + "scenario | hexId ", + "null | ", + "empty | '' ", + "negative one | '-1' ", + "too long | '10000000000000000'", + "invalid middle | 'ffffffffffffffzf' ", + "invalid tail | 'fffffffffffffffz' " + }) + @ParameterizedTest void failOnIllegalHexString(String hexId) { assertThrows(NumberFormatException.class, () -> DDSpanId.fromHex(hexId)); } - static Stream failOnIllegalHexStringArguments() { - return Stream.of( - Arguments.of((Object) null), - Arguments.of(""), - Arguments.of("-1"), - Arguments.of("1" + repeat("0", 16)), - Arguments.of(repeat("f", 14) + "zf"), - Arguments.of(repeat("f", 15) + "z")); - } - - @ParameterizedTest(name = "generate id with {0}") - @ValueSource(strings = {"RANDOM", "SEQUENTIAL", "SECURE_RANDOM"}) + @TableTest({ + "scenario | strategyName ", + "random | RANDOM ", + "sequential | SEQUENTIAL ", + "secure random | SECURE_RANDOM" + }) + @ParameterizedTest void generateIdWithStrategy(String strategyName) { IdGenerationStrategy strategy = IdGenerationStrategy.fromName(strategyName); Set checked = new HashSet(); diff --git a/dd-trace-api/src/test/java/datadog/trace/api/DDTraceIdTest.java b/dd-trace-api/src/test/java/datadog/trace/api/DDTraceIdTest.java index 176b0aeed3f..384084b2077 100644 --- a/dd-trace-api/src/test/java/datadog/trace/api/DDTraceIdTest.java +++ b/dd-trace-api/src/test/java/datadog/trace/api/DDTraceIdTest.java @@ -5,24 +5,25 @@ import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; -import java.math.BigInteger; -import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; +import org.tabletest.junit.TableTest; class DDTraceIdTest { - @ParameterizedTest(name = "convert 64-bit ids from/to long {1} and check strings") - @MethodSource("convert64BitIdsFromToLongAndCheckStringsArguments") + @TableTest({ + "scenario | longId | expectedString | expectedHex ", + "zero | 0 | '0' | '00000000000000000000000000000000'", + "one | 1 | '1' | '00000000000000000000000000000001'", + "minus one | -1 | '18446744073709551615'| '0000000000000000ffffffffffffffff'", + "long max | 9223372036854775807 | '9223372036854775807' | '00000000000000007fffffffffffffff'", + "long min | -9223372036854775808 | '9223372036854775808' | '00000000000000008000000000000000'" + }) + @ParameterizedTest void convert64BitIdsFromToLongAndCheckStrings( - String displayName, - long longId, - DD64bTraceId expectedId, - String expectedString, - String expectedHex) { + long longId, String expectedString, String expectedHex) { DD64bTraceId ddid = DD64bTraceId.from(longId); + DD64bTraceId expectedId = DD64bTraceId.from(expectedString); DDTraceId defaultDdid = DDTraceId.from(longId); assertEquals(expectedId, ddid); @@ -33,74 +34,54 @@ void convert64BitIdsFromToLongAndCheckStrings( assertEquals(expectedHex, ddid.toHexString()); } - static Stream convert64BitIdsFromToLongAndCheckStringsArguments() { - return Stream.of( - Arguments.of("zero", 0L, DD64bTraceId.ZERO, "0", repeat("0", 32)), - Arguments.of("one", 1L, DD64bTraceId.ONE, "1", repeat("0", 31) + "1"), - Arguments.of( - "minus one", - -1L, - DD64bTraceId.MAX, - "18446744073709551615", - repeat("0", 16) + repeat("f", 16)), - Arguments.of( - "long max", - Long.MAX_VALUE, - DD64bTraceId.from(Long.MAX_VALUE), - "9223372036854775807", - repeat("0", 16) + "7" + repeat("f", 15)), - Arguments.of( - "long min", - Long.MIN_VALUE, - DD64bTraceId.from(Long.MIN_VALUE), - "9223372036854775808", - repeat("0", 16) + "8" + repeat("0", 15))); - } - - @ParameterizedTest(name = "convert 64-bit ids from/to String representation: {1}") - @MethodSource("convert64BitIdsFromToStringRepresentationArguments") - void convert64BitIdsFromToStringRepresentation( - String displayName, String stringId, DD64bTraceId expectedId) { + @TableTest({ + "scenario | stringId | expectedLongId ", + "zero | '0' | 0 ", + "one | '1' | 1 ", + "max | '18446744073709551615' | -1 ", + "long max | '9223372036854775807' | 9223372036854775807 ", + "long max plus one | '9223372036854775808' | -9223372036854775808" + }) + @ParameterizedTest + void convert64BitIdsFromToStringRepresentation(String stringId, long expectedLongId) { DD64bTraceId ddid = DD64bTraceId.from(stringId); - assertEquals(expectedId, ddid); + assertEquals(DD64bTraceId.from(expectedLongId), ddid); + assertEquals(expectedLongId, ddid.toLong()); assertEquals(stringId, ddid.toString()); } - static Stream convert64BitIdsFromToStringRepresentationArguments() { - return Stream.of( - Arguments.of("zero", "0", DD64bTraceId.ZERO), - Arguments.of("one", "1", DD64bTraceId.ONE), - Arguments.of("max", "18446744073709551615", DD64bTraceId.MAX), - Arguments.of("long max", String.valueOf(Long.MAX_VALUE), DD64bTraceId.from(Long.MAX_VALUE)), - Arguments.of( - "long max plus one", - BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE).toString(), - DD64bTraceId.from(Long.MIN_VALUE))); - } - - @ParameterizedTest(name = "fail parsing illegal 64-bit id String representation: {0}") - @MethodSource("failParsingIllegal64BitIdStringRepresentationArguments") + @TableTest({ + "scenario | stringId ", + "null | ", + "empty | '' ", + "negative one | '-1' ", + "too large | '18446744073709551616'", + "too large variant | '18446744073709551625'", + "too large long | '184467440737095516150'", + "contains alpha first | '18446744073709551a1' ", + "contains alpha last | '184467440737095511a' " + }) + @ParameterizedTest void failParsingIllegal64BitIdStringRepresentation(String stringId) { assertThrows(NumberFormatException.class, () -> DD64bTraceId.from(stringId)); } - static Stream failParsingIllegal64BitIdStringRepresentationArguments() { - return Stream.of( - Arguments.of((Object) null), - Arguments.of(""), - Arguments.of("-1"), - Arguments.of("18446744073709551616"), - Arguments.of("18446744073709551625"), - Arguments.of("184467440737095516150"), - Arguments.of("18446744073709551a1"), - Arguments.of("184467440737095511a")); - } - - @ParameterizedTest(name = "convert 64-bit ids from/to hex String representation: {0}") - @MethodSource("convert64BitIdsFromToHexStringRepresentationArguments") - void convert64BitIdsFromToHexStringRepresentation(String hexId, DD64bTraceId expectedId) { + @TableTest({ + "scenario | hexId | expectedLongId ", + "zero | '0' | 0 ", + "one | '1' | 1 ", + "max | 'ffffffffffffffff' | -1 ", + "long max | '7fffffffffffffff' | 9223372036854775807 ", + "long min | '8000000000000000' | -9223372036854775808", + "long min with leading zeros | '00008000000000000000' | -9223372036854775808", + "cafebabe | 'cafebabe' | 3405691582 ", + "fifteen hex digits | '123456789abcdef' | 81985529216486895 " + }) + @ParameterizedTest + void convert64BitIdsFromToHexStringRepresentation(String hexId, long expectedLongId) { DD64bTraceId ddid = DD64bTraceId.fromHex(hexId); + DD64bTraceId expectedId = DD64bTraceId.from(expectedLongId); String padded16 = hexId.length() <= 16 ? leftPadWithZeros(hexId, 16) : hexId.substring(hexId.length() - 16); String padded32 = leftPadWithZeros(hexId, 32); @@ -111,38 +92,44 @@ void convert64BitIdsFromToHexStringRepresentation(String hexId, DD64bTraceId exp assertEquals(padded32, ddid.toHexStringPadded(32)); } - static Stream convert64BitIdsFromToHexStringRepresentationArguments() { - return Stream.of( - Arguments.of("0", DD64bTraceId.ZERO), - Arguments.of("1", DD64bTraceId.ONE), - Arguments.of(repeat("f", 16), DD64bTraceId.MAX), - Arguments.of("7" + repeat("f", 15), DD64bTraceId.from(Long.MAX_VALUE)), - Arguments.of("8" + repeat("0", 15), DD64bTraceId.from(Long.MIN_VALUE)), - Arguments.of(repeat("0", 4) + "8" + repeat("0", 15), DD64bTraceId.from(Long.MIN_VALUE)), - Arguments.of("cafebabe", DD64bTraceId.from(3405691582L)), - Arguments.of("123456789abcdef", DD64bTraceId.from(81985529216486895L))); - } - - @ParameterizedTest(name = "fail parsing illegal 64-bit hexadecimal String representation: {0}") - @MethodSource("failParsingIllegal64BitHexadecimalStringRepresentationArguments") + @TableTest({ + "scenario | hexId ", + "null | ", + "empty | '' ", + "negative one | '-1' ", + "too long | '10000000000000000'", + "invalid middle | 'ffffffffffffffzf' ", + "invalid tail | 'fffffffffffffffz' " + }) + @ParameterizedTest void failParsingIllegal64BitHexadecimalStringRepresentation(String hexId) { assertThrows(NumberFormatException.class, () -> DD64bTraceId.fromHex(hexId)); } - static Stream failParsingIllegal64BitHexadecimalStringRepresentationArguments() { - return Stream.of( - Arguments.of((Object) null), - Arguments.of(""), - Arguments.of("-1"), - Arguments.of("1" + repeat("0", 16)), - Arguments.of(repeat("f", 14) + "zf"), - Arguments.of(repeat("f", 15) + "z")); - } - - @ParameterizedTest(name = "convert 128-bit ids from/to hexadecimal String representation {3}") - @MethodSource("convert128BitIdsFromToHexadecimalStringRepresentationArguments") + @TableTest({ + "scenario | highOrderBits | lowOrderBits | hexId ", + "both long min | -9223372036854775808 | -9223372036854775808 | '80000000000000008000000000000000'", + "high long min low one | -9223372036854775808 | 1 | '80000000000000000000000000000001'", + "high long min low long max | -9223372036854775808 | 9223372036854775807 | '80000000000000007fffffffffffffff'", + "high one low long min | 1 | -9223372036854775808 | '00000000000000018000000000000000'", + "high one low one | 1 | 1 | '00000000000000010000000000000001'", + "high one low long max | 1 | 9223372036854775807 | '00000000000000017fffffffffffffff'", + "high long max low long min | 9223372036854775807 | -9223372036854775808 | '7fffffffffffffff8000000000000000'", + "high long max low one | 9223372036854775807 | 1 | '7fffffffffffffff0000000000000001'", + "high long max low long max | 9223372036854775807 | 9223372036854775807 | '7fffffffffffffff7fffffffffffffff'", + "all zeros length one | 0 | 0 | '0' ", + "all zeros length sixteen | 0 | 0 | '0000000000000000' ", + "all zeros length seventeen | 0 | 0 | '00000000000000000' ", + "all zeros length thirty-two | 0 | 0 | '00000000000000000000000000000000'", + "low fifteen | 0 | 15 | 'f' ", + "low minus one | 0 | -1 | 'ffffffffffffffff' ", + "high fifteen low minus one | 15 | -1 | 'fffffffffffffffff' ", + "all f | -1 | -1 | 'ffffffffffffffffffffffffffffffff'", + "hex literal | 1311768467463790320 | 1311768467463790320 | '123456789abcdef0123456789abcdef0'" + }) + @ParameterizedTest void convert128BitIdsFromToHexadecimalStringRepresentation( - String displayName, long highOrderBits, long lowOrderBits, String hexId) { + long highOrderBits, long lowOrderBits, String hexId) { DDTraceId parsedId = DD128bTraceId.fromHex(hexId); DDTraceId id = DD128bTraceId.from(highOrderBits, lowOrderBits); String paddedHexId = leftPadWithZeros(hexId, 32); @@ -156,110 +143,43 @@ void convert128BitIdsFromToHexadecimalStringRepresentation( assertEquals(Long.toUnsignedString(lowOrderBits), parsedId.toString()); } - static Stream convert128BitIdsFromToHexadecimalStringRepresentationArguments() { - return Stream.of( - Arguments.of( - "both long min", - Long.MIN_VALUE, - Long.MIN_VALUE, - "8" + repeat("0", 15) + "8" + repeat("0", 15)), - Arguments.of( - "high long min low one", - Long.MIN_VALUE, - 1L, - "8" + repeat("0", 15) + repeat("0", 15) + "1"), - Arguments.of( - "high long min low long max", - Long.MIN_VALUE, - Long.MAX_VALUE, - "8" + repeat("0", 15) + "7" + repeat("f", 15)), - Arguments.of( - "high one low long min", - 1L, - Long.MIN_VALUE, - repeat("0", 15) + "1" + "8" + repeat("0", 15)), - Arguments.of("high one low one", 1L, 1L, repeat("0", 15) + "1" + repeat("0", 15) + "1"), - Arguments.of( - "high one low long max", - 1L, - Long.MAX_VALUE, - repeat("0", 15) + "1" + "7" + repeat("f", 15)), - Arguments.of( - "high long max low long min", - Long.MAX_VALUE, - Long.MIN_VALUE, - "7" + repeat("f", 15) + "8" + repeat("0", 15)), - Arguments.of( - "high long max low one", - Long.MAX_VALUE, - 1L, - "7" + repeat("f", 15) + repeat("0", 15) + "1"), - Arguments.of( - "high long max low long max", - Long.MAX_VALUE, - Long.MAX_VALUE, - "7" + repeat("f", 15) + "7" + repeat("f", 15)), - Arguments.of("all zeros length one", 0L, 0L, repeat("0", 1)), - Arguments.of("all zeros length sixteen", 0L, 0L, repeat("0", 16)), - Arguments.of("all zeros length seventeen", 0L, 0L, repeat("0", 17)), - Arguments.of("all zeros length thirty-two", 0L, 0L, repeat("0", 32)), - Arguments.of("low fifteen", 0L, 15L, repeat("f", 1)), - Arguments.of("low minus one", 0L, -1L, repeat("f", 16)), - Arguments.of("high fifteen low minus one", 15L, -1L, repeat("f", 17)), - Arguments.of("all f", -1L, -1L, repeat("f", 32)), - Arguments.of( - "hex literal", - 1311768467463790320L, - 1311768467463790320L, - "123456789abcdef0123456789abcdef0")); - } - - @ParameterizedTest( - name = "fail parsing illegal 128-bit id hexadecimal String representation: {0}") - @MethodSource("failParsingIllegal128BitIdHexadecimalStringRepresentationArguments") + @TableTest({ + "scenario | hexId ", + "null | ", + "empty | '' ", + "negative one | '-1' ", + "negative A | '-A' ", + "too long | '111111111111111111111111111111111' ", + "upper case allowed? | '123ABC' ", + "invalid character | '123abcg' " + }) + @ParameterizedTest void failParsingIllegal128BitIdHexadecimalStringRepresentation(String hexId) { assertThrows(NumberFormatException.class, () -> DD128bTraceId.fromHex(hexId)); } - static Stream failParsingIllegal128BitIdHexadecimalStringRepresentationArguments() { - return Stream.of( - Arguments.of((Object) null), - Arguments.of(""), - Arguments.of("-1"), - Arguments.of("-A"), - Arguments.of(repeat("1", 33)), - Arguments.of("123ABC"), - Arguments.of("123abcg")); - } - - @ParameterizedTest( - name = - "fail parsing illegal 128-bit id hexadecimal String representation from partial String: {1}") - @MethodSource( - "failParsingIllegal128BitIdHexadecimalStringRepresentationFromPartialStringArguments") + @TableTest({ + "scenario | hexId | start | length | lowerCaseOnly", + "null string | | 0 | 0 | true ", + "empty string | '' | 0 | 0 | true ", + "out of bound length | '123456789abcdef0' | 0 | 17 | true ", + "out of bound end | '123456789abcdef0' | 7 | 10 | true ", + "out of bound start | '123456789abcdef0' | 17 | 0 | true ", + "invalid minus one | '-1' | 0 | 1 | true ", + "invalid minus a | '-a' | 0 | 1 | true ", + "invalid character | '123abcg' | 0 | 7 | true ", + "invalid upper case A | 'A' | 0 | 1 | true ", + "invalid upper case | '123ABC' | 0 | 6 | true ", + "too long | '111111111111111111111111111111111' | 0 | 33 | true" + }) + @ParameterizedTest void failParsingIllegal128BitIdHexadecimalStringRepresentationFromPartialString( - String displayName, String hexId, int start, int length, boolean lowerCaseOnly) { + String hexId, int start, int length, boolean lowerCaseOnly) { assertThrows( NumberFormatException.class, () -> DD128bTraceId.fromHex(hexId, start, length, lowerCaseOnly)); } - static Stream - failParsingIllegal128BitIdHexadecimalStringRepresentationFromPartialStringArguments() { - return Stream.of( - Arguments.of("null string", null, 0, 0, true), - Arguments.of("empty string", "", 0, 0, true), - Arguments.of("out of bound length", "123456789abcdef0", 0, 17, true), - Arguments.of("out of bound end", "123456789abcdef0", 7, 10, true), - Arguments.of("out of bound start", "123456789abcdef0", 17, 0, true), - Arguments.of("invalid minus one", "-1", 0, 1, true), - Arguments.of("invalid minus a", "-a", 0, 1, true), - Arguments.of("invalid character", "123abcg", 0, 7, true), - Arguments.of("invalid upper case A", "A", 0, 1, true), - Arguments.of("invalid upper case ABC", "123ABC", 0, 6, true), - Arguments.of("too long", repeat("1", 33), 0, 33, true)); - } - @Test void checkZeroConstantInitialization() { DDTraceId zero = DDTraceId.ZERO; diff --git a/dd-trace-api/src/test/java/datadog/trace/api/IdGenerationStrategyTest.java b/dd-trace-api/src/test/java/datadog/trace/api/IdGenerationStrategyTest.java index 2177dcef1d5..bca172c5c5c 100644 --- a/dd-trace-api/src/test/java/datadog/trace/api/IdGenerationStrategyTest.java +++ b/dd-trace-api/src/test/java/datadog/trace/api/IdGenerationStrategyTest.java @@ -12,20 +12,20 @@ import java.util.Set; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; -import org.junit.jupiter.params.provider.ValueSource; +import org.tabletest.junit.TableTest; class IdGenerationStrategyTest { - @ParameterizedTest(name = "generate id with {1} and {0} bits") - @CsvSource({ - "false,RANDOM", - "false,SEQUENTIAL", - "false,SECURE_RANDOM", - "true,RANDOM", - "true,SEQUENTIAL", - "true,SECURE_RANDOM" + @TableTest({ + "scenario | traceId128BitGenerationEnabled | strategyName ", + "random-64-bit | false | RANDOM ", + "sequential-64-bit | false | SEQUENTIAL ", + "secure-random-64-bit | false | SECURE_RANDOM", + "random-128-bit | true | RANDOM ", + "sequential-128-bit | true | SEQUENTIAL ", + "secure-random-128-bit | true | SECURE_RANDOM" }) + @ParameterizedTest(name = "generate id with {1} and {0} bits") void generateIdWithStrategyAndBitSize( boolean traceId128BitGenerationEnabled, String strategyName) { IdGenerationStrategy strategy = @@ -52,8 +52,13 @@ void generateIdWithStrategyAndBitSize( } } + @TableTest({ + "scenario | strategyName", + "some-strategy | SOME ", + "unknown-strategy | UNKNOWN ", + "plural-strategies | STRATEGIES " + }) @ParameterizedTest(name = "return null for non existing strategy {0}") - @ValueSource(strings = {"SOME", "UNKNOWN", "STRATEGIES"}) void returnNullForNonExistingStrategy(String strategyName) { assertNull(IdGenerationStrategy.fromName(strategyName)); } diff --git a/dd-trace-api/src/test/java/datadog/trace/api/internal/util/HexStringUtilsTest.java b/dd-trace-api/src/test/java/datadog/trace/api/internal/util/HexStringUtilsTest.java index 53fd9ac485e..f6ae06c716e 100644 --- a/dd-trace-api/src/test/java/datadog/trace/api/internal/util/HexStringUtilsTest.java +++ b/dd-trace-api/src/test/java/datadog/trace/api/internal/util/HexStringUtilsTest.java @@ -3,28 +3,29 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; +import org.tabletest.junit.TableTest; class HexStringUtilsTest { - @ParameterizedTest(name = "test hexadecimal String representations high={0} low={1} size={2}") - @CsvSource({ - "0,0,10", - "0,0,16", - "0,0,20", - "0,0,32", - "0,0,40", - "1,2,10", - "1,2,16", - "1,2,20", - "1,2,32", - "1,2,40", - "6536977903480360123,3270264562721133536,10", - "6536977903480360123,3270264562721133536,16", - "6536977903480360123,3270264562721133536,20", - "6536977903480360123,3270264562721133536,32", - "6536977903480360123,3270264562721133536,40" + @TableTest({ + "scenario | highOrderBits | lowOrderBits | size", + "zero-size-10 | 0 | 0 | 10 ", + "zero-size-16 | 0 | 0 | 16 ", + "zero-size-20 | 0 | 0 | 20 ", + "zero-size-32 | 0 | 0 | 32 ", + "zero-size-40 | 0 | 0 | 40 ", + "one-two-10 | 1 | 2 | 10 ", + "one-two-16 | 1 | 2 | 16 ", + "one-two-20 | 1 | 2 | 20 ", + "one-two-32 | 1 | 2 | 32 ", + "one-two-40 | 1 | 2 | 40 ", + "large-size-10 | 6536977903480360123 | 3270264562721133536 | 10 ", + "large-size-16 | 6536977903480360123 | 3270264562721133536 | 16 ", + "large-size-20 | 6536977903480360123 | 3270264562721133536 | 20 ", + "large-size-32 | 6536977903480360123 | 3270264562721133536 | 32 ", + "large-size-40 | 6536977903480360123 | 3270264562721133536 | 40 " }) + @ParameterizedTest(name = "test hexadecimal String representations high={0} low={1} size={2}") void testHexadecimalStringRepresentations(long highOrderBits, long lowOrderBits, int size) { int highOrderSize = Math.min(16, Math.max(0, size - 16)); int lowOrderSize = Math.min(16, size); From 2f706c9be414db302ef30ccd7d9b09942cd6286e Mon Sep 17 00:00:00 2001 From: Sarah Chen Date: Fri, 13 Mar 2026 17:21:02 -0400 Subject: [PATCH 2/2] Fix test formatting and add tabletest to java_deps --- .../SKILL.md | 5 ++-- dd-trace-api/build.gradle.kts | 1 - .../java/datadog/trace/api/DDTraceIdTest.java | 24 +++++++++---------- gradle/java_deps.gradle | 1 + 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/.claude/skills/migrate-junit-source-to-tabletest/SKILL.md b/.claude/skills/migrate-junit-source-to-tabletest/SKILL.md index ae4008039c5..75fac116dc6 100644 --- a/.claude/skills/migrate-junit-source-to-tabletest/SKILL.md +++ b/.claude/skills/migrate-junit-source-to-tabletest/SKILL.md @@ -12,9 +12,8 @@ Process (do in this order): 5) Run module tests once and verify "BUILD SUCCESSFUL". If failed, inspect JUnit XML report. Dependency: -- If missing, add: - - Groovy: testImplementation libs.tabletest - - Kotlin: testImplementation(libs.tabletest) +- @TableTest should be in `gradle/java_deps.gradle` as `testImplementation libs.tabletest` where Java modules inherit it via `gradle/java.gradle`. +- As a fallback, add module-specific `testImplementation(libs.tabletest)` or `testImplementation libs.tabletest`. Import: `import org.tabletest.junit.TableTest;` diff --git a/dd-trace-api/build.gradle.kts b/dd-trace-api/build.gradle.kts index c715fb62bdd..bc05a8753a4 100644 --- a/dd-trace-api/build.gradle.kts +++ b/dd-trace-api/build.gradle.kts @@ -75,6 +75,5 @@ dependencies { api(libs.slf4j) testImplementation(libs.guava) testImplementation(libs.bundles.mockito) - testImplementation(libs.tabletest) testImplementation(project(":utils:test-utils")) } diff --git a/dd-trace-api/src/test/java/datadog/trace/api/DDTraceIdTest.java b/dd-trace-api/src/test/java/datadog/trace/api/DDTraceIdTest.java index 384084b2077..14febcf7408 100644 --- a/dd-trace-api/src/test/java/datadog/trace/api/DDTraceIdTest.java +++ b/dd-trace-api/src/test/java/datadog/trace/api/DDTraceIdTest.java @@ -159,18 +159,18 @@ void failParsingIllegal128BitIdHexadecimalStringRepresentation(String hexId) { } @TableTest({ - "scenario | hexId | start | length | lowerCaseOnly", - "null string | | 0 | 0 | true ", - "empty string | '' | 0 | 0 | true ", - "out of bound length | '123456789abcdef0' | 0 | 17 | true ", - "out of bound end | '123456789abcdef0' | 7 | 10 | true ", - "out of bound start | '123456789abcdef0' | 17 | 0 | true ", - "invalid minus one | '-1' | 0 | 1 | true ", - "invalid minus a | '-a' | 0 | 1 | true ", - "invalid character | '123abcg' | 0 | 7 | true ", - "invalid upper case A | 'A' | 0 | 1 | true ", - "invalid upper case | '123ABC' | 0 | 6 | true ", - "too long | '111111111111111111111111111111111' | 0 | 33 | true" + "scenario | hexId | start | length | lowerCaseOnly", + "null string | | 0 | 0 | true ", + "empty string | '' | 0 | 0 | true ", + "out of bound length | '123456789abcdef0' | 0 | 17 | true ", + "out of bound end | '123456789abcdef0' | 7 | 10 | true ", + "out of bound start | '123456789abcdef0' | 17 | 0 | true ", + "invalid minus one | '-1' | 0 | 1 | true ", + "invalid minus a | '-a' | 0 | 1 | true ", + "invalid character | '123abcg' | 0 | 7 | true ", + "invalid upper case A | 'A' | 0 | 1 | true ", + "invalid upper case | '123ABC' | 0 | 6 | true ", + "too long | '111111111111111111111111111111111' | 0 | 33 | true " }) @ParameterizedTest void failParsingIllegal128BitIdHexadecimalStringRepresentationFromPartialString( diff --git a/gradle/java_deps.gradle b/gradle/java_deps.gradle index cb0762bf10c..80c4eda9aa3 100644 --- a/gradle/java_deps.gradle +++ b/gradle/java_deps.gradle @@ -3,6 +3,7 @@ apply plugin: 'groovy' dependencies { testImplementation libs.bundles.spock testImplementation libs.bundles.groovy + testImplementation libs.tabletest testImplementation libs.bundles.test.logging