py2docfx 0.1.11rc1981066__py3-none-any.whl → 0.1.11rc1996319__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/authorization_code.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/azd_cli.py +20 -14
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/azure_arc.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/azure_cli.py +36 -14
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/azure_powershell.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/chained.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/default.py +4 -3
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/imds.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_credentials/managed_identity.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/__init__.py +2 -0
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/auth_code_redirect_handler.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/decorators.py +15 -7
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/interactive.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/managed_identity_client.py +0 -1
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/msal_client.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/msal_managed_identity_client.py +2 -1
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/shared_token_cache.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_internal/utils.py +17 -2
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/_version.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/azd_cli.py +14 -11
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/azure_cli.py +30 -12
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/default.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/imds.py +3 -3
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_credentials/managed_identity.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_internal/decorators.py +15 -7
- py2docfx/venv/venv1/Lib/site-packages/azure/identity/aio/_internal/managed_identity_client.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/cryptography/__about__.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/google/api/annotations_pb2.py +7 -4
- py2docfx/venv/venv1/Lib/site-packages/google/api/auth_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/api/backend_pb2.py +14 -7
- py2docfx/venv/venv1/Lib/site-packages/google/api/billing_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/api/client_pb2.py +47 -38
- py2docfx/venv/venv1/Lib/site-packages/google/api/config_change_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/api/consumer_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/api/context_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/api/control_pb2.py +6 -4
- py2docfx/venv/venv1/Lib/site-packages/google/api/distribution_pb2.py +7 -5
- py2docfx/venv/venv1/Lib/site-packages/google/api/documentation_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/api/endpoint_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/api/error_reason_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/api/field_behavior_pb2.py +8 -6
- py2docfx/venv/venv1/Lib/site-packages/google/api/field_info_pb2.py +6 -4
- py2docfx/venv/venv1/Lib/site-packages/google/api/http_pb2.py +7 -4
- py2docfx/venv/venv1/Lib/site-packages/google/api/httpbody_pb2.py +6 -4
- py2docfx/venv/venv1/Lib/site-packages/google/api/label_pb2.py +7 -4
- py2docfx/venv/venv1/Lib/site-packages/google/api/launch_stage_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/api/log_pb2.py +6 -4
- py2docfx/venv/venv1/Lib/site-packages/google/api/logging_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/api/metric_pb2.py +12 -9
- py2docfx/venv/venv1/Lib/site-packages/google/api/monitored_resource_pb2.py +15 -10
- py2docfx/venv/venv1/Lib/site-packages/google/api/monitoring_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/api/policy_pb2.py +7 -5
- py2docfx/venv/venv1/Lib/site-packages/google/api/quota_pb2.py +10 -7
- py2docfx/venv/venv1/Lib/site-packages/google/api/resource_pb2.py +7 -5
- py2docfx/venv/venv1/Lib/site-packages/google/api/routing_pb2.py +6 -4
- py2docfx/venv/venv1/Lib/site-packages/google/api/service_pb2.py +15 -12
- py2docfx/venv/venv1/Lib/site-packages/google/api/source_info_pb2.py +6 -4
- py2docfx/venv/venv1/Lib/site-packages/google/api/system_parameter_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/api/usage_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/api/visibility_pb2.py +7 -5
- py2docfx/venv/venv1/Lib/site-packages/google/cloud/extended_operations_pb2.py +6 -4
- py2docfx/venv/venv1/Lib/site-packages/google/cloud/location/locations_pb2.py +18 -13
- py2docfx/venv/venv1/Lib/site-packages/google/gapic/metadata/gapic_metadata_pb2.py +31 -26
- py2docfx/venv/venv1/Lib/site-packages/google/logging/type/http_request_pb2.py +6 -4
- py2docfx/venv/venv1/Lib/site-packages/google/logging/type/log_severity_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/longrunning/operations_grpc.py +2 -1
- py2docfx/venv/venv1/Lib/site-packages/google/longrunning/operations_grpc_pb2.py +11 -10
- py2docfx/venv/venv1/Lib/site-packages/google/longrunning/operations_pb2.py +20 -17
- py2docfx/venv/venv1/Lib/site-packages/google/longrunning/operations_pb2_grpc.py +1 -2
- py2docfx/venv/venv1/Lib/site-packages/google/longrunning/operations_proto.py +2 -1
- py2docfx/venv/venv1/Lib/site-packages/google/longrunning/operations_proto_pb2.py +22 -19
- py2docfx/venv/venv1/Lib/site-packages/google/rpc/code_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/rpc/context/attribute_context_pb2.py +20 -16
- py2docfx/venv/venv1/Lib/site-packages/google/rpc/context/audit_context_pb2.py +7 -5
- py2docfx/venv/venv1/Lib/site-packages/google/rpc/error_details_pb2.py +21 -19
- py2docfx/venv/venv1/Lib/site-packages/google/rpc/http_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/rpc/status_pb2.py +6 -4
- py2docfx/venv/venv1/Lib/site-packages/google/type/calendar_period_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/type/color_pb2.py +6 -4
- py2docfx/venv/venv1/Lib/site-packages/google/type/date_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/type/datetime_pb2.py +6 -4
- py2docfx/venv/venv1/Lib/site-packages/google/type/dayofweek_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/type/decimal_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/type/expr_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/type/fraction_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/type/interval_pb2.py +6 -4
- py2docfx/venv/venv1/Lib/site-packages/google/type/latlng_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/type/localized_text_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/type/money_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/type/month_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/type/phone_number_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/type/postal_address_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/type/quaternion_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/google/type/timeofday_pb2.py +6 -3
- py2docfx/venv/venv1/Lib/site-packages/psutil/__init__.py +122 -201
- py2docfx/venv/venv1/Lib/site-packages/psutil/_common.py +84 -128
- py2docfx/venv/venv1/Lib/site-packages/psutil/_psaix.py +24 -38
- py2docfx/venv/venv1/Lib/site-packages/psutil/_psbsd.py +44 -58
- py2docfx/venv/venv1/Lib/site-packages/psutil/_pslinux.py +170 -254
- py2docfx/venv/venv1/Lib/site-packages/psutil/_psosx.py +8 -16
- py2docfx/venv/venv1/Lib/site-packages/psutil/_psposix.py +13 -49
- py2docfx/venv/venv1/Lib/site-packages/psutil/_pssunos.py +41 -60
- py2docfx/venv/venv1/Lib/site-packages/psutil/_pswindows.py +75 -145
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/__init__.py +105 -193
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_aix.py +2 -2
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_bsd.py +27 -26
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_connections.py +16 -17
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_contracts.py +5 -19
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_linux.py +153 -211
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_memleaks.py +0 -6
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_misc.py +22 -207
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_osx.py +9 -4
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_posix.py +8 -15
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_process.py +104 -184
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_process_all.py +28 -36
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_scripts.py +240 -0
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_sunos.py +1 -1
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_system.py +44 -50
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_testutils.py +23 -33
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_unicode.py +8 -67
- py2docfx/venv/venv1/Lib/site-packages/psutil/tests/test_windows.py +32 -52
- {py2docfx-0.1.11rc1981066.dist-info → py2docfx-0.1.11rc1996319.dist-info}/METADATA +1 -1
- {py2docfx-0.1.11rc1981066.dist-info → py2docfx-0.1.11rc1996319.dist-info}/RECORD +125 -125
- py2docfx/venv/venv1/Lib/site-packages/psutil/_compat.py +0 -477
- {py2docfx-0.1.11rc1981066.dist-info → py2docfx-0.1.11rc1996319.dist-info}/WHEEL +0 -0
- {py2docfx-0.1.11rc1981066.dist-info → py2docfx-0.1.11rc1996319.dist-info}/top_level.txt +0 -0
@@ -6,8 +6,8 @@
|
|
6
6
|
|
7
7
|
"""Tests for system APIS."""
|
8
8
|
|
9
|
-
import contextlib
|
10
9
|
import datetime
|
10
|
+
import enum
|
11
11
|
import errno
|
12
12
|
import os
|
13
13
|
import platform
|
@@ -17,6 +17,7 @@ import signal
|
|
17
17
|
import socket
|
18
18
|
import sys
|
19
19
|
import time
|
20
|
+
from unittest import mock
|
20
21
|
|
21
22
|
import psutil
|
22
23
|
from psutil import AIX
|
@@ -29,12 +30,10 @@ from psutil import OPENBSD
|
|
29
30
|
from psutil import POSIX
|
30
31
|
from psutil import SUNOS
|
31
32
|
from psutil import WINDOWS
|
32
|
-
from psutil.
|
33
|
-
from psutil.
|
34
|
-
from psutil._compat import long
|
33
|
+
from psutil._common import broadcast_addr
|
34
|
+
from psutil.tests import AARCH64
|
35
35
|
from psutil.tests import ASCII_FS
|
36
36
|
from psutil.tests import CI_TESTING
|
37
|
-
from psutil.tests import DEVNULL
|
38
37
|
from psutil.tests import GITHUB_ACTIONS
|
39
38
|
from psutil.tests import GLOBAL_TIMEOUT
|
40
39
|
from psutil.tests import HAS_BATTERY
|
@@ -47,12 +46,9 @@ from psutil.tests import HAS_SENSORS_TEMPERATURES
|
|
47
46
|
from psutil.tests import IS_64BIT
|
48
47
|
from psutil.tests import MACOS_12PLUS
|
49
48
|
from psutil.tests import PYPY
|
50
|
-
from psutil.tests import QEMU_USER
|
51
49
|
from psutil.tests import UNICODE_SUFFIX
|
52
50
|
from psutil.tests import PsutilTestCase
|
53
51
|
from psutil.tests import check_net_address
|
54
|
-
from psutil.tests import enum
|
55
|
-
from psutil.tests import mock
|
56
52
|
from psutil.tests import pytest
|
57
53
|
from psutil.tests import retry_on_failure
|
58
54
|
|
@@ -73,7 +69,7 @@ class TestProcessIter(PsutilTestCase):
|
|
73
69
|
assert sproc.pid not in [x.pid for x in psutil.process_iter()]
|
74
70
|
|
75
71
|
def test_no_duplicates(self):
|
76
|
-
ls =
|
72
|
+
ls = list(psutil.process_iter())
|
77
73
|
assert sorted(ls, key=lambda x: x.pid) == sorted(
|
78
74
|
set(ls), key=lambda x: x.pid
|
79
75
|
)
|
@@ -85,7 +81,7 @@ class TestProcessIter(PsutilTestCase):
|
|
85
81
|
'psutil.Process.as_dict',
|
86
82
|
side_effect=psutil.NoSuchProcess(os.getpid()),
|
87
83
|
):
|
88
|
-
assert list(psutil.process_iter(attrs=["cpu_times"]))
|
84
|
+
assert not list(psutil.process_iter(attrs=["cpu_times"]))
|
89
85
|
psutil.process_iter.cache_clear() # repeat test without cache
|
90
86
|
|
91
87
|
def test_emulate_access_denied(self):
|
@@ -156,9 +152,9 @@ class TestProcessAPIs(PsutilTestCase):
|
|
156
152
|
gone, alive = psutil.wait_procs(procs, timeout=0.01, callback=callback)
|
157
153
|
|
158
154
|
assert time.time() - t < 0.5
|
159
|
-
assert gone
|
155
|
+
assert not gone
|
160
156
|
assert len(alive) == 3
|
161
|
-
assert pids
|
157
|
+
assert not pids
|
162
158
|
for p in alive:
|
163
159
|
assert not hasattr(p, 'returncode')
|
164
160
|
|
@@ -194,7 +190,7 @@ class TestProcessAPIs(PsutilTestCase):
|
|
194
190
|
sproc1.terminate()
|
195
191
|
sproc2.terminate()
|
196
192
|
gone, alive = test_2(procs, callback)
|
197
|
-
assert set(pids) ==
|
193
|
+
assert set(pids) == {sproc1.pid, sproc2.pid, sproc3.pid}
|
198
194
|
for p in gone:
|
199
195
|
assert hasattr(p, 'returncode')
|
200
196
|
|
@@ -248,7 +244,7 @@ class TestMiscAPIs(PsutilTestCase):
|
|
248
244
|
)
|
249
245
|
def test_users(self):
|
250
246
|
users = psutil.users()
|
251
|
-
assert users
|
247
|
+
assert users
|
252
248
|
for user in users:
|
253
249
|
with self.subTest(user=user):
|
254
250
|
assert user.name
|
@@ -256,8 +252,8 @@ class TestMiscAPIs(PsutilTestCase):
|
|
256
252
|
assert isinstance(user.terminal, (str, type(None)))
|
257
253
|
if user.host is not None:
|
258
254
|
assert isinstance(user.host, (str, type(None)))
|
259
|
-
user.terminal # noqa
|
260
|
-
user.host # noqa
|
255
|
+
user.terminal # noqa: B018
|
256
|
+
user.host # noqa: B018
|
261
257
|
assert user.started > 0.0
|
262
258
|
datetime.datetime.fromtimestamp(user.started)
|
263
259
|
if WINDOWS or OPENBSD:
|
@@ -265,15 +261,6 @@ class TestMiscAPIs(PsutilTestCase):
|
|
265
261
|
else:
|
266
262
|
psutil.Process(user.pid)
|
267
263
|
|
268
|
-
def test_test(self):
|
269
|
-
# test for psutil.test() function
|
270
|
-
stdout = sys.stdout
|
271
|
-
sys.stdout = DEVNULL
|
272
|
-
try:
|
273
|
-
psutil.test()
|
274
|
-
finally:
|
275
|
-
sys.stdout = stdout
|
276
|
-
|
277
264
|
def test_os_constants(self):
|
278
265
|
names = [
|
279
266
|
"POSIX",
|
@@ -335,14 +322,13 @@ class TestMemoryAPIs(PsutilTestCase):
|
|
335
322
|
for name in mem._fields:
|
336
323
|
value = getattr(mem, name)
|
337
324
|
if name != 'percent':
|
338
|
-
assert isinstance(value,
|
325
|
+
assert isinstance(value, int)
|
339
326
|
if name != 'total':
|
340
327
|
if not value >= 0:
|
341
|
-
raise self.fail("
|
328
|
+
raise self.fail(f"{name!r} < 0 ({value})")
|
342
329
|
if value > mem.total:
|
343
330
|
raise self.fail(
|
344
|
-
"
|
345
|
-
% (name, mem.total, name, value)
|
331
|
+
f"{name!r} > total (total={mem.total}, {name}={value})"
|
346
332
|
)
|
347
333
|
|
348
334
|
def test_swap_memory(self):
|
@@ -431,8 +417,9 @@ class TestCpuAPIs(PsutilTestCase):
|
|
431
417
|
# for field in new._fields:
|
432
418
|
# new_t = getattr(new, field)
|
433
419
|
# last_t = getattr(last, field)
|
434
|
-
# self.assertGreaterEqual(
|
435
|
-
#
|
420
|
+
# self.assertGreaterEqual(
|
421
|
+
# new_t, last_t,
|
422
|
+
# msg="{} {}".format(new_t, last_t))
|
436
423
|
# last = new
|
437
424
|
|
438
425
|
def test_cpu_times_time_increases(self):
|
@@ -476,7 +463,7 @@ class TestCpuAPIs(PsutilTestCase):
|
|
476
463
|
# new_t = getattr(newcpu, field)
|
477
464
|
# last_t = getattr(lastcpu, field)
|
478
465
|
# self.assertGreaterEqual(
|
479
|
-
# new_t, last_t, msg="
|
466
|
+
# new_t, last_t, msg="{} {}".format(lastcpu, newcpu))
|
480
467
|
# last = new
|
481
468
|
|
482
469
|
def test_per_cpu_times_2(self):
|
@@ -492,11 +479,12 @@ class TestCpuAPIs(PsutilTestCase):
|
|
492
479
|
t1, t2 = psutil._cpu_busy_time(t1), psutil._cpu_busy_time(t2)
|
493
480
|
difference = t2 - t1
|
494
481
|
if difference >= 0.05:
|
495
|
-
return
|
482
|
+
return None
|
496
483
|
|
497
484
|
@pytest.mark.skipif(
|
498
485
|
CI_TESTING and OPENBSD, reason="unreliable on OPENBSD + CI"
|
499
486
|
)
|
487
|
+
@retry_on_failure(30)
|
500
488
|
def test_cpu_times_comparison(self):
|
501
489
|
# Make sure the sum of all per cpu times is almost equal to
|
502
490
|
# base "one cpu" times. On OpenBSD the sum of per-CPUs is
|
@@ -508,7 +496,7 @@ class TestCpuAPIs(PsutilTestCase):
|
|
508
496
|
with self.subTest(field=field, base=base, per_cpu=per_cpu):
|
509
497
|
assert (
|
510
498
|
abs(getattr(base, field) - getattr(summed_values, field))
|
511
|
-
<
|
499
|
+
< 2
|
512
500
|
)
|
513
501
|
|
514
502
|
def _test_cpu_percent(self, percent, last_ret, new_ret):
|
@@ -518,8 +506,9 @@ class TestCpuAPIs(PsutilTestCase):
|
|
518
506
|
assert percent <= 100.0 * psutil.cpu_count()
|
519
507
|
except AssertionError as err:
|
520
508
|
raise AssertionError(
|
521
|
-
"\n
|
522
|
-
|
509
|
+
"\n{}\nlast={}\nnew={}".format(
|
510
|
+
err, pprint.pformat(last_ret), pprint.pformat(new_ret)
|
511
|
+
)
|
523
512
|
)
|
524
513
|
|
525
514
|
def test_cpu_percent(self):
|
@@ -605,12 +594,14 @@ class TestCpuAPIs(PsutilTestCase):
|
|
605
594
|
assert nt.current <= nt.max
|
606
595
|
for name in nt._fields:
|
607
596
|
value = getattr(nt, name)
|
608
|
-
assert isinstance(value, (int,
|
597
|
+
assert isinstance(value, (int, float))
|
609
598
|
assert value >= 0
|
610
599
|
|
611
600
|
ls = psutil.cpu_freq(percpu=True)
|
612
|
-
if FREEBSD and not ls:
|
613
|
-
raise pytest.skip(
|
601
|
+
if (FREEBSD or AARCH64) and not ls:
|
602
|
+
raise pytest.skip(
|
603
|
+
"returns empty list on FreeBSD and Linux aarch64"
|
604
|
+
)
|
614
605
|
|
615
606
|
assert ls, ls
|
616
607
|
check_ls([psutil.cpu_freq(percpu=False)])
|
@@ -685,7 +676,7 @@ class TestDiskAPIs(PsutilTestCase):
|
|
685
676
|
else:
|
686
677
|
# we cannot make any assumption about this, see:
|
687
678
|
# http://goo.gl/p9c43
|
688
|
-
disk.device # noqa
|
679
|
+
disk.device # noqa: B018
|
689
680
|
# on modern systems mount points can also be files
|
690
681
|
assert os.path.exists(disk.mountpoint), disk
|
691
682
|
assert disk.fstype, disk
|
@@ -811,7 +802,6 @@ class TestNetAPIs(PsutilTestCase):
|
|
811
802
|
assert psutil.net_io_counters(pernic=True) == {}
|
812
803
|
assert m.called
|
813
804
|
|
814
|
-
@pytest.mark.skipif(QEMU_USER, reason="QEMU user not supported")
|
815
805
|
def test_net_if_addrs(self):
|
816
806
|
nics = psutil.net_if_addrs()
|
817
807
|
assert nics, nics
|
@@ -823,7 +813,7 @@ class TestNetAPIs(PsutilTestCase):
|
|
823
813
|
# self.assertEqual(sorted(nics.keys()),
|
824
814
|
# sorted(psutil.net_io_counters(pernic=True).keys()))
|
825
815
|
|
826
|
-
families =
|
816
|
+
families = {socket.AF_INET, socket.AF_INET6, psutil.AF_LINK}
|
827
817
|
for nic, addrs in nics.items():
|
828
818
|
assert isinstance(nic, str)
|
829
819
|
assert len(set(addrs)) == len(addrs)
|
@@ -833,14 +823,12 @@ class TestNetAPIs(PsutilTestCase):
|
|
833
823
|
assert isinstance(addr.netmask, (str, type(None)))
|
834
824
|
assert isinstance(addr.broadcast, (str, type(None)))
|
835
825
|
assert addr.family in families
|
836
|
-
|
837
|
-
assert isinstance(addr.family, enum.IntEnum)
|
826
|
+
assert isinstance(addr.family, enum.IntEnum)
|
838
827
|
if nic_stats[nic].isup:
|
839
828
|
# Do not test binding to addresses of interfaces
|
840
829
|
# that are down
|
841
830
|
if addr.family == socket.AF_INET:
|
842
|
-
|
843
|
-
with contextlib.closing(s):
|
831
|
+
with socket.socket(addr.family) as s:
|
844
832
|
s.bind((addr.address, 0))
|
845
833
|
elif addr.family == socket.AF_INET6:
|
846
834
|
info = socket.getaddrinfo(
|
@@ -852,8 +840,7 @@ class TestNetAPIs(PsutilTestCase):
|
|
852
840
|
socket.AI_PASSIVE,
|
853
841
|
)[0]
|
854
842
|
af, socktype, proto, _canonname, sa = info
|
855
|
-
|
856
|
-
with contextlib.closing(s):
|
843
|
+
with socket.socket(af, socktype, proto) as s:
|
857
844
|
s.bind(sa)
|
858
845
|
for ip in (
|
859
846
|
addr.address,
|
@@ -873,6 +860,14 @@ class TestNetAPIs(PsutilTestCase):
|
|
873
860
|
elif addr.ptp:
|
874
861
|
assert addr.broadcast is None
|
875
862
|
|
863
|
+
# check broadcast address
|
864
|
+
if (
|
865
|
+
addr.broadcast
|
866
|
+
and addr.netmask
|
867
|
+
and addr.family in {socket.AF_INET, socket.AF_INET6}
|
868
|
+
):
|
869
|
+
assert addr.broadcast == broadcast_addr(addr)
|
870
|
+
|
876
871
|
if BSD or MACOS or SUNOS:
|
877
872
|
if hasattr(socket, "AF_LINK"):
|
878
873
|
assert psutil.AF_LINK == socket.AF_LINK
|
@@ -899,7 +894,6 @@ class TestNetAPIs(PsutilTestCase):
|
|
899
894
|
else:
|
900
895
|
assert addr.address == '06-3d-29-00-00-00'
|
901
896
|
|
902
|
-
@pytest.mark.skipif(QEMU_USER, reason="QEMU user not supported")
|
903
897
|
def test_net_if_stats(self):
|
904
898
|
nics = psutil.net_if_stats()
|
905
899
|
assert nics, nics
|
@@ -981,5 +975,5 @@ class TestSensorsAPIs(PsutilTestCase):
|
|
981
975
|
assert isinstance(name, str)
|
982
976
|
for entry in entries:
|
983
977
|
assert isinstance(entry.label, str)
|
984
|
-
assert isinstance(entry.current,
|
978
|
+
assert isinstance(entry.current, int)
|
985
979
|
assert entry.current >= 0
|
@@ -1,5 +1,4 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
|
-
# -*- coding: utf-8 -*-
|
3
2
|
|
4
3
|
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
|
5
4
|
# Use of this source code is governed by a BSD-style license that can be
|
@@ -8,7 +7,6 @@
|
|
8
7
|
"""Tests for testing utils (psutil.tests namespace)."""
|
9
8
|
|
10
9
|
import collections
|
11
|
-
import contextlib
|
12
10
|
import errno
|
13
11
|
import os
|
14
12
|
import socket
|
@@ -17,6 +15,7 @@ import subprocess
|
|
17
15
|
import textwrap
|
18
16
|
import unittest
|
19
17
|
import warnings
|
18
|
+
from unittest import mock
|
20
19
|
|
21
20
|
import psutil
|
22
21
|
import psutil.tests
|
@@ -26,7 +25,6 @@ from psutil import POSIX
|
|
26
25
|
from psutil._common import open_binary
|
27
26
|
from psutil._common import open_text
|
28
27
|
from psutil._common import supports_ipv6
|
29
|
-
from psutil._compat import PY3
|
30
28
|
from psutil.tests import CI_TESTING
|
31
29
|
from psutil.tests import COVERAGE
|
32
30
|
from psutil.tests import HAS_NET_CONNECTIONS_UNIX
|
@@ -44,7 +42,6 @@ from psutil.tests import fake_pytest
|
|
44
42
|
from psutil.tests import filter_proc_net_connections
|
45
43
|
from psutil.tests import get_free_port
|
46
44
|
from psutil.tests import is_namedtuple
|
47
|
-
from psutil.tests import mock
|
48
45
|
from psutil.tests import process_namespace
|
49
46
|
from psutil.tests import pytest
|
50
47
|
from psutil.tests import reap_children
|
@@ -74,7 +71,7 @@ class TestRetryDecorator(PsutilTestCase):
|
|
74
71
|
def foo():
|
75
72
|
while queue:
|
76
73
|
queue.pop()
|
77
|
-
1 / 0 # noqa
|
74
|
+
1 / 0 # noqa: B018
|
78
75
|
return 1
|
79
76
|
|
80
77
|
queue = list(range(3))
|
@@ -88,7 +85,7 @@ class TestRetryDecorator(PsutilTestCase):
|
|
88
85
|
def foo():
|
89
86
|
while queue:
|
90
87
|
queue.pop()
|
91
|
-
1 / 0 # noqa
|
88
|
+
1 / 0 # noqa: B018
|
92
89
|
return 1
|
93
90
|
|
94
91
|
queue = list(range(6))
|
@@ -112,7 +109,7 @@ class TestRetryDecorator(PsutilTestCase):
|
|
112
109
|
|
113
110
|
@retry(retries=5, interval=None, logfun=None)
|
114
111
|
def foo():
|
115
|
-
1 / 0 # noqa
|
112
|
+
1 / 0 # noqa: B018
|
116
113
|
|
117
114
|
with pytest.raises(ZeroDivisionError):
|
118
115
|
foo()
|
@@ -122,7 +119,7 @@ class TestRetryDecorator(PsutilTestCase):
|
|
122
119
|
def test_retries_arg(self, sleep):
|
123
120
|
@retry(retries=5, interval=1, logfun=None)
|
124
121
|
def foo():
|
125
|
-
1 / 0 # noqa
|
122
|
+
1 / 0 # noqa: B018
|
126
123
|
|
127
124
|
with pytest.raises(ZeroDivisionError):
|
128
125
|
foo()
|
@@ -159,7 +156,7 @@ class TestSyncTestUtils(PsutilTestCase):
|
|
159
156
|
def test_wait_for_file_no_file(self):
|
160
157
|
testfn = self.get_testfn()
|
161
158
|
with mock.patch('psutil.tests.retry.__iter__', return_value=iter([0])):
|
162
|
-
with pytest.raises(
|
159
|
+
with pytest.raises(OSError):
|
163
160
|
wait_for_file(testfn)
|
164
161
|
|
165
162
|
def test_wait_for_file_no_delete(self):
|
@@ -298,14 +295,13 @@ class TestProcessUtils(PsutilTestCase):
|
|
298
295
|
class TestNetUtils(PsutilTestCase):
|
299
296
|
def bind_socket(self):
|
300
297
|
port = get_free_port()
|
301
|
-
with
|
298
|
+
with bind_socket(addr=('', port)) as s:
|
302
299
|
assert s.getsockname()[1] == port
|
303
300
|
|
304
301
|
@pytest.mark.skipif(not POSIX, reason="POSIX only")
|
305
302
|
def test_bind_unix_socket(self):
|
306
303
|
name = self.get_testfn()
|
307
|
-
|
308
|
-
with contextlib.closing(sock):
|
304
|
+
with bind_unix_socket(name) as sock:
|
309
305
|
assert sock.family == socket.AF_UNIX
|
310
306
|
assert sock.type == socket.SOCK_STREAM
|
311
307
|
assert sock.getsockname() == name
|
@@ -313,20 +309,17 @@ class TestNetUtils(PsutilTestCase):
|
|
313
309
|
assert stat.S_ISSOCK(os.stat(name).st_mode)
|
314
310
|
# UDP
|
315
311
|
name = self.get_testfn()
|
316
|
-
|
317
|
-
with contextlib.closing(sock):
|
312
|
+
with bind_unix_socket(name, type=socket.SOCK_DGRAM) as sock:
|
318
313
|
assert sock.type == socket.SOCK_DGRAM
|
319
314
|
|
320
315
|
def test_tcp_socketpair(self):
|
321
316
|
addr = ("127.0.0.1", get_free_port())
|
322
317
|
server, client = tcp_socketpair(socket.AF_INET, addr=addr)
|
323
|
-
with
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
assert client.getpeername() == addr
|
329
|
-
assert client.getsockname() != addr
|
318
|
+
with server, client:
|
319
|
+
# Ensure they are connected and the positions are correct.
|
320
|
+
assert server.getsockname() == addr
|
321
|
+
assert client.getpeername() == addr
|
322
|
+
assert client.getsockname() != addr
|
330
323
|
|
331
324
|
@pytest.mark.skipif(not POSIX, reason="POSIX only")
|
332
325
|
@pytest.mark.skipif(
|
@@ -335,9 +328,7 @@ class TestNetUtils(PsutilTestCase):
|
|
335
328
|
def test_unix_socketpair(self):
|
336
329
|
p = psutil.Process()
|
337
330
|
num_fds = p.num_fds()
|
338
|
-
assert (
|
339
|
-
filter_proc_net_connections(p.net_connections(kind='unix')) == []
|
340
|
-
)
|
331
|
+
assert not filter_proc_net_connections(p.net_connections(kind='unix'))
|
341
332
|
name = self.get_testfn()
|
342
333
|
server, client = unix_socketpair(name)
|
343
334
|
try:
|
@@ -414,7 +405,7 @@ class TestMemLeakClass(TestMemoryLeak):
|
|
414
405
|
|
415
406
|
def test_unclosed_files(self):
|
416
407
|
def fun():
|
417
|
-
f = open(__file__)
|
408
|
+
f = open(__file__) # noqa: SIM115
|
418
409
|
self.addCleanup(f.close)
|
419
410
|
box.append(f)
|
420
411
|
|
@@ -436,7 +427,7 @@ class TestMemLeakClass(TestMemoryLeak):
|
|
436
427
|
|
437
428
|
def test_execute_w_exc(self):
|
438
429
|
def fun_1():
|
439
|
-
1 / 0 # noqa
|
430
|
+
1 / 0 # noqa: B018
|
440
431
|
|
441
432
|
self.execute_w_exc(ZeroDivisionError, fun_1)
|
442
433
|
with pytest.raises(ZeroDivisionError):
|
@@ -459,7 +450,7 @@ class TestFakePytest(PsutilTestCase):
|
|
459
450
|
|
460
451
|
def test_raises(self):
|
461
452
|
with fake_pytest.raises(ZeroDivisionError) as cm:
|
462
|
-
1 / 0 # noqa
|
453
|
+
1 / 0 # noqa: B018
|
463
454
|
assert isinstance(cm.value, ZeroDivisionError)
|
464
455
|
|
465
456
|
with fake_pytest.raises(ValueError, match="foo") as cm:
|
@@ -491,7 +482,7 @@ class TestFakePytest(PsutilTestCase):
|
|
491
482
|
class TestCase(unittest.TestCase):
|
492
483
|
@fake_pytest.mark.skipif(True, reason="reason")
|
493
484
|
def foo(self):
|
494
|
-
assert 1 == 1 # noqa
|
485
|
+
assert 1 == 1 # noqa: PLR0133
|
495
486
|
|
496
487
|
result = self.run_test_class(TestCase("foo"))
|
497
488
|
assert result.wasSuccessful()
|
@@ -501,18 +492,17 @@ class TestFakePytest(PsutilTestCase):
|
|
501
492
|
class TestCase(unittest.TestCase):
|
502
493
|
@fake_pytest.mark.skipif(False, reason="reason")
|
503
494
|
def foo(self):
|
504
|
-
assert 1 == 1 # noqa
|
495
|
+
assert 1 == 1 # noqa: PLR0133
|
505
496
|
|
506
497
|
result = self.run_test_class(TestCase("foo"))
|
507
498
|
assert result.wasSuccessful()
|
508
499
|
assert len(result.skipped) == 0
|
509
500
|
|
510
|
-
@pytest.mark.skipif(not PY3, reason="not PY3")
|
511
501
|
def test_skip(self):
|
512
502
|
class TestCase(unittest.TestCase):
|
513
503
|
def foo(self):
|
514
504
|
fake_pytest.skip("reason")
|
515
|
-
assert 1 == 0 # noqa
|
505
|
+
assert 1 == 0 # noqa: PLR0133
|
516
506
|
|
517
507
|
result = self.run_test_class(TestCase("foo"))
|
518
508
|
assert result.wasSuccessful()
|
@@ -572,12 +562,12 @@ class TestTestingUtils(PsutilTestCase):
|
|
572
562
|
p = psutil.Process()
|
573
563
|
ns = process_namespace(p)
|
574
564
|
ns.test()
|
575
|
-
fun =
|
565
|
+
fun = next(x for x in ns.iter(ns.getters) if x[1] == 'ppid')[0]
|
576
566
|
assert fun() == p.ppid()
|
577
567
|
|
578
568
|
def test_system_namespace(self):
|
579
569
|
ns = system_namespace()
|
580
|
-
fun =
|
570
|
+
fun = next(x for x in ns.iter(ns.getters) if x[1] == 'net_if_addrs')[0]
|
581
571
|
assert fun() == psutil.net_if_addrs()
|
582
572
|
|
583
573
|
|
@@ -1,5 +1,4 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
|
-
# -*- coding: utf-8 -*-
|
3
2
|
|
4
3
|
# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
|
5
4
|
# Use of this source code is governed by a BSD-style license that can be
|
@@ -20,13 +19,8 @@ process exe(), cwd() or username():
|
|
20
19
|
* instead, in case of badly encoded data returned by the OS, the
|
21
20
|
following error handlers are used to replace the corrupted characters in
|
22
21
|
the string:
|
23
|
-
*
|
24
|
-
"
|
25
|
-
* Python 2: "replace"
|
26
|
-
* on Python 2 all APIs return bytes (str type), never unicode
|
27
|
-
* on Python 2, you can go back to unicode by doing:
|
28
|
-
|
29
|
-
>>> unicode(p.exe(), sys.getdefaultencoding(), errors="replace")
|
22
|
+
* sys.getfilesystemencodeerrors() or "surrogatescape" on POSIX and
|
23
|
+
"replace" on Windows.
|
30
24
|
|
31
25
|
For a detailed explanation of how psutil handles unicode see #1040.
|
32
26
|
|
@@ -74,18 +68,13 @@ etc.) and make sure that:
|
|
74
68
|
|
75
69
|
import os
|
76
70
|
import shutil
|
77
|
-
import traceback
|
78
71
|
import warnings
|
79
72
|
from contextlib import closing
|
80
73
|
|
81
74
|
import psutil
|
82
75
|
from psutil import BSD
|
83
|
-
from psutil import MACOS
|
84
76
|
from psutil import POSIX
|
85
77
|
from psutil import WINDOWS
|
86
|
-
from psutil._compat import PY3
|
87
|
-
from psutil._compat import super
|
88
|
-
from psutil.tests import APPVEYOR
|
89
78
|
from psutil.tests import ASCII_FS
|
90
79
|
from psutil.tests import CI_TESTING
|
91
80
|
from psutil.tests import HAS_ENVIRON
|
@@ -109,27 +98,6 @@ from psutil.tests import spawn_testproc
|
|
109
98
|
from psutil.tests import terminate
|
110
99
|
|
111
100
|
|
112
|
-
if APPVEYOR:
|
113
|
-
|
114
|
-
def safe_rmpath(path): # NOQA
|
115
|
-
# TODO - this is quite random and I'm not sure why it happens,
|
116
|
-
# nor I can reproduce it locally:
|
117
|
-
# https://ci.appveyor.com/project/giampaolo/psutil/build/job/
|
118
|
-
# jiq2cgd6stsbtn60
|
119
|
-
# safe_rmpath() happens after reap_children() so this is weird
|
120
|
-
# Perhaps wait_procs() on Windows is broken? Maybe because
|
121
|
-
# of STILL_ACTIVE?
|
122
|
-
# https://github.com/giampaolo/psutil/blob/
|
123
|
-
# 68c7a70728a31d8b8b58f4be6c4c0baa2f449eda/psutil/arch/
|
124
|
-
# windows/process_info.c#L146
|
125
|
-
from psutil.tests import safe_rmpath as rm
|
126
|
-
|
127
|
-
try:
|
128
|
-
return rm(path)
|
129
|
-
except WindowsError:
|
130
|
-
traceback.print_exc()
|
131
|
-
|
132
|
-
|
133
101
|
def try_unicode(suffix):
|
134
102
|
"""Return True if both the fs and the subprocess module can
|
135
103
|
deal with a unicode file name.
|
@@ -142,7 +110,7 @@ def try_unicode(suffix):
|
|
142
110
|
sproc = spawn_testproc(cmd=[testfn])
|
143
111
|
shutil.copyfile(testfn, testfn + '-2')
|
144
112
|
safe_rmpath(testfn + '-2')
|
145
|
-
except (UnicodeEncodeError,
|
113
|
+
except (UnicodeEncodeError, OSError):
|
146
114
|
return False
|
147
115
|
else:
|
148
116
|
return True
|
@@ -180,23 +148,18 @@ class BaseUnicodeTest(PsutilTestCase):
|
|
180
148
|
|
181
149
|
@pytest.mark.xdist_group(name="serial")
|
182
150
|
@pytest.mark.skipif(ASCII_FS, reason="ASCII fs")
|
183
|
-
@pytest.mark.skipif(PYPY and not PY3, reason="too much trouble on PYPY2")
|
184
151
|
class TestFSAPIs(BaseUnicodeTest):
|
185
152
|
"""Test FS APIs with a funky, valid, UTF8 path name."""
|
186
153
|
|
187
154
|
funky_suffix = UNICODE_SUFFIX
|
188
155
|
|
189
156
|
def expect_exact_path_match(self):
|
190
|
-
# Do not expect psutil to correctly handle unicode paths on
|
191
|
-
# Python 2 if os.listdir() is not able either.
|
192
|
-
here = '.' if isinstance(self.funky_name, str) else u'.'
|
193
157
|
with warnings.catch_warnings():
|
194
158
|
warnings.simplefilter("ignore")
|
195
|
-
return self.funky_name in os.listdir(
|
159
|
+
return self.funky_name in os.listdir(".")
|
196
160
|
|
197
161
|
# ---
|
198
162
|
|
199
|
-
@pytest.mark.skipif(MACOS and not PY3, reason="broken MACOS + PY2")
|
200
163
|
def test_proc_exe(self):
|
201
164
|
cmd = [
|
202
165
|
self.funky_name,
|
@@ -222,7 +185,6 @@ class TestFSAPIs(BaseUnicodeTest):
|
|
222
185
|
if self.expect_exact_path_match():
|
223
186
|
assert name == os.path.basename(self.funky_name)
|
224
187
|
|
225
|
-
@pytest.mark.skipif(MACOS and not PY3, reason="broken MACOS + PY2")
|
226
188
|
def test_proc_cmdline(self):
|
227
189
|
cmd = [
|
228
190
|
self.funky_name,
|
@@ -265,13 +227,7 @@ class TestFSAPIs(BaseUnicodeTest):
|
|
265
227
|
@pytest.mark.skipif(not POSIX, reason="POSIX only")
|
266
228
|
def test_proc_net_connections(self):
|
267
229
|
name = self.get_testfn(suffix=self.funky_suffix)
|
268
|
-
|
269
|
-
sock = bind_unix_socket(name)
|
270
|
-
except UnicodeEncodeError:
|
271
|
-
if PY3:
|
272
|
-
raise
|
273
|
-
else:
|
274
|
-
raise pytest.skip("not supported")
|
230
|
+
sock = bind_unix_socket(name)
|
275
231
|
with closing(sock):
|
276
232
|
conn = psutil.Process().net_connections('unix')[0]
|
277
233
|
assert isinstance(conn.laddr, str)
|
@@ -290,13 +246,7 @@ class TestFSAPIs(BaseUnicodeTest):
|
|
290
246
|
raise ValueError("connection not found")
|
291
247
|
|
292
248
|
name = self.get_testfn(suffix=self.funky_suffix)
|
293
|
-
|
294
|
-
sock = bind_unix_socket(name)
|
295
|
-
except UnicodeEncodeError:
|
296
|
-
if PY3:
|
297
|
-
raise
|
298
|
-
else:
|
299
|
-
raise pytest.skip("not supported")
|
249
|
+
sock = bind_unix_socket(name)
|
300
250
|
with closing(sock):
|
301
251
|
cons = psutil.net_connections(kind='unix')
|
302
252
|
conn = find_sock(cons)
|
@@ -310,13 +260,8 @@ class TestFSAPIs(BaseUnicodeTest):
|
|
310
260
|
psutil.disk_usage(dname)
|
311
261
|
|
312
262
|
@pytest.mark.skipif(not HAS_MEMORY_MAPS, reason="not supported")
|
313
|
-
@pytest.mark.skipif(
|
314
|
-
not PY3, reason="ctypes does not support unicode on PY2"
|
315
|
-
)
|
316
263
|
@pytest.mark.skipif(PYPY, reason="unstable on PYPY")
|
317
264
|
def test_memory_maps(self):
|
318
|
-
# XXX: on Python 2, using ctypes.CDLL with a unicode path
|
319
|
-
# opens a message box which blocks the test run.
|
320
265
|
with copyload_shared_lib(suffix=self.funky_suffix) as funky_path:
|
321
266
|
|
322
267
|
def normpath(p):
|
@@ -339,7 +284,6 @@ class TestFSAPIsWithInvalidPath(TestFSAPIs):
|
|
339
284
|
funky_suffix = INVALID_UNICODE_SUFFIX
|
340
285
|
|
341
286
|
def expect_exact_path_match(self):
|
342
|
-
# Invalid unicode names are supposed to work on Python 2.
|
343
287
|
return True
|
344
288
|
|
345
289
|
|
@@ -351,16 +295,13 @@ class TestFSAPIsWithInvalidPath(TestFSAPIs):
|
|
351
295
|
class TestNonFSAPIS(BaseUnicodeTest):
|
352
296
|
"""Unicode tests for non fs-related APIs."""
|
353
297
|
|
354
|
-
funky_suffix = UNICODE_SUFFIX
|
298
|
+
funky_suffix = UNICODE_SUFFIX
|
355
299
|
|
356
300
|
@pytest.mark.skipif(not HAS_ENVIRON, reason="not supported")
|
357
301
|
@pytest.mark.skipif(PYPY and WINDOWS, reason="segfaults on PYPY + WINDOWS")
|
358
302
|
def test_proc_environ(self):
|
359
303
|
# Note: differently from others, this test does not deal
|
360
|
-
# with fs paths.
|
361
|
-
# it's not able to handle with non-ASCII env vars, so
|
362
|
-
# we use "è", which is part of the extended ASCII table
|
363
|
-
# (unicode point <= 255).
|
304
|
+
# with fs paths.
|
364
305
|
env = os.environ.copy()
|
365
306
|
env['FUNNY_ARG'] = self.funky_suffix
|
366
307
|
sproc = self.spawn_testproc(env=env)
|