1/*
2 * Copyright (C) 2016 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
17package com.android.server.connectivity;
18
19import android.net.ConnectivityMetricsEvent;
20import android.net.metrics.ApfProgramEvent;
21import android.net.metrics.ApfStats;
22import android.net.metrics.DefaultNetworkEvent;
23import android.net.metrics.DhcpClientEvent;
24import android.net.metrics.DhcpErrorEvent;
25import android.net.metrics.DnsEvent;
26import android.net.metrics.IpManagerEvent;
27import android.net.metrics.IpReachabilityEvent;
28import android.net.metrics.NetworkEvent;
29import android.net.metrics.RaEvent;
30import android.net.metrics.ValidationProbeEvent;
31import com.google.protobuf.nano.MessageNano;
32import java.util.Arrays;
33import junit.framework.TestCase;
34
35import static com.android.server.connectivity.metrics.IpConnectivityLogClass.IpConnectivityLog;
36import static com.android.server.connectivity.MetricsTestUtil.aBool;
37import static com.android.server.connectivity.MetricsTestUtil.aByteArray;
38import static com.android.server.connectivity.MetricsTestUtil.aLong;
39import static com.android.server.connectivity.MetricsTestUtil.aString;
40import static com.android.server.connectivity.MetricsTestUtil.aType;
41import static com.android.server.connectivity.MetricsTestUtil.anInt;
42import static com.android.server.connectivity.MetricsTestUtil.anIntArray;
43import static com.android.server.connectivity.MetricsTestUtil.b;
44import static com.android.server.connectivity.MetricsTestUtil.describeIpEvent;
45import static com.android.server.connectivity.MetricsTestUtil.ipEv;
46
47public class IpConnectivityEventBuilderTest extends TestCase {
48
49    public void testDefaultNetworkEventSerialization() {
50        ConnectivityMetricsEvent ev = describeIpEvent(
51                aType(DefaultNetworkEvent.class),
52                anInt(102),
53                anIntArray(1, 2, 3),
54                anInt(101),
55                aBool(true),
56                aBool(false));
57
58        String want = joinLines(
59                "dropped_events: 0",
60                "events <",
61                "  default_network_event <",
62                "    network_id <",
63                "      network_id: 102",
64                "    >",
65                "    previous_network_id <",
66                "      network_id: 101",
67                "    >",
68                "    previous_network_ip_support: 1",
69                "    transport_types: 1",
70                "    transport_types: 2",
71                "    transport_types: 3",
72                "  >",
73                "  time_ms: 1",
74                ">");
75
76        verifySerialization(want, ev);
77    }
78
79    public void testDhcpClientEventSerialization() {
80        ConnectivityMetricsEvent ev = describeIpEvent(
81                aType(DhcpClientEvent.class),
82                aString("wlan0"),
83                aString("SomeState"),
84                anInt(192));
85
86        String want = joinLines(
87                "dropped_events: 0",
88                "events <",
89                "  dhcp_event <",
90                "    duration_ms: 192",
91                "    error_code: 0",
92                "    if_name: \"wlan0\"",
93                "    state_transition: \"SomeState\"",
94                "  >",
95                "  time_ms: 1",
96                ">");
97
98        verifySerialization(want, ev);
99    }
100
101    public void testDhcpErrorEventSerialization() {
102        ConnectivityMetricsEvent ev = describeIpEvent(
103                aType(DhcpErrorEvent.class),
104                aString("wlan0"),
105                anInt(DhcpErrorEvent.L4_NOT_UDP));
106
107        String want = joinLines(
108                "dropped_events: 0",
109                "events <",
110                "  dhcp_event <",
111                "    duration_ms: 0",
112                "    error_code: 50397184",
113                "    if_name: \"wlan0\"",
114                "    state_transition: \"\"",
115                "  >",
116                "  time_ms: 1",
117                ">");
118
119        verifySerialization(want, ev);
120    }
121
122    public void testDnsEventSerialization() {
123        ConnectivityMetricsEvent ev = describeIpEvent(
124                aType(DnsEvent.class),
125                anInt(101),
126                aByteArray(b(1), b(1), b(2), b(1), b(1), b(1), b(2), b(2)),
127                aByteArray(b(0), b(0), b(22), b(3), b(1), b(0), b(200), b(178)),
128                anIntArray(3456, 267, 1230, 45, 2111, 450, 638, 1300));
129
130        String want = joinLines(
131                "dropped_events: 0",
132                "events <",
133                "  dns_lookup_batch <",
134                "    event_types: 1",
135                "    event_types: 1",
136                "    event_types: 2",
137                "    event_types: 1",
138                "    event_types: 1",
139                "    event_types: 1",
140                "    event_types: 2",
141                "    event_types: 2",
142                "    latencies_ms: 3456",
143                "    latencies_ms: 267",
144                "    latencies_ms: 1230",
145                "    latencies_ms: 45",
146                "    latencies_ms: 2111",
147                "    latencies_ms: 450",
148                "    latencies_ms: 638",
149                "    latencies_ms: 1300",
150                "    network_id <",
151                "      network_id: 101",
152                "    >",
153                "    return_codes: 0",
154                "    return_codes: 0",
155                "    return_codes: 22",
156                "    return_codes: 3",
157                "    return_codes: 1",
158                "    return_codes: 0",
159                "    return_codes: 200",
160                "    return_codes: 178",
161                "  >",
162                "  time_ms: 1",
163                ">");
164
165        verifySerialization(want, ev);
166    }
167
168    public void testIpManagerEventSerialization() {
169        ConnectivityMetricsEvent ev = describeIpEvent(
170                aType(IpManagerEvent.class),
171                aString("wlan0"),
172                anInt(IpManagerEvent.PROVISIONING_OK),
173                aLong(5678));
174
175        String want = joinLines(
176                "dropped_events: 0",
177                "events <",
178                "  ip_provisioning_event <",
179                "    event_type: 1",
180                "    if_name: \"wlan0\"",
181                "    latency_ms: 5678",
182                "  >",
183                "  time_ms: 1",
184                ">");
185
186        verifySerialization(want, ev);
187    }
188
189    public void testIpReachabilityEventSerialization() {
190        ConnectivityMetricsEvent ev = describeIpEvent(
191                aType(IpReachabilityEvent.class),
192                aString("wlan0"),
193                anInt(IpReachabilityEvent.NUD_FAILED));
194
195        String want = joinLines(
196                "dropped_events: 0",
197                "events <",
198                "  ip_reachability_event <",
199                "    event_type: 512",
200                "    if_name: \"wlan0\"",
201                "  >",
202                "  time_ms: 1",
203                ">");
204
205        verifySerialization(want, ev);
206    }
207
208    public void testNetworkEventSerialization() {
209        ConnectivityMetricsEvent ev = describeIpEvent(
210                aType(NetworkEvent.class),
211                anInt(100),
212                anInt(5),
213                aLong(20410));
214
215        String want = joinLines(
216                "dropped_events: 0",
217                "events <",
218                "  network_event <",
219                "    event_type: 5",
220                "    latency_ms: 20410",
221                "    network_id <",
222                "      network_id: 100",
223                "    >",
224                "  >",
225                "  time_ms: 1",
226                ">");
227
228        verifySerialization(want, ev);
229    }
230
231    public void testValidationProbeEventSerialization() {
232        ConnectivityMetricsEvent ev = describeIpEvent(
233                aType(ValidationProbeEvent.class),
234                anInt(120),
235                aLong(40730),
236                anInt(ValidationProbeEvent.PROBE_HTTP),
237                anInt(204));
238
239        String want = joinLines(
240                "dropped_events: 0",
241                "events <",
242                "  time_ms: 1",
243                "  validation_probe_event <",
244                "    latency_ms: 40730",
245                "    network_id <",
246                "      network_id: 120",
247                "    >",
248                "    probe_result: 204",
249                "    probe_type: 1",
250                "  >",
251                ">");
252
253        verifySerialization(want, ev);
254    }
255
256    public void testApfProgramEventSerialization() {
257        ConnectivityMetricsEvent ev = describeIpEvent(
258                aType(ApfProgramEvent.class),
259                aLong(200),
260                anInt(7),
261                anInt(9),
262                anInt(2048),
263                anInt(3));
264
265        String want = joinLines(
266                "dropped_events: 0",
267                "events <",
268                "  apf_program_event <",
269                "    current_ras: 9",
270                "    drop_multicast: true",
271                "    filtered_ras: 7",
272                "    has_ipv4_addr: true",
273                "    lifetime: 200",
274                "    program_length: 2048",
275                "  >",
276                "  time_ms: 1",
277                ">");
278
279        verifySerialization(want, ev);
280    }
281
282    public void testApfStatsSerialization() {
283        ConnectivityMetricsEvent ev = describeIpEvent(
284                aType(ApfStats.class),
285                aLong(45000),
286                anInt(10),
287                anInt(2),
288                anInt(2),
289                anInt(1),
290                anInt(2),
291                anInt(4),
292                anInt(2048));
293
294        String want = joinLines(
295                "dropped_events: 0",
296                "events <",
297                "  apf_statistics <",
298                "    dropped_ras: 2",
299                "    duration_ms: 45000",
300                "    matching_ras: 2",
301                "    max_program_size: 2048",
302                "    parse_errors: 2",
303                "    program_updates: 4",
304                "    received_ras: 10",
305                "    zero_lifetime_ras: 1",
306                "  >",
307                "  time_ms: 1",
308                ">");
309
310        verifySerialization(want, ev);
311    }
312
313    public void testRaEventSerialization() {
314        ConnectivityMetricsEvent ev = describeIpEvent(
315                aType(RaEvent.class),
316                aLong(2000),
317                aLong(400),
318                aLong(300),
319                aLong(-1),
320                aLong(1000),
321                aLong(-1));
322
323        String want = joinLines(
324                "dropped_events: 0",
325                "events <",
326                "  ra_event <",
327                "    dnssl_lifetime: -1",
328                "    prefix_preferred_lifetime: 300",
329                "    prefix_valid_lifetime: 400",
330                "    rdnss_lifetime: 1000",
331                "    route_info_lifetime: -1",
332                "    router_lifetime: 2000",
333                "  >",
334                "  time_ms: 1",
335                ">");
336
337        verifySerialization(want, ev);
338    }
339
340    static void verifySerialization(String want, ConnectivityMetricsEvent... input) {
341        try {
342            byte[] got = IpConnectivityEventBuilder.serialize(0, Arrays.asList(input));
343            IpConnectivityLog log = new IpConnectivityLog();
344            MessageNano.mergeFrom(log, got);
345            assertEquals(want, log.toString());
346        } catch (Exception e) {
347            fail(e.toString());
348        }
349    }
350
351    static String joinLines(String ... elems) {
352        StringBuilder b = new StringBuilder();
353        for (String s : elems) {
354            b.append(s);
355            b.append("\n");
356        }
357        return b.toString();
358    }
359}
360