blob: f8ff1cb29c237b93fa5a296aab2385e8f0cea027 [file] [log] [blame]
Mark Chien56f007b2020-05-13 09:13:59 +00001/*
2 * Copyright (C) 2020 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.networkstack.tethering;
18
19import static android.net.util.TetheringUtils.uint16;
20
21import static org.junit.Assert.assertEquals;
22import static org.junit.Assert.assertNotNull;
23import static org.mockito.ArgumentMatchers.any;
24import static org.mockito.ArgumentMatchers.eq;
25import static org.mockito.Mockito.spy;
26import static org.mockito.Mockito.verify;
27
28import android.hardware.tetheroffload.config.V1_0.IOffloadConfig;
29import android.hardware.tetheroffload.control.V1_0.IOffloadControl;
30import android.hardware.tetheroffload.control.V1_0.ITetheringOffloadCallback;
31import android.hardware.tetheroffload.control.V1_0.NatTimeoutUpdate;
32import android.hardware.tetheroffload.control.V1_0.NetworkProtocol;
33import android.hardware.tetheroffload.control.V1_0.OffloadCallbackEvent;
34import android.net.util.SharedLog;
35import android.os.Handler;
36import android.os.NativeHandle;
37import android.os.test.TestLooper;
38import android.system.OsConstants;
39
40import androidx.test.filters.SmallTest;
41import androidx.test.runner.AndroidJUnit4;
42
43import org.junit.Before;
44import org.junit.Test;
45import org.junit.runner.RunWith;
46import org.mockito.ArgumentCaptor;
47import org.mockito.Mock;
48import org.mockito.MockitoAnnotations;
49
50import java.util.ArrayList;
51
52@RunWith(AndroidJUnit4.class)
53@SmallTest
54public final class OffloadHardwareInterfaceTest {
55 private static final String RMNET0 = "test_rmnet_data0";
56
57 private final TestLooper mTestLooper = new TestLooper();
58
59 private OffloadHardwareInterface mOffloadHw;
60 private ITetheringOffloadCallback mTetheringOffloadCallback;
61 private OffloadHardwareInterface.ControlCallback mControlCallback;
62
63 @Mock private IOffloadConfig mIOffloadConfig;
64 @Mock private IOffloadControl mIOffloadControl;
65 @Mock private NativeHandle mNativeHandle;
66
67 class MyDependencies extends OffloadHardwareInterface.Dependencies {
68 MyDependencies(SharedLog log) {
69 super(log);
70 }
71
72 @Override
73 public IOffloadConfig getOffloadConfig() {
74 return mIOffloadConfig;
75 }
76
77 @Override
78 public IOffloadControl getOffloadControl() {
79 return mIOffloadControl;
80 }
81
82 @Override
83 public NativeHandle createConntrackSocket(final int groups) {
84 return mNativeHandle;
85 }
86 }
87
88 @Before
89 public void setUp() {
90 MockitoAnnotations.initMocks(this);
91 final SharedLog log = new SharedLog("test");
92 mOffloadHw = new OffloadHardwareInterface(new Handler(mTestLooper.getLooper()), log,
93 new MyDependencies(log));
94 mControlCallback = spy(new OffloadHardwareInterface.ControlCallback());
95 }
96
97 private void startOffloadHardwareInterface() throws Exception {
98 mOffloadHw.initOffloadConfig();
99 mOffloadHw.initOffloadControl(mControlCallback);
100 final ArgumentCaptor<ITetheringOffloadCallback> mOffloadCallbackCaptor =
101 ArgumentCaptor.forClass(ITetheringOffloadCallback.class);
102 verify(mIOffloadControl).initOffload(mOffloadCallbackCaptor.capture(), any());
103 mTetheringOffloadCallback = mOffloadCallbackCaptor.getValue();
104 }
105
106 @Test
107 public void testGetForwardedStats() throws Exception {
108 startOffloadHardwareInterface();
109 final OffloadHardwareInterface.ForwardedStats stats = mOffloadHw.getForwardedStats(RMNET0);
110 verify(mIOffloadControl).getForwardedStats(eq(RMNET0), any());
111 assertNotNull(stats);
112 }
113
114 @Test
115 public void testSetLocalPrefixes() throws Exception {
116 startOffloadHardwareInterface();
117 final ArrayList<String> localPrefixes = new ArrayList<>();
118 localPrefixes.add("127.0.0.0/8");
119 localPrefixes.add("fe80::/64");
120 mOffloadHw.setLocalPrefixes(localPrefixes);
121 verify(mIOffloadControl).setLocalPrefixes(eq(localPrefixes), any());
122 }
123
124 @Test
125 public void testSetDataLimit() throws Exception {
126 startOffloadHardwareInterface();
127 final long limit = 12345;
128 mOffloadHw.setDataLimit(RMNET0, limit);
129 verify(mIOffloadControl).setDataLimit(eq(RMNET0), eq(limit), any());
130 }
131
132 @Test
133 public void testSetUpstreamParameters() throws Exception {
134 startOffloadHardwareInterface();
135 final String v4addr = "192.168.10.1";
136 final String v4gateway = "192.168.10.255";
137 final ArrayList<String> v6gws = new ArrayList<>(0);
138 v6gws.add("2001:db8::1");
139 mOffloadHw.setUpstreamParameters(RMNET0, v4addr, v4gateway, v6gws);
140 verify(mIOffloadControl).setUpstreamParameters(eq(RMNET0), eq(v4addr), eq(v4gateway),
141 eq(v6gws), any());
142
143 final ArgumentCaptor<ArrayList<String>> mArrayListCaptor =
144 ArgumentCaptor.forClass(ArrayList.class);
145 mOffloadHw.setUpstreamParameters(null, null, null, null);
146 verify(mIOffloadControl).setUpstreamParameters(eq(""), eq(""), eq(""),
147 mArrayListCaptor.capture(), any());
148 assertEquals(mArrayListCaptor.getValue().size(), 0);
149 }
150
151 @Test
152 public void testUpdateDownstreamPrefix() throws Exception {
153 startOffloadHardwareInterface();
154 final String ifName = "wlan1";
155 final String prefix = "192.168.43.0/24";
156 mOffloadHw.addDownstreamPrefix(ifName, prefix);
157 verify(mIOffloadControl).addDownstream(eq(ifName), eq(prefix), any());
158
159 mOffloadHw.removeDownstreamPrefix(ifName, prefix);
160 verify(mIOffloadControl).removeDownstream(eq(ifName), eq(prefix), any());
161 }
162
163 @Test
164 public void testTetheringOffloadCallback() throws Exception {
165 startOffloadHardwareInterface();
166
167 mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STARTED);
168 mTestLooper.dispatchAll();
169 verify(mControlCallback).onStarted();
170
171 mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_ERROR);
172 mTestLooper.dispatchAll();
173 verify(mControlCallback).onStoppedError();
174
175 mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_UNSUPPORTED);
176 mTestLooper.dispatchAll();
177 verify(mControlCallback).onStoppedUnsupported();
178
179 mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_SUPPORT_AVAILABLE);
180 mTestLooper.dispatchAll();
181 verify(mControlCallback).onSupportAvailable();
182
183 mTetheringOffloadCallback.onEvent(OffloadCallbackEvent.OFFLOAD_STOPPED_LIMIT_REACHED);
184 mTestLooper.dispatchAll();
185 verify(mControlCallback).onStoppedLimitReached();
186
187 final NatTimeoutUpdate tcpParams = buildNatTimeoutUpdate(NetworkProtocol.TCP);
188 mTetheringOffloadCallback.updateTimeout(tcpParams);
189 mTestLooper.dispatchAll();
190 verify(mControlCallback).onNatTimeoutUpdate(eq(OsConstants.IPPROTO_TCP),
191 eq(tcpParams.src.addr),
192 eq(uint16(tcpParams.src.port)),
193 eq(tcpParams.dst.addr),
194 eq(uint16(tcpParams.dst.port)));
195
196 final NatTimeoutUpdate udpParams = buildNatTimeoutUpdate(NetworkProtocol.UDP);
197 mTetheringOffloadCallback.updateTimeout(udpParams);
198 mTestLooper.dispatchAll();
199 verify(mControlCallback).onNatTimeoutUpdate(eq(OsConstants.IPPROTO_UDP),
200 eq(udpParams.src.addr),
201 eq(uint16(udpParams.src.port)),
202 eq(udpParams.dst.addr),
203 eq(uint16(udpParams.dst.port)));
204 }
205
206 private NatTimeoutUpdate buildNatTimeoutUpdate(final int proto) {
207 final NatTimeoutUpdate params = new NatTimeoutUpdate();
208 params.proto = proto;
209 params.src.addr = "192.168.43.200";
210 params.src.port = 100;
211 params.dst.addr = "172.50.46.169";
212 params.dst.port = 150;
213 return params;
214 }
215}