blob: 0d851b83caf0327b77e3bc937fd8f96b2fe7da25 [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.adservices.service.measurement.aggregation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import androidx.test.filters.SmallTest;
import org.junit.Test;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/** Unit tests for {@link AggregatePayloadGenerator} */
@SmallTest
public final class AggregatePayloadGeneratorTest {
@Test
public void testIsFilterMatchReturnTrue() {
Map<String, List<String>> sourceFilterMap = new HashMap<>();
sourceFilterMap.put("conversion_subdomain",
Collections.singletonList("electronics.megastore"));
sourceFilterMap.put("product", Arrays.asList("1234", "234"));
sourceFilterMap.put("ctid", Collections.singletonList("id"));
AggregateFilterData sourceFilter = new AggregateFilterData.Builder()
.setAttributionFilterMap(sourceFilterMap).build();
Map<String, List<String>> triggerFilterMap = new HashMap<>();
triggerFilterMap.put("conversion_subdomain",
Collections.singletonList("electronics.megastore"));
triggerFilterMap.put("product", Arrays.asList("1234", "2345"));
triggerFilterMap.put("id", Arrays.asList("1", "2"));
AggregateFilterData triggerFilter = new AggregateFilterData.Builder()
.setAttributionFilterMap(triggerFilterMap).build();
assertTrue(
AggregatePayloadGenerator.isFilterMatch(sourceFilter, triggerFilter, true));
}
@Test
public void testIsFilterMatchReturnFalse() {
Map<String, List<String>> sourceFilterMap = new HashMap<>();
sourceFilterMap.put("conversion_subdomain",
Collections.singletonList("electronics.megastore"));
sourceFilterMap.put("product", Arrays.asList("1234", "234"));
sourceFilterMap.put("ctid", Collections.singletonList("id"));
AggregateFilterData sourceFilter = new AggregateFilterData.Builder()
.setAttributionFilterMap(sourceFilterMap).build();
Map<String, List<String>> triggerFilterMap = new HashMap<>();
triggerFilterMap.put("conversion_subdomain",
Collections.singletonList("electronics.megastore"));
triggerFilterMap.put("product", Arrays.asList("1", "2")); // doesn't match.
triggerFilterMap.put("id", Arrays.asList("1", "2"));
AggregateFilterData triggerFilter = new AggregateFilterData.Builder()
.setAttributionFilterMap(triggerFilterMap).build();
assertFalse(
AggregatePayloadGenerator.isFilterMatch(sourceFilter, triggerFilter, true));
}
@Test
public void testIsNotFilterMatchReturnTrue() {
Map<String, List<String>> sourceFilterMap = new HashMap<>();
sourceFilterMap.put("conversion_subdomain",
Collections.singletonList("electronics.megastore"));
sourceFilterMap.put("product", Arrays.asList("1234", "234"));
sourceFilterMap.put("ctid", Collections.singletonList("id"));
AggregateFilterData sourceFilter = new AggregateFilterData.Builder()
.setAttributionFilterMap(sourceFilterMap).build();
Map<String, List<String>> triggerFilterMap = new HashMap<>();
triggerFilterMap.put("conversion_subdomain", Collections.singletonList("electronics"));
triggerFilterMap.put("product", Arrays.asList("1", "2")); // doesn't match.
triggerFilterMap.put("id", Arrays.asList("1", "2"));
AggregateFilterData triggerFilter = new AggregateFilterData.Builder()
.setAttributionFilterMap(triggerFilterMap).build();
assertTrue(AggregatePayloadGenerator.isFilterMatch(
sourceFilter, triggerFilter, false));
}
@Test
public void testIsNotFilterMatchReturnFalse() {
Map<String, List<String>> sourceFilterMap = new HashMap<>();
sourceFilterMap.put("conversion_subdomain",
Collections.singletonList("electronics.megastore"));
sourceFilterMap.put("product", Arrays.asList("1234", "234"));
sourceFilterMap.put("ctid", Collections.singletonList("id"));
AggregateFilterData sourceFilter = new AggregateFilterData.Builder()
.setAttributionFilterMap(sourceFilterMap).build();
Map<String, List<String>> triggerFilterMap = new HashMap<>();
triggerFilterMap.put("conversion_subdomain",
Collections.singletonList("electronics.megastore"));
triggerFilterMap.put("product", Arrays.asList("1234", "2345"));
triggerFilterMap.put("id", Arrays.asList("1", "2"));
AggregateFilterData triggerFilter = new AggregateFilterData.Builder()
.setAttributionFilterMap(triggerFilterMap).build();
assertFalse(
AggregatePayloadGenerator.isFilterMatch(sourceFilter, triggerFilter, false));
}
@Test
public void testGenerateAttributionReportTwoContributionsSuccessfully() {
// Build AggregatableAttributionSource.
Map<String, AttributionAggregatableKey> aggregatableSource = new HashMap<>();
aggregatableSource.put("campaignCounts",
new AttributionAggregatableKey.Builder().setHighBits(0L).setLowBits(345L).build());
aggregatableSource.put("geoValue",
new AttributionAggregatableKey.Builder().setHighBits(0L).setLowBits(5L).build());
Map<String, List<String>> sourceFilterMap = new HashMap<>();
sourceFilterMap.put("conversion_subdomain",
Collections.singletonList("electronics.megastore"));
sourceFilterMap.put("product", Arrays.asList("1234", "234"));
sourceFilterMap.put("ctid", Collections.singletonList("id"));
AggregateFilterData sourceFilter = new AggregateFilterData.Builder()
.setAttributionFilterMap(sourceFilterMap).build();
AggregatableAttributionSource attributionSource =
new AggregatableAttributionSource.Builder()
.setAggregatableSource(aggregatableSource)
.setAggregateFilterData(sourceFilter).build();
// Build AggregatableAttributionTrigger.
List<AggregateTriggerData> triggerDataList = new ArrayList<>();
// Apply this key_piece to "campaignCounts".
Map<String, List<String>> triggerDataFilter1 = new HashMap<>();
triggerDataFilter1.put("product", Collections.singletonList("1234"));
triggerDataFilter1.put("ctid", Collections.singletonList("id"));
Map<String, List<String>> triggerDataNotFilter1 = new HashMap<>();
triggerDataNotFilter1.put("product", Collections.singletonList("100"));
triggerDataList.add(
new AggregateTriggerData.Builder()
.setKey(new AttributionAggregatableKey.Builder()
.setHighBits(0L).setLowBits(1024L).build())
.setSourceKeys(new HashSet<>(Collections.singletonList("campaignCounts")))
.setFilter(new AggregateFilterData.Builder()
.setAttributionFilterMap(triggerDataFilter1).build())
.setNotFilter(new AggregateFilterData.Builder()
.setAttributionFilterMap(triggerDataNotFilter1).build()).build());
// Apply this key_piece to "geoValue".
triggerDataList.add(
new AggregateTriggerData.Builder()
.setKey(new AttributionAggregatableKey.Builder()
.setHighBits(0L).setLowBits(2688L).build())
.setSourceKeys(new HashSet<>(Arrays.asList("geoValue", "nonMatch")))
.build());
Map<String, Integer> values = new HashMap<>();
values.put("campaignCounts", 32768);
values.put("geoValue", 1664);
AggregatableAttributionTrigger attributionTrigger =
new AggregatableAttributionTrigger.Builder()
.setTriggerData(triggerDataList)
.setValues(values).build();
Optional<CleartextAggregatePayload> attributionReport =
AggregatePayloadGenerator.generateAttributionReport(
attributionSource, attributionTrigger);
assertTrue(attributionReport.isPresent());
List<AggregateHistogramContribution> contributions =
attributionReport.get().getAggregateAttributionData().getContributions();
assertEquals(contributions.size(), 2);
assertTrue(contributions.contains(
new AggregateHistogramContribution.Builder()
.setKey(BigInteger.valueOf(1369L)).setValue(32768).build()));
assertTrue(contributions.contains(
new AggregateHistogramContribution.Builder()
.setKey(BigInteger.valueOf(2693L)).setValue(1664).build()));
}
@Test
public void testGenerateAttributionReportOnlyTwoContributionsSuccessfully() {
// Build AggregatableAttributionSource.
Map<String, AttributionAggregatableKey> aggregatableSource = new HashMap<>();
aggregatableSource.put("campaignCounts",
new AttributionAggregatableKey.Builder().setHighBits(0L).setLowBits(345L).build());
aggregatableSource.put("geoValue",
new AttributionAggregatableKey.Builder().setHighBits(0L).setLowBits(5L).build());
aggregatableSource.put("thirdSource",
new AttributionAggregatableKey.Builder().setHighBits(0L).setLowBits(100L).build());
Map<String, List<String>> sourceFilterMap = new HashMap<>();
sourceFilterMap.put("conversion_subdomain",
Collections.singletonList("electronics.megastore"));
sourceFilterMap.put("product", Arrays.asList("1234", "234"));
sourceFilterMap.put("ctid", Collections.singletonList("id"));
AggregateFilterData sourceFilter = new AggregateFilterData.Builder()
.setAttributionFilterMap(sourceFilterMap).build();
AggregatableAttributionSource attributionSource =
new AggregatableAttributionSource.Builder()
.setAggregatableSource(aggregatableSource)
.setAggregateFilterData(sourceFilter).build();
// Build AggregatableAttributionTrigger.
List<AggregateTriggerData> triggerDataList = new ArrayList<>();
// Apply this key_piece to "campaignCounts".
Map<String, List<String>> triggerDataFilter1 = new HashMap<>();
triggerDataFilter1.put("product", Collections.singletonList("1234"));
triggerDataFilter1.put("ctid", Collections.singletonList("id"));
Map<String, List<String>> triggerDataNotFilter1 = new HashMap<>();
triggerDataNotFilter1.put("product", Collections.singletonList("100"));
triggerDataList.add(
new AggregateTriggerData.Builder()
.setKey(new AttributionAggregatableKey.Builder()
.setHighBits(0L).setLowBits(1024L).build())
.setSourceKeys(new HashSet<>(Collections.singletonList("campaignCounts")))
.setFilter(new AggregateFilterData.Builder()
.setAttributionFilterMap(triggerDataFilter1).build())
.setNotFilter(new AggregateFilterData.Builder()
.setAttributionFilterMap(triggerDataNotFilter1).build())
.build());
// Apply this key_piece to "geoValue".
triggerDataList.add(
new AggregateTriggerData.Builder()
.setKey(new AttributionAggregatableKey.Builder()
.setHighBits(0L).setLowBits(2688L).build())
.setSourceKeys(new HashSet<>(Arrays.asList("geoValue", "nonMatch")))
.build());
Map<String, Integer> values = new HashMap<>();
values.put("campaignCounts", 32768);
values.put("geoValue", 1664);
values.put("thirdSource", 100);
AggregatableAttributionTrigger attributionTrigger =
new AggregatableAttributionTrigger.Builder()
.setTriggerData(triggerDataList)
.setValues(values).build();
Optional<CleartextAggregatePayload> attributionReport =
AggregatePayloadGenerator.generateAttributionReport(
attributionSource, attributionTrigger);
assertTrue(attributionReport.isPresent());
List<AggregateHistogramContribution> contributions =
attributionReport.get().getAggregateAttributionData().getContributions();
assertEquals(contributions.size(), 2);
assertTrue(contributions.contains(
new AggregateHistogramContribution.Builder()
.setKey(BigInteger.valueOf(1369L)).setValue(32768).build()));
assertTrue(contributions.contains(
new AggregateHistogramContribution.Builder()
.setKey(BigInteger.valueOf(2693L)).setValue(1664).build()));
}
@Test
public void testGenerateAttributionReportMoreTriggerDataSuccessfully() {
// Build AggregatableAttributionSource.
Map<String, AttributionAggregatableKey> aggregatableSource = new HashMap<>();
aggregatableSource.put("campaignCounts",
new AttributionAggregatableKey.Builder().setHighBits(0L).setLowBits(345L).build());
aggregatableSource.put("geoValue",
new AttributionAggregatableKey.Builder().setHighBits(0L).setLowBits(5L).build());
Map<String, List<String>> sourceFilterMap = new HashMap<>();
sourceFilterMap.put("conversion_subdomain",
Collections.singletonList("electronics.megastore"));
sourceFilterMap.put("product", Arrays.asList("1234", "234"));
sourceFilterMap.put("ctid", Collections.singletonList("id"));
AggregateFilterData sourceFilter = new AggregateFilterData.Builder()
.setAttributionFilterMap(sourceFilterMap).build();
AggregatableAttributionSource attributionSource =
new AggregatableAttributionSource.Builder()
.setAggregatableSource(aggregatableSource)
.setAggregateFilterData(sourceFilter).build();
// Build AggregatableAttributionTrigger.
List<AggregateTriggerData> triggerDataList = new ArrayList<>();
// Apply this key_piece to "campaignCounts".
Map<String, List<String>> triggerDataFilter1 = new HashMap<>();
triggerDataFilter1.put("product", Collections.singletonList("1234"));
triggerDataFilter1.put("ctid", Collections.singletonList("id"));
Map<String, List<String>> triggerDataNotFilter1 = new HashMap<>();
triggerDataNotFilter1.put("product", Collections.singletonList("100"));
triggerDataList.add(
new AggregateTriggerData.Builder()
.setKey(new AttributionAggregatableKey.Builder()
.setHighBits(0L).setLowBits(1024L).build())
.setSourceKeys(new HashSet<>(Collections.singletonList("campaignCounts")))
.setFilter(new AggregateFilterData.Builder()
.setAttributionFilterMap(triggerDataFilter1).build())
.setNotFilter(new AggregateFilterData.Builder()
.setAttributionFilterMap(triggerDataNotFilter1).build())
.build());
// Apply this key_piece to "geoValue".
triggerDataList.add(
new AggregateTriggerData.Builder()
.setKey(new AttributionAggregatableKey.Builder()
.setHighBits(0L).setLowBits(2688L).build())
.setSourceKeys(new HashSet<>(Arrays.asList("geoValue", "nonMatch")))
.build());
// Apply this key_piece to "geoValue".
triggerDataList.add(
new AggregateTriggerData.Builder()
.setKey(new AttributionAggregatableKey.Builder()
.setHighBits(0L).setLowBits(768L).build())
.setSourceKeys(new HashSet<>(Collections.singletonList("geoValue")))
.build());
// Don't apply this key_piece.
Map<String, List<String>> triggerDataFilter2 = new HashMap<>();
triggerDataFilter2.put("product", Collections.singletonList("0"));
triggerDataList.add(
new AggregateTriggerData.Builder()
.setKey(new AttributionAggregatableKey.Builder()
.setHighBits(0L).setLowBits(200L).build())
.setSourceKeys(new HashSet<>(Arrays.asList("campaignCounts", "geoValue")))
.setFilter(new AggregateFilterData.Builder()
.setAttributionFilterMap(triggerDataFilter2).build())
.build());
Map<String, Integer> values = new HashMap<>();
values.put("campaignCounts", 32768);
values.put("geoValue", 1664);
AggregatableAttributionTrigger attributionTrigger =
new AggregatableAttributionTrigger.Builder()
.setTriggerData(triggerDataList)
.setValues(values).build();
Optional<CleartextAggregatePayload> attributionReport =
AggregatePayloadGenerator.generateAttributionReport(
attributionSource, attributionTrigger);
assertTrue(attributionReport.isPresent());
List<AggregateHistogramContribution> contributions =
attributionReport.get().getAggregateAttributionData().getContributions();
assertEquals(contributions.size(), 2);
assertTrue(contributions.contains(
new AggregateHistogramContribution.Builder()
.setKey(BigInteger.valueOf(1369L)).setValue(32768).build()));
assertTrue(contributions.contains(
new AggregateHistogramContribution.Builder()
.setKey(BigInteger.valueOf(3461L)).setValue(1664).build()));
}
}