@@ -136,6 +136,8 @@ def socket_setdefaulttimeout(timeout):
136136
137137HAVE_SOCKET_VSOCK = _have_socket_vsock ()
138138
139+ HAVE_SOCKET_UDPLITE = hasattr (socket , "IPPROTO_UDPLITE" )
140+
139141# Size in bytes of the int type
140142SIZEOF_INT = array .array ("i" ).itemsize
141143
@@ -160,6 +162,12 @@ def tearDown(self):
160162 self .serv .close ()
161163 self .serv = None
162164
165+ class SocketUDPLITETest (SocketUDPTest ):
166+
167+ def setUp (self ):
168+ self .serv = socket .socket (socket .AF_INET , socket .SOCK_DGRAM , socket .IPPROTO_UDPLITE )
169+ self .port = support .bind_port (self .serv )
170+
163171class ThreadSafeCleanupTestCase (unittest .TestCase ):
164172 """Subclass of unittest.TestCase with thread-safe cleanup methods.
165173
@@ -391,6 +399,22 @@ def clientTearDown(self):
391399 self .cli = None
392400 ThreadableTest .clientTearDown (self )
393401
402+ @unittest .skipUnless (HAVE_SOCKET_UDPLITE ,
403+ 'UDPLITE sockets required for this test.' )
404+ class ThreadedUDPLITESocketTest (SocketUDPLITETest , ThreadableTest ):
405+
406+ def __init__ (self , methodName = 'runTest' ):
407+ SocketUDPLITETest .__init__ (self , methodName = methodName )
408+ ThreadableTest .__init__ (self )
409+
410+ def clientSetUp (self ):
411+ self .cli = socket .socket (socket .AF_INET , socket .SOCK_DGRAM , socket .IPPROTO_UDPLITE )
412+
413+ def clientTearDown (self ):
414+ self .cli .close ()
415+ self .cli = None
416+ ThreadableTest .clientTearDown (self )
417+
394418class ThreadedCANSocketTest (SocketCANTest , ThreadableTest ):
395419
396420 def __init__ (self , methodName = 'runTest' ):
@@ -676,6 +700,12 @@ class UDPTestBase(InetTestBase):
676700 def newSocket (self ):
677701 return socket .socket (socket .AF_INET , socket .SOCK_DGRAM )
678702
703+ class UDPLITETestBase (InetTestBase ):
704+ """Base class for UDPLITE-over-IPv4 tests."""
705+
706+ def newSocket (self ):
707+ return socket .socket (socket .AF_INET , socket .SOCK_DGRAM , socket .IPPROTO_UDPLITE )
708+
679709class SCTPStreamBase (InetTestBase ):
680710 """Base class for SCTP tests in one-to-one (SOCK_STREAM) mode."""
681711
@@ -695,6 +725,12 @@ class UDP6TestBase(Inet6TestBase):
695725 def newSocket (self ):
696726 return socket .socket (socket .AF_INET6 , socket .SOCK_DGRAM )
697727
728+ class UDPLITE6TestBase (Inet6TestBase ):
729+ """Base class for UDPLITE-over-IPv6 tests."""
730+
731+ def newSocket (self ):
732+ return socket .socket (socket .AF_INET6 , socket .SOCK_DGRAM , socket .IPPROTO_UDPLITE )
733+
698734
699735# Test-skipping decorators for use with ThreadableTest.
700736
@@ -2359,6 +2395,37 @@ def testRecvFromNegative(self):
23592395 def _testRecvFromNegative (self ):
23602396 self .cli .sendto (MSG , 0 , (HOST , self .port ))
23612397
2398+
2399+ @unittest .skipUnless (HAVE_SOCKET_UDPLITE ,
2400+ 'UDPLITE sockets required for this test.' )
2401+ class BasicUDPLITETest (ThreadedUDPLITESocketTest ):
2402+
2403+ def __init__ (self , methodName = 'runTest' ):
2404+ ThreadedUDPLITESocketTest .__init__ (self , methodName = methodName )
2405+
2406+ def testSendtoAndRecv (self ):
2407+ # Testing sendto() and Recv() over UDPLITE
2408+ msg = self .serv .recv (len (MSG ))
2409+ self .assertEqual (msg , MSG )
2410+
2411+ def _testSendtoAndRecv (self ):
2412+ self .cli .sendto (MSG , 0 , (HOST , self .port ))
2413+
2414+ def testRecvFrom (self ):
2415+ # Testing recvfrom() over UDPLITE
2416+ msg , addr = self .serv .recvfrom (len (MSG ))
2417+ self .assertEqual (msg , MSG )
2418+
2419+ def _testRecvFrom (self ):
2420+ self .cli .sendto (MSG , 0 , (HOST , self .port ))
2421+
2422+ def testRecvFromNegative (self ):
2423+ # Negative lengths passed to recvfrom should give ValueError.
2424+ self .assertRaises (ValueError , self .serv .recvfrom , - 1 )
2425+
2426+ def _testRecvFromNegative (self ):
2427+ self .cli .sendto (MSG , 0 , (HOST , self .port ))
2428+
23622429# Tests for the sendmsg()/recvmsg() interface. Where possible, the
23632430# same test code is used with different families and types of socket
23642431# (e.g. stream, datagram), and tests using recvmsg() are repeated
@@ -3992,6 +4059,89 @@ class RecvmsgIntoRFC3542AncillaryUDP6Test(RecvmsgIntoMixin,
39924059 pass
39934060
39944061
4062+ @unittest .skipUnless (HAVE_SOCKET_UDPLITE ,
4063+ 'UDPLITE sockets required for this test.' )
4064+ class SendrecvmsgUDPLITETestBase (SendrecvmsgDgramFlagsBase ,
4065+ SendrecvmsgConnectionlessBase ,
4066+ ThreadedSocketTestMixin , UDPLITETestBase ):
4067+ pass
4068+
4069+ @unittest .skipUnless (HAVE_SOCKET_UDPLITE ,
4070+ 'UDPLITE sockets required for this test.' )
4071+ @requireAttrs (socket .socket , "sendmsg" )
4072+ class SendmsgUDPLITETest (SendmsgConnectionlessTests , SendrecvmsgUDPLITETestBase ):
4073+ pass
4074+
4075+ @unittest .skipUnless (HAVE_SOCKET_UDPLITE ,
4076+ 'UDPLITE sockets required for this test.' )
4077+ @requireAttrs (socket .socket , "recvmsg" )
4078+ class RecvmsgUDPLITETest (RecvmsgTests , SendrecvmsgUDPLITETestBase ):
4079+ pass
4080+
4081+ @unittest .skipUnless (HAVE_SOCKET_UDPLITE ,
4082+ 'UDPLITE sockets required for this test.' )
4083+ @requireAttrs (socket .socket , "recvmsg_into" )
4084+ class RecvmsgIntoUDPLITETest (RecvmsgIntoTests , SendrecvmsgUDPLITETestBase ):
4085+ pass
4086+
4087+
4088+ @unittest .skipUnless (HAVE_SOCKET_UDPLITE ,
4089+ 'UDPLITE sockets required for this test.' )
4090+ class SendrecvmsgUDPLITE6TestBase (SendrecvmsgDgramFlagsBase ,
4091+ SendrecvmsgConnectionlessBase ,
4092+ ThreadedSocketTestMixin , UDPLITE6TestBase ):
4093+
4094+ def checkRecvmsgAddress (self , addr1 , addr2 ):
4095+ # Called to compare the received address with the address of
4096+ # the peer, ignoring scope ID
4097+ self .assertEqual (addr1 [:- 1 ], addr2 [:- 1 ])
4098+
4099+ @requireAttrs (socket .socket , "sendmsg" )
4100+ @unittest .skipUnless (support .IPV6_ENABLED , 'IPv6 required for this test.' )
4101+ @unittest .skipUnless (HAVE_SOCKET_UDPLITE ,
4102+ 'UDPLITE sockets required for this test.' )
4103+ @requireSocket ("AF_INET6" , "SOCK_DGRAM" )
4104+ class SendmsgUDPLITE6Test (SendmsgConnectionlessTests , SendrecvmsgUDPLITE6TestBase ):
4105+ pass
4106+
4107+ @requireAttrs (socket .socket , "recvmsg" )
4108+ @unittest .skipUnless (support .IPV6_ENABLED , 'IPv6 required for this test.' )
4109+ @unittest .skipUnless (HAVE_SOCKET_UDPLITE ,
4110+ 'UDPLITE sockets required for this test.' )
4111+ @requireSocket ("AF_INET6" , "SOCK_DGRAM" )
4112+ class RecvmsgUDPLITE6Test (RecvmsgTests , SendrecvmsgUDPLITE6TestBase ):
4113+ pass
4114+
4115+ @requireAttrs (socket .socket , "recvmsg_into" )
4116+ @unittest .skipUnless (support .IPV6_ENABLED , 'IPv6 required for this test.' )
4117+ @unittest .skipUnless (HAVE_SOCKET_UDPLITE ,
4118+ 'UDPLITE sockets required for this test.' )
4119+ @requireSocket ("AF_INET6" , "SOCK_DGRAM" )
4120+ class RecvmsgIntoUDPLITE6Test (RecvmsgIntoTests , SendrecvmsgUDPLITE6TestBase ):
4121+ pass
4122+
4123+ @requireAttrs (socket .socket , "recvmsg" )
4124+ @unittest .skipUnless (support .IPV6_ENABLED , 'IPv6 required for this test.' )
4125+ @unittest .skipUnless (HAVE_SOCKET_UDPLITE ,
4126+ 'UDPLITE sockets required for this test.' )
4127+ @requireAttrs (socket , "IPPROTO_IPV6" )
4128+ @requireSocket ("AF_INET6" , "SOCK_DGRAM" )
4129+ class RecvmsgRFC3542AncillaryUDPLITE6Test (RFC3542AncillaryTest ,
4130+ SendrecvmsgUDPLITE6TestBase ):
4131+ pass
4132+
4133+ @requireAttrs (socket .socket , "recvmsg_into" )
4134+ @unittest .skipUnless (support .IPV6_ENABLED , 'IPv6 required for this test.' )
4135+ @unittest .skipUnless (HAVE_SOCKET_UDPLITE ,
4136+ 'UDPLITE sockets required for this test.' )
4137+ @requireAttrs (socket , "IPPROTO_IPV6" )
4138+ @requireSocket ("AF_INET6" , "SOCK_DGRAM" )
4139+ class RecvmsgIntoRFC3542AncillaryUDPLITE6Test (RecvmsgIntoMixin ,
4140+ RFC3542AncillaryTest ,
4141+ SendrecvmsgUDPLITE6TestBase ):
4142+ pass
4143+
4144+
39954145class SendrecvmsgTCPTestBase (SendrecvmsgConnectedBase ,
39964146 ConnectedStreamTestMixin , TCPTestBase ):
39974147 pass
@@ -4998,6 +5148,31 @@ def testTimeoutZero(self):
49985148 if not ok :
49995149 self .fail ("recv() returned success when we did not expect it" )
50005150
5151+ @unittest .skipUnless (HAVE_SOCKET_UDPLITE ,
5152+ 'UDPLITE sockets required for this test.' )
5153+ class UDPLITETimeoutTest (SocketUDPLITETest ):
5154+
5155+ def testUDPLITETimeout (self ):
5156+ def raise_timeout (* args , ** kwargs ):
5157+ self .serv .settimeout (1.0 )
5158+ self .serv .recv (1024 )
5159+ self .assertRaises (socket .timeout , raise_timeout ,
5160+ "Error generating a timeout exception (UDPLITE)" )
5161+
5162+ def testTimeoutZero (self ):
5163+ ok = False
5164+ try :
5165+ self .serv .settimeout (0.0 )
5166+ foo = self .serv .recv (1024 )
5167+ except socket .timeout :
5168+ self .fail ("caught timeout instead of error (UDPLITE)" )
5169+ except OSError :
5170+ ok = True
5171+ except :
5172+ self .fail ("caught unexpected exception (UDPLITE)" )
5173+ if not ok :
5174+ self .fail ("recv() returned success when we did not expect it" )
5175+
50015176class TestExceptions (unittest .TestCase ):
50025177
50035178 def testExceptionTree (self ):
@@ -6230,6 +6405,14 @@ def test_main():
62306405 RecvmsgRFC3542AncillaryUDP6Test ,
62316406 RecvmsgIntoRFC3542AncillaryUDP6Test ,
62326407 RecvmsgIntoUDP6Test ,
6408+ SendmsgUDPLITETest ,
6409+ RecvmsgUDPLITETest ,
6410+ RecvmsgIntoUDPLITETest ,
6411+ SendmsgUDPLITE6Test ,
6412+ RecvmsgUDPLITE6Test ,
6413+ RecvmsgRFC3542AncillaryUDPLITE6Test ,
6414+ RecvmsgIntoRFC3542AncillaryUDPLITE6Test ,
6415+ RecvmsgIntoUDPLITE6Test ,
62336416 SendmsgTCPTest ,
62346417 RecvmsgTCPTest ,
62356418 RecvmsgIntoTCPTest ,
0 commit comments