1/*
2 * Copyright (C) 2012 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;
18
19import android.content.Context;
20import android.net.LinkAddress;
21import android.net.LocalSocket;
22import android.net.LocalServerSocket;
23import android.os.Binder;
24import android.test.AndroidTestCase;
25import android.test.suitebuilder.annotation.LargeTest;
26import com.android.server.net.BaseNetworkObserver;
27import com.android.internal.util.test.BroadcastInterceptingContext;
28
29import static org.mockito.Mockito.doReturn;
30import static org.mockito.Mockito.mock;
31import static org.mockito.Mockito.reset;
32import static org.mockito.Mockito.timeout;
33import static org.mockito.Mockito.verify;
34import static org.mockito.Mockito.verifyNoMoreInteractions;
35
36import java.io.IOException;
37import java.io.OutputStream;
38
39/**
40 * Tests for {@link NetworkManagementService}.
41 */
42@LargeTest
43public class NetworkManagementServiceTest extends AndroidTestCase {
44
45    private static final String SOCKET_NAME = "__test__NetworkManagementServiceTest";
46    private NetworkManagementService mNMService;
47    private LocalServerSocket mServerSocket;
48    private LocalSocket mSocket;
49    private OutputStream mOutputStream;
50
51    @Override
52    public void setUp() throws Exception {
53        super.setUp();
54        // TODO: make this unnecessary. runtest might already make it unnecessary.
55        System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
56
57        // Set up a sheltered test environment.
58        BroadcastInterceptingContext context = new BroadcastInterceptingContext(getContext());
59        mServerSocket = new LocalServerSocket(SOCKET_NAME);
60
61        // Start the service and wait until it connects to our socket.
62        mNMService = NetworkManagementService.create(context, SOCKET_NAME);
63        mSocket = mServerSocket.accept();
64        mOutputStream = mSocket.getOutputStream();
65    }
66
67    @Override
68    public void tearDown() throws Exception {
69        if (mSocket != null) mSocket.close();
70        if (mServerSocket != null) mServerSocket.close();
71        super.tearDown();
72    }
73
74    /**
75     * Sends a message on the netd socket and gives the events some time to make it back.
76     */
77    private void sendMessage(String message) throws IOException {
78        // Strings are null-terminated, so add "\0" at the end.
79        mOutputStream.write((message + "\0").getBytes());
80    }
81
82    private static <T> T expectSoon(T mock) {
83        return verify(mock, timeout(100));
84    }
85
86    /**
87     * Tests that network observers work properly.
88     */
89    public void testNetworkObservers() throws Exception {
90        BaseNetworkObserver observer = mock(BaseNetworkObserver.class);
91        doReturn(new Binder()).when(observer).asBinder();  // Used by registerObserver.
92        mNMService.registerObserver(observer);
93
94        // Forget everything that happened to the mock so far, so we can explicitly verify
95        // everything that happens and does not happen to it from now on.
96        reset(observer);
97
98        // Now send NetworkManagementService messages and ensure that the observer methods are
99        // called. After every valid message we expect a callback soon after; to ensure that
100        // invalid messages don't cause any callbacks, we call verifyNoMoreInteractions at the end.
101
102        /**
103         * Interface changes.
104         */
105        sendMessage("600 Iface added rmnet12");
106        expectSoon(observer).interfaceAdded("rmnet12");
107
108        sendMessage("600 Iface removed eth1");
109        expectSoon(observer).interfaceRemoved("eth1");
110
111        sendMessage("607 Iface removed eth1");
112        // Invalid code.
113
114        sendMessage("600 Iface borked lo down");
115        // Invalid event.
116
117        sendMessage("600 Iface changed clat4 up again");
118        // Extra tokens.
119
120        sendMessage("600 Iface changed clat4 up");
121        expectSoon(observer).interfaceStatusChanged("clat4", true);
122
123        sendMessage("600 Iface linkstate rmnet0 down");
124        expectSoon(observer).interfaceLinkStateChanged("rmnet0", false);
125
126        sendMessage("600 IFACE linkstate clat4 up");
127        // Invalid group.
128
129        /**
130         * Bandwidth control events.
131         */
132        sendMessage("601 limit alert data rmnet_usb0");
133        expectSoon(observer).limitReached("data", "rmnet_usb0");
134
135        sendMessage("601 invalid alert data rmnet0");
136        // Invalid group.
137
138        sendMessage("601 limit increased data rmnet0");
139        // Invalid event.
140
141
142        /**
143         * Interface class activity.
144         */
145
146        sendMessage("613 IfaceClass active rmnet0");
147        expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", true, 0);
148
149        sendMessage("613 IfaceClass active rmnet0 1234");
150        expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", true, 1234);
151
152        sendMessage("613 IfaceClass idle eth0");
153        expectSoon(observer).interfaceClassDataActivityChanged("eth0", false, 0);
154
155        sendMessage("613 IfaceClass idle eth0 1234");
156        expectSoon(observer).interfaceClassDataActivityChanged("eth0", false, 1234);
157
158        sendMessage("613 IfaceClass reallyactive rmnet0 1234");
159        expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", false, 1234);
160
161        sendMessage("613 InterfaceClass reallyactive rmnet0");
162        // Invalid group.
163
164
165        /**
166         * IP address changes.
167         */
168        sendMessage("614 Address updated fe80::1/64 wlan0 128 253");
169        expectSoon(observer).addressUpdated("wlan0", new LinkAddress("fe80::1/64", 128, 253));
170
171        // There is no "added", so we take this as "removed".
172        sendMessage("614 Address added fe80::1/64 wlan0 128 253");
173        expectSoon(observer).addressRemoved("wlan0", new LinkAddress("fe80::1/64", 128, 253));
174
175        sendMessage("614 Address removed 2001:db8::1/64 wlan0 1 0");
176        expectSoon(observer).addressRemoved("wlan0", new LinkAddress("2001:db8::1/64", 1, 0));
177
178        sendMessage("614 Address removed 2001:db8::1/64 wlan0 1");
179        // Not enough arguments.
180
181        sendMessage("666 Address removed 2001:db8::1/64 wlan0 1 0");
182        // Invalid code.
183
184
185        /**
186         * DNS information broadcasts.
187         */
188        sendMessage("615 DnsInfo servers rmnet_usb0 3600 2001:db8::1");
189        expectSoon(observer).interfaceDnsServerInfo("rmnet_usb0", 3600,
190                new String[]{"2001:db8::1"});
191
192        sendMessage("615 DnsInfo servers wlan0 14400 2001:db8::1,2001:db8::2");
193        expectSoon(observer).interfaceDnsServerInfo("wlan0", 14400,
194                new String[]{"2001:db8::1", "2001:db8::2"});
195
196        // We don't check for negative lifetimes, only for parse errors.
197        sendMessage("615 DnsInfo servers wlan0 -3600 ::1");
198        expectSoon(observer).interfaceDnsServerInfo("wlan0", -3600,
199                new String[]{"::1"});
200
201        sendMessage("615 DnsInfo servers wlan0 SIXHUNDRED ::1");
202        // Non-numeric lifetime.
203
204        sendMessage("615 DnsInfo servers wlan0 2001:db8::1");
205        // Missing lifetime.
206
207        sendMessage("615 DnsInfo servers wlan0 3600");
208        // No servers.
209
210        sendMessage("615 DnsInfo servers 3600 wlan0 2001:db8::1,2001:db8::2");
211        // Non-numeric lifetime.
212
213        sendMessage("615 DnsInfo wlan0 7200 2001:db8::1,2001:db8::2");
214        // Invalid tokens.
215
216        sendMessage("666 DnsInfo servers wlan0 5400 2001:db8::1");
217        // Invalid code.
218
219        // No syntax checking on the addresses.
220        sendMessage("615 DnsInfo servers wlan0 600 ,::,,foo,::1,");
221        expectSoon(observer).interfaceDnsServerInfo("wlan0", 600,
222                new String[]{"", "::", "", "foo", "::1"});
223
224        // Make sure nothing else was called.
225        verifyNoMoreInteractions(observer);
226    }
227}
228