Skip to content

Commit ddcd546

Browse files
aiskcorona10
authored andcommitted
pythongh-112278: Add retry in WMI tests in case of slow initialization (pythonGH-113154)
1 parent 9df6e0f commit ddcd546

File tree

1 file changed

+19
-7
lines changed

1 file changed

+19
-7
lines changed

Lib/test/test_wmi.py

+19-7
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,29 @@
11
# Test the internal _wmi module on Windows
22
# This is used by the platform module, and potentially others
33

4+
import time
45
import unittest
5-
from test.support import import_helper, requires_resource
6+
from test.support import import_helper, requires_resource, LOOPBACK_TIMEOUT
67

78

89
# Do this first so test will be skipped if module doesn't exist
910
_wmi = import_helper.import_module('_wmi', required_on=['win'])
1011

1112

13+
def wmi_exec_query(query):
14+
# gh-112278: WMI maybe slow response when first call.
15+
try:
16+
return _wmi.exec_query(query)
17+
except WindowsError as e:
18+
if e.winerror != 258:
19+
raise
20+
time.sleep(LOOPBACK_TIMEOUT)
21+
return _wmi.exec_query(query)
22+
23+
1224
class WmiTests(unittest.TestCase):
1325
def test_wmi_query_os_version(self):
14-
r = _wmi.exec_query("SELECT Version FROM Win32_OperatingSystem").split("\0")
26+
r = wmi_exec_query("SELECT Version FROM Win32_OperatingSystem").split("\0")
1527
self.assertEqual(1, len(r))
1628
k, eq, v = r[0].partition("=")
1729
self.assertEqual("=", eq, r[0])
@@ -28,7 +40,7 @@ def test_wmi_query_repeated(self):
2840
def test_wmi_query_error(self):
2941
# Invalid queries fail with OSError
3042
try:
31-
_wmi.exec_query("SELECT InvalidColumnName FROM InvalidTableName")
43+
wmi_exec_query("SELECT InvalidColumnName FROM InvalidTableName")
3244
except OSError as ex:
3345
if ex.winerror & 0xFFFFFFFF == 0x80041010:
3446
# This is the expected error code. All others should fail the test
@@ -42,19 +54,19 @@ def test_wmi_query_repeated_error(self):
4254
def test_wmi_query_not_select(self):
4355
# Queries other than SELECT are blocked to avoid potential exploits
4456
with self.assertRaises(ValueError):
45-
_wmi.exec_query("not select, just in case someone tries something")
57+
wmi_exec_query("not select, just in case someone tries something")
4658

4759
@requires_resource('cpu')
4860
def test_wmi_query_overflow(self):
4961
# Ensure very big queries fail
5062
# Test multiple times to ensure consistency
5163
for _ in range(2):
5264
with self.assertRaises(OSError):
53-
_wmi.exec_query("SELECT * FROM CIM_DataFile")
65+
wmi_exec_query("SELECT * FROM CIM_DataFile")
5466

5567
def test_wmi_query_multiple_rows(self):
5668
# Multiple instances should have an extra null separator
57-
r = _wmi.exec_query("SELECT ProcessId FROM Win32_Process WHERE ProcessId < 1000")
69+
r = wmi_exec_query("SELECT ProcessId FROM Win32_Process WHERE ProcessId < 1000")
5870
self.assertFalse(r.startswith("\0"), r)
5971
self.assertFalse(r.endswith("\0"), r)
6072
it = iter(r.split("\0"))
@@ -69,6 +81,6 @@ def test_wmi_query_threads(self):
6981
from concurrent.futures import ThreadPoolExecutor
7082
query = "SELECT ProcessId FROM Win32_Process WHERE ProcessId < 1000"
7183
with ThreadPoolExecutor(4) as pool:
72-
task = [pool.submit(_wmi.exec_query, query) for _ in range(32)]
84+
task = [pool.submit(wmi_exec_query, query) for _ in range(32)]
7385
for t in task:
7486
self.assertRegex(t.result(), "ProcessId=")

0 commit comments

Comments
 (0)