From 4adfb1292488eedcf39d0d8f30df579160de0221 Mon Sep 17 00:00:00 2001 From: Aleksandrs Ulme Date: Wed, 4 Jun 2025 16:43:03 +0800 Subject: [PATCH 1/5] Batch email test for identity map --- src/test/java/suite/operator/TestData.java | 30 ++++++++++++++++--- .../suite/operator/V2ApiOperatorTest.java | 26 ++++++++++++++++ 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/test/java/suite/operator/TestData.java b/src/test/java/suite/operator/TestData.java index 38a6df8..fc366fb 100644 --- a/src/test/java/suite/operator/TestData.java +++ b/src/test/java/suite/operator/TestData.java @@ -3,14 +3,15 @@ import app.AppsMap; import app.component.App; import app.component.Operator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.uid2.client.DecryptionStatus; import org.junit.jupiter.params.provider.Arguments; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; +import java.util.stream.IntStream; import java.util.stream.Stream; import static org.junit.jupiter.api.Named.named; @@ -326,6 +327,27 @@ public static Set identityMapBatchEmailArgs() { return args; } + public static Set identityMapBigBatchArgs() throws JsonProcessingException { + Set operators = AppsMap.getApps(Operator.class); + + List emails = IntStream.range(0, 10_000) + .mapToObj(i -> "email_" + i + "_" + UUID.randomUUID() + "@example.com") + .collect(Collectors.toList()); + + ObjectMapper mapper = new ObjectMapper(); + ObjectNode root = mapper.createObjectNode(); + root.putPOJO("email", emails); + root.put("policy", 1); + + String emailsPayload = mapper.writeValueAsString(root); + + Set args = new HashSet<>(); + for (Operator operator : operators) { + args.add(Arguments.of("10k emails", operator, operator.getName(), emailsPayload, emails)); + } + return args; + } + public static Set identityMapBatchEmailArgsBadPolicy() { Set operators = getPublicOperators(); Set> inputs = Set.of( diff --git a/src/test/java/suite/operator/V2ApiOperatorTest.java b/src/test/java/suite/operator/V2ApiOperatorTest.java index 1a5430d..84f1030 100644 --- a/src/test/java/suite/operator/V2ApiOperatorTest.java +++ b/src/test/java/suite/operator/V2ApiOperatorTest.java @@ -7,9 +7,13 @@ import app.component.Operator; import com.fasterxml.jackson.databind.JsonNode; import com.uid2.client.*; +import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; +import java.time.Duration; +import java.util.List; + import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; @@ -105,6 +109,28 @@ public void testV2IdentityMap(String label, Operator operator, String operatorNa assertThat(response.at("/status").asText()).isEqualTo("success"); } + @ParameterizedTest(name = "/v2/identity/map - {0} - {2}") + @MethodSource({ + "suite.operator.TestData#identityMapBigBatchArgs" + }) + public void testV2IdentityMapLargeBatch(String label, Operator operator, String operatorName, String payload, List diis) { + assertTimeoutPreemptively(Duration.ofSeconds(5), () -> { // Validate we didn't make mapping too slow. + JsonNode response = operator.v2IdentityMap(payload); + + assertThat(response.at("/status").asText()).isEqualTo("success"); + + var mapped = response.at("/body/mapped"); + assertThat(mapped.size()).isEqualTo(10_000); + + for (int i = 0; i < 10_000; i++) { + assertThat(mapped.get(i).get("identifier").asText()).isEqualTo(diis.get(i)); + assertThat(mapped.get(i).get("advertising_id").asText()).isNotNull().isNotEmpty(); + assertThat(mapped.get(i).get("bucket_id").asText()).isNotNull().isNotEmpty(); + } + }); + } + + @ParameterizedTest(name = "/v2/identity/map - VALIDATE EMAIL - {0} - {2}") @MethodSource({ "suite.operator.TestData#tokenValidateEmailArgs", From cdc93297187cda130fd2dd1350332b9e3d4ac6af Mon Sep 17 00:00:00 2001 From: Aleksandrs Ulme Date: Wed, 4 Jun 2025 17:28:42 +0800 Subject: [PATCH 2/5] Added phones to identity map batch test --- src/test/java/suite/operator/TestData.java | 23 ++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/test/java/suite/operator/TestData.java b/src/test/java/suite/operator/TestData.java index fc366fb..940debf 100644 --- a/src/test/java/suite/operator/TestData.java +++ b/src/test/java/suite/operator/TestData.java @@ -328,22 +328,29 @@ public static Set identityMapBatchEmailArgs() { } public static Set identityMapBigBatchArgs() throws JsonProcessingException { + ObjectMapper mapper = new ObjectMapper(); + Random random = new Random(); Set operators = AppsMap.getApps(Operator.class); - List emails = IntStream.range(0, 10_000) - .mapToObj(i -> "email_" + i + "_" + UUID.randomUUID() + "@example.com") - .collect(Collectors.toList()); + List emails = new ArrayList<>(); + List phones = new ArrayList<>(); + for (int i = 0; i < 10_000; i++) { + emails.add("email_" + Math.abs(random.nextLong()) + "@example.com"); - ObjectMapper mapper = new ObjectMapper(); - ObjectNode root = mapper.createObjectNode(); - root.putPOJO("email", emails); - root.put("policy", 1); + // Phone numbers with 15 digits are technically valid but are not used in any country + phones.add("+" + String.format("%015d", Math.abs(random.nextLong() % 1_000_000_000_000_000L))); + } + + var emailsJson = mapper.createObjectNode().putPOJO("email", emails).put("policy", 1); + String emailsPayload = mapper.writeValueAsString(emailsJson); - String emailsPayload = mapper.writeValueAsString(root); + var phonesJson = mapper.createObjectNode().putPOJO("phone", phones).put("policy", 1); + String phonesPayload = mapper.writeValueAsString(phonesJson); Set args = new HashSet<>(); for (Operator operator : operators) { args.add(Arguments.of("10k emails", operator, operator.getName(), emailsPayload, emails)); + args.add(Arguments.of("10k phones", operator, operator.getName(), phonesPayload, phones)); } return args; } From bcba9a9ad9dfad29e91136c2f36d00ff9e64ba00 Mon Sep 17 00:00:00 2001 From: Aleksandrs Ulme Date: Wed, 4 Jun 2025 17:40:58 +0800 Subject: [PATCH 3/5] Added phone hashes to bulk V2 identity map test --- src/test/java/suite/operator/TestData.java | 27 ++++++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/test/java/suite/operator/TestData.java b/src/test/java/suite/operator/TestData.java index 940debf..c5a6cba 100644 --- a/src/test/java/suite/operator/TestData.java +++ b/src/test/java/suite/operator/TestData.java @@ -5,19 +5,18 @@ import app.component.Operator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; import com.uid2.client.DecryptionStatus; import org.junit.jupiter.params.provider.Arguments; import java.util.*; import java.util.stream.Collectors; -import java.util.stream.IntStream; import java.util.stream.Stream; import static org.junit.jupiter.api.Named.named; public final class TestData { public static final int RAW_UID2_LENGTH = 44; + private static final Random RANDOM = new Random(); private TestData() { } @@ -329,16 +328,20 @@ public static Set identityMapBatchEmailArgs() { public static Set identityMapBigBatchArgs() throws JsonProcessingException { ObjectMapper mapper = new ObjectMapper(); - Random random = new Random(); Set operators = AppsMap.getApps(Operator.class); List emails = new ArrayList<>(); List phones = new ArrayList<>(); + List emailHashes = new ArrayList<>(); + List phoneHashes = new ArrayList<>(); for (int i = 0; i < 10_000; i++) { - emails.add("email_" + Math.abs(random.nextLong()) + "@example.com"); + emails.add("email_" + Math.abs(RANDOM.nextLong()) + "@example.com"); // Phone numbers with 15 digits are technically valid but are not used in any country - phones.add("+" + String.format("%015d", Math.abs(random.nextLong() % 1_000_000_000_000_000L))); + phones.add("+" + String.format("%015d", Math.abs(RANDOM.nextLong() % 1_000_000_000_000_000L))); + + emailHashes.add(fakeRandomHash()); + phoneHashes.add(fakeRandomHash()); } var emailsJson = mapper.createObjectNode().putPOJO("email", emails).put("policy", 1); @@ -347,14 +350,28 @@ public static Set identityMapBigBatchArgs() throws JsonProcessingExce var phonesJson = mapper.createObjectNode().putPOJO("phone", phones).put("policy", 1); String phonesPayload = mapper.writeValueAsString(phonesJson); + var emailHashesJson = mapper.createObjectNode().putPOJO("email_hash", emailHashes).put("policy", 1); + String emailHashesPayload = mapper.writeValueAsString(emailHashesJson); + + var phoneHashesJson = mapper.createObjectNode().putPOJO("phone_hash", phoneHashes).put("policy", 1); + String phoneHashesPayload = mapper.writeValueAsString(phoneHashesJson); + Set args = new HashSet<>(); for (Operator operator : operators) { args.add(Arguments.of("10k emails", operator, operator.getName(), emailsPayload, emails)); args.add(Arguments.of("10k phones", operator, operator.getName(), phonesPayload, phones)); + args.add(Arguments.of("10k email hashes", operator, operator.getName(), emailHashesPayload, emailHashes)); + args.add(Arguments.of("10k phone hashes", operator, operator.getName(), phoneHashesPayload, phoneHashes)); } return args; } + private static String fakeRandomHash() { + byte[] randomBytes = new byte[32]; + RANDOM.nextBytes(randomBytes); + return Base64.getEncoder().encodeToString(randomBytes); + } + public static Set identityMapBatchEmailArgsBadPolicy() { Set operators = getPublicOperators(); Set> inputs = Set.of( From 7fff38b89b7b680d27c2ee47178006b85d1cf7b7 Mon Sep 17 00:00:00 2001 From: Aleksandrs Ulme Date: Wed, 4 Jun 2025 17:45:36 +0800 Subject: [PATCH 4/5] refactoring --- src/test/java/suite/operator/TestData.java | 43 +++++++++++-------- .../suite/operator/V2ApiOperatorTest.java | 1 - 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/test/java/suite/operator/TestData.java b/src/test/java/suite/operator/TestData.java index c5a6cba..a78ed9b 100644 --- a/src/test/java/suite/operator/TestData.java +++ b/src/test/java/suite/operator/TestData.java @@ -335,26 +335,16 @@ public static Set identityMapBigBatchArgs() throws JsonProcessingExce List emailHashes = new ArrayList<>(); List phoneHashes = new ArrayList<>(); for (int i = 0; i < 10_000; i++) { - emails.add("email_" + Math.abs(RANDOM.nextLong()) + "@example.com"); - - // Phone numbers with 15 digits are technically valid but are not used in any country - phones.add("+" + String.format("%015d", Math.abs(RANDOM.nextLong() % 1_000_000_000_000_000L))); - - emailHashes.add(fakeRandomHash()); - phoneHashes.add(fakeRandomHash()); + emails.add(random_email()); + phones.add(randomPhoneNumber()); + emailHashes.add(randomHash()); + phoneHashes.add(randomHash()); } - var emailsJson = mapper.createObjectNode().putPOJO("email", emails).put("policy", 1); - String emailsPayload = mapper.writeValueAsString(emailsJson); - - var phonesJson = mapper.createObjectNode().putPOJO("phone", phones).put("policy", 1); - String phonesPayload = mapper.writeValueAsString(phonesJson); - - var emailHashesJson = mapper.createObjectNode().putPOJO("email_hash", emailHashes).put("policy", 1); - String emailHashesPayload = mapper.writeValueAsString(emailHashesJson); - - var phoneHashesJson = mapper.createObjectNode().putPOJO("phone_hash", phoneHashes).put("policy", 1); - String phoneHashesPayload = mapper.writeValueAsString(phoneHashesJson); + var emailsPayload = identityMapPayload(mapper, "email", emails); + var phonesPayload = identityMapPayload(mapper, "phone", phones); + var emailHashesPayload = identityMapPayload(mapper, "email_hash", emailHashes); + var phoneHashesPayload = identityMapPayload(mapper, "phone_hash", phoneHashes); Set args = new HashSet<>(); for (Operator operator : operators) { @@ -366,7 +356,22 @@ public static Set identityMapBigBatchArgs() throws JsonProcessingExce return args; } - private static String fakeRandomHash() { + private static String identityMapPayload(ObjectMapper mapper, String field, List diis) throws JsonProcessingException { + var json = mapper.createObjectNode().putPOJO(field, diis).put("policy", 1); + return mapper.writeValueAsString(json); + } + + private static String random_email() { + return "email_" + Math.abs(RANDOM.nextLong()) + "@example.com"; + } + + private static String randomPhoneNumber() { + // Phone numbers with 15 digits are technically valid but are not used in any country + return "+" + String.format("%015d", Math.abs(RANDOM.nextLong() % 1_000_000_000_000_000L)); + } + + private static String randomHash() { + // This isn't really a hashed DII but looks like one ot UID2 byte[] randomBytes = new byte[32]; RANDOM.nextBytes(randomBytes); return Base64.getEncoder().encodeToString(randomBytes); diff --git a/src/test/java/suite/operator/V2ApiOperatorTest.java b/src/test/java/suite/operator/V2ApiOperatorTest.java index 84f1030..3800af1 100644 --- a/src/test/java/suite/operator/V2ApiOperatorTest.java +++ b/src/test/java/suite/operator/V2ApiOperatorTest.java @@ -7,7 +7,6 @@ import app.component.Operator; import com.fasterxml.jackson.databind.JsonNode; import com.uid2.client.*; -import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.MethodSource; From b4b6378403afe0d947daad5a39ea9cd9d9e877e3 Mon Sep 17 00:00:00 2001 From: Aleksandrs Ulme Date: Fri, 6 Jun 2025 07:48:08 +0800 Subject: [PATCH 5/5] Using camelCase --- src/test/java/suite/operator/TestData.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/suite/operator/TestData.java b/src/test/java/suite/operator/TestData.java index a78ed9b..bee844e 100644 --- a/src/test/java/suite/operator/TestData.java +++ b/src/test/java/suite/operator/TestData.java @@ -335,7 +335,7 @@ public static Set identityMapBigBatchArgs() throws JsonProcessingExce List emailHashes = new ArrayList<>(); List phoneHashes = new ArrayList<>(); for (int i = 0; i < 10_000; i++) { - emails.add(random_email()); + emails.add(randomEmail()); phones.add(randomPhoneNumber()); emailHashes.add(randomHash()); phoneHashes.add(randomHash()); @@ -361,7 +361,7 @@ private static String identityMapPayload(ObjectMapper mapper, String field, List return mapper.writeValueAsString(json); } - private static String random_email() { + private static String randomEmail() { return "email_" + Math.abs(RANDOM.nextLong()) + "@example.com"; }