1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.android.managedprovisioning.analytics;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 
21 import android.annotation.NonNull;
22 import android.app.admin.DevicePolicyEventLogger;
23 import android.text.TextUtils;
24 
25 import java.util.Arrays;
26 import java.util.Objects;
27 
28 class AnalyticsRoboTestUtils {
assertDevicePolicyEventLoggerEqual( @onNull DevicePolicyEventLogger logger1, @NonNull DevicePolicyEventLogger logger2)29     static void assertDevicePolicyEventLoggerEqual(
30             @NonNull DevicePolicyEventLogger logger1, @NonNull DevicePolicyEventLogger logger2) {
31         assertThat(logger1).isNotNull();
32         assertThat(logger2).isNotNull();
33         assertAdminPackageNamesEqual(logger1, logger2);
34         assertThat(logger1.getBoolean()).isEqualTo(logger2.getBoolean());
35         assertThat(logger1.getInt()).isEqualTo(logger2.getInt());
36         assertThat(logger1.getEventId()).isEqualTo(logger2.getEventId());
37         assertThat(logger1.getTimePeriod()).isEqualTo(logger2.getTimePeriod());
38         assertStringArraysEqual(logger1, logger2);
39     }
40 
41     /**
42      * For string types, protos write an empty string instead of nulls.
43      */
assertAdminPackageNamesEqual( DevicePolicyEventLogger logger1, DevicePolicyEventLogger logger2)44     private static void assertAdminPackageNamesEqual(
45             DevicePolicyEventLogger logger1, DevicePolicyEventLogger logger2) {
46         if (logger1.getAdminPackageName() == null || logger2.getAdminPackageName() == null) {
47             assertThat(TextUtils.isEmpty(logger1.getAdminPackageName())).isTrue();
48             assertThat(TextUtils.isEmpty(logger2.getAdminPackageName())).isTrue();
49         } else {
50             assertThat(logger1.getAdminPackageName()).isEqualTo(logger2.getAdminPackageName());
51         }
52     }
53 
54     /**
55      * Since protos drop null values when writing string arrays, we ignore them.
56      *
57      * <p>If the string array is, for example <code>[null, null, "abc", null]</code>,
58      * when it gets written to the proto, it's then read as ["abc"], because protos drop null
59      * values. Since we are comparing the array we've written and the array we've read, we must
60      * account for that.
61      *
62      * <p>Note that if the array is <code>[null, null, null]</code>, it's never
63      * written to the proto, so the expected read value is a <code>null</code> array.
64      */
assertStringArraysEqual( DevicePolicyEventLogger logger1, DevicePolicyEventLogger logger2)65     private static void assertStringArraysEqual(
66             DevicePolicyEventLogger logger1, DevicePolicyEventLogger logger2) {
67         final String[] strings1 = sanitize(logger1.getStringArray());
68         final String[] strings2 = sanitize(logger2.getStringArray());
69 
70         if (strings1 == null || strings2 == null) {
71             assertThat(strings1).isNull();
72             assertThat(strings2).isNull();
73             return;
74         }
75 
76         assertThat(strings1.length).isEqualTo(strings2.length);
77         for (int i = 0; i < strings1.length; i++) {
78             assertThat(strings1[i]).isEqualTo(strings2[i]);
79         }
80     }
81 
82     /**
83      * Strips the array of null values.
84      *
85      * <p><p><i>Examples</i>:
86      * <p>If array1 is <code>["abc", "def"]</code> and array2 is <code>["abc", "def"]</code>,
87      * we return <code>true</code>.
88      *
89      * <p>If array1 is <code>[null, "abc", null]</code> and array2 is <code>["abc"]</code> (or vice
90      * versa), we return <code>true</code>.
91      *
92      * <p>If array1 is <code>[null, null, null]</code> and array2 is <code>null</code> (or vice
93      * versa), we return <code>true</code>.
94      */
sanitize(String[] stringArray)95     private static String[] sanitize(String[] stringArray) {
96         if (stringArray == null) {
97             return null;
98         }
99         final String[] strippedArray =
100                 Arrays.stream(stringArray).filter(Objects::nonNull).toArray(String[]::new);
101         if (strippedArray.length == 0) {
102             return null;
103         }
104         return strippedArray;
105     }
106 
assertDevicePolicyEventLoggersEqual( DevicePolicyEventLogger[] loggers1, DevicePolicyEventLogger[] loggers2)107     static void assertDevicePolicyEventLoggersEqual(
108             DevicePolicyEventLogger[] loggers1, DevicePolicyEventLogger[] loggers2) {
109         assertThat(loggers1).isNotNull();
110         assertThat(loggers2).isNotNull();
111         assertThat(loggers1.length).isEqualTo(loggers2.length);
112         for (int i = 0; i < loggers1.length; i++) {
113             assertDevicePolicyEventLoggerEqual(loggers1[i], loggers2[i]);
114         }
115     }
116 }
117