Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
4ed41e9
uuid: correct the field seperator value of ethernet adapter MAC addre…
aixtools Aug 4, 2018
ba47933
Merge branch 'master' into bpo-28009-1
aixtools Aug 4, 2018
c6029a4
correct test logic, cut/paste error
aixtools Aug 4, 2018
7e1874d
specify shorter getters list per https://bugs.python.org/issue28009#m…
aixtools Aug 5, 2018
6a5bccb
write _notAIX as non-negative constant and use 'not AIX'
aixtools Aug 22, 2018
a98309b
simplify NEWS entry
aixtools Aug 22, 2018
53ef750
skip a test the right way
aixtools Aug 22, 2018
6fd5f8e
capitalize constants
aixtools Aug 22, 2018
3bb1c08
oops - restore missing assignment
aixtools Aug 22, 2018
1af8e3d
skip both tests the right way
aixtools Aug 22, 2018
d3eaab9
write _notAIX as non-negative constant and use 'not _AIX'
aixtools Aug 22, 2018
3469a01
added additional 'skip' entries for commands that do not exist on AIX
aixtools Aug 22, 2018
399e8ec
Use and set a single _NODE_GETTERS constant with platform test outsid…
aixtools Aug 24, 2018
6e2a9bf
modify the lambda function so it does not look like a bug
aixtools Sep 16, 2018
bb3a460
resolve differences in imports
aixtools Sep 16, 2018
db6767f
Switch back to using sys.platform.startswith() to resolve conflicts
aixtools Sep 16, 2018
25d3ef1
still trying to get differencs to resolve...
aixtools Sep 16, 2018
fa9b43b
changes per request. Thx for the review!
aixtools Oct 28, 2018
4a0c8f0
resolve merge conflict
aixtools Oct 28, 2018
6463707
resolve merge conflict, 2nd try
aixtools Oct 28, 2018
a0ef760
remove unused added import
taleinat Nov 12, 2018
095e221
Per requested changes
aixtools Nov 14, 2018
ec4c0e8
Merge branch 'bpo-28009-1' of github.com:aixtools/cpython into bpo-28…
aixtools Nov 14, 2018
70a45f0
Merge branch 'master' into bpo-28009-1
ncoghlan Dec 26, 2018
b1b4952
sync with master
aixtools Jun 14, 2019
8f0687a
rename find_mac_routines (in test_uuid.py)
aixtools Jun 14, 2019
4756670
fix sync issues
aixtools Jun 14, 2019
c55714a
sync with master
aixtools Jun 16, 2019
10f272e
add inline comments, correct typos
aixtools Jun 17, 2019
27b6c32
Improve blurb
aixtools Jun 21, 2019
33969b9
refactor more of getting a command's stdout into the helper func
taleinat Jun 24, 2019
7a57734
reduce scope of try/except blocks, for clarity
taleinat Jun 24, 2019
4628cea
make tests run regardless of host OS
taleinat Jun 24, 2019
d2830a2
remove no longer necessary _AIX definition in the test file
taleinat Jul 14, 2019
0688727
fix unittest import and indentation in one place
taleinat Jul 14, 2019
ff1ee20
simplify macaddr parsing and control flow in _find_mac_nextlines()
taleinat Jul 14, 2019
083e9c6
no need for extra return value check in _netstart_getnode()
taleinat Jul 14, 2019
30cd017
improve wording of NEWS entry
taleinat Jul 14, 2019
27a972b
make AIX formatted MAC address handling AIX-specific
taleinat Jul 15, 2019
543e66d
Stop reverse DNS lookups with netstat
aixtools Jul 15, 2019
588fda7
add _MAC_OMITS_LEADING_ZEROES, better function names and doc-strings
taleinat Jul 17, 2019
28f7a01
update blurb and comments in test_uuid.py
aixtools Aug 30, 2019
6fc2129
Update News blurb
aixtools Sep 3, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Use and set a single _NODE_GETTERS constant with platform test outsid…
…e getnode()

Move _netstat_getnode() find alg so that it can be tested using unittest.mock
Add new test `test_uuid/find_mac_netstat` for AIX and netstat
  • Loading branch information
aixtools committed Aug 24, 2018
commit 399e8ec61382b3f040822d26599e72de55c09114
41 changes: 29 additions & 12 deletions Lib/test/test_uuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,7 @@ def test_uuid1_eui64(self):
with unittest.mock.patch.multiple(
self.uuid,
_node=None, # Ignore any cached node value.
_NODE_GETTERS_WIN32=[too_large_getter],
_NODE_GETTERS_UNIX=[too_large_getter],
_NODE_GETTERS=[too_large_getter],
):
node = self.uuid.getnode()
self.assertTrue(0 < node < (1 << 48), '%012x' % node)
Expand Down Expand Up @@ -516,21 +515,39 @@ class TestUUIDWithExtModule(BaseTestUUID, unittest.TestCase):
class BaseTestInternals:
uuid = None

@unittest.skipUnless(AIX, 'requires AIX')
def test_find_mac_netstat(self):
data = '''Name Mtu Network Address Ipkts Ierrs Opkts Oerrs Coll
en0 1500 link#2 fe.ad.c.1.23.4 1714807956 0 711348489 0 0
01:00:5e:00:00:01
en0 1500 192.168.129 x071 1714807956 0 711348489 0 0
224.0.0.1
en0 1500 192.168.90 x071 1714807956 0 711348489 0 0
224.0.0.1
'''
popen = unittest.mock.MagicMock()
popen.stdout = io.BytesIO(data.encode())

with unittest.mock.patch.object(shutil, 'which',
Comment thread
aixtools marked this conversation as resolved.
Outdated
return_value='/usr/bin/netstat'):
with unittest.mock.patch.object(subprocess, 'Popen',
return_value=popen):
mac = self.uuid._find_mac_netstat(
command='netstat',
args='-ia',
hw_identifiers=b'Address',
get_index=lambda x: x * 1,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why you need to use i+1 here. It looks like a bug.

Copy link
Copy Markdown
Contributor Author

@aixtools aixtools Aug 26, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Guess my replies did not make it here.
a) It is "* 1" not plus 1
b) it may indicate a bug (not in the test I fear, but elsewhere in core) - when I was trying to use the find_mac code to parse netstat output I first tried "get_index=lambda x: x", but it always evaluated as get_index=lambda x: x + 1. I may have also tried x + 0, but I do not recall. Before merging I can experiment with other values - and if they are not working that is a different bug - not the one I am trying to resolve.

)

self.assertEqual(mac, 0xfead0c012304)
Comment thread
aixtools marked this conversation as resolved.

@unittest.skipUnless(os.name == 'posix', 'requires Posix')
@unittest.skipIf(AIX, 'because AIX "ifconfig" does not provide macaddr')
Comment thread
aixtools marked this conversation as resolved.
Outdated
def test_find_mac(self):
if not AIX:
data = '''
fake hwaddr
data = '''fake Link encap:UNSPEC hwaddr 00-00
Comment thread
aixtools marked this conversation as resolved.
Outdated
cscotun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
eth0 Link encap:Ethernet HWaddr 12:34:56:78:90:ab
'''
else:
data = '''
fake hwaddr
cscotun0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
eth0 Link encap:Ethernet HWaddr 12.34.56.78.90.ab
'''

popen = unittest.mock.MagicMock()
popen.stdout = io.BytesIO(data.encode())

Expand Down
104 changes: 54 additions & 50 deletions Lib/uuid.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@

__author__ = 'Ka-Ping Yee <ping@zesty.ca>'

_WIN32 = sys.platform == 'win32'
_AIX = sys.platform.startswith("aix")
_MAC_DELIM = b':' if not _AIX else b'.'
Comment thread
taleinat marked this conversation as resolved.
Outdated

Expand Down Expand Up @@ -391,6 +392,48 @@ def _find_mac(command, args, hw_identifiers, get_index):
pass
return first_local_mac or None

def _find_mac_netstat(command, args, hw_identifiers, get_index):
Comment thread
aixtools marked this conversation as resolved.
Outdated
Comment thread
aixtools marked this conversation as resolved.
Outdated
first_local_mac = None
mac = None
try:
proc = _popen(command, *args.split())
if not proc:
return None
with proc:
words = proc.stdout.readline().rstrip().split()
try:
i = words.index(hw_identifiers)
except ValueError:
return None
for line in proc.stdout:
try:
words = line.rstrip().split()
word = words[get_index(i)]
if len(word) == 17 and word.count(_MAC_DELIM) == 5:
mac = int(word.replace(_MAC_DELIM, b''), 16)
elif _AIX and word.count(_MAC_DELIM) == 5:
# the extracted hex string is not a 12 hex digit
# string, so add the fields piece by piece
if len(word) < 17 and len(word) >= 11:
mac = 0
fields = word.split(_MAC_DELIM)
for hex in fields:
mac <<= 8
mac += int(hex, 16)
if mac and _is_universal(mac):
return mac
first_local_mac = first_local_mac or mac
except (ValueError, IndexError):
# Virtual interfaces, such as those provided by
# VPNs, do not have a colon-delimited MAC address
# as expected, but a 16-byte HWAddr separated by
# dashes. These should be ignored in favor of a
# real MAC address
pass
except OSError:
pass
return first_local_mac or None

def _ifconfig_getnode():
"""Get the hardware address on Unix by running ifconfig."""
# This works on Linux ('' or '-a'), Tru64 ('-av'), but not all Unixes.
Expand Down Expand Up @@ -442,42 +485,9 @@ def _lanscan_getnode():

def _netstat_getnode():
"""Get the hardware address on Unix by running netstat."""
# This might work on AIX, Tru64 UNIX.
first_local_mac = None
try:
proc = _popen('netstat', '-ia')
if not proc:
return None
with proc:
words = proc.stdout.readline().rstrip().split()
try:
i = words.index(b'Address')
except ValueError:
return None
for line in proc.stdout:
try:
words = line.rstrip().split()
word = words[i]
if word.count(_MAC_DELIM) == 5:
if len(word) == 17:
mac = int(word.replace(_MAC_DELIM, b''), 16)
# the extracted hex string will not be a 12 hex digit
# string, so extract the fields and add them in
# piece by piece
elif len(word) < 17 and len(word) >= 11:
mac = 0
hexs = word.split(_MAC_DELIM)
for hex in hexs:
mac <<= 8
mac += int(hex, 16)
if _is_universal(mac):
return mac
first_local_mac = first_local_mac or mac
except (ValueError, IndexError):
pass
except OSError:
pass
return first_local_mac or None
# This works on AIX and might work on Tru64 UNIX.
mac = _find_mac_netstat('netstat', '-ia', b'Address', lambda i: i+0)
return mac if mac else None
Comment thread
aixtools marked this conversation as resolved.
Outdated

def _ipconfig_getnode():
"""Get the hardware address on Windows by running ipconfig.exe."""
Expand Down Expand Up @@ -669,15 +679,15 @@ def _random_getnode():
return random.getrandbits(48) | (1 << 40)


if _AIX:
_NODE_GETTERS = [_unix_getnode, _netstat_getnode]
elif _WIN32:
_NODE_GETTERS = [_windll_getnode, _netbios_getnode, _ipconfig_getnode]
else:
_NODE_GETTERS = [_unix_getnode, _ifconfig_getnode, _ip_getnode,
_arp_getnode, _lanscan_getnode, _netstat_getnode]
_node = None

_NODE_GETTERS_WIN32 = [_windll_getnode, _netbios_getnode, _ipconfig_getnode]

_NODE_GETTERS_UNIX = [_unix_getnode, _ifconfig_getnode, _ip_getnode,
_arp_getnode, _lanscan_getnode, _netstat_getnode]

_NODE_GETTERS_AIX = [_unix_getnode, _netstat_getnode]

def getnode(*, getters=None):
"""Get the hardware address as a 48-bit positive integer.

Expand All @@ -690,12 +700,7 @@ def getnode(*, getters=None):
if _node is not None:
return _node

if sys.platform == 'win32':
getters = _NODE_GETTERS_WIN32
else:
getters = _NODE_GETTERS_UNIX if not _AIX else _NODE_GETTERS_AIX

for getter in getters + [_random_getnode]:
for getter in _NODE_GETTERS + [_random_getnode]:
try:
_node = getter()
except:
Expand All @@ -704,7 +709,6 @@ def getnode(*, getters=None):
return _node
assert False, '_random_getnode() returned invalid value: {}'.format(_node)


_last_timestamp = None

def uuid1(node=None, clock_seq=None):
Expand Down