17421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti/*
27421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti * Copyright (C) 2012 The Android Open Source Project
37421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti *
47421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti * Licensed under the Apache License, Version 2.0 (the "License");
57421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti * you may not use this file except in compliance with the License.
67421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti * You may obtain a copy of the License at
77421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti *
87421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti *      http://www.apache.org/licenses/LICENSE-2.0
97421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti *
107421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti * Unless required by applicable law or agreed to in writing, software
117421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti * distributed under the License is distributed on an "AS IS" BASIS,
127421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti * See the License for the specific language governing permissions and
147421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti * limitations under the License.
157421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti */
167421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
177421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittipackage com.android.server;
187421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
197421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittiimport android.content.Context;
205ad421a3d00c92c155d57af9d1a05d81cc2fa88fLorenzo Colittiimport android.net.LinkAddress;
217421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittiimport android.net.LocalSocket;
227421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittiimport android.net.LocalServerSocket;
237421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittiimport android.os.Binder;
247421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittiimport android.test.AndroidTestCase;
257421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittiimport android.test.suitebuilder.annotation.LargeTest;
267421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittiimport com.android.server.net.BaseNetworkObserver;
277421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
287421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittiimport static org.mockito.Mockito.doReturn;
297421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittiimport static org.mockito.Mockito.mock;
307421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittiimport static org.mockito.Mockito.reset;
317421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittiimport static org.mockito.Mockito.timeout;
327421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittiimport static org.mockito.Mockito.verify;
337421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittiimport static org.mockito.Mockito.verifyNoMoreInteractions;
347421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
357421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittiimport java.io.IOException;
367421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittiimport java.io.OutputStream;
377421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
387421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti/**
397421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti * Tests for {@link NetworkManagementService}.
407421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti */
417421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti@LargeTest
427421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colittipublic class NetworkManagementServiceTest extends AndroidTestCase {
437421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
447421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    private static final String SOCKET_NAME = "__test__NetworkManagementServiceTest";
457421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    private NetworkManagementService mNMService;
467421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    private LocalServerSocket mServerSocket;
477421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    private LocalSocket mSocket;
487421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    private OutputStream mOutputStream;
497421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
507421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    @Override
517421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    public void setUp() throws Exception {
527421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        super.setUp();
537421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // TODO: make this unnecessary. runtest might already make it unnecessary.
547421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        System.setProperty("dexmaker.dexcache", getContext().getCacheDir().toString());
557421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
567421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // Set up a sheltered test environment.
577421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        BroadcastInterceptingContext context = new BroadcastInterceptingContext(getContext());
587421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        mServerSocket = new LocalServerSocket(SOCKET_NAME);
597421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
607421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // Start the service and wait until it connects to our socket.
617421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        mNMService = NetworkManagementService.create(context, SOCKET_NAME);
627421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        mSocket = mServerSocket.accept();
637421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        mOutputStream = mSocket.getOutputStream();
647421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    }
657421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
667421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    @Override
677421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    public void tearDown() throws Exception {
687421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        if (mSocket != null) mSocket.close();
697421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        if (mServerSocket != null) mServerSocket.close();
707421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        super.tearDown();
717421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    }
727421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
737421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    /**
747421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti     * Sends a message on the netd socket and gives the events some time to make it back.
757421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti     */
767421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    private void sendMessage(String message) throws IOException {
777421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // Strings are null-terminated, so add "\0" at the end.
787421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        mOutputStream.write((message + "\0").getBytes());
797421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    }
807421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
817421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    private static <T> T expectSoon(T mock) {
827421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        return verify(mock, timeout(100));
837421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    }
847421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
857421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    /**
867421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti     * Tests that network observers work properly.
877421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti     */
887421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    public void testNetworkObservers() throws Exception {
897421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        BaseNetworkObserver observer = mock(BaseNetworkObserver.class);
907421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        doReturn(new Binder()).when(observer).asBinder();  // Used by registerObserver.
917421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        mNMService.registerObserver(observer);
927421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
937421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // Forget everything that happened to the mock so far, so we can explicitly verify
947421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // everything that happens and does not happen to it from now on.
957421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        reset(observer);
967421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
977421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // Now send NetworkManagementService messages and ensure that the observer methods are
987421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // called. After every valid message we expect a callback soon after; to ensure that
997421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // invalid messages don't cause any callbacks, we call verifyNoMoreInteractions at the end.
1007421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1017421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        /**
1027421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti         * Interface changes.
1037421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti         */
1047421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("600 Iface added rmnet12");
1057421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        expectSoon(observer).interfaceAdded("rmnet12");
1067421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1077421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("600 Iface removed eth1");
1087421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        expectSoon(observer).interfaceRemoved("eth1");
1097421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1107421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("607 Iface removed eth1");
1117421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // Invalid code.
1127421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1137421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("600 Iface borked lo down");
1147421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // Invalid event.
1157421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1167421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("600 Iface changed clat4 up again");
1177421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // Extra tokens.
1187421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1197421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("600 Iface changed clat4 up");
1207421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        expectSoon(observer).interfaceStatusChanged("clat4", true);
1217421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1227421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("600 Iface linkstate rmnet0 down");
1237421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        expectSoon(observer).interfaceLinkStateChanged("rmnet0", false);
1247421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1257421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("600 IFACE linkstate clat4 up");
1267421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // Invalid group.
1277421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1287421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        /**
1297421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti         * Bandwidth control events.
1307421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti         */
1317421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("601 limit alert data rmnet_usb0");
1327421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        expectSoon(observer).limitReached("data", "rmnet_usb0");
1337421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1347421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("601 invalid alert data rmnet0");
1357421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // Invalid group.
1367421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1377421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("601 limit increased data rmnet0");
1387421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // Invalid event.
1397421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1407421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1417421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        /**
1427421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti         * Interface class activity.
1437421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti         */
144a3f828ba3079408543091a4ccd6c11896ec4e0c7Ashish Sharma
1457421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("613 IfaceClass active rmnet0");
146a3f828ba3079408543091a4ccd6c11896ec4e0c7Ashish Sharma        expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", true, 0);
147a3f828ba3079408543091a4ccd6c11896ec4e0c7Ashish Sharma
148a3f828ba3079408543091a4ccd6c11896ec4e0c7Ashish Sharma        sendMessage("613 IfaceClass active rmnet0 1234");
149a3f828ba3079408543091a4ccd6c11896ec4e0c7Ashish Sharma        expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", true, 1234);
1507421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1517421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("613 IfaceClass idle eth0");
152a3f828ba3079408543091a4ccd6c11896ec4e0c7Ashish Sharma        expectSoon(observer).interfaceClassDataActivityChanged("eth0", false, 0);
153a3f828ba3079408543091a4ccd6c11896ec4e0c7Ashish Sharma
154a3f828ba3079408543091a4ccd6c11896ec4e0c7Ashish Sharma        sendMessage("613 IfaceClass idle eth0 1234");
155a3f828ba3079408543091a4ccd6c11896ec4e0c7Ashish Sharma        expectSoon(observer).interfaceClassDataActivityChanged("eth0", false, 1234);
1567421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
157a3f828ba3079408543091a4ccd6c11896ec4e0c7Ashish Sharma        sendMessage("613 IfaceClass reallyactive rmnet0 1234");
158a3f828ba3079408543091a4ccd6c11896ec4e0c7Ashish Sharma        expectSoon(observer).interfaceClassDataActivityChanged("rmnet0", false, 1234);
1597421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1607421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("613 InterfaceClass reallyactive rmnet0");
1617421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // Invalid group.
1627421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1637421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1647421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        /**
1657421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti         * IP address changes.
1667421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti         */
1677421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("614 Address updated fe80::1/64 wlan0 128 253");
16864483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        expectSoon(observer).addressUpdated("wlan0", new LinkAddress("fe80::1/64", 128, 253));
1697421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1705ad421a3d00c92c155d57af9d1a05d81cc2fa88fLorenzo Colitti        // There is no "added", so we take this as "removed".
1717421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("614 Address added fe80::1/64 wlan0 128 253");
17264483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        expectSoon(observer).addressRemoved("wlan0", new LinkAddress("fe80::1/64", 128, 253));
1737421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1747421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        sendMessage("614 Address removed 2001:db8::1/64 wlan0 1 0");
17564483947fdb03bf838e317ac0a4af5e0f53a5bbfLorenzo Colitti        expectSoon(observer).addressRemoved("wlan0", new LinkAddress("2001:db8::1/64", 1, 0));
1767421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
177a9626c1c956f51e7b4cb783d70b75abc3b180a00Lorenzo Colitti        sendMessage("614 Address removed 2001:db8::1/64 wlan0 1");
178a9626c1c956f51e7b4cb783d70b75abc3b180a00Lorenzo Colitti        // Not enough arguments.
179a9626c1c956f51e7b4cb783d70b75abc3b180a00Lorenzo Colitti
1805ad421a3d00c92c155d57af9d1a05d81cc2fa88fLorenzo Colitti        sendMessage("666 Address removed 2001:db8::1/64 wlan0 1 0");
1817421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // Invalid code.
1827421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti
1835ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti
1845ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        /**
1855ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti         * DNS information broadcasts.
1865ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti         */
1875ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        sendMessage("615 DnsInfo servers rmnet_usb0 3600 2001:db8::1");
1885ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        expectSoon(observer).interfaceDnsServerInfo("rmnet_usb0", 3600,
1895ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                new String[]{"2001:db8::1"});
1905ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti
1915ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        sendMessage("615 DnsInfo servers wlan0 14400 2001:db8::1,2001:db8::2");
1925ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        expectSoon(observer).interfaceDnsServerInfo("wlan0", 14400,
1935ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                new String[]{"2001:db8::1", "2001:db8::2"});
1945ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti
1955ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        // We don't check for negative lifetimes, only for parse errors.
1965ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        sendMessage("615 DnsInfo servers wlan0 -3600 ::1");
1975ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        expectSoon(observer).interfaceDnsServerInfo("wlan0", -3600,
1985ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                new String[]{"::1"});
1995ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti
2005ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        sendMessage("615 DnsInfo servers wlan0 SIXHUNDRED ::1");
2015ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        // Non-numeric lifetime.
2025ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti
2035ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        sendMessage("615 DnsInfo servers wlan0 2001:db8::1");
2045ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        // Missing lifetime.
2055ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti
2065ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        sendMessage("615 DnsInfo servers wlan0 3600");
2075ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        // No servers.
2085ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti
2095ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        sendMessage("615 DnsInfo servers 3600 wlan0 2001:db8::1,2001:db8::2");
2105ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        // Non-numeric lifetime.
2115ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti
2125ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        sendMessage("615 DnsInfo wlan0 7200 2001:db8::1,2001:db8::2");
2135ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        // Invalid tokens.
2145ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti
2155ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        sendMessage("666 DnsInfo servers wlan0 5400 2001:db8::1");
2165ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        // Invalid code.
2175ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti
2185ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        // No syntax checking on the addresses.
2195ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        sendMessage("615 DnsInfo servers wlan0 600 ,::,,foo,::1,");
2205ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti        expectSoon(observer).interfaceDnsServerInfo("wlan0", 600,
2215ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti                new String[]{"", "::", "", "foo", "::1"});
2225ae4a531cc31be2868f65c40e8636658f1ae2f06Lorenzo Colitti
2237421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        // Make sure nothing else was called.
2247421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti        verifyNoMoreInteractions(observer);
2257421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti    }
2267421a01f18f34d554ca7a9fd987c4f96da2bdf2fLorenzo Colitti}
227