summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--net/test/BUILD.bazel22
-rwxr-xr-xnet/test/all_tests.py8
-rwxr-xr-xnet/test/all_tests.sh4
-rw-r--r--net/test/iproute.py1
-rwxr-xr-xnet/test/leak_test.py1
-rw-r--r--net/test/namespace.py33
-rwxr-xr-xnet/test/pf_key_test.py25
-rwxr-xr-xnet/test/ping6_test.py48
-rwxr-xr-xnet/test/run_net_test.sh11
-rwxr-xr-xnet/test/sock_diag_test.py47
-rwxr-xr-xnet/test/srcaddr_selection_test.py28
-rw-r--r--net/test/tcp_test.py9
-rwxr-xr-xnet/test/xfrm_algorithm_test.py107
-rwxr-xr-xnet/test/xfrm_tunnel_test.py25
-rw-r--r--test_mappings/BUILD.bazel64
15 files changed, 225 insertions, 208 deletions
diff --git a/net/test/BUILD.bazel b/net/test/BUILD.bazel
deleted file mode 100644
index f0fc0f9..0000000
--- a/net/test/BUILD.bazel
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2024 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-load("@rules_pkg//pkg:mappings.bzl", "pkg_files")
-
-pkg_files(
- name = "test_mappings",
- srcs = ["TEST_MAPPING"],
- prefix = package_name(),
- visibility = ["//kernel/tests/test_mappings:__pkg__"],
-)
diff --git a/net/test/all_tests.py b/net/test/all_tests.py
index 2e2d487..f6ff469 100755
--- a/net/test/all_tests.py
+++ b/net/test/all_tests.py
@@ -15,10 +15,13 @@
# limitations under the License.
import importlib
+import os
import sys
import unittest
+import gki
import namespace
+import net_test
all_test_modules = [
'anycast_test',
@@ -49,6 +52,11 @@ all_test_modules = [
def RunTests(modules_to_test):
+ print('Running on %s %s %s %s-%sbit%s%s'
+ % (os.uname()[0], os.uname()[2], net_test.LINUX_VERSION, os.uname()[4],
+ '64' if sys.maxsize > 0x7FFFFFFF else '32',
+ ' GKI' if gki.IS_GKI else '', ' GSI' if net_test.IS_GSI else ''),
+ file=sys.stderr)
namespace.EnterNewNetworkNamespace()
# First, run InjectTests on all modules, to ensure that any parameterized
diff --git a/net/test/all_tests.sh b/net/test/all_tests.sh
index aa63cdd..63576b0 100755
--- a/net/test/all_tests.sh
+++ b/net/test/all_tests.sh
@@ -18,10 +18,6 @@ readonly PREFIX="#####"
readonly RETRIES=2
test_prefix=
-# The tests currently have hundreds of ResourceWarnings that make it hard
-# to see errors/failures. Disable this warning for now.
-export PYTHONWARNINGS="ignore::ResourceWarning"
-
function checkArgOrExit() {
if [[ $# -lt 2 ]]; then
echo "Missing argument for option $1" >&2
diff --git a/net/test/iproute.py b/net/test/iproute.py
index 6822fa5..307f836 100644
--- a/net/test/iproute.py
+++ b/net/test/iproute.py
@@ -596,6 +596,7 @@ class IPRoute(netlink.NetlinkSocket):
if version == 6:
self._WaitForAddress(sock, address, ifindex)
+ sock.close()
def DelAddress(self, address, prefixlen, ifindex):
self._Address(csocket.AddressVersion(address),
diff --git a/net/test/leak_test.py b/net/test/leak_test.py
index 54bbe73..9b7d2c6 100755
--- a/net/test/leak_test.py
+++ b/net/test/leak_test.py
@@ -45,6 +45,7 @@ class LeakTest(net_test.NetworkTest):
data, addr = csocket.Recvfrom(s, 4096)
self.assertEqual(b"", data)
self.assertEqual(None, addr)
+ s.close()
class ForceSocketBufferOptionTest(net_test.NetworkTest):
diff --git a/net/test/namespace.py b/net/test/namespace.py
index d16a1ad..7ebcbde 100644
--- a/net/test/namespace.py
+++ b/net/test/namespace.py
@@ -18,7 +18,6 @@
import ctypes
import ctypes.util
-import errno
import os
import socket
import sys
@@ -27,6 +26,8 @@ import net_test
import sock_diag
import tcp_test
+# pylint: disable=bad-whitespace
+
# //include/linux/fs.h
MNT_FORCE = 1 # Attempt to forcibily umount
MNT_DETACH = 2 # Just detach from the tree
@@ -66,6 +67,8 @@ CLONE_NEWUSER = 0x10000000 # New user namespace
CLONE_NEWPID = 0x20000000 # New pid namespace
CLONE_NEWNET = 0x40000000 # New network namespace
+# pylint: enable=bad-whitespace
+
libc = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True)
# See the relevant system call's man pages and:
@@ -81,9 +84,9 @@ def Mount(src, tgt, fs, flags=MS_NODEV|MS_NOEXEC|MS_NOSUID|MS_RELATIME):
ret = libc.mount(src.encode(), tgt.encode(), fs.encode() if fs else None,
flags, None)
if ret < 0:
- errno = ctypes.get_errno()
- raise OSError(errno, '%s mounting %s on %s (fs=%s flags=0x%x)'
- % (os.strerror(errno), src, tgt, fs, flags))
+ err = ctypes.get_errno()
+ raise OSError(err, '%s mounting %s on %s (fs=%s flags=0x%x)'
+ % (os.strerror(err), src, tgt, fs, flags))
def ReMountProc():
@@ -92,9 +95,9 @@ def ReMountProc():
def ReMountSys():
- libc.umount2(b'/sys/fs/cgroup', MNT_DETACH) # Ignore failure: might not be mounted
- libc.umount2(b'/sys/fs/bpf', MNT_DETACH) # Ignore failure: might not be mounted
- libc.umount2(b'/sys', MNT_DETACH) # Ignore failure: might not be mounted
+ libc.umount2(b'/sys/fs/cgroup', MNT_DETACH) # Ign. fail: might not be mounted
+ libc.umount2(b'/sys/fs/bpf', MNT_DETACH) # Ignore fail: might not be mounted
+ libc.umount2(b'/sys', MNT_DETACH) # Ignore fail: might not be mounted
Mount('sysfs', '/sys', 'sysfs')
Mount('bpf', '/sys/fs/bpf', 'bpf')
Mount('cgroup2', '/sys/fs/cgroup', 'cgroup2')
@@ -109,15 +112,15 @@ def SetHostname(s):
hostname = s.encode()
ret = libc.sethostname(hostname, len(hostname))
if ret < 0:
- errno = ctypes.get_errno()
- raise OSError(errno, '%s while sethostname(%s)' % (os.strerror(errno), s))
+ err = ctypes.get_errno()
+ raise OSError(err, '%s while sethostname(%s)' % (os.strerror(err), s))
def UnShare(flags):
ret = libc.unshare(flags)
if ret < 0:
- errno = ctypes.get_errno()
- raise OSError(errno, '%s while unshare(0x%x)' % (os.strerror(errno), flags))
+ err = ctypes.get_errno()
+ raise OSError(err, '%s while unshare(0x%x)' % (os.strerror(err), flags))
def DumpMounts(hdr):
@@ -135,8 +138,6 @@ def DumpMounts(hdr):
def EnterNewNetworkNamespace():
"""Instantiate and transition into a fresh new network namespace."""
- sys.stdout.write('Creating clean namespace... ')
-
try:
UnShare(CLONE_NEWNS | CLONE_NEWUTS | CLONE_NEWNET)
except OSError as err:
@@ -163,12 +164,12 @@ def EnterNewNetworkNamespace():
def HasEstablishedTcpSessionOnPort(port):
sd = sock_diag.SockDiag()
- sock_id = sd._EmptyInetDiagSockId()
+ sock_id = sd._EmptyInetDiagSockId() # pylint: disable=protected-access
sock_id.sport = port
states = 1 << tcp_test.TCP_ESTABLISHED
- matches = sd.DumpAllInetSockets(socket.IPPROTO_TCP, b"",
+ matches = sd.DumpAllInetSockets(socket.IPPROTO_TCP, b'',
sock_id=sock_id, states=states)
- return len(matches) > 0
+ return True if matches else False
diff --git a/net/test/pf_key_test.py b/net/test/pf_key_test.py
index 7791bd1..7a2b7ef 100755
--- a/net/test/pf_key_test.py
+++ b/net/test/pf_key_test.py
@@ -14,11 +14,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# pylint: disable=g-bad-todo,g-bad-file-header,wildcard-import
-from socket import *
+import binascii
+from socket import * # pylint: disable=g-importing-member,wildcard-import
import unittest
-import binascii
import csocket
import pf_key
import xfrm
@@ -30,11 +29,11 @@ AUTH_KEY = binascii.unhexlify("af442892cdcd0ef650e9c299f9a8436a")
class PfKeyTest(unittest.TestCase):
- def setUp(self):
+ def setUp(self): # pylint: disable=g-missing-super-call
self.pf_key = pf_key.PfKey()
self.xfrm = xfrm.Xfrm()
- def tearDown(self):
+ def tearDown(self): # pylint: disable=g-missing-super-call
self.pf_key.close()
self.pf_key = None
@@ -92,24 +91,24 @@ class PfKeyTest(unittest.TestCase):
self.assertEqual(256, attrs6["XFRMA_ALG_AUTH_TRUNC"].key_len)
if attrs4["XFRMA_ALG_AUTH_TRUNC"].trunc_len == 96:
- missing4 = True
+ missing4 = True
else:
- self.assertEqual(128, attrs4["XFRMA_ALG_AUTH_TRUNC"].trunc_len)
- missing4 = False
+ self.assertEqual(128, attrs4["XFRMA_ALG_AUTH_TRUNC"].trunc_len)
+ missing4 = False
if attrs6["XFRMA_ALG_AUTH_TRUNC"].trunc_len == 96:
- missing6 = True
+ missing6 = True
else:
- self.assertEqual(128, attrs6["XFRMA_ALG_AUTH_TRUNC"].trunc_len)
- missing6 = False
+ self.assertEqual(128, attrs6["XFRMA_ALG_AUTH_TRUNC"].trunc_len)
+ missing6 = False
self.pf_key.DelSa(src4, dst4, 0xdeadbeef, pf_key.SADB_TYPE_ESP)
self.assertEqual(1, len(self.xfrm.DumpSaInfo()))
self.pf_key.DelSa(src6, dst6, 0xbeefdead, pf_key.SADB_TYPE_ESP)
self.assertEqual(0, len(self.xfrm.DumpSaInfo()))
- if missing4 or missing6:
- self.assertFalse("missing b8a72fd7c4e9 ANDROID: net: xfrm: make PF_KEY SHA256 use RFC-compliant truncation.")
+ self.assertFalse(missing4 or missing6, "missing b8a72fd7c4e9 ANDROID: net" +
+ ": xfrm: make PF_KEY SHA256 use RFC-compliant truncation.")
if __name__ == "__main__":
diff --git a/net/test/ping6_test.py b/net/test/ping6_test.py
index af2e4c5..59021e2 100755
--- a/net/test/ping6_test.py
+++ b/net/test/ping6_test.py
@@ -21,18 +21,17 @@ import errno
import os
import posix
import random
-from socket import * # pylint: disable=wildcard-import
+from socket import * # pylint: disable=g-importing-member,wildcard-import
import struct
import sys
import threading
import time
import unittest
-from scapy import all as scapy
-
import csocket
import multinetwork_base
import net_test
+from scapy import all as scapy
ICMP_ECHO = 8
@@ -116,12 +115,12 @@ class PingReplyThread(threading.Thread):
packet)
def SendPacketTooBig(self, packet):
- src = packet.getlayer(scapy.IPv6).src
- datalen = IPV6_MIN_MTU - ICMPV6_HEADER_LEN
- self.SendPacket(
- scapy.IPv6(src=self.INTERMEDIATE_IPV6, dst=src) /
- scapy.ICMPv6PacketTooBig(mtu=self.LINK_MTU) /
- bytes(packet)[:datalen])
+ src = packet.getlayer(scapy.IPv6).src
+ datalen = IPV6_MIN_MTU - ICMPV6_HEADER_LEN
+ self.SendPacket(
+ scapy.IPv6(src=self.INTERMEDIATE_IPV6, dst=src) /
+ scapy.ICMPv6PacketTooBig(mtu=self.LINK_MTU) /
+ bytes(packet)[:datalen])
def IPv4Packet(self, ip):
icmp = ip.getlayer(scapy.ICMP)
@@ -184,7 +183,7 @@ class PingReplyThread(threading.Thread):
packet = scapy.Ether(src=self._routermac, dst=self._mymac) / packet
try:
posix.write(self._tun.fileno(), bytes(packet))
- except Exception as e:
+ except Exception as e: # pylint: disable=broad-exception-caught
if not self._stopped_flag:
raise e
@@ -217,15 +216,15 @@ class Ping6Test(multinetwork_base.MultiNetworkBaseTest):
# that would cause tearDownClass not to be called and thus not clean up
# routing configuration, breaking subsequent tests. Instead, just let these
# tests fail.
- _INTERVAL = 0.1
- _ATTEMPTS = 20
- for i in range(0, _ATTEMPTS):
- for netid in cls.NETIDS:
- if all(thread.IsStarted() for thread in list(cls.reply_threads.values())):
+ interval = 0.1
+ attempts = 20
+ for _ in range(attempts):
+ for _ in cls.NETIDS:
+ if all(thrd.IsStarted() for thrd in list(cls.reply_threads.values())):
return
- time.sleep(_INTERVAL)
+ time.sleep(interval)
msg = "WARNING: reply threads not all started after %.1f seconds\n" % (
- _ATTEMPTS * _INTERVAL)
+ attempts * interval)
sys.stderr.write(msg)
@classmethod
@@ -239,10 +238,10 @@ class Ping6Test(multinetwork_base.MultiNetworkBaseTest):
cls.reply_threads = {}
for netid in cls.NETIDS:
cls.reply_threads[netid] = PingReplyThread(
- cls.tuns[netid],
- cls.MyMacAddress(netid),
- cls.RouterMacAddress(netid),
- cls._RouterAddress(netid, 6))
+ cls.tuns[netid],
+ cls.MyMacAddress(netid),
+ cls.RouterMacAddress(netid),
+ cls._RouterAddress(netid, 6))
cls.reply_threads[netid].start()
cls.WaitForReplyThreads()
cls.netid = random.choice(cls.NETIDS)
@@ -255,6 +254,7 @@ class Ping6Test(multinetwork_base.MultiNetworkBaseTest):
super(Ping6Test, cls).tearDownClass()
def setUp(self):
+ super(Ping6Test, self).setUp()
self.ifname = self.GetInterfaceName(self.netid)
self.ifindex = self.ifindices[self.netid]
self.lladdr = net_test.GetLinkAddress(self.ifname, True)
@@ -294,7 +294,7 @@ class Ping6Test(multinetwork_base.MultiNetworkBaseTest):
# Check that the flow label is zero and that the scope ID is sane.
self.assertEqual(flowlabel, 0)
if addr.startswith("fe80::"):
- self.assertTrue(scope_id in list(self.ifindices.values()))
+ self.assertIn(scope_id, list(self.ifindices.values()))
else:
self.assertEqual(0, scope_id)
@@ -326,7 +326,7 @@ class Ping6Test(multinetwork_base.MultiNetworkBaseTest):
# Check all the parameters except rxmem and txmem.
expected[3] = actual[3]
- # also do not check ref, it's always 2 on older kernels, but 1 for 'raw6' on 6.0+
+ # Don't check ref, it's always 2 on old kernels, but 1 for 'raw6' on 6.0+
expected[5] = actual[5]
if expected == actual:
return
@@ -735,7 +735,7 @@ class Ping6Test(multinetwork_base.MultiNetworkBaseTest):
# that is not registered with the flow manager should return EINVAL...
s.setsockopt(net_test.SOL_IPV6, net_test.IPV6_FLOWINFO_SEND, 1)
# ... but this doesn't work yet.
- if False:
+ if False: # pylint: disable=using-constant-test
self.assertRaisesErrno(errno.EINVAL, s.sendto, net_test.IPV6_PING,
(net_test.IPV6_ADDR, 93, 0xdead, 0))
diff --git a/net/test/run_net_test.sh b/net/test/run_net_test.sh
index 8d44cf3..8635eab 100755
--- a/net/test/run_net_test.sh
+++ b/net/test/run_net_test.sh
@@ -88,9 +88,6 @@ OPTIONS="$OPTIONS INIT_STACK_NONE"
# These two break the flo kernel due to differences in -Werror on recent GCC.
DISABLE_OPTIONS=" REISERFS_FS ANDROID_PMEM"
-# Disable frame size warning on arm64. GCC 10 generates >1k stack frames.
-DISABLE_OPTIONS="$DISABLE_OPTIONS FRAME_WARN"
-
# How many TAP interfaces to create to provide the VM with real network access
# via the host. This requires privileges (e.g., root access) on the host.
#
@@ -128,6 +125,11 @@ nowrite=1
nobuild=0
norun=0
+if [[ ! -f "${KERNEL_DIR}/Makefile" ]]; then
+ echo "No kernel Makefile found. Are you running this from a kernel directory?"
+ exit 1
+fi
+
KVER_MAJOR="$(sed -rn 's@^ *VERSION *= *([0-9]+)$@\1@p' < "${KERNEL_DIR}/Makefile")"
KVER_MINOR="$(sed -rn 's@^ *PATCHLEVEL *= *([0-9]+)$@\1@p' < "${KERNEL_DIR}/Makefile")"
KVER_LEVEL="$(sed -rn 's@^ *SUBLEVEL *= *([0-9]+)$@\1@p' < "${KERNEL_DIR}/Makefile")"
@@ -303,6 +305,9 @@ if ((nobuild == 0)); then
# Enable the kernel config options listed in $OPTIONS.
$CONFIG_SCRIPT --file $CONFIG_FILE ${OPTIONS// / -e }
+ # Increase acceptable frame size.
+ $CONFIG_SCRIPT --file $CONFIG_FILE --set-val FRAME_WARN 3172
+
# Disable the kernel config options listed in $DISABLE_OPTIONS.
$CONFIG_SCRIPT --file $CONFIG_FILE ${DISABLE_OPTIONS// / -d }
diff --git a/net/test/sock_diag_test.py b/net/test/sock_diag_test.py
index 8aac69d..58e8f01 100755
--- a/net/test/sock_diag_test.py
+++ b/net/test/sock_diag_test.py
@@ -179,6 +179,9 @@ class SockDiagTest(SockDiagBaseTest):
self.sock_diag.GetSockInfo(diag_req)
# No errors? Good.
+ for sock in socketpair:
+ sock.close()
+
def CheckFindsAllMySockets(self, socktype, proto):
"""Tests that basic socket dumping works."""
self.socketpairs = self._CreateLotsOfSockets(socktype)
@@ -220,6 +223,10 @@ class SockDiagTest(SockDiagBaseTest):
info = self.sock_diag.GetSockInfo(req)
self.assertSockInfoMatchesSocket(sock, info)
+ for socketpair in socketpairs:
+ for sock in socketpair:
+ sock.close()
+
def assertItemsEqual(self, expected, actual):
try:
super(SockDiagTest, self).assertItemsEqual(expected, actual)
@@ -332,6 +339,15 @@ class SockDiagTest(SockDiagBaseTest):
self.assertTrue(all(d in v4socks for d in diag_msgs))
self.assertTrue(all(d in v6socks for d in diag_msgs))
+ for sock in unused_pair4:
+ sock.close()
+
+ for sock in unused_pair6:
+ sock.close()
+
+ for sock in pair5:
+ sock.close()
+
def testPortComparisonValidation(self):
"""Checks for a bug in validating port comparison bytecode.
@@ -365,6 +381,9 @@ class SockDiagTest(SockDiagBaseTest):
cookie = sock.getsockopt(net_test.SOL_SOCKET, net_test.SO_COOKIE, 8)
self.assertEqual(diag_msg.id.cookie, cookie)
+ for sock in socketpair:
+ sock.close()
+
def testGetsockoptcookie(self):
self.CheckSocketCookie(AF_INET, "127.0.0.1")
self.CheckSocketCookie(AF_INET6, "::1")
@@ -399,6 +418,8 @@ class SockDiagTest(SockDiagBaseTest):
self.assertSockInfoMatchesSocket(s, self.sock_diag.GetSockInfo(req))
+ s.close()
+
class SockDestroyTest(SockDiagBaseTest):
"""Tests that SOCK_DESTROY works correctly.
@@ -538,6 +559,7 @@ class TcpRcvWindowTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
"Tcp rwnd of netid=%d, version=%d is not enough. "
"Expect: %d, actual: %d" % (netid, version, self.RWND_SIZE,
tcpInfo.tcpi_rcv_ssthresh))
+ self.CloseSockets()
def checkSynPacketWindowSize(self, version, netid):
s = self.BuildSocket(version, net_test.TCPSocket, netid, "mark")
@@ -595,6 +617,7 @@ class SockDestroyTcpTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
if state != tcp_test.TCP_LISTEN:
msg = "Closing accepted IPv%d %s socket" % (version, statename)
self.CheckRstOnClose(self.accepted, None, True, msg)
+ self.CloseSockets()
def testTcpResets(self):
"""Checks that closing sockets in appropriate states sends a RST."""
@@ -613,6 +636,7 @@ class SockDestroyTcpTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
# Close the socket and check that it goes into FIN_WAIT1 and sends a FIN.
net_test.EnableFinWait(self.accepted)
self.accepted.close()
+ del self.accepted
diag_req.states = 1 << tcp_test.TCP_FIN_WAIT1
diag_msg, attrs = self.sock_diag.GetSockInfo(diag_req)
self.assertEqual(tcp_test.TCP_FIN_WAIT1, diag_msg.state)
@@ -640,6 +664,8 @@ class SockDestroyTcpTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
for diag_msg, attrs in infos),
"Expected to find FIN_WAIT2 socket in %s" % infos)
+ self.CloseSockets()
+
def FindChildSockets(self, s):
"""Finds the SYN_RECV child sockets of a given listening socket."""
d = self.sock_diag.FindSockDiagFromFd(self.s)
@@ -703,11 +729,11 @@ class SockDestroyTcpTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
else:
CloseChildren()
CheckChildrenClosed()
- self.s.close()
else:
CloseChildren()
CloseParent(False)
- self.s.close()
+
+ self.CloseSockets()
def testChildSockets(self):
for version in [4, 5, 6]:
@@ -726,6 +752,7 @@ class SockDestroyTcpTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
self.assertRaisesErrno(EINVAL, self.s.accept)
# TODO: this should really return an error such as ENOTCONN...
self.assertEqual(b"", self.s.recv(4096))
+ self.CloseSockets()
def testReadInterrupted(self):
"""Tests that read() is interrupted by SOCK_DESTROY."""
@@ -737,6 +764,7 @@ class SockDestroyTcpTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
self.assertRaisesErrno(EPIPE, self.accepted.send, b"foo")
self.assertEqual(b"", self.accepted.recv(4096))
self.assertEqual(b"", self.accepted.recv(4096))
+ self.CloseSockets()
def testConnectInterrupted(self):
"""Tests that connect() is interrupted by SOCK_DESTROY."""
@@ -756,6 +784,7 @@ class SockDestroyTcpTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
self.ExpectPacketOn(self.netid, desc, syn)
msg = "SOCK_DESTROY of socket in connect, expected no RST"
self.ExpectNoPacketsOn(self.netid, msg)
+ s.close()
class PollOnCloseTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
@@ -817,6 +846,7 @@ class PollOnCloseTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
lambda sock: self.BlockingPoll(sock, mask, expected, ignoremask),
None)
self.assertSocketErrors(ECONNABORTED)
+ self.CloseSockets()
def CheckPollRst(self, mask, expected, ignoremask):
"""Interrupts a poll() by receiving a TCP RST."""
@@ -827,6 +857,7 @@ class PollOnCloseTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
lambda sock: self.BlockingPoll(sock, mask, expected, ignoremask),
None)
self.assertSocketErrors(ECONNRESET)
+ self.CloseSockets()
def testReadPollRst(self):
self.CheckPollRst(select.POLLIN, self.POLLIN_ERR_HUP, 0)
@@ -899,6 +930,7 @@ class SockDestroyUdpTest(SockDiagBaseTest):
s.connect((dst, 53))
self.sock_diag.CloseSocketFromFd(s)
self.assertEqual((unspec, 0), s.getsockname()[:2])
+ s.close()
# Closing a socket bound to an IP address leaves the address as is.
s = self.BuildSocket(version, net_test.UDPSocket, netid, "mark")
@@ -908,6 +940,7 @@ class SockDestroyUdpTest(SockDiagBaseTest):
port = s.getsockname()[1]
self.sock_diag.CloseSocketFromFd(s)
self.assertEqual((src, 0), s.getsockname()[:2])
+ s.close()
# Closing a socket bound to a port leaves the port as is.
s = self.BuildSocket(version, net_test.UDPSocket, netid, "mark")
@@ -915,6 +948,7 @@ class SockDestroyUdpTest(SockDiagBaseTest):
s.connect((dst, 53))
self.sock_diag.CloseSocketFromFd(s)
self.assertEqual((unspec, port), s.getsockname()[:2])
+ s.close()
# Closing a socket bound to IP address and port leaves both as is.
s = self.BuildSocket(version, net_test.UDPSocket, netid, "mark")
@@ -922,6 +956,7 @@ class SockDestroyUdpTest(SockDiagBaseTest):
port = self.BindToRandomPort(s, src)
self.sock_diag.CloseSocketFromFd(s)
self.assertEqual((src, port), s.getsockname()[:2])
+ s.close()
def testReadInterrupted(self):
"""Tests that read() is interrupted by SOCK_DESTROY."""
@@ -945,6 +980,8 @@ class SockDestroyUdpTest(SockDiagBaseTest):
self.CloseDuringBlockingCall(s, lambda sock: sock.recv(4096),
ECONNABORTED)
+ s.close()
+
class SockDestroyPermissionTest(SockDiagBaseTest):
def CheckPermissions(self, socktype):
@@ -964,6 +1001,8 @@ class SockDestroyPermissionTest(SockDiagBaseTest):
self.sock_diag.CloseSocketFromFd(s)
self.assertRaises(ValueError, self.sock_diag.CloseSocketFromFd, s)
+ s.close()
+
def testUdp(self):
self.CheckPermissions(SOCK_DGRAM)
@@ -1050,6 +1089,9 @@ class SockDiagMarkTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
self.assertRaisesErrno(EPERM, self.FilterEstablishedSockets,
0xfff0000, 0xf0fed00)
+ s1.close()
+ s2.close()
+
@staticmethod
def SetRandomMark(s):
# Python doesn't like marks that don't fit into a signed int.
@@ -1091,6 +1133,7 @@ class SockDiagMarkTest(tcp_test.TcpBaseTest, SockDiagBaseTest):
self.assertSocketMarkIs(accepted, accepted_mark)
self.assertSocketMarkIs(server, server_mark)
+ accepted.close()
server.close()
client.close()
diff --git a/net/test/srcaddr_selection_test.py b/net/test/srcaddr_selection_test.py
index f515c47..8c327c3 100755
--- a/net/test/srcaddr_selection_test.py
+++ b/net/test/srcaddr_selection_test.py
@@ -83,6 +83,7 @@ class IPv6SourceAddressSelectionTest(multinetwork_base.MultiNetworkBaseTest):
s.connect((net_test.IPV6_ADDR, 123))
src_addr = s.getsockname()[0]
self.assertTrue(src_addr)
+ s.close()
return src_addr
def assertAddressNotPresent(self, address):
@@ -103,13 +104,19 @@ class IPv6SourceAddressSelectionTest(multinetwork_base.MultiNetworkBaseTest):
def BindToAddress(self, address):
s = net_test.UDPSocket(AF_INET6)
- s.bind((address, 0, 0, 0))
+ try:
+ s.bind((address, 0, 0, 0))
+ finally:
+ s.close()
def SendWithSourceAddress(self, address, netid, dest=net_test.IPV6_ADDR):
pktinfo = multinetwork_base.MakePktInfo(6, address, 0)
cmsgs = [(net_test.SOL_IPV6, IPV6_PKTINFO, pktinfo)]
s = self.BuildSocket(6, net_test.UDPSocket, netid, "mark")
- return csocket.Sendmsg(s, (dest, 53), b"Hello", cmsgs, 0)
+ try:
+ return csocket.Sendmsg(s, (dest, 53), b"Hello", cmsgs, 0)
+ finally:
+ s.close()
def assertAddressUsable(self, address, netid):
self.BindToAddress(address)
@@ -132,7 +139,19 @@ class IPv6SourceAddressSelectionTest(multinetwork_base.MultiNetworkBaseTest):
if not self.AddressIsTentative(address):
return
time.sleep(0.1)
- raise AssertionError("%s did not complete DAD after 2 seconds")
+ raise AssertionError(f"{address} did not complete DAD after 2 seconds")
+
+ def WaitForDadFailure(self, address):
+ # Address should be either deleted or set IFA_F_DADFAILED flag after DAD failure
+ for _ in range(20):
+ try:
+ ifa_msg = self.iproute.GetAddress(address)[0]
+ except OSError:
+ return
+ if ifa_msg.flags & iproute.IFA_F_DADFAILED:
+ return
+ time.sleep(0.1)
+ raise AssertionError(f"{address} did not complete DAD failure after 2 seconds")
class MultiInterfaceSourceAddressSelectionTest(IPv6SourceAddressSelectionTest):
@@ -279,6 +298,7 @@ class DadFailureTest(MultiInterfaceSourceAddressSelectionTest):
self.SetUseOptimistic(self.test_ifname, 1)
# Send a RA to start SLAAC and subsequent DAD.
self.SendRA(self.test_netid, retranstimer=RETRANS_TIMER)
+ time.sleep(0.1) # Give the kernel time to notice our RA
# Prove optimism and usability.
self.assertAddressHasExpectedAttributes(
self.test_ip, self.test_ifindex, iproute.IFA_F_OPTIMISTIC)
@@ -293,7 +313,7 @@ class DadFailureTest(MultiInterfaceSourceAddressSelectionTest):
scapy.ICMPv6ND_NA(tgt=self.test_ip, R=0, S=0, O=1) /
scapy.ICMPv6NDOptDstLLAddr(lladdr=conflict_macaddr))
self.ReceiveEtherPacketOn(self.test_netid, dad_defense)
- self.WaitForDad(self.test_lladdr)
+ self.WaitForDadFailure(self.test_ip)
# The address should have failed DAD, and therefore no longer be usable.
self.assertAddressNotUsable(self.test_ip, self.test_netid)
diff --git a/net/test/tcp_test.py b/net/test/tcp_test.py
index 5a073e6..f3ee291 100644
--- a/net/test/tcp_test.py
+++ b/net/test/tcp_test.py
@@ -40,9 +40,16 @@ TCP_NOT_YET_ACCEPTED = -1
class TcpBaseTest(multinetwork_base.MultiNetworkBaseTest):
- def tearDown(self):
+ def CloseSockets(self):
+ if hasattr(self, "accepted"):
+ self.accepted.close()
+ del self.accepted
if hasattr(self, "s"):
self.s.close()
+ del self.s
+
+ def tearDown(self):
+ self.CloseSockets()
super(TcpBaseTest, self).tearDown()
def OpenListenSocket(self, version, netid):
diff --git a/net/test/xfrm_algorithm_test.py b/net/test/xfrm_algorithm_test.py
index 8466953..5fa5352 100755
--- a/net/test/xfrm_algorithm_test.py
+++ b/net/test/xfrm_algorithm_test.py
@@ -14,17 +14,16 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# pylint: disable=g-bad-todo,g-bad-file-header,wildcard-import
-from errno import * # pylint: disable=wildcard-import
-import os
+from errno import * # pylint: disable=wildcard-import,g-importing-member
import itertools
-from scapy import all as scapy
-from socket import * # pylint: disable=wildcard-import
+import os
+from socket import * # pylint: disable=wildcard-import,g-importing-member
import threading
+import time
import unittest
-import multinetwork_base
import net_test
+from scapy import all as scapy
from tun_twister import TapTwister
import util
import xfrm
@@ -87,14 +86,17 @@ AEAD_ALGOS = [
# 4 bytes (32 bits) of nonce. A fresh nonce value MUST be assigned for
# each SA. RFC 7634 also specifies that ICV length must be 16 bytes.
# ChaCha20-Poly1305 is enforced since kernel version 5.8
- (xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_CHACHA20_POLY1305, 256+32, 16*8)), (5, 8)),
+ (xfrm.XfrmAlgoAead((xfrm.XFRM_AEAD_CHACHA20_POLY1305, 256+32, 16*8)),
+ (5, 8)),
]
+
def GenerateKey(key_len):
if key_len % 8 != 0:
raise ValueError("Invalid key length in bits: " + str(key_len))
return os.urandom(key_len // 8)
+
# Does the kernel support this algorithm?
def HaveAlgo(crypt_algo, auth_algo, aead_algo):
try:
@@ -133,28 +135,33 @@ def HaveAlgo(crypt_algo, auth_algo, aead_algo):
# False.
algoState = {}
+
def AlgoEnforcedOrEnabled(crypt, auth, aead, target_algo, target_kernel):
if algoState.get(target_algo) is None:
- algoState[target_algo] = net_test.LINUX_VERSION >= target_kernel or HaveAlgo(
- crypt, auth, aead)
+ algoState[target_algo] = (net_test.LINUX_VERSION >= target_kernel
+ or HaveAlgo(crypt, auth, aead))
return algoState.get(target_algo)
+
# Return true if this algorithm should be enforced or is enabled on this kernel
-def AuthEnforcedOrEnabled(authCase):
- auth = authCase[0]
+def AuthEnforcedOrEnabled(auth_case):
+ auth = auth_case[0]
crypt = xfrm.XfrmAlgo((b"ecb(cipher_null)", 0))
- return AlgoEnforcedOrEnabled(crypt, auth, None, auth.name, authCase[1])
+ return AlgoEnforcedOrEnabled(crypt, auth, None, auth.name, auth_case[1])
+
# Return true if this algorithm should be enforced or is enabled on this kernel
-def CryptEnforcedOrEnabled(cryptCase):
- crypt = cryptCase[0]
+def CryptEnforcedOrEnabled(crypt_case):
+ crypt = crypt_case[0]
auth = xfrm.XfrmAlgoAuth((b"digest_null", 0, 0))
- return AlgoEnforcedOrEnabled(crypt, auth, None, crypt.name, cryptCase[1])
+ return AlgoEnforcedOrEnabled(crypt, auth, None, crypt.name, crypt_case[1])
+
# Return true if this algorithm should be enforced or is enabled on this kernel
-def AeadEnforcedOrEnabled(aeadCase):
- aead = aeadCase[0]
- return AlgoEnforcedOrEnabled(None, None, aead, aead.name, aeadCase[1])
+def AeadEnforcedOrEnabled(aead_case):
+ aead = aead_case[0]
+ return AlgoEnforcedOrEnabled(None, None, aead, aead.name, aead_case[1])
+
def InjectTests():
XfrmAlgorithmTest.InjectTests()
@@ -163,66 +170,67 @@ def InjectTests():
class XfrmAlgorithmTest(xfrm_base.XfrmLazyTest):
@classmethod
def InjectTests(cls):
- VERSIONS = (4, 6)
- TYPES = (SOCK_DGRAM, SOCK_STREAM)
+ versions = (4, 6)
+ types = (SOCK_DGRAM, SOCK_STREAM)
# Tests all combinations of auth & crypt. Mutually exclusive with aead.
- param_list = itertools.product(VERSIONS, TYPES, AUTH_ALGOS, CRYPT_ALGOS,
+ param_list = itertools.product(versions, types, AUTH_ALGOS, CRYPT_ALGOS,
[None])
util.InjectParameterizedTest(cls, param_list, cls.TestNameGenerator)
# Tests all combinations of aead. Mutually exclusive with auth/crypt.
- param_list = itertools.product(VERSIONS, TYPES, [None], [None], AEAD_ALGOS)
+ param_list = itertools.product(versions, types, [None], [None], AEAD_ALGOS)
util.InjectParameterizedTest(cls, param_list, cls.TestNameGenerator)
@staticmethod
- def TestNameGenerator(version, proto, authCase, cryptCase, aeadCase):
+ def TestNameGenerator(version, proto, auth_case, crypt_case, aead_case):
# Produce a unique and readable name for each test. e.g.
# testSocketPolicySimple_cbc-aes_256_hmac-sha512_512_256_IPv6_UDP
param_string = ""
- if cryptCase is not None:
- crypt = cryptCase[0]
+ if crypt_case is not None:
+ crypt = crypt_case[0]
param_string += "%s_%d_" % (crypt.name.decode(), crypt.key_len)
- if authCase is not None:
- auth = authCase[0]
+ if auth_case is not None:
+ auth = auth_case[0]
param_string += "%s_%d_%d_" % (auth.name.decode(), auth.key_len,
- auth.trunc_len)
+ auth.trunc_len)
- if aeadCase is not None:
- aead = aeadCase[0]
+ if aead_case is not None:
+ aead = aead_case[0]
param_string += "%s_%d_%d_" % (aead.name.decode(), aead.key_len,
- aead.icv_len)
+ aead.icv_len)
param_string += "%s_%s" % ("IPv4" if version == 4 else "IPv6",
- "UDP" if proto == SOCK_DGRAM else "TCP")
+ "UDP" if proto == SOCK_DGRAM else "TCP")
return param_string
- def ParamTestSocketPolicySimple(self, version, proto, authCase, cryptCase, aeadCase):
+ def ParamTestSocketPolicySimple(self, version, proto, auth_case, crypt_case,
+ aead_case):
"""Test two-way traffic using transport mode and socket policies."""
# Bypass the test if any algorithm going to be tested is not enforced
# or enabled on this kernel
- if authCase is not None and not AuthEnforcedOrEnabled(authCase):
+ if auth_case is not None and not AuthEnforcedOrEnabled(auth_case):
return
- if cryptCase is not None and not CryptEnforcedOrEnabled(cryptCase):
+ if crypt_case is not None and not CryptEnforcedOrEnabled(crypt_case):
return
- if aeadCase is not None and not AeadEnforcedOrEnabled(aeadCase):
+ if aead_case is not None and not AeadEnforcedOrEnabled(aead_case):
return
- auth = authCase[0] if authCase else None
- crypt = cryptCase[0] if cryptCase else None
- aead = aeadCase[0] if aeadCase else None
+ auth = auth_case[0] if auth_case else None
+ crypt = crypt_case[0] if crypt_case else None
+ aead = aead_case[0] if aead_case else None
def AssertEncrypted(packet):
# This gives a free pass to ICMP and ICMPv6 packets, which show up
# nondeterministically in tests.
self.assertEqual(None,
- packet.getlayer(scapy.UDP),
- "UDP packet sent in the clear")
+ packet.getlayer(scapy.UDP),
+ "UDP packet sent in the clear")
self.assertEqual(None,
- packet.getlayer(scapy.TCP),
- "TCP packet sent in the clear")
+ packet.getlayer(scapy.TCP),
+ "TCP packet sent in the clear")
# We create a pair of sockets, "left" and "right", that will talk to each
# other using transport mode ESP. Because of TapTwister, both sockets
@@ -342,7 +350,10 @@ class XfrmAlgorithmTest(xfrm_base.XfrmLazyTest):
data = accepted.recv(2048)
self.assertEqual(b"hello request", data)
accepted.send(b"hello response")
- except Exception as e:
+ time.sleep(0.1)
+ accepted.close()
+ except Exception as e: # pylint: disable=broad-exception-caught
+ nonlocal server_error
server_error = e
finally:
sock.close()
@@ -355,7 +366,8 @@ class XfrmAlgorithmTest(xfrm_base.XfrmLazyTest):
self.assertEqual(client_port, peer[1])
self.assertEqual(b"hello request", data)
sock.sendto(b"hello response", peer)
- except Exception as e:
+ except Exception as e: # pylint: disable=broad-exception-caught
+ nonlocal server_error
server_error = e
finally:
sock.close()
@@ -377,7 +389,8 @@ class XfrmAlgorithmTest(xfrm_base.XfrmLazyTest):
# Wait for server to be ready before attempting to connect. TCP retries
# hide this problem, but UDP will fail outright if the server socket has
# not bound when we send.
- self.assertTrue(server_ready.wait(2.0), "Timed out waiting for server thread")
+ self.assertTrue(server_ready.wait(3.0),
+ "Timed out waiting for server thread")
with TapTwister(fd=self.tuns[netid].fileno(), validator=AssertEncrypted):
sock_left.connect((remote_addr, right_port))
@@ -385,7 +398,7 @@ class XfrmAlgorithmTest(xfrm_base.XfrmLazyTest):
data = sock_left.recv(2048)
self.assertEqual(b"hello response", data)
sock_left.close()
- server.join(timeout=2.0)
+ server.join(timeout=3.0)
self.assertFalse(server.is_alive(), "Timed out waiting for server exit")
if server_error:
raise server_error
diff --git a/net/test/xfrm_tunnel_test.py b/net/test/xfrm_tunnel_test.py
index 715b559..3d0aa53 100755
--- a/net/test/xfrm_tunnel_test.py
+++ b/net/test/xfrm_tunnel_test.py
@@ -162,6 +162,7 @@ def _SendPacket(testInstance, netid, version, remote, remote_port):
testInstance.SelectInterface(write_sock, netid, "mark")
write_sock.sendto(net_test.UDP_PAYLOAD, (remote, remote_port))
local_port = write_sock.getsockname()[1]
+ write_sock.close()
return local_port
@@ -260,6 +261,9 @@ class XfrmTunnelTest(xfrm_base.XfrmLazyTest):
sock = write_sock if direction == xfrm.XFRM_POLICY_OUT else read_sock
func(inner_version, outer_version, u_netid, netid, local_inner,
remote_inner, local_outer, remote_outer, sock)
+
+ write_sock.close()
+ read_sock.close()
finally:
if test_output_mark_unset:
self.ClearDefaultNetwork()
@@ -731,14 +735,17 @@ class XfrmTunnelBase(xfrm_base.XfrmBaseTest):
local_inner, tunnel.local, local_port, sa_info.spi, sa_info.seq_num)
self.ReceivePacketOn(tunnel.underlying_netid, input_pkt)
- if expect_fail:
- self.assertRaisesErrno(EAGAIN, read_sock.recv, 4096)
- else:
- # Verify that the packet data and src are correct
- data, src = read_sock.recvfrom(4096)
- self.assertReceivedPacket(tunnel, sa_info)
- self.assertEqual(net_test.UDP_PAYLOAD, data)
- self.assertEqual((remote_inner, _TEST_REMOTE_PORT), src[:2])
+ try:
+ if expect_fail:
+ self.assertRaisesErrno(EAGAIN, read_sock.recv, 4096)
+ else:
+ # Verify that the packet data and src are correct
+ data, src = read_sock.recvfrom(4096)
+ self.assertReceivedPacket(tunnel, sa_info)
+ self.assertEqual(net_test.UDP_PAYLOAD, data)
+ self.assertEqual((remote_inner, _TEST_REMOTE_PORT), src[:2])
+ finally:
+ read_sock.close()
def _CheckTunnelOutput(self, tunnel, inner_version, local_inner,
remote_inner, sa_info=None):
@@ -826,6 +833,8 @@ class XfrmTunnelBase(xfrm_base.XfrmBaseTest):
# Check that the interface statistics recorded the inbound packet
self.assertReceivedPacket(tunnel, tunnel.in_sa)
+
+ read_sock.close()
finally:
# Swap the interface addresses to pretend we are the remote
self._SwapInterfaceAddress(
diff --git a/test_mappings/BUILD.bazel b/test_mappings/BUILD.bazel
deleted file mode 100644
index fb6f994..0000000
--- a/test_mappings/BUILD.bazel
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright (C) 2024 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-load("@rules_pkg//pkg:pkg.bzl", "pkg_zip")
-
-# Collect into a .zip file the TEST_MAPPING files for packages whose tests
-# should be run in kernel presubmit and postsubmit testing.
-# This rule is in this directory
-# because these TEST_MAPPING files are used when testing kernel code and
-# kernel/tests is the good place for that.
-#
-# Conventions:
-# - Each package declares a :test_mappings pkg_files() target that contains
-# all TEST_MAPPING files in that package. Avoid
-# exports_files(["TEST_MAPPING"])
-# because it requires this target to poke into the implementation
-# detail of each package, and it is less flexible if the package has
-# more TEST_MAPPING files in the future.
-# - Be careful about package boundaries, especially if you are using a
-# glob() expression. See
-# https://bazel.build/reference/be/functions#glob
-#
-# Example for a package with a single TEST_MAPPING file at the top level:
-#
-# pkg_files(
-# name = "test_mappings",
-# srcs = ["TEST_MAPPING"],
-# prefix = package_name(),
-# visibility = ["//kernel/tests/test_mappings:__pkg__"],
-# )
-#
-# Example for a package with multiple TEST_MAPPING files. Use `renames`
-# to preserve the directory structure within the archive:
-#
-# _TEST_MAPPINGS = glob(["**/TEST_MAPPING"])
-# pkg_files(
-# name = "test_mappings",
-# srcs = _TEST_MAPPINGS,
-# prefix = package_name(),
-# renames = {file: file for file in _TEST_MAPPINGS},
-# visibility = ["//kernel/tests/test_mappings:__pkg__"],
-# )
-pkg_zip(
- name = "test_mappings_zip",
- srcs = [
- "//common:test_mappings",
- "//external/zlib:test_mappings",
- "//kernel/tests/net/test:test_mappings",
- "//prebuilts/rust:test_mappings",
- ],
- out = "test_mappings.zip",
- visibility = ["//visibility:public"],
-)