mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-08-20 13:23:24 -07:00
Bump cherrypy from 18.8.0 to 18.9.0 (#2266)
* Bump cherrypy from 18.8.0 to 18.9.0 Bumps [cherrypy](https://github.com/cherrypy/cherrypy) from 18.8.0 to 18.9.0. - [Changelog](https://github.com/cherrypy/cherrypy/blob/main/CHANGES.rst) - [Commits](https://github.com/cherrypy/cherrypy/compare/v18.8.0...v18.9.0) --- updated-dependencies: - dependency-name: cherrypy dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Update cherrypy==18.9.0 --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: JonnyWong16 <9099342+JonnyWong16@users.noreply.github.com> [skip ci]
This commit is contained in:
parent
cfefa928be
commit
faef9a94c4
673 changed files with 159850 additions and 11583 deletions
171
lib/win32/test/handles.py
Normal file
171
lib/win32/test/handles.py
Normal file
|
@ -0,0 +1,171 @@
|
|||
import sys
|
||||
import unittest
|
||||
|
||||
import pywintypes
|
||||
import win32api
|
||||
|
||||
|
||||
# A class that will never die vie refcounting, but will die via GC.
|
||||
class Cycle:
|
||||
def __init__(self, handle):
|
||||
self.cycle = self
|
||||
self.handle = handle
|
||||
|
||||
|
||||
class PyHandleTestCase(unittest.TestCase):
|
||||
def testCleanup1(self):
|
||||
# We used to clobber all outstanding exceptions.
|
||||
def f1(invalidate):
|
||||
import win32event
|
||||
|
||||
h = win32event.CreateEvent(None, 0, 0, None)
|
||||
if invalidate:
|
||||
win32api.CloseHandle(int(h))
|
||||
1 / 0
|
||||
# If we invalidated, then the object destruction code will attempt
|
||||
# to close an invalid handle. We don't wan't an exception in
|
||||
# this case
|
||||
|
||||
def f2(invalidate):
|
||||
"""This function should throw an IOError."""
|
||||
try:
|
||||
f1(invalidate)
|
||||
except ZeroDivisionError as exc:
|
||||
raise IOError("raise 2")
|
||||
|
||||
self.assertRaises(IOError, f2, False)
|
||||
# Now do it again, but so the auto object destruction
|
||||
# actually fails.
|
||||
self.assertRaises(IOError, f2, True)
|
||||
|
||||
def testCleanup2(self):
|
||||
# Cause an exception during object destruction.
|
||||
# The worst this does is cause an ".XXX undetected error (why=3)"
|
||||
# So avoiding that is the goal
|
||||
import win32event
|
||||
|
||||
h = win32event.CreateEvent(None, 0, 0, None)
|
||||
# Close the handle underneath the object.
|
||||
win32api.CloseHandle(int(h))
|
||||
# Object destructor runs with the implicit close failing
|
||||
h = None
|
||||
|
||||
def testCleanup3(self):
|
||||
# And again with a class - no __del__
|
||||
import win32event
|
||||
|
||||
class Test:
|
||||
def __init__(self):
|
||||
self.h = win32event.CreateEvent(None, 0, 0, None)
|
||||
win32api.CloseHandle(int(self.h))
|
||||
|
||||
t = Test()
|
||||
t = None
|
||||
|
||||
def testCleanupGood(self):
|
||||
# And check that normal error semantics *do* work.
|
||||
import win32event
|
||||
|
||||
h = win32event.CreateEvent(None, 0, 0, None)
|
||||
win32api.CloseHandle(int(h))
|
||||
self.assertRaises(win32api.error, h.Close)
|
||||
# A following Close is documented as working
|
||||
h.Close()
|
||||
|
||||
def testInvalid(self):
|
||||
h = pywintypes.HANDLE(-2)
|
||||
try:
|
||||
h.Close()
|
||||
# Ideally, we'd:
|
||||
# self.assertRaises(win32api.error, h.Close)
|
||||
# and everywhere markh has tried, that would pass - but not on
|
||||
# github automation, where the .Close apparently works fine.
|
||||
# (same for -1. Using 0 appears to work fine everywhere)
|
||||
# There still seems value in testing it though, so we just accept
|
||||
# either working or failing.
|
||||
except win32api.error:
|
||||
pass
|
||||
|
||||
def testOtherHandle(self):
|
||||
h = pywintypes.HANDLE(1)
|
||||
h2 = pywintypes.HANDLE(h)
|
||||
self.assertEqual(h, h2)
|
||||
# but the above doesn't really test everything - we want a way to
|
||||
# pass the handle directly into PyWinLong_AsVoidPtr. One way to
|
||||
# to that is to abuse win32api.GetProcAddress() - the 2nd param
|
||||
# is passed to PyWinLong_AsVoidPtr() if its not a string.
|
||||
# passing a handle value of '1' should work - there is something
|
||||
# at that ordinal
|
||||
win32api.GetProcAddress(sys.dllhandle, h)
|
||||
|
||||
def testHandleInDict(self):
|
||||
h = pywintypes.HANDLE(1)
|
||||
d = dict(foo=h)
|
||||
self.assertEqual(d["foo"], h)
|
||||
|
||||
def testHandleInDictThenInt(self):
|
||||
h = pywintypes.HANDLE(1)
|
||||
d = dict(foo=h)
|
||||
self.assertEqual(d["foo"], 1)
|
||||
|
||||
def testHandleCompareNone(self):
|
||||
h = pywintypes.HANDLE(1)
|
||||
self.assertNotEqual(h, None)
|
||||
self.assertNotEqual(None, h)
|
||||
# ensure we use both __eq__ and __ne__ ops
|
||||
self.assertFalse(h == None)
|
||||
self.assertTrue(h != None)
|
||||
|
||||
def testHandleCompareInt(self):
|
||||
h = pywintypes.HANDLE(1)
|
||||
self.assertNotEqual(h, 0)
|
||||
self.assertEqual(h, 1)
|
||||
# ensure we use both __eq__ and __ne__ ops
|
||||
self.assertTrue(h == 1)
|
||||
self.assertTrue(1 == h)
|
||||
self.assertFalse(h != 1)
|
||||
self.assertFalse(1 != h)
|
||||
self.assertFalse(h == 0)
|
||||
self.assertFalse(0 == h)
|
||||
self.assertTrue(h != 0)
|
||||
self.assertTrue(0 != h)
|
||||
|
||||
def testHandleNonZero(self):
|
||||
h = pywintypes.HANDLE(0)
|
||||
self.assertFalse(h)
|
||||
|
||||
h = pywintypes.HANDLE(1)
|
||||
self.assertTrue(h)
|
||||
|
||||
def testLong(self):
|
||||
# sys.maxint+1 should always be a 'valid' handle, treated as an
|
||||
# unsigned int, even though it is a long. Although pywin32 should not
|
||||
# directly create such longs, using struct.unpack() with a P format
|
||||
# may well return them. eg:
|
||||
# >>> struct.unpack("P", struct.pack("P", -1))
|
||||
# (4294967295L,)
|
||||
try:
|
||||
big = sys.maxsize
|
||||
except AttributeError:
|
||||
big = sys.maxint
|
||||
pywintypes.HANDLE(big + 1)
|
||||
|
||||
def testGC(self):
|
||||
# This used to provoke:
|
||||
# Fatal Python error: unexpected exception during garbage collection
|
||||
def make():
|
||||
h = pywintypes.HANDLE(-2)
|
||||
c = Cycle(h)
|
||||
|
||||
import gc
|
||||
|
||||
make()
|
||||
gc.collect()
|
||||
|
||||
def testTypes(self):
|
||||
self.assertRaises(TypeError, pywintypes.HANDLE, "foo")
|
||||
self.assertRaises(TypeError, pywintypes.HANDLE, ())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
127
lib/win32/test/test_clipboard.py
Normal file
127
lib/win32/test/test_clipboard.py
Normal file
|
@ -0,0 +1,127 @@
|
|||
# General test module for win32api - please add some :)
|
||||
import array
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import pywintypes
|
||||
import win32con
|
||||
import win32gui
|
||||
from pywin32_testutil import str2bytes
|
||||
from win32clipboard import *
|
||||
|
||||
custom_format_name = "PythonClipboardTestFormat"
|
||||
|
||||
|
||||
class CrashingTestCase(unittest.TestCase):
|
||||
def test_722082(self):
|
||||
class crasher(object):
|
||||
pass
|
||||
|
||||
obj = crasher()
|
||||
OpenClipboard()
|
||||
try:
|
||||
EmptyClipboard()
|
||||
# This used to crash - now correctly raises type error.
|
||||
self.assertRaises(TypeError, SetClipboardData, 0, obj)
|
||||
finally:
|
||||
CloseClipboard()
|
||||
|
||||
|
||||
class TestBitmap(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.bmp_handle = None
|
||||
try:
|
||||
this_file = __file__
|
||||
except NameError:
|
||||
this_file = sys.argv[0]
|
||||
this_dir = os.path.dirname(this_file)
|
||||
self.bmp_name = os.path.join(
|
||||
os.path.abspath(this_dir), "..", "Demos", "images", "smiley.bmp"
|
||||
)
|
||||
self.assertTrue(os.path.isfile(self.bmp_name), self.bmp_name)
|
||||
flags = win32con.LR_DEFAULTSIZE | win32con.LR_LOADFROMFILE
|
||||
self.bmp_handle = win32gui.LoadImage(
|
||||
0, self.bmp_name, win32con.IMAGE_BITMAP, 0, 0, flags
|
||||
)
|
||||
self.assertTrue(self.bmp_handle, "Failed to get a bitmap handle")
|
||||
|
||||
def tearDown(self):
|
||||
if self.bmp_handle:
|
||||
win32gui.DeleteObject(self.bmp_handle)
|
||||
|
||||
def test_bitmap_roundtrip(self):
|
||||
OpenClipboard()
|
||||
try:
|
||||
SetClipboardData(win32con.CF_BITMAP, self.bmp_handle)
|
||||
got_handle = GetClipboardDataHandle(win32con.CF_BITMAP)
|
||||
self.assertEqual(got_handle, self.bmp_handle)
|
||||
finally:
|
||||
CloseClipboard()
|
||||
|
||||
|
||||
class TestStrings(unittest.TestCase):
|
||||
def setUp(self):
|
||||
OpenClipboard()
|
||||
|
||||
def tearDown(self):
|
||||
CloseClipboard()
|
||||
|
||||
def test_unicode(self):
|
||||
val = "test-\a9har"
|
||||
SetClipboardData(win32con.CF_UNICODETEXT, val)
|
||||
self.assertEqual(GetClipboardData(win32con.CF_UNICODETEXT), val)
|
||||
|
||||
def test_unicode_text(self):
|
||||
val = "test-val"
|
||||
SetClipboardText(val)
|
||||
# GetClipboardData doesn't to auto string conversions - so on py3k,
|
||||
# CF_TEXT returns bytes.
|
||||
expected = str2bytes(val)
|
||||
self.assertEqual(GetClipboardData(win32con.CF_TEXT), expected)
|
||||
SetClipboardText(val, win32con.CF_UNICODETEXT)
|
||||
self.assertEqual(GetClipboardData(win32con.CF_UNICODETEXT), val)
|
||||
|
||||
def test_string(self):
|
||||
val = str2bytes("test")
|
||||
SetClipboardData(win32con.CF_TEXT, val)
|
||||
self.assertEqual(GetClipboardData(win32con.CF_TEXT), val)
|
||||
|
||||
|
||||
class TestGlobalMemory(unittest.TestCase):
|
||||
def setUp(self):
|
||||
OpenClipboard()
|
||||
|
||||
def tearDown(self):
|
||||
CloseClipboard()
|
||||
|
||||
def test_mem(self):
|
||||
val = str2bytes("test")
|
||||
expected = str2bytes("test\0")
|
||||
SetClipboardData(win32con.CF_TEXT, val)
|
||||
# Get the raw data - this will include the '\0'
|
||||
raw_data = GetGlobalMemory(GetClipboardDataHandle(win32con.CF_TEXT))
|
||||
self.assertEqual(expected, raw_data)
|
||||
|
||||
def test_bad_mem(self):
|
||||
self.assertRaises(pywintypes.error, GetGlobalMemory, 0)
|
||||
self.assertRaises(pywintypes.error, GetGlobalMemory, -1)
|
||||
if sys.getwindowsversion()[0] <= 5:
|
||||
# For some reason, the value '1' dies from a 64bit process, but
|
||||
# "works" (ie, gives the correct exception) from a 32bit process.
|
||||
# just silently skip this value on Vista.
|
||||
self.assertRaises(pywintypes.error, GetGlobalMemory, 1)
|
||||
|
||||
def test_custom_mem(self):
|
||||
test_data = str2bytes("hello\x00\xff")
|
||||
test_buffer = array.array("b", test_data)
|
||||
cf = RegisterClipboardFormat(custom_format_name)
|
||||
self.assertEqual(custom_format_name, GetClipboardFormatName(cf))
|
||||
SetClipboardData(cf, test_buffer)
|
||||
hglobal = GetClipboardDataHandle(cf)
|
||||
data = GetGlobalMemory(hglobal)
|
||||
self.assertEqual(data, test_data)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
223
lib/win32/test/test_exceptions.py
Normal file
223
lib/win32/test/test_exceptions.py
Normal file
|
@ -0,0 +1,223 @@
|
|||
"""Test pywin32's error semantics"""
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import pythoncom
|
||||
import pywintypes
|
||||
import win32api
|
||||
import win32file
|
||||
import winerror
|
||||
|
||||
|
||||
class TestBase(unittest.TestCase):
|
||||
def _testExceptionIndex(self, exc, index, expected):
|
||||
# check the exception itself can be indexed if not py3k
|
||||
if sys.version_info < (3,):
|
||||
self.assertEqual(exc[index], expected)
|
||||
# and that exception.args can is the same.
|
||||
self.assertEqual(exc.args[index], expected)
|
||||
|
||||
|
||||
class TestAPISimple(TestBase):
|
||||
def _getInvalidHandleException(self):
|
||||
try:
|
||||
win32api.CloseHandle(1)
|
||||
except win32api.error as exc:
|
||||
return exc
|
||||
self.fail("Didn't get invalid-handle exception.")
|
||||
|
||||
def testSimple(self):
|
||||
self.assertRaises(pywintypes.error, win32api.CloseHandle, 1)
|
||||
|
||||
def testErrnoIndex(self):
|
||||
exc = self._getInvalidHandleException()
|
||||
self._testExceptionIndex(exc, 0, winerror.ERROR_INVALID_HANDLE)
|
||||
|
||||
def testFuncIndex(self):
|
||||
exc = self._getInvalidHandleException()
|
||||
self._testExceptionIndex(exc, 1, "CloseHandle")
|
||||
|
||||
def testMessageIndex(self):
|
||||
exc = self._getInvalidHandleException()
|
||||
expected = win32api.FormatMessage(winerror.ERROR_INVALID_HANDLE).rstrip()
|
||||
self._testExceptionIndex(exc, 2, expected)
|
||||
|
||||
def testUnpack(self):
|
||||
try:
|
||||
win32api.CloseHandle(1)
|
||||
self.fail("expected exception!")
|
||||
except win32api.error as exc:
|
||||
self.assertEqual(exc.winerror, winerror.ERROR_INVALID_HANDLE)
|
||||
self.assertEqual(exc.funcname, "CloseHandle")
|
||||
expected_msg = win32api.FormatMessage(
|
||||
winerror.ERROR_INVALID_HANDLE
|
||||
).rstrip()
|
||||
self.assertEqual(exc.strerror, expected_msg)
|
||||
|
||||
def testAsStr(self):
|
||||
exc = self._getInvalidHandleException()
|
||||
err_msg = win32api.FormatMessage(winerror.ERROR_INVALID_HANDLE).rstrip()
|
||||
# early on the result actually *was* a tuple - it must always look like one
|
||||
err_tuple = (winerror.ERROR_INVALID_HANDLE, "CloseHandle", err_msg)
|
||||
self.assertEqual(str(exc), str(err_tuple))
|
||||
|
||||
def testAsTuple(self):
|
||||
exc = self._getInvalidHandleException()
|
||||
err_msg = win32api.FormatMessage(winerror.ERROR_INVALID_HANDLE).rstrip()
|
||||
# early on the result actually *was* a tuple - it must be able to be one
|
||||
err_tuple = (winerror.ERROR_INVALID_HANDLE, "CloseHandle", err_msg)
|
||||
if sys.version_info < (3,):
|
||||
self.assertEqual(tuple(exc), err_tuple)
|
||||
else:
|
||||
self.assertEqual(exc.args, err_tuple)
|
||||
|
||||
def testClassName(self):
|
||||
exc = self._getInvalidHandleException()
|
||||
# The error class has always been named 'error'. That's not ideal :(
|
||||
self.assertEqual(exc.__class__.__name__, "error")
|
||||
|
||||
def testIdentity(self):
|
||||
exc = self._getInvalidHandleException()
|
||||
self.assertTrue(exc.__class__ is pywintypes.error)
|
||||
|
||||
def testBaseClass(self):
|
||||
self.assertEqual(pywintypes.error.__bases__, (Exception,))
|
||||
|
||||
def testAttributes(self):
|
||||
exc = self._getInvalidHandleException()
|
||||
err_msg = win32api.FormatMessage(winerror.ERROR_INVALID_HANDLE).rstrip()
|
||||
self.assertEqual(exc.winerror, winerror.ERROR_INVALID_HANDLE)
|
||||
self.assertEqual(exc.strerror, err_msg)
|
||||
self.assertEqual(exc.funcname, "CloseHandle")
|
||||
|
||||
# some tests for 'insane' args.
|
||||
def testStrangeArgsNone(self):
|
||||
try:
|
||||
raise pywintypes.error()
|
||||
self.fail("Expected exception")
|
||||
except pywintypes.error as exc:
|
||||
self.assertEqual(exc.args, ())
|
||||
self.assertEqual(exc.winerror, None)
|
||||
self.assertEqual(exc.funcname, None)
|
||||
self.assertEqual(exc.strerror, None)
|
||||
|
||||
def testStrangeArgsNotEnough(self):
|
||||
try:
|
||||
raise pywintypes.error("foo")
|
||||
self.fail("Expected exception")
|
||||
except pywintypes.error as exc:
|
||||
assert exc.args[0] == "foo"
|
||||
# 'winerror' always args[0]
|
||||
self.assertEqual(exc.winerror, "foo")
|
||||
self.assertEqual(exc.funcname, None)
|
||||
self.assertEqual(exc.strerror, None)
|
||||
|
||||
def testStrangeArgsTooMany(self):
|
||||
try:
|
||||
raise pywintypes.error("foo", "bar", "you", "never", "kn", 0)
|
||||
self.fail("Expected exception")
|
||||
except pywintypes.error as exc:
|
||||
self.assertEqual(exc.args[0], "foo")
|
||||
self.assertEqual(exc.args[-1], 0)
|
||||
self.assertEqual(exc.winerror, "foo")
|
||||
self.assertEqual(exc.funcname, "bar")
|
||||
self.assertEqual(exc.strerror, "you")
|
||||
|
||||
|
||||
class TestCOMSimple(TestBase):
|
||||
def _getException(self):
|
||||
try:
|
||||
pythoncom.StgOpenStorage("foo", None, 0)
|
||||
except pythoncom.com_error as exc:
|
||||
return exc
|
||||
self.fail("Didn't get storage exception.")
|
||||
|
||||
def testIs(self):
|
||||
self.assertTrue(pythoncom.com_error is pywintypes.com_error)
|
||||
|
||||
def testSimple(self):
|
||||
self.assertRaises(pythoncom.com_error, pythoncom.StgOpenStorage, "foo", None, 0)
|
||||
|
||||
def testErrnoIndex(self):
|
||||
exc = self._getException()
|
||||
self._testExceptionIndex(exc, 0, winerror.STG_E_INVALIDFLAG)
|
||||
|
||||
def testMessageIndex(self):
|
||||
exc = self._getException()
|
||||
expected = win32api.FormatMessage(winerror.STG_E_INVALIDFLAG).rstrip()
|
||||
self._testExceptionIndex(exc, 1, expected)
|
||||
|
||||
def testAsStr(self):
|
||||
exc = self._getException()
|
||||
err_msg = win32api.FormatMessage(winerror.STG_E_INVALIDFLAG).rstrip()
|
||||
# early on the result actually *was* a tuple - it must always look like one
|
||||
err_tuple = (winerror.STG_E_INVALIDFLAG, err_msg, None, None)
|
||||
self.assertEqual(str(exc), str(err_tuple))
|
||||
|
||||
def testAsTuple(self):
|
||||
exc = self._getException()
|
||||
err_msg = win32api.FormatMessage(winerror.STG_E_INVALIDFLAG).rstrip()
|
||||
# early on the result actually *was* a tuple - it must be able to be one
|
||||
err_tuple = (winerror.STG_E_INVALIDFLAG, err_msg, None, None)
|
||||
if sys.version_info < (3,):
|
||||
self.assertEqual(tuple(exc), err_tuple)
|
||||
else:
|
||||
self.assertEqual(exc.args, err_tuple)
|
||||
|
||||
def testClassName(self):
|
||||
exc = self._getException()
|
||||
self.assertEqual(exc.__class__.__name__, "com_error")
|
||||
|
||||
def testIdentity(self):
|
||||
exc = self._getException()
|
||||
self.assertTrue(exc.__class__ is pywintypes.com_error)
|
||||
|
||||
def testBaseClass(self):
|
||||
exc = self._getException()
|
||||
self.assertEqual(pywintypes.com_error.__bases__, (Exception,))
|
||||
|
||||
def testAttributes(self):
|
||||
exc = self._getException()
|
||||
err_msg = win32api.FormatMessage(winerror.STG_E_INVALIDFLAG).rstrip()
|
||||
self.assertEqual(exc.hresult, winerror.STG_E_INVALIDFLAG)
|
||||
self.assertEqual(exc.strerror, err_msg)
|
||||
self.assertEqual(exc.argerror, None)
|
||||
self.assertEqual(exc.excepinfo, None)
|
||||
|
||||
def testStrangeArgsNone(self):
|
||||
try:
|
||||
raise pywintypes.com_error()
|
||||
self.fail("Expected exception")
|
||||
except pywintypes.com_error as exc:
|
||||
self.assertEqual(exc.args, ())
|
||||
self.assertEqual(exc.hresult, None)
|
||||
self.assertEqual(exc.strerror, None)
|
||||
self.assertEqual(exc.argerror, None)
|
||||
self.assertEqual(exc.excepinfo, None)
|
||||
|
||||
def testStrangeArgsNotEnough(self):
|
||||
try:
|
||||
raise pywintypes.com_error("foo")
|
||||
self.fail("Expected exception")
|
||||
except pywintypes.com_error as exc:
|
||||
self.assertEqual(exc.args[0], "foo")
|
||||
self.assertEqual(exc.hresult, "foo")
|
||||
self.assertEqual(exc.strerror, None)
|
||||
self.assertEqual(exc.excepinfo, None)
|
||||
self.assertEqual(exc.argerror, None)
|
||||
|
||||
def testStrangeArgsTooMany(self):
|
||||
try:
|
||||
raise pywintypes.com_error("foo", "bar", "you", "never", "kn", 0)
|
||||
self.fail("Expected exception")
|
||||
except pywintypes.com_error as exc:
|
||||
self.assertEqual(exc.args[0], "foo")
|
||||
self.assertEqual(exc.args[-1], 0)
|
||||
self.assertEqual(exc.hresult, "foo")
|
||||
self.assertEqual(exc.strerror, "bar")
|
||||
self.assertEqual(exc.excepinfo, "you")
|
||||
self.assertEqual(exc.argerror, "never")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
267
lib/win32/test/test_odbc.py
Normal file
267
lib/win32/test/test_odbc.py
Normal file
|
@ -0,0 +1,267 @@
|
|||
# odbc test suite kindly contributed by Frank Millman.
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import odbc
|
||||
import pythoncom
|
||||
from pywin32_testutil import TestSkipped, str2bytes, str2memory
|
||||
from win32com.client import constants
|
||||
|
||||
# We use the DAO ODBC driver
|
||||
from win32com.client.gencache import EnsureDispatch
|
||||
|
||||
|
||||
class TestStuff(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.tablename = "pywin32test_users"
|
||||
self.db_filename = None
|
||||
self.conn = self.cur = None
|
||||
try:
|
||||
# Test any database if a connection string is supplied...
|
||||
conn_str = os.environ["TEST_ODBC_CONNECTION_STRING"]
|
||||
except KeyError:
|
||||
# Create a local MSAccess DB for testing.
|
||||
self.db_filename = tempfile.NamedTemporaryFile().name + ".mdb"
|
||||
|
||||
# Create a brand-new database - what is the story with these?
|
||||
for suffix in (".36", ".35", ".30"):
|
||||
try:
|
||||
dbe = EnsureDispatch("DAO.DBEngine" + suffix)
|
||||
break
|
||||
except pythoncom.com_error:
|
||||
pass
|
||||
else:
|
||||
raise TestSkipped("Can't find a DB engine")
|
||||
|
||||
workspace = dbe.Workspaces(0)
|
||||
|
||||
newdb = workspace.CreateDatabase(
|
||||
self.db_filename, constants.dbLangGeneral, constants.dbEncrypt
|
||||
)
|
||||
|
||||
newdb.Close()
|
||||
|
||||
conn_str = "Driver={Microsoft Access Driver (*.mdb)};dbq=%s;Uid=;Pwd=;" % (
|
||||
self.db_filename,
|
||||
)
|
||||
## print 'Connection string:', conn_str
|
||||
self.conn = odbc.odbc(conn_str)
|
||||
# And we expect a 'users' table for these tests.
|
||||
self.cur = self.conn.cursor()
|
||||
## self.cur.setoutputsize(1000)
|
||||
try:
|
||||
self.cur.execute("""drop table %s""" % self.tablename)
|
||||
except (odbc.error, odbc.progError):
|
||||
pass
|
||||
|
||||
## This needs to be adjusted for sql server syntax for unicode fields
|
||||
## - memo -> TEXT
|
||||
## - varchar -> nvarchar
|
||||
self.assertEqual(
|
||||
self.cur.execute(
|
||||
"""create table %s (
|
||||
userid varchar(25),
|
||||
username varchar(25),
|
||||
bitfield bit,
|
||||
intfield integer,
|
||||
floatfield float,
|
||||
datefield datetime,
|
||||
rawfield varbinary(100),
|
||||
longtextfield memo,
|
||||
longbinaryfield image
|
||||
)"""
|
||||
% self.tablename
|
||||
),
|
||||
-1,
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
if self.cur is not None:
|
||||
try:
|
||||
self.cur.execute("""drop table %s""" % self.tablename)
|
||||
except (odbc.error, odbc.progError) as why:
|
||||
print("Failed to delete test table %s" % self.tablename, why)
|
||||
|
||||
self.cur.close()
|
||||
self.cur = None
|
||||
if self.conn is not None:
|
||||
self.conn.close()
|
||||
self.conn = None
|
||||
if self.db_filename is not None:
|
||||
try:
|
||||
os.unlink(self.db_filename)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
def test_insert_select(self, userid="Frank", username="Frank Millman"):
|
||||
self.assertEqual(
|
||||
self.cur.execute(
|
||||
"insert into %s (userid, username) \
|
||||
values (?,?)"
|
||||
% self.tablename,
|
||||
[userid, username],
|
||||
),
|
||||
1,
|
||||
)
|
||||
self.assertEqual(
|
||||
self.cur.execute(
|
||||
"select * from %s \
|
||||
where userid = ?"
|
||||
% self.tablename,
|
||||
[userid.lower()],
|
||||
),
|
||||
0,
|
||||
)
|
||||
self.assertEqual(
|
||||
self.cur.execute(
|
||||
"select * from %s \
|
||||
where username = ?"
|
||||
% self.tablename,
|
||||
[username.lower()],
|
||||
),
|
||||
0,
|
||||
)
|
||||
|
||||
def test_insert_select_unicode(self, userid="Frank", username="Frank Millman"):
|
||||
self.assertEqual(
|
||||
self.cur.execute(
|
||||
"insert into %s (userid, username)\
|
||||
values (?,?)"
|
||||
% self.tablename,
|
||||
[userid, username],
|
||||
),
|
||||
1,
|
||||
)
|
||||
self.assertEqual(
|
||||
self.cur.execute(
|
||||
"select * from %s \
|
||||
where userid = ?"
|
||||
% self.tablename,
|
||||
[userid.lower()],
|
||||
),
|
||||
0,
|
||||
)
|
||||
self.assertEqual(
|
||||
self.cur.execute(
|
||||
"select * from %s \
|
||||
where username = ?"
|
||||
% self.tablename,
|
||||
[username.lower()],
|
||||
),
|
||||
0,
|
||||
)
|
||||
|
||||
def test_insert_select_unicode_ext(self):
|
||||
userid = "t-\xe0\xf2"
|
||||
username = "test-\xe0\xf2 name"
|
||||
self.test_insert_select_unicode(userid, username)
|
||||
|
||||
def _test_val(self, fieldName, value):
|
||||
for x in range(100):
|
||||
self.cur.execute("delete from %s where userid='Frank'" % self.tablename)
|
||||
self.assertEqual(
|
||||
self.cur.execute(
|
||||
"insert into %s (userid, %s) values (?,?)"
|
||||
% (self.tablename, fieldName),
|
||||
["Frank", value],
|
||||
),
|
||||
1,
|
||||
)
|
||||
self.cur.execute(
|
||||
"select %s from %s where userid = ?" % (fieldName, self.tablename),
|
||||
["Frank"],
|
||||
)
|
||||
rows = self.cur.fetchmany()
|
||||
self.assertEqual(1, len(rows))
|
||||
row = rows[0]
|
||||
self.assertEqual(row[0], value)
|
||||
|
||||
def testBit(self):
|
||||
self._test_val("bitfield", 1)
|
||||
self._test_val("bitfield", 0)
|
||||
|
||||
def testInt(self):
|
||||
self._test_val("intfield", 1)
|
||||
self._test_val("intfield", 0)
|
||||
try:
|
||||
big = sys.maxsize
|
||||
except AttributeError:
|
||||
big = sys.maxint
|
||||
self._test_val("intfield", big)
|
||||
|
||||
def testFloat(self):
|
||||
self._test_val("floatfield", 1.01)
|
||||
self._test_val("floatfield", 0)
|
||||
|
||||
def testVarchar(
|
||||
self,
|
||||
):
|
||||
self._test_val("username", "foo")
|
||||
|
||||
def testLongVarchar(self):
|
||||
"""Test a long text field in excess of internal cursor data size (65536)"""
|
||||
self._test_val("longtextfield", "abc" * 70000)
|
||||
|
||||
def testLongBinary(self):
|
||||
"""Test a long raw field in excess of internal cursor data size (65536)"""
|
||||
self._test_val("longbinaryfield", str2memory("\0\1\2" * 70000))
|
||||
|
||||
def testRaw(self):
|
||||
## Test binary data
|
||||
self._test_val("rawfield", str2memory("\1\2\3\4\0\5\6\7\8"))
|
||||
|
||||
def test_widechar(self):
|
||||
"""Test a unicode character that would be mangled if bound as plain character.
|
||||
For example, previously the below was returned as ascii 'a'
|
||||
"""
|
||||
self._test_val("username", "\u0101")
|
||||
|
||||
def testDates(self):
|
||||
import datetime
|
||||
|
||||
for v in ((1900, 12, 25, 23, 39, 59),):
|
||||
d = datetime.datetime(*v)
|
||||
self._test_val("datefield", d)
|
||||
|
||||
def test_set_nonzero_length(self):
|
||||
self.assertEqual(
|
||||
self.cur.execute(
|
||||
"insert into %s (userid,username) " "values (?,?)" % self.tablename,
|
||||
["Frank", "Frank Millman"],
|
||||
),
|
||||
1,
|
||||
)
|
||||
self.assertEqual(
|
||||
self.cur.execute("update %s set username = ?" % self.tablename, ["Frank"]),
|
||||
1,
|
||||
)
|
||||
self.assertEqual(self.cur.execute("select * from %s" % self.tablename), 0)
|
||||
self.assertEqual(len(self.cur.fetchone()[1]), 5)
|
||||
|
||||
def test_set_zero_length(self):
|
||||
self.assertEqual(
|
||||
self.cur.execute(
|
||||
"insert into %s (userid,username) " "values (?,?)" % self.tablename,
|
||||
[str2bytes("Frank"), ""],
|
||||
),
|
||||
1,
|
||||
)
|
||||
self.assertEqual(self.cur.execute("select * from %s" % self.tablename), 0)
|
||||
self.assertEqual(len(self.cur.fetchone()[1]), 0)
|
||||
|
||||
def test_set_zero_length_unicode(self):
|
||||
self.assertEqual(
|
||||
self.cur.execute(
|
||||
"insert into %s (userid,username) " "values (?,?)" % self.tablename,
|
||||
["Frank", ""],
|
||||
),
|
||||
1,
|
||||
)
|
||||
self.assertEqual(self.cur.execute("select * from %s" % self.tablename), 0)
|
||||
self.assertEqual(len(self.cur.fetchone()[1]), 0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
116
lib/win32/test/test_pywintypes.py
Normal file
116
lib/win32/test/test_pywintypes.py
Normal file
|
@ -0,0 +1,116 @@
|
|||
import datetime
|
||||
import operator
|
||||
import sys
|
||||
import time
|
||||
import unittest
|
||||
|
||||
import pywintypes
|
||||
from pywin32_testutil import ob2memory, str2bytes
|
||||
|
||||
|
||||
class TestCase(unittest.TestCase):
|
||||
def testPyTimeFormat(self):
|
||||
struct_current = time.localtime()
|
||||
pytime_current = pywintypes.Time(struct_current)
|
||||
# try and test all the standard parts of the format
|
||||
# Note we used to include '%Z' testing, but that was pretty useless as
|
||||
# it always returned the local timezone.
|
||||
format_strings = "%a %A %b %B %c %d %H %I %j %m %M %p %S %U %w %W %x %X %y %Y"
|
||||
for fmt in format_strings.split():
|
||||
v1 = pytime_current.Format(fmt)
|
||||
v2 = time.strftime(fmt, struct_current)
|
||||
self.assertEqual(v1, v2, "format %s failed - %r != %r" % (fmt, v1, v2))
|
||||
|
||||
def testPyTimePrint(self):
|
||||
# This used to crash with an invalid, or too early time.
|
||||
# We don't really want to check that it does cause a ValueError
|
||||
# (as hopefully this wont be true forever). So either working, or
|
||||
# ValueError is OK.
|
||||
try:
|
||||
t = pywintypes.Time(-2)
|
||||
t.Format()
|
||||
except ValueError:
|
||||
return
|
||||
|
||||
def testTimeInDict(self):
|
||||
d = {}
|
||||
d["t1"] = pywintypes.Time(1)
|
||||
self.assertEqual(d["t1"], pywintypes.Time(1))
|
||||
|
||||
def testPyTimeCompare(self):
|
||||
t1 = pywintypes.Time(100)
|
||||
t1_2 = pywintypes.Time(100)
|
||||
t2 = pywintypes.Time(101)
|
||||
|
||||
self.assertEqual(t1, t1_2)
|
||||
self.assertTrue(t1 <= t1_2)
|
||||
self.assertTrue(t1_2 >= t1)
|
||||
|
||||
self.assertNotEqual(t1, t2)
|
||||
self.assertTrue(t1 < t2)
|
||||
self.assertTrue(t2 > t1)
|
||||
|
||||
def testPyTimeCompareOther(self):
|
||||
t1 = pywintypes.Time(100)
|
||||
t2 = None
|
||||
self.assertNotEqual(t1, t2)
|
||||
|
||||
def testTimeTuple(self):
|
||||
now = datetime.datetime.now() # has usec...
|
||||
# timetuple() lost usec - pt must be <=...
|
||||
pt = pywintypes.Time(now.timetuple())
|
||||
# *sob* - only if we have a datetime object can we compare like this.
|
||||
if isinstance(pt, datetime.datetime):
|
||||
self.assertTrue(pt <= now)
|
||||
|
||||
def testTimeTuplems(self):
|
||||
now = datetime.datetime.now() # has usec...
|
||||
tt = now.timetuple() + (now.microsecond // 1000,)
|
||||
pt = pywintypes.Time(tt)
|
||||
# we can't compare if using the old type, as it loses all sub-second res.
|
||||
if isinstance(pt, datetime.datetime):
|
||||
# but even with datetime, we lose sub-millisecond.
|
||||
expectedDelta = datetime.timedelta(milliseconds=1)
|
||||
self.assertTrue(-expectedDelta < (now - pt) < expectedDelta)
|
||||
|
||||
def testPyTimeFromTime(self):
|
||||
t1 = pywintypes.Time(time.time())
|
||||
self.assertTrue(pywintypes.Time(t1) is t1)
|
||||
|
||||
def testPyTimeTooLarge(self):
|
||||
MAX_TIMESTAMP = 0x7FFFFFFFFFFFFFFF # used by some API function to mean "never"
|
||||
ts = pywintypes.TimeStamp(MAX_TIMESTAMP)
|
||||
self.assertEqual(ts, datetime.datetime.max)
|
||||
|
||||
def testGUID(self):
|
||||
s = "{00020400-0000-0000-C000-000000000046}"
|
||||
iid = pywintypes.IID(s)
|
||||
iid2 = pywintypes.IID(ob2memory(iid), True)
|
||||
self.assertEqual(iid, iid2)
|
||||
self.assertRaises(
|
||||
ValueError, pywintypes.IID, str2bytes("00"), True
|
||||
) # too short
|
||||
self.assertRaises(TypeError, pywintypes.IID, 0, True) # no buffer
|
||||
|
||||
def testGUIDRichCmp(self):
|
||||
s = "{00020400-0000-0000-C000-000000000046}"
|
||||
iid = pywintypes.IID(s)
|
||||
self.assertFalse(s == None)
|
||||
self.assertFalse(None == s)
|
||||
self.assertTrue(s != None)
|
||||
self.assertTrue(None != s)
|
||||
if sys.version_info > (3, 0):
|
||||
self.assertRaises(TypeError, operator.gt, None, s)
|
||||
self.assertRaises(TypeError, operator.gt, s, None)
|
||||
self.assertRaises(TypeError, operator.lt, None, s)
|
||||
self.assertRaises(TypeError, operator.lt, s, None)
|
||||
|
||||
def testGUIDInDict(self):
|
||||
s = "{00020400-0000-0000-C000-000000000046}"
|
||||
iid = pywintypes.IID(s)
|
||||
d = dict(item=iid)
|
||||
self.assertEqual(d["item"], iid)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
166
lib/win32/test/test_security.py
Normal file
166
lib/win32/test/test_security.py
Normal file
|
@ -0,0 +1,166 @@
|
|||
# Tests for the win32security module.
|
||||
import unittest
|
||||
|
||||
import ntsecuritycon
|
||||
import pywintypes
|
||||
import win32api
|
||||
import win32con
|
||||
import win32security
|
||||
import winerror
|
||||
from pywin32_testutil import TestSkipped, ob2memory, testmain
|
||||
|
||||
|
||||
class SecurityTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.pwr_sid = win32security.LookupAccountName("", "Power Users")[0]
|
||||
try:
|
||||
self.admin_sid = win32security.LookupAccountName("", "Administrator")[0]
|
||||
except pywintypes.error as exc:
|
||||
# in automation we see:
|
||||
# pywintypes.error: (1332, 'LookupAccountName', 'No mapping between account names and security IDs was done.')
|
||||
if exc.winerror != winerror.ERROR_NONE_MAPPED:
|
||||
raise
|
||||
self.admin_sid = None
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def testEqual(self):
|
||||
if self.admin_sid is None:
|
||||
raise TestSkipped("No 'Administrator' account is available")
|
||||
self.assertEqual(
|
||||
win32security.LookupAccountName("", "Administrator")[0],
|
||||
win32security.LookupAccountName("", "Administrator")[0],
|
||||
)
|
||||
|
||||
def testNESID(self):
|
||||
self.assertTrue(self.pwr_sid == self.pwr_sid)
|
||||
if self.admin_sid:
|
||||
self.assertTrue(self.pwr_sid != self.admin_sid)
|
||||
|
||||
def testNEOther(self):
|
||||
self.assertTrue(self.pwr_sid != None)
|
||||
self.assertTrue(None != self.pwr_sid)
|
||||
self.assertFalse(self.pwr_sid == None)
|
||||
self.assertFalse(None == self.pwr_sid)
|
||||
self.assertNotEqual(None, self.pwr_sid)
|
||||
|
||||
def testSIDInDict(self):
|
||||
d = dict(foo=self.pwr_sid)
|
||||
self.assertEqual(d["foo"], self.pwr_sid)
|
||||
|
||||
def testBuffer(self):
|
||||
if self.admin_sid is None:
|
||||
raise TestSkipped("No 'Administrator' account is available")
|
||||
self.assertEqual(
|
||||
ob2memory(win32security.LookupAccountName("", "Administrator")[0]),
|
||||
ob2memory(win32security.LookupAccountName("", "Administrator")[0]),
|
||||
)
|
||||
|
||||
def testMemory(self):
|
||||
pwr_sid = self.pwr_sid
|
||||
admin_sid = self.admin_sid
|
||||
sd1 = win32security.SECURITY_DESCRIPTOR()
|
||||
sd2 = win32security.SECURITY_DESCRIPTOR()
|
||||
sd3 = win32security.SECURITY_DESCRIPTOR()
|
||||
dacl = win32security.ACL()
|
||||
dacl.AddAccessAllowedAce(
|
||||
win32security.ACL_REVISION, win32con.GENERIC_READ, pwr_sid
|
||||
)
|
||||
if admin_sid is not None:
|
||||
dacl.AddAccessAllowedAce(
|
||||
win32security.ACL_REVISION, win32con.GENERIC_ALL, admin_sid
|
||||
)
|
||||
sd4 = win32security.SECURITY_DESCRIPTOR()
|
||||
sacl = win32security.ACL()
|
||||
if admin_sid is not None:
|
||||
sacl.AddAuditAccessAce(
|
||||
win32security.ACL_REVISION, win32con.DELETE, admin_sid, 1, 1
|
||||
)
|
||||
sacl.AddAuditAccessAce(
|
||||
win32security.ACL_REVISION, win32con.GENERIC_ALL, pwr_sid, 1, 1
|
||||
)
|
||||
for x in range(0, 200000):
|
||||
if admin_sid is not None:
|
||||
sd1.SetSecurityDescriptorOwner(admin_sid, 0)
|
||||
sd2.SetSecurityDescriptorGroup(pwr_sid, 0)
|
||||
sd3.SetSecurityDescriptorDacl(1, dacl, 0)
|
||||
sd4.SetSecurityDescriptorSacl(1, sacl, 0)
|
||||
|
||||
|
||||
class DomainTests(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.ds_handle = None
|
||||
try:
|
||||
# saving the handle means the other test itself should bind faster.
|
||||
self.ds_handle = win32security.DsBind()
|
||||
except win32security.error as exc:
|
||||
if exc.winerror != winerror.ERROR_NO_SUCH_DOMAIN:
|
||||
raise
|
||||
raise TestSkipped(exc)
|
||||
|
||||
def tearDown(self):
|
||||
if self.ds_handle is not None:
|
||||
self.ds_handle.close()
|
||||
|
||||
|
||||
class TestDS(DomainTests):
|
||||
def testDsGetDcName(self):
|
||||
# Not sure what we can actually test here! At least calling it
|
||||
# does something :)
|
||||
win32security.DsGetDcName()
|
||||
|
||||
def testDsListServerInfo(self):
|
||||
# again, not checking much, just exercising the code.
|
||||
h = win32security.DsBind()
|
||||
for status, ignore, site in win32security.DsListSites(h):
|
||||
for status, ignore, server in win32security.DsListServersInSite(h, site):
|
||||
info = win32security.DsListInfoForServer(h, server)
|
||||
for status, ignore, domain in win32security.DsListDomainsInSite(h, site):
|
||||
pass
|
||||
|
||||
def testDsCrackNames(self):
|
||||
h = win32security.DsBind()
|
||||
fmt_offered = ntsecuritycon.DS_FQDN_1779_NAME
|
||||
name = win32api.GetUserNameEx(fmt_offered)
|
||||
result = win32security.DsCrackNames(h, 0, fmt_offered, fmt_offered, (name,))
|
||||
self.assertEqual(name, result[0][2])
|
||||
|
||||
def testDsCrackNamesSyntax(self):
|
||||
# Do a syntax check only - that allows us to avoid binding.
|
||||
# But must use DS_CANONICAL_NAME (or _EX)
|
||||
expected = win32api.GetUserNameEx(win32api.NameCanonical)
|
||||
fmt_offered = ntsecuritycon.DS_FQDN_1779_NAME
|
||||
name = win32api.GetUserNameEx(fmt_offered)
|
||||
result = win32security.DsCrackNames(
|
||||
None,
|
||||
ntsecuritycon.DS_NAME_FLAG_SYNTACTICAL_ONLY,
|
||||
fmt_offered,
|
||||
ntsecuritycon.DS_CANONICAL_NAME,
|
||||
(name,),
|
||||
)
|
||||
self.assertEqual(expected, result[0][2])
|
||||
|
||||
|
||||
class TestTranslate(DomainTests):
|
||||
def _testTranslate(self, fmt_from, fmt_to):
|
||||
name = win32api.GetUserNameEx(fmt_from)
|
||||
expected = win32api.GetUserNameEx(fmt_to)
|
||||
got = win32security.TranslateName(name, fmt_from, fmt_to)
|
||||
self.assertEqual(got, expected)
|
||||
|
||||
def testTranslate1(self):
|
||||
self._testTranslate(win32api.NameFullyQualifiedDN, win32api.NameSamCompatible)
|
||||
|
||||
def testTranslate2(self):
|
||||
self._testTranslate(win32api.NameSamCompatible, win32api.NameFullyQualifiedDN)
|
||||
|
||||
def testTranslate3(self):
|
||||
self._testTranslate(win32api.NameFullyQualifiedDN, win32api.NameUniqueId)
|
||||
|
||||
def testTranslate4(self):
|
||||
self._testTranslate(win32api.NameUniqueId, win32api.NameFullyQualifiedDN)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
testmain()
|
231
lib/win32/test/test_sspi.py
Normal file
231
lib/win32/test/test_sspi.py
Normal file
|
@ -0,0 +1,231 @@
|
|||
# Some tests of the win32security sspi functions.
|
||||
# Stolen from Roger's original test_sspi.c, a version of which is in "Demos"
|
||||
# See also the other SSPI demos.
|
||||
import re
|
||||
import unittest
|
||||
|
||||
import sspi
|
||||
import sspicon
|
||||
import win32api
|
||||
import win32security
|
||||
from pywin32_testutil import TestSkipped, str2bytes, testmain
|
||||
|
||||
|
||||
# It is quite likely that the Kerberos tests will fail due to not being
|
||||
# installed. The NTLM tests do *not* get the same behaviour as they should
|
||||
# always be there.
|
||||
def applyHandlingSkips(func, *args):
|
||||
try:
|
||||
return func(*args)
|
||||
except win32api.error as exc:
|
||||
if exc.winerror in [
|
||||
sspicon.SEC_E_NO_CREDENTIALS,
|
||||
sspicon.SEC_E_NO_AUTHENTICATING_AUTHORITY,
|
||||
]:
|
||||
raise TestSkipped(exc)
|
||||
raise
|
||||
|
||||
|
||||
class TestSSPI(unittest.TestCase):
|
||||
def assertRaisesHRESULT(self, hr, func, *args):
|
||||
try:
|
||||
return func(*args)
|
||||
raise RuntimeError("expecting %s failure" % (hr,))
|
||||
except win32security.error as exc:
|
||||
self.assertEqual(exc.winerror, hr)
|
||||
|
||||
def _doAuth(self, pkg_name):
|
||||
sspiclient = sspi.ClientAuth(pkg_name, targetspn=win32api.GetUserName())
|
||||
sspiserver = sspi.ServerAuth(pkg_name)
|
||||
|
||||
sec_buffer = None
|
||||
err = 1
|
||||
while err != 0:
|
||||
err, sec_buffer = sspiclient.authorize(sec_buffer)
|
||||
err, sec_buffer = sspiserver.authorize(sec_buffer)
|
||||
return sspiclient, sspiserver
|
||||
|
||||
def _doTestImpersonate(self, pkg_name):
|
||||
# Just for the sake of code exercising!
|
||||
sspiclient, sspiserver = self._doAuth(pkg_name)
|
||||
sspiserver.ctxt.ImpersonateSecurityContext()
|
||||
sspiserver.ctxt.RevertSecurityContext()
|
||||
|
||||
def testImpersonateKerberos(self):
|
||||
applyHandlingSkips(self._doTestImpersonate, "Kerberos")
|
||||
|
||||
def testImpersonateNTLM(self):
|
||||
self._doTestImpersonate("NTLM")
|
||||
|
||||
def _doTestEncrypt(self, pkg_name):
|
||||
sspiclient, sspiserver = self._doAuth(pkg_name)
|
||||
|
||||
pkg_size_info = sspiclient.ctxt.QueryContextAttributes(
|
||||
sspicon.SECPKG_ATTR_SIZES
|
||||
)
|
||||
msg = str2bytes("some data to be encrypted ......")
|
||||
|
||||
trailersize = pkg_size_info["SecurityTrailer"]
|
||||
encbuf = win32security.PySecBufferDescType()
|
||||
encbuf.append(win32security.PySecBufferType(len(msg), sspicon.SECBUFFER_DATA))
|
||||
encbuf.append(
|
||||
win32security.PySecBufferType(trailersize, sspicon.SECBUFFER_TOKEN)
|
||||
)
|
||||
encbuf[0].Buffer = msg
|
||||
sspiclient.ctxt.EncryptMessage(0, encbuf, 1)
|
||||
sspiserver.ctxt.DecryptMessage(encbuf, 1)
|
||||
self.assertEqual(msg, encbuf[0].Buffer)
|
||||
# and test the higher-level functions
|
||||
data_in = str2bytes("hello")
|
||||
data, sig = sspiclient.encrypt(data_in)
|
||||
self.assertEqual(sspiserver.decrypt(data, sig), data_in)
|
||||
|
||||
data, sig = sspiserver.encrypt(data_in)
|
||||
self.assertEqual(sspiclient.decrypt(data, sig), data_in)
|
||||
|
||||
def _doTestEncryptStream(self, pkg_name):
|
||||
# Test out the SSPI/GSSAPI interop wrapping examples at
|
||||
# https://docs.microsoft.com/en-us/windows/win32/secauthn/sspi-kerberos-interoperability-with-gssapi
|
||||
|
||||
sspiclient, sspiserver = self._doAuth(pkg_name)
|
||||
|
||||
pkg_size_info = sspiclient.ctxt.QueryContextAttributes(
|
||||
sspicon.SECPKG_ATTR_SIZES
|
||||
)
|
||||
msg = str2bytes("some data to be encrypted ......")
|
||||
|
||||
trailersize = pkg_size_info["SecurityTrailer"]
|
||||
blocksize = pkg_size_info["BlockSize"]
|
||||
encbuf = win32security.PySecBufferDescType()
|
||||
encbuf.append(
|
||||
win32security.PySecBufferType(trailersize, sspicon.SECBUFFER_TOKEN)
|
||||
)
|
||||
encbuf.append(win32security.PySecBufferType(len(msg), sspicon.SECBUFFER_DATA))
|
||||
encbuf.append(
|
||||
win32security.PySecBufferType(blocksize, sspicon.SECBUFFER_PADDING)
|
||||
)
|
||||
encbuf[1].Buffer = msg
|
||||
sspiclient.ctxt.EncryptMessage(0, encbuf, 1)
|
||||
|
||||
encmsg = encbuf[0].Buffer + encbuf[1].Buffer + encbuf[2].Buffer
|
||||
decbuf = win32security.PySecBufferDescType()
|
||||
decbuf.append(
|
||||
win32security.PySecBufferType(len(encmsg), sspicon.SECBUFFER_STREAM)
|
||||
)
|
||||
decbuf.append(win32security.PySecBufferType(0, sspicon.SECBUFFER_DATA))
|
||||
decbuf[0].Buffer = encmsg
|
||||
|
||||
sspiserver.ctxt.DecryptMessage(decbuf, 1)
|
||||
self.assertEqual(msg, decbuf[1].Buffer)
|
||||
|
||||
def testEncryptNTLM(self):
|
||||
self._doTestEncrypt("NTLM")
|
||||
|
||||
def testEncryptStreamNTLM(self):
|
||||
self._doTestEncryptStream("NTLM")
|
||||
|
||||
def testEncryptKerberos(self):
|
||||
applyHandlingSkips(self._doTestEncrypt, "Kerberos")
|
||||
|
||||
def testEncryptStreamKerberos(self):
|
||||
applyHandlingSkips(self._doTestEncryptStream, "Kerberos")
|
||||
|
||||
def _doTestSign(self, pkg_name):
|
||||
sspiclient, sspiserver = self._doAuth(pkg_name)
|
||||
|
||||
pkg_size_info = sspiclient.ctxt.QueryContextAttributes(
|
||||
sspicon.SECPKG_ATTR_SIZES
|
||||
)
|
||||
msg = str2bytes("some data to be encrypted ......")
|
||||
|
||||
sigsize = pkg_size_info["MaxSignature"]
|
||||
sigbuf = win32security.PySecBufferDescType()
|
||||
sigbuf.append(win32security.PySecBufferType(len(msg), sspicon.SECBUFFER_DATA))
|
||||
sigbuf.append(win32security.PySecBufferType(sigsize, sspicon.SECBUFFER_TOKEN))
|
||||
sigbuf[0].Buffer = msg
|
||||
sspiclient.ctxt.MakeSignature(0, sigbuf, 0)
|
||||
sspiserver.ctxt.VerifySignature(sigbuf, 0)
|
||||
# and test the higher-level functions
|
||||
sspiclient.next_seq_num = 1
|
||||
sspiserver.next_seq_num = 1
|
||||
data = str2bytes("hello")
|
||||
key = sspiclient.sign(data)
|
||||
sspiserver.verify(data, key)
|
||||
key = sspiclient.sign(data)
|
||||
self.assertRaisesHRESULT(
|
||||
sspicon.SEC_E_MESSAGE_ALTERED, sspiserver.verify, data + data, key
|
||||
)
|
||||
|
||||
# and the other way
|
||||
key = sspiserver.sign(data)
|
||||
sspiclient.verify(data, key)
|
||||
key = sspiserver.sign(data)
|
||||
self.assertRaisesHRESULT(
|
||||
sspicon.SEC_E_MESSAGE_ALTERED, sspiclient.verify, data + data, key
|
||||
)
|
||||
|
||||
def testSignNTLM(self):
|
||||
self._doTestSign("NTLM")
|
||||
|
||||
def testSignKerberos(self):
|
||||
applyHandlingSkips(self._doTestSign, "Kerberos")
|
||||
|
||||
def _testSequenceSign(self):
|
||||
# Only Kerberos supports sequence detection.
|
||||
sspiclient, sspiserver = self._doAuth("Kerberos")
|
||||
key = sspiclient.sign(b"hello")
|
||||
sspiclient.sign(b"hello")
|
||||
self.assertRaisesHRESULT(
|
||||
sspicon.SEC_E_OUT_OF_SEQUENCE, sspiserver.verify, b"hello", key
|
||||
)
|
||||
|
||||
def testSequenceSign(self):
|
||||
applyHandlingSkips(self._testSequenceSign)
|
||||
|
||||
def _testSequenceEncrypt(self):
|
||||
# Only Kerberos supports sequence detection.
|
||||
sspiclient, sspiserver = self._doAuth("Kerberos")
|
||||
blob, key = sspiclient.encrypt(b"hello")
|
||||
blob, key = sspiclient.encrypt(b"hello")
|
||||
self.assertRaisesHRESULT(
|
||||
sspicon.SEC_E_OUT_OF_SEQUENCE, sspiserver.decrypt, blob, key
|
||||
)
|
||||
|
||||
def testSequenceEncrypt(self):
|
||||
applyHandlingSkips(self._testSequenceEncrypt)
|
||||
|
||||
def testSecBufferRepr(self):
|
||||
desc = win32security.PySecBufferDescType()
|
||||
assert re.match(
|
||||
"PySecBufferDesc\(ulVersion: 0 \| cBuffers: 0 \| pBuffers: 0x[\da-fA-F]{8,16}\)",
|
||||
repr(desc),
|
||||
)
|
||||
|
||||
buffer1 = win32security.PySecBufferType(0, sspicon.SECBUFFER_TOKEN)
|
||||
assert re.match(
|
||||
"PySecBuffer\(cbBuffer: 0 \| BufferType: 2 \| pvBuffer: 0x[\da-fA-F]{8,16}\)",
|
||||
repr(buffer1),
|
||||
)
|
||||
"PySecBuffer(cbBuffer: 0 | BufferType: 2 | pvBuffer: 0x000001B8CC6D8020)"
|
||||
desc.append(buffer1)
|
||||
|
||||
assert re.match(
|
||||
"PySecBufferDesc\(ulVersion: 0 \| cBuffers: 1 \| pBuffers: 0x[\da-fA-F]{8,16}\)",
|
||||
repr(desc),
|
||||
)
|
||||
|
||||
buffer2 = win32security.PySecBufferType(4, sspicon.SECBUFFER_DATA)
|
||||
assert re.match(
|
||||
"PySecBuffer\(cbBuffer: 4 \| BufferType: 1 \| pvBuffer: 0x[\da-fA-F]{8,16}\)",
|
||||
repr(buffer2),
|
||||
)
|
||||
desc.append(buffer2)
|
||||
|
||||
assert re.match(
|
||||
"PySecBufferDesc\(ulVersion: 0 \| cBuffers: 2 \| pBuffers: 0x[\da-fA-F]{8,16}\)",
|
||||
repr(desc),
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
testmain()
|
268
lib/win32/test/test_win32api.py
Normal file
268
lib/win32/test/test_win32api.py
Normal file
|
@ -0,0 +1,268 @@
|
|||
# General test module for win32api - please add some :)
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import win32api
|
||||
import win32con
|
||||
import win32event
|
||||
import winerror
|
||||
from pywin32_testutil import TestSkipped, str2bytes
|
||||
|
||||
|
||||
class CurrentUserTestCase(unittest.TestCase):
|
||||
def testGetCurrentUser(self):
|
||||
domain = win32api.GetDomainName()
|
||||
if domain == "NT AUTHORITY":
|
||||
# Running as a service account, so the comparison will fail
|
||||
raise TestSkipped("running as service account")
|
||||
name = "%s\\%s" % (domain, win32api.GetUserName())
|
||||
self.assertEqual(name, win32api.GetUserNameEx(win32api.NameSamCompatible))
|
||||
|
||||
|
||||
class TestTime(unittest.TestCase):
|
||||
def testTimezone(self):
|
||||
# GetTimeZoneInformation
|
||||
rc, tzinfo = win32api.GetTimeZoneInformation()
|
||||
if rc == win32con.TIME_ZONE_ID_DAYLIGHT:
|
||||
tz_str = tzinfo[4]
|
||||
tz_time = tzinfo[5]
|
||||
else:
|
||||
tz_str = tzinfo[1]
|
||||
tz_time = tzinfo[2]
|
||||
# for the sake of code exercise but don't output
|
||||
tz_str.encode()
|
||||
if not isinstance(tz_time, datetime.datetime) and not isinstance(
|
||||
tz_time, tuple
|
||||
):
|
||||
tz_time.Format()
|
||||
|
||||
def TestDateFormat(self):
|
||||
DATE_LONGDATE = 2
|
||||
date_flags = DATE_LONGDATE
|
||||
win32api.GetDateFormat(0, date_flags, None)
|
||||
win32api.GetDateFormat(0, date_flags, 0)
|
||||
win32api.GetDateFormat(0, date_flags, datetime.datetime.now())
|
||||
win32api.GetDateFormat(0, date_flags, time.time())
|
||||
|
||||
def TestTimeFormat(self):
|
||||
win32api.GetTimeFormat(0, 0, None)
|
||||
win32api.GetTimeFormat(0, 0, 0)
|
||||
win32api.GetTimeFormat(0, 0, datetime.datetime.now())
|
||||
win32api.GetTimeFormat(0, 0, time.time())
|
||||
|
||||
|
||||
class Registry(unittest.TestCase):
|
||||
key_name = r"PythonTestHarness\Whatever"
|
||||
|
||||
def test1(self):
|
||||
# This used to leave a stale exception behind.
|
||||
def reg_operation():
|
||||
hkey = win32api.RegCreateKey(win32con.HKEY_CURRENT_USER, self.key_name)
|
||||
x = 3 / 0 # or a statement like: raise 'error'
|
||||
|
||||
# do the test
|
||||
try:
|
||||
try:
|
||||
try:
|
||||
reg_operation()
|
||||
except:
|
||||
1 / 0 # Force exception
|
||||
finally:
|
||||
win32api.RegDeleteKey(win32con.HKEY_CURRENT_USER, self.key_name)
|
||||
except ZeroDivisionError:
|
||||
pass
|
||||
|
||||
def testValues(self):
|
||||
key_name = r"PythonTestHarness\win32api"
|
||||
## tuples containing value name, value type, data
|
||||
values = (
|
||||
(None, win32con.REG_SZ, "This is default unnamed value"),
|
||||
("REG_SZ", win32con.REG_SZ, "REG_SZ text data"),
|
||||
("REG_EXPAND_SZ", win32con.REG_EXPAND_SZ, "%systemdir%"),
|
||||
## REG_MULTI_SZ value needs to be a list since strings are returned as a list
|
||||
(
|
||||
"REG_MULTI_SZ",
|
||||
win32con.REG_MULTI_SZ,
|
||||
["string 1", "string 2", "string 3", "string 4"],
|
||||
),
|
||||
("REG_MULTI_SZ_empty", win32con.REG_MULTI_SZ, []),
|
||||
("REG_DWORD", win32con.REG_DWORD, 666),
|
||||
("REG_QWORD_INT", win32con.REG_QWORD, 99),
|
||||
("REG_QWORD", win32con.REG_QWORD, 2**33),
|
||||
(
|
||||
"REG_BINARY",
|
||||
win32con.REG_BINARY,
|
||||
str2bytes("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x01\x00"),
|
||||
),
|
||||
)
|
||||
|
||||
hkey = win32api.RegCreateKey(win32con.HKEY_CURRENT_USER, key_name)
|
||||
for value_name, reg_type, data in values:
|
||||
win32api.RegSetValueEx(hkey, value_name, None, reg_type, data)
|
||||
|
||||
for value_name, orig_type, orig_data in values:
|
||||
data, typ = win32api.RegQueryValueEx(hkey, value_name)
|
||||
self.assertEqual(typ, orig_type)
|
||||
self.assertEqual(data, orig_data)
|
||||
|
||||
def testNotifyChange(self):
|
||||
def change():
|
||||
hkey = win32api.RegCreateKey(win32con.HKEY_CURRENT_USER, self.key_name)
|
||||
try:
|
||||
win32api.RegSetValue(hkey, None, win32con.REG_SZ, "foo")
|
||||
finally:
|
||||
win32api.RegDeleteKey(win32con.HKEY_CURRENT_USER, self.key_name)
|
||||
|
||||
evt = win32event.CreateEvent(None, 0, 0, None)
|
||||
## REG_NOTIFY_CHANGE_LAST_SET - values
|
||||
## REG_CHANGE_NOTIFY_NAME - keys
|
||||
## REG_NOTIFY_CHANGE_SECURITY - security descriptor
|
||||
## REG_NOTIFY_CHANGE_ATTRIBUTES
|
||||
win32api.RegNotifyChangeKeyValue(
|
||||
win32con.HKEY_CURRENT_USER,
|
||||
1,
|
||||
win32api.REG_NOTIFY_CHANGE_LAST_SET,
|
||||
evt,
|
||||
True,
|
||||
)
|
||||
ret_code = win32event.WaitForSingleObject(evt, 0)
|
||||
# Should be no change.
|
||||
self.assertTrue(ret_code == win32con.WAIT_TIMEOUT)
|
||||
change()
|
||||
# Our event should now be in a signalled state.
|
||||
ret_code = win32event.WaitForSingleObject(evt, 0)
|
||||
self.assertTrue(ret_code == win32con.WAIT_OBJECT_0)
|
||||
|
||||
|
||||
class FileNames(unittest.TestCase):
|
||||
def testShortLongPathNames(self):
|
||||
try:
|
||||
me = __file__
|
||||
except NameError:
|
||||
me = sys.argv[0]
|
||||
fname = os.path.abspath(me).lower()
|
||||
short_name = win32api.GetShortPathName(fname).lower()
|
||||
long_name = win32api.GetLongPathName(short_name).lower()
|
||||
self.assertTrue(
|
||||
long_name == fname,
|
||||
"Expected long name ('%s') to be original name ('%s')" % (long_name, fname),
|
||||
)
|
||||
self.assertEqual(long_name, win32api.GetLongPathNameW(short_name).lower())
|
||||
long_name = win32api.GetLongPathNameW(short_name).lower()
|
||||
self.assertTrue(
|
||||
type(long_name) == str,
|
||||
"GetLongPathNameW returned type '%s'" % (type(long_name),),
|
||||
)
|
||||
self.assertTrue(
|
||||
long_name == fname,
|
||||
"Expected long name ('%s') to be original name ('%s')" % (long_name, fname),
|
||||
)
|
||||
|
||||
def testShortUnicodeNames(self):
|
||||
try:
|
||||
me = __file__
|
||||
except NameError:
|
||||
me = sys.argv[0]
|
||||
fname = os.path.abspath(me).lower()
|
||||
# passing unicode should cause GetShortPathNameW to be called.
|
||||
short_name = win32api.GetShortPathName(str(fname)).lower()
|
||||
self.assertTrue(isinstance(short_name, str))
|
||||
long_name = win32api.GetLongPathName(short_name).lower()
|
||||
self.assertTrue(
|
||||
long_name == fname,
|
||||
"Expected long name ('%s') to be original name ('%s')" % (long_name, fname),
|
||||
)
|
||||
self.assertEqual(long_name, win32api.GetLongPathNameW(short_name).lower())
|
||||
long_name = win32api.GetLongPathNameW(short_name).lower()
|
||||
self.assertTrue(
|
||||
type(long_name) == str,
|
||||
"GetLongPathNameW returned type '%s'" % (type(long_name),),
|
||||
)
|
||||
self.assertTrue(
|
||||
long_name == fname,
|
||||
"Expected long name ('%s') to be original name ('%s')" % (long_name, fname),
|
||||
)
|
||||
|
||||
def testLongLongPathNames(self):
|
||||
# We need filename where the FQN is > 256 - simplest way is to create a
|
||||
# 250 character directory in the cwd (except - cwd may be on a drive
|
||||
# not supporting \\\\?\\ (eg, network share) - so use temp.
|
||||
import win32file
|
||||
|
||||
basename = "a" * 250
|
||||
# but we need to ensure we use the 'long' version of the
|
||||
# temp dir for later comparison.
|
||||
long_temp_dir = win32api.GetLongPathNameW(tempfile.gettempdir())
|
||||
fname = "\\\\?\\" + os.path.join(long_temp_dir, basename)
|
||||
try:
|
||||
win32file.CreateDirectoryW(fname, None)
|
||||
except win32api.error as details:
|
||||
if details.winerror != winerror.ERROR_ALREADY_EXISTS:
|
||||
raise
|
||||
try:
|
||||
# GetFileAttributes automatically calls GetFileAttributesW when
|
||||
# passed unicode
|
||||
try:
|
||||
attr = win32api.GetFileAttributes(fname)
|
||||
except win32api.error as details:
|
||||
if details.winerror != winerror.ERROR_FILENAME_EXCED_RANGE:
|
||||
raise
|
||||
|
||||
attr = win32api.GetFileAttributes(str(fname))
|
||||
self.assertTrue(attr & win32con.FILE_ATTRIBUTE_DIRECTORY, attr)
|
||||
|
||||
long_name = win32api.GetLongPathNameW(fname)
|
||||
self.assertEqual(long_name.lower(), fname.lower())
|
||||
finally:
|
||||
win32file.RemoveDirectory(fname)
|
||||
|
||||
|
||||
class FormatMessage(unittest.TestCase):
|
||||
def test_FromString(self):
|
||||
msg = "Hello %1, how are you %2?"
|
||||
inserts = ["Mark", "today"]
|
||||
result = win32api.FormatMessage(
|
||||
win32con.FORMAT_MESSAGE_FROM_STRING,
|
||||
msg, # source
|
||||
0, # ID
|
||||
0, # LangID
|
||||
inserts,
|
||||
)
|
||||
self.assertEqual(result, "Hello Mark, how are you today?")
|
||||
|
||||
|
||||
class Misc(unittest.TestCase):
|
||||
def test_last_error(self):
|
||||
for x in (0, 1, -1, winerror.TRUST_E_PROVIDER_UNKNOWN):
|
||||
win32api.SetLastError(x)
|
||||
self.assertEqual(x, win32api.GetLastError())
|
||||
|
||||
def testVkKeyScan(self):
|
||||
# hopefully ' ' doesn't depend on the locale!
|
||||
self.assertEqual(win32api.VkKeyScan(" "), 32)
|
||||
|
||||
def testVkKeyScanEx(self):
|
||||
# hopefully ' ' doesn't depend on the locale!
|
||||
self.assertEqual(win32api.VkKeyScanEx(" ", 0), 32)
|
||||
|
||||
def testGetSystemPowerStatus(self):
|
||||
# Dummy
|
||||
sps = win32api.GetSystemPowerStatus()
|
||||
self.assertIsInstance(sps, dict)
|
||||
test_keys = (
|
||||
"ACLineStatus",
|
||||
"BatteryFlag",
|
||||
"BatteryLifePercent",
|
||||
"SystemStatusFlag",
|
||||
"BatteryLifeTime",
|
||||
"BatteryFullLifeTime",
|
||||
)
|
||||
self.assertEqual(set(test_keys), set(sps.keys()))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
129
lib/win32/test/test_win32crypt.py
Normal file
129
lib/win32/test/test_win32crypt.py
Normal file
|
@ -0,0 +1,129 @@
|
|||
# Test module for win32crypt
|
||||
|
||||
import contextlib
|
||||
import unittest
|
||||
from typing import Any, Iterator
|
||||
|
||||
import win32crypt
|
||||
from pywin32_testutil import TestSkipped, find_test_fixture, testmain
|
||||
from win32cryptcon import *
|
||||
|
||||
|
||||
class Crypt(unittest.TestCase):
|
||||
def testSimple(self):
|
||||
data = b"My test data"
|
||||
entropy = None
|
||||
desc = "My description"
|
||||
flags = 0
|
||||
ps = None
|
||||
blob = win32crypt.CryptProtectData(data, desc, entropy, None, ps, flags)
|
||||
got_desc, got_data = win32crypt.CryptUnprotectData(
|
||||
blob, entropy, None, ps, flags
|
||||
)
|
||||
self.assertEqual(data, got_data)
|
||||
self.assertEqual(desc, got_desc)
|
||||
|
||||
def testEntropy(self):
|
||||
data = b"My test data"
|
||||
entropy = b"My test entropy"
|
||||
desc = "My description"
|
||||
flags = 0
|
||||
ps = None
|
||||
blob = win32crypt.CryptProtectData(data, desc, entropy, None, ps, flags)
|
||||
got_desc, got_data = win32crypt.CryptUnprotectData(
|
||||
blob, entropy, None, ps, flags
|
||||
)
|
||||
self.assertEqual(data, got_data)
|
||||
self.assertEqual(desc, got_desc)
|
||||
|
||||
|
||||
# via https://github.com/mhammond/pywin32/issues/1859
|
||||
_LOCAL_MACHINE = "LocalMachine"
|
||||
_CURRENT_USER = "CurrentUser"
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def open_windows_certstore(store_name: str, store_location: str) -> Iterator[Any]:
|
||||
"""Open a windows certificate store
|
||||
|
||||
:param store_name: store name
|
||||
:param store_location: store location
|
||||
:return: handle to cert store
|
||||
"""
|
||||
handle = None
|
||||
try:
|
||||
handle = win32crypt.CertOpenStore(
|
||||
CERT_STORE_PROV_SYSTEM,
|
||||
0,
|
||||
None,
|
||||
CERT_SYSTEM_STORE_LOCAL_MACHINE
|
||||
if store_location == _LOCAL_MACHINE
|
||||
else CERT_SYSTEM_STORE_CURRENT_USER,
|
||||
store_name,
|
||||
)
|
||||
yield handle
|
||||
finally:
|
||||
if handle is not None:
|
||||
handle.CertCloseStore()
|
||||
|
||||
|
||||
class TestCerts(unittest.TestCase):
|
||||
def readCertFile(self, file_name):
|
||||
with open(find_test_fixture(file_name), "rb") as f:
|
||||
buf = bytearray(f.read())
|
||||
return win32crypt.CryptQueryObject(
|
||||
CERT_QUERY_OBJECT_BLOB,
|
||||
buf,
|
||||
CERT_QUERY_CONTENT_FLAG_CERT,
|
||||
CERT_QUERY_FORMAT_FLAG_ALL,
|
||||
0,
|
||||
)
|
||||
|
||||
def testReadCertFiles(self):
|
||||
# readCertFile has Python read the file and load it as a blob.
|
||||
# win32crypt can read the file directly - let's check that works too
|
||||
# (ideally we'd compare the 2 approaches etc, but the objects don't support
|
||||
# equality checks etc, so this will do for now.)
|
||||
# No need to do this for different filenames!
|
||||
filename = "win32crypt_testcert_base64.cer"
|
||||
cert = win32crypt.CryptQueryObject(
|
||||
CERT_QUERY_OBJECT_FILE,
|
||||
find_test_fixture(filename),
|
||||
CERT_QUERY_CONTENT_FLAG_CERT,
|
||||
CERT_QUERY_FORMAT_FLAG_ALL,
|
||||
0,
|
||||
)
|
||||
self.assertEqual(cert["FormatType"], CERT_QUERY_FORMAT_BASE64_ENCODED)
|
||||
self.assertEqual(cert["ContentType"], CERT_QUERY_CONTENT_CERT)
|
||||
|
||||
def checkCertFile(self, filename, expected_format):
|
||||
cert = self.readCertFile(filename)
|
||||
self.assertEqual(cert["FormatType"], expected_format)
|
||||
self.assertEqual(cert["ContentType"], CERT_QUERY_CONTENT_CERT)
|
||||
|
||||
with open_windows_certstore(_CURRENT_USER, "Temp") as store:
|
||||
context = store.CertAddCertificateContextToStore(
|
||||
cert["Context"], CERT_STORE_ADD_REPLACE_EXISTING
|
||||
)
|
||||
# Getting 2 certs here - main thing is we get 1!
|
||||
self.assertTrue(len(store.CertEnumCertificatesInStore()))
|
||||
self.assertFalse(len(store.CertEnumCTLsInStore()))
|
||||
context.CertFreeCertificateContext()
|
||||
try:
|
||||
context.CertFreeCertificateContext()
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
raise RuntimeError("should not be able to close the context twice")
|
||||
|
||||
def testCertBase64(self):
|
||||
self.checkCertFile(
|
||||
"win32crypt_testcert_base64.cer", CERT_QUERY_FORMAT_BASE64_ENCODED
|
||||
)
|
||||
|
||||
def testCertBinary(self):
|
||||
self.checkCertFile("win32crypt_testcert_bin.cer", CERT_QUERY_FORMAT_BINARY)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
testmain()
|
119
lib/win32/test/test_win32event.py
Normal file
119
lib/win32/test/test_win32event.py
Normal file
|
@ -0,0 +1,119 @@
|
|||
import unittest
|
||||
|
||||
import pywintypes
|
||||
import win32event
|
||||
|
||||
|
||||
class TestWaitableTimer(unittest.TestCase):
|
||||
def testWaitableFire(self):
|
||||
h = win32event.CreateWaitableTimer(None, 0, None)
|
||||
dt = -160 # 160 ns.
|
||||
win32event.SetWaitableTimer(h, dt, 0, None, None, 0)
|
||||
rc = win32event.WaitForSingleObject(h, 1000)
|
||||
self.assertEqual(rc, win32event.WAIT_OBJECT_0)
|
||||
|
||||
def testCreateWaitableTimerEx(self):
|
||||
h = win32event.CreateWaitableTimerEx(
|
||||
None,
|
||||
None,
|
||||
win32event.CREATE_WAITABLE_TIMER_HIGH_RESOLUTION,
|
||||
win32event.TIMER_ALL_ACCESS,
|
||||
)
|
||||
dt = -160 # 160 ns.
|
||||
win32event.SetWaitableTimer(h, dt, 0, None, None, 0)
|
||||
rc = win32event.WaitForSingleObject(h, 1000)
|
||||
self.assertEqual(rc, win32event.WAIT_OBJECT_0)
|
||||
|
||||
def testWaitableTrigger(self):
|
||||
h = win32event.CreateWaitableTimer(None, 0, None)
|
||||
# for the sake of this, pass a long that doesn't fit in an int.
|
||||
dt = -2000000000
|
||||
win32event.SetWaitableTimer(h, dt, 0, None, None, 0)
|
||||
rc = win32event.WaitForSingleObject(h, 10) # 10 ms.
|
||||
self.assertEqual(rc, win32event.WAIT_TIMEOUT)
|
||||
|
||||
def testWaitableError(self):
|
||||
h = win32event.CreateWaitableTimer(None, 0, None)
|
||||
h.close()
|
||||
self.assertRaises(
|
||||
pywintypes.error, win32event.SetWaitableTimer, h, -42, 0, None, None, 0
|
||||
)
|
||||
|
||||
|
||||
class TestWaitFunctions(unittest.TestCase):
|
||||
def testMsgWaitForMultipleObjects(self):
|
||||
# this function used to segfault when called with an empty list
|
||||
res = win32event.MsgWaitForMultipleObjects([], 0, 0, 0)
|
||||
self.assertEqual(res, win32event.WAIT_TIMEOUT)
|
||||
|
||||
def testMsgWaitForMultipleObjects2(self):
|
||||
# test with non-empty list
|
||||
event = win32event.CreateEvent(None, 0, 0, None)
|
||||
res = win32event.MsgWaitForMultipleObjects([event], 0, 0, 0)
|
||||
self.assertEqual(res, win32event.WAIT_TIMEOUT)
|
||||
|
||||
def testMsgWaitForMultipleObjectsEx(self):
|
||||
# this function used to segfault when called with an empty list
|
||||
res = win32event.MsgWaitForMultipleObjectsEx([], 0, 0, 0)
|
||||
self.assertEqual(res, win32event.WAIT_TIMEOUT)
|
||||
|
||||
def testMsgWaitForMultipleObjectsEx2(self):
|
||||
# test with non-empty list
|
||||
event = win32event.CreateEvent(None, 0, 0, None)
|
||||
res = win32event.MsgWaitForMultipleObjectsEx([event], 0, 0, 0)
|
||||
self.assertEqual(res, win32event.WAIT_TIMEOUT)
|
||||
|
||||
|
||||
class TestEvent(unittest.TestCase):
|
||||
def assertSignaled(self, event):
|
||||
self.assertEqual(
|
||||
win32event.WaitForSingleObject(event, 0), win32event.WAIT_OBJECT_0
|
||||
)
|
||||
|
||||
def assertNotSignaled(self, event):
|
||||
self.assertEqual(
|
||||
win32event.WaitForSingleObject(event, 0), win32event.WAIT_TIMEOUT
|
||||
)
|
||||
|
||||
def testCreateEvent(self):
|
||||
event = win32event.CreateEvent(None, False, False, None)
|
||||
self.assertNotSignaled(event)
|
||||
event = win32event.CreateEvent(None, False, True, None)
|
||||
self.assertSignaled(event)
|
||||
self.assertNotSignaled(event)
|
||||
event = win32event.CreateEvent(None, True, True, None)
|
||||
self.assertSignaled(event)
|
||||
self.assertSignaled(event)
|
||||
|
||||
def testSetEvent(self):
|
||||
event = win32event.CreateEvent(None, True, False, None)
|
||||
self.assertNotSignaled(event)
|
||||
res = win32event.SetEvent(event)
|
||||
self.assertEqual(res, None)
|
||||
self.assertSignaled(event)
|
||||
event.close()
|
||||
self.assertRaises(pywintypes.error, win32event.SetEvent, event)
|
||||
|
||||
def testResetEvent(self):
|
||||
event = win32event.CreateEvent(None, True, True, None)
|
||||
self.assertSignaled(event)
|
||||
res = win32event.ResetEvent(event)
|
||||
self.assertEqual(res, None)
|
||||
self.assertNotSignaled(event)
|
||||
event.close()
|
||||
self.assertRaises(pywintypes.error, win32event.ResetEvent, event)
|
||||
|
||||
|
||||
class TestMutex(unittest.TestCase):
|
||||
def testReleaseMutex(self):
|
||||
mutex = win32event.CreateMutex(None, True, None)
|
||||
res = win32event.ReleaseMutex(mutex)
|
||||
self.assertEqual(res, None)
|
||||
res = win32event.WaitForSingleObject(mutex, 0)
|
||||
self.assertEqual(res, win32event.WAIT_OBJECT_0)
|
||||
mutex.close()
|
||||
self.assertRaises(pywintypes.error, win32event.ReleaseMutex, mutex)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
1085
lib/win32/test/test_win32file.py
Normal file
1085
lib/win32/test/test_win32file.py
Normal file
File diff suppressed because it is too large
Load diff
65
lib/win32/test/test_win32gui.py
Normal file
65
lib/win32/test/test_win32gui.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
# tests for win32gui
|
||||
import array
|
||||
import operator
|
||||
import unittest
|
||||
|
||||
import pywin32_testutil
|
||||
import win32gui
|
||||
|
||||
|
||||
class TestPyGetString(unittest.TestCase):
|
||||
def test_get_string(self):
|
||||
# test invalid addresses cause a ValueError rather than crash!
|
||||
self.assertRaises(ValueError, win32gui.PyGetString, 0)
|
||||
self.assertRaises(ValueError, win32gui.PyGetString, 1)
|
||||
self.assertRaises(ValueError, win32gui.PyGetString, 1, 1)
|
||||
|
||||
|
||||
class TestPyGetMemory(unittest.TestCase):
|
||||
def test_ob(self):
|
||||
# Check the PyGetMemory result and a bytes string can be compared
|
||||
test_data = b"\0\1\2\3\4\5\6"
|
||||
c = array.array("b", test_data)
|
||||
addr, buflen = c.buffer_info()
|
||||
got = win32gui.PyGetMemory(addr, buflen)
|
||||
self.assertEqual(len(got), len(test_data))
|
||||
self.assertEqual(bytes(got), test_data)
|
||||
|
||||
def test_memory_index(self):
|
||||
# Check we can index into the buffer object returned by PyGetMemory
|
||||
test_data = b"\0\1\2\3\4\5\6"
|
||||
c = array.array("b", test_data)
|
||||
addr, buflen = c.buffer_info()
|
||||
got = win32gui.PyGetMemory(addr, buflen)
|
||||
self.assertEqual(got[0], 0)
|
||||
|
||||
def test_memory_slice(self):
|
||||
# Check we can slice the buffer object returned by PyGetMemory
|
||||
test_data = b"\0\1\2\3\4\5\6"
|
||||
c = array.array("b", test_data)
|
||||
addr, buflen = c.buffer_info()
|
||||
got = win32gui.PyGetMemory(addr, buflen)
|
||||
self.assertEqual(list(got[0:3]), [0, 1, 2])
|
||||
|
||||
def test_real_view(self):
|
||||
# Do the PyGetMemory, then change the original memory, then ensure
|
||||
# the initial object we fetched sees the new value.
|
||||
test_data = b"\0\1\2\3\4\5\6"
|
||||
c = array.array("b", test_data)
|
||||
addr, buflen = c.buffer_info()
|
||||
got = win32gui.PyGetMemory(addr, buflen)
|
||||
self.assertEqual(got[0], 0)
|
||||
c[0] = 1
|
||||
self.assertEqual(got[0], 1)
|
||||
|
||||
def test_memory_not_writable(self):
|
||||
# Check the buffer object fetched by PyGetMemory isn't writable.
|
||||
test_data = b"\0\1\2\3\4\5\6"
|
||||
c = array.array("b", test_data)
|
||||
addr, buflen = c.buffer_info()
|
||||
got = win32gui.PyGetMemory(addr, buflen)
|
||||
self.assertRaises(TypeError, operator.setitem, got, 0, 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
330
lib/win32/test/test_win32guistruct.py
Normal file
330
lib/win32/test/test_win32guistruct.py
Normal file
|
@ -0,0 +1,330 @@
|
|||
import array
|
||||
import unittest
|
||||
|
||||
import pythoncom
|
||||
import win32con
|
||||
import win32gui
|
||||
import win32gui_struct
|
||||
|
||||
|
||||
class TestBase(unittest.TestCase):
|
||||
def assertDictEquals(self, d, **kw):
|
||||
checked = dict()
|
||||
for n, v in kw.items():
|
||||
self.assertEqual(v, d[n], "'%s' doesn't match: %r != %r" % (n, v, d[n]))
|
||||
checked[n] = True
|
||||
checked_keys = list(checked.keys())
|
||||
passed_keys = list(kw.keys())
|
||||
checked_keys.sort()
|
||||
passed_keys.sort()
|
||||
self.assertEqual(checked_keys, passed_keys)
|
||||
|
||||
|
||||
class TestMenuItemInfo(TestBase):
|
||||
def _testPackUnpack(self, text):
|
||||
vals = dict(
|
||||
fType=win32con.MFT_MENUBARBREAK,
|
||||
fState=win32con.MFS_CHECKED,
|
||||
wID=123,
|
||||
hSubMenu=1234,
|
||||
hbmpChecked=12345,
|
||||
hbmpUnchecked=123456,
|
||||
dwItemData=1234567,
|
||||
text=text,
|
||||
hbmpItem=321,
|
||||
)
|
||||
mii, extras = win32gui_struct.PackMENUITEMINFO(**vals)
|
||||
(
|
||||
fType,
|
||||
fState,
|
||||
wID,
|
||||
hSubMenu,
|
||||
hbmpChecked,
|
||||
hbmpUnchecked,
|
||||
dwItemData,
|
||||
text,
|
||||
hbmpItem,
|
||||
) = win32gui_struct.UnpackMENUITEMINFO(mii)
|
||||
self.assertDictEquals(
|
||||
vals,
|
||||
fType=fType,
|
||||
fState=fState,
|
||||
wID=wID,
|
||||
hSubMenu=hSubMenu,
|
||||
hbmpChecked=hbmpChecked,
|
||||
hbmpUnchecked=hbmpUnchecked,
|
||||
dwItemData=dwItemData,
|
||||
text=text,
|
||||
hbmpItem=hbmpItem,
|
||||
)
|
||||
|
||||
def testPackUnpack(self):
|
||||
self._testPackUnpack("Hello")
|
||||
|
||||
def testPackUnpackNone(self):
|
||||
self._testPackUnpack(None)
|
||||
|
||||
def testEmptyMenuItemInfo(self):
|
||||
mii, extra = win32gui_struct.EmptyMENUITEMINFO()
|
||||
(
|
||||
fType,
|
||||
fState,
|
||||
wID,
|
||||
hSubMenu,
|
||||
hbmpChecked,
|
||||
hbmpUnchecked,
|
||||
dwItemData,
|
||||
text,
|
||||
hbmpItem,
|
||||
) = win32gui_struct.UnpackMENUITEMINFO(mii)
|
||||
self.assertEqual(fType, 0)
|
||||
self.assertEqual(fState, 0)
|
||||
self.assertEqual(wID, 0)
|
||||
self.assertEqual(hSubMenu, 0)
|
||||
self.assertEqual(hbmpChecked, 0)
|
||||
self.assertEqual(hbmpUnchecked, 0)
|
||||
self.assertEqual(dwItemData, 0)
|
||||
self.assertEqual(hbmpItem, 0)
|
||||
# it's not clear if UnpackMENUITEMINFO() should ignore cch, instead
|
||||
# assuming it is a buffer size rather than 'current length' - but it
|
||||
# never has (and this gives us every \0 in the string), and actually
|
||||
# helps us test the unicode/str semantics.
|
||||
self.assertEqual(text, "\0" * len(text))
|
||||
|
||||
|
||||
class TestMenuInfo(TestBase):
|
||||
def testPackUnpack(self):
|
||||
vals = dict(dwStyle=1, cyMax=2, hbrBack=3, dwContextHelpID=4, dwMenuData=5)
|
||||
|
||||
mi = win32gui_struct.PackMENUINFO(**vals)
|
||||
(
|
||||
dwStyle,
|
||||
cyMax,
|
||||
hbrBack,
|
||||
dwContextHelpID,
|
||||
dwMenuData,
|
||||
) = win32gui_struct.UnpackMENUINFO(mi)
|
||||
|
||||
self.assertDictEquals(
|
||||
vals,
|
||||
dwStyle=dwStyle,
|
||||
cyMax=cyMax,
|
||||
hbrBack=hbrBack,
|
||||
dwContextHelpID=dwContextHelpID,
|
||||
dwMenuData=dwMenuData,
|
||||
)
|
||||
|
||||
def testEmptyMenuItemInfo(self):
|
||||
mi = win32gui_struct.EmptyMENUINFO()
|
||||
(
|
||||
dwStyle,
|
||||
cyMax,
|
||||
hbrBack,
|
||||
dwContextHelpID,
|
||||
dwMenuData,
|
||||
) = win32gui_struct.UnpackMENUINFO(mi)
|
||||
self.assertEqual(dwStyle, 0)
|
||||
self.assertEqual(cyMax, 0)
|
||||
self.assertEqual(hbrBack, 0)
|
||||
self.assertEqual(dwContextHelpID, 0)
|
||||
self.assertEqual(dwMenuData, 0)
|
||||
|
||||
|
||||
class TestTreeViewItem(TestBase):
|
||||
def _testPackUnpack(self, text):
|
||||
vals = dict(
|
||||
hitem=1,
|
||||
state=2,
|
||||
stateMask=3,
|
||||
text=text,
|
||||
image=4,
|
||||
selimage=5,
|
||||
citems=6,
|
||||
param=7,
|
||||
)
|
||||
|
||||
ti, extra = win32gui_struct.PackTVITEM(**vals)
|
||||
(
|
||||
hitem,
|
||||
state,
|
||||
stateMask,
|
||||
text,
|
||||
image,
|
||||
selimage,
|
||||
citems,
|
||||
param,
|
||||
) = win32gui_struct.UnpackTVITEM(ti)
|
||||
|
||||
self.assertDictEquals(
|
||||
vals,
|
||||
hitem=hitem,
|
||||
state=state,
|
||||
stateMask=stateMask,
|
||||
text=text,
|
||||
image=image,
|
||||
selimage=selimage,
|
||||
citems=citems,
|
||||
param=param,
|
||||
)
|
||||
|
||||
def testPackUnpack(self):
|
||||
self._testPackUnpack("Hello")
|
||||
|
||||
def testPackUnpackNone(self):
|
||||
self._testPackUnpack(None)
|
||||
|
||||
def testEmpty(self):
|
||||
ti, extras = win32gui_struct.EmptyTVITEM(0)
|
||||
(
|
||||
hitem,
|
||||
state,
|
||||
stateMask,
|
||||
text,
|
||||
image,
|
||||
selimage,
|
||||
citems,
|
||||
param,
|
||||
) = win32gui_struct.UnpackTVITEM(ti)
|
||||
self.assertEqual(hitem, 0)
|
||||
self.assertEqual(state, 0)
|
||||
self.assertEqual(stateMask, 0)
|
||||
self.assertEqual(text, "")
|
||||
self.assertEqual(image, 0)
|
||||
self.assertEqual(selimage, 0)
|
||||
self.assertEqual(citems, 0)
|
||||
self.assertEqual(param, 0)
|
||||
|
||||
|
||||
class TestListViewItem(TestBase):
|
||||
def _testPackUnpack(self, text):
|
||||
vals = dict(
|
||||
item=None,
|
||||
subItem=None,
|
||||
state=1,
|
||||
stateMask=2,
|
||||
text=text,
|
||||
image=3,
|
||||
param=4,
|
||||
indent=5,
|
||||
)
|
||||
|
||||
ti, extra = win32gui_struct.PackLVITEM(**vals)
|
||||
(
|
||||
item,
|
||||
subItem,
|
||||
state,
|
||||
stateMask,
|
||||
text,
|
||||
image,
|
||||
param,
|
||||
indent,
|
||||
) = win32gui_struct.UnpackLVITEM(ti)
|
||||
|
||||
# patch expected values.
|
||||
vals["item"] = 0
|
||||
vals["subItem"] = 0
|
||||
self.assertDictEquals(
|
||||
vals,
|
||||
item=item,
|
||||
subItem=subItem,
|
||||
state=state,
|
||||
stateMask=stateMask,
|
||||
text=text,
|
||||
image=image,
|
||||
param=param,
|
||||
indent=indent,
|
||||
)
|
||||
|
||||
def testPackUnpack(self):
|
||||
self._testPackUnpack("Hello")
|
||||
|
||||
def testPackUnpackNone(self):
|
||||
self._testPackUnpack(None)
|
||||
|
||||
def testEmpty(self):
|
||||
ti, extras = win32gui_struct.EmptyLVITEM(1, 2)
|
||||
(
|
||||
item,
|
||||
subItem,
|
||||
state,
|
||||
stateMask,
|
||||
text,
|
||||
image,
|
||||
param,
|
||||
indent,
|
||||
) = win32gui_struct.UnpackLVITEM(ti)
|
||||
self.assertEqual(item, 1)
|
||||
self.assertEqual(subItem, 2)
|
||||
self.assertEqual(state, 0)
|
||||
self.assertEqual(stateMask, 0)
|
||||
self.assertEqual(text, "")
|
||||
self.assertEqual(image, 0)
|
||||
self.assertEqual(param, 0)
|
||||
self.assertEqual(indent, 0)
|
||||
|
||||
|
||||
class TestLVColumn(TestBase):
|
||||
def _testPackUnpack(self, text):
|
||||
vals = dict(fmt=1, cx=2, text=text, subItem=3, image=4, order=5)
|
||||
|
||||
ti, extra = win32gui_struct.PackLVCOLUMN(**vals)
|
||||
fmt, cx, text, subItem, image, order = win32gui_struct.UnpackLVCOLUMN(ti)
|
||||
|
||||
self.assertDictEquals(
|
||||
vals, fmt=fmt, cx=cx, text=text, subItem=subItem, image=image, order=order
|
||||
)
|
||||
|
||||
def testPackUnpack(self):
|
||||
self._testPackUnpack("Hello")
|
||||
|
||||
def testPackUnpackNone(self):
|
||||
self._testPackUnpack(None)
|
||||
|
||||
def testEmpty(self):
|
||||
ti, extras = win32gui_struct.EmptyLVCOLUMN()
|
||||
fmt, cx, text, subItem, image, order = win32gui_struct.UnpackLVCOLUMN(ti)
|
||||
self.assertEqual(fmt, 0)
|
||||
self.assertEqual(cx, 0)
|
||||
self.assertEqual(text, "")
|
||||
self.assertEqual(subItem, 0)
|
||||
self.assertEqual(image, 0)
|
||||
self.assertEqual(order, 0)
|
||||
|
||||
|
||||
class TestDEV_BROADCAST_HANDLE(TestBase):
|
||||
def testPackUnpack(self):
|
||||
s = win32gui_struct.PackDEV_BROADCAST_HANDLE(123)
|
||||
c = array.array("b", s)
|
||||
got = win32gui_struct.UnpackDEV_BROADCAST(c.buffer_info()[0])
|
||||
self.assertEqual(got.handle, 123)
|
||||
|
||||
def testGUID(self):
|
||||
s = win32gui_struct.PackDEV_BROADCAST_HANDLE(123, guid=pythoncom.IID_IUnknown)
|
||||
c = array.array("b", s)
|
||||
got = win32gui_struct.UnpackDEV_BROADCAST(c.buffer_info()[0])
|
||||
self.assertEqual(got.handle, 123)
|
||||
self.assertEqual(got.eventguid, pythoncom.IID_IUnknown)
|
||||
|
||||
|
||||
class TestDEV_BROADCAST_DEVICEINTERFACE(TestBase):
|
||||
def testPackUnpack(self):
|
||||
s = win32gui_struct.PackDEV_BROADCAST_DEVICEINTERFACE(
|
||||
pythoncom.IID_IUnknown, "hello"
|
||||
)
|
||||
c = array.array("b", s)
|
||||
got = win32gui_struct.UnpackDEV_BROADCAST(c.buffer_info()[0])
|
||||
self.assertEqual(got.classguid, pythoncom.IID_IUnknown)
|
||||
self.assertEqual(got.name, "hello")
|
||||
|
||||
|
||||
class TestDEV_BROADCAST_VOLUME(TestBase):
|
||||
def testPackUnpack(self):
|
||||
s = win32gui_struct.PackDEV_BROADCAST_VOLUME(123, 456)
|
||||
c = array.array("b", s)
|
||||
got = win32gui_struct.UnpackDEV_BROADCAST(c.buffer_info()[0])
|
||||
self.assertEqual(got.unitmask, 123)
|
||||
self.assertEqual(got.flags, 456)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
93
lib/win32/test/test_win32inet.py
Normal file
93
lib/win32/test/test_win32inet.py
Normal file
|
@ -0,0 +1,93 @@
|
|||
import unittest
|
||||
|
||||
import winerror
|
||||
from pywin32_testutil import str2bytes # py3k-friendly helper
|
||||
from pywin32_testutil import TestSkipped, testmain
|
||||
from win32inet import *
|
||||
from win32inetcon import *
|
||||
|
||||
|
||||
class CookieTests(unittest.TestCase):
|
||||
def testCookies(self):
|
||||
data = "TestData=Test"
|
||||
InternetSetCookie("http://www.python.org", None, data)
|
||||
got = InternetGetCookie("http://www.python.org", None)
|
||||
# handle that there might already be cookies for the domain.
|
||||
bits = map(lambda x: x.strip(), got.split(";"))
|
||||
self.assertTrue(data in bits)
|
||||
|
||||
def testCookiesEmpty(self):
|
||||
try:
|
||||
InternetGetCookie("http://site-with-no-cookie.python.org", None)
|
||||
self.fail("expected win32 exception")
|
||||
except error as exc:
|
||||
self.assertEqual(exc.winerror, winerror.ERROR_NO_MORE_ITEMS)
|
||||
|
||||
|
||||
class UrlTests(unittest.TestCase):
|
||||
def testSimpleCanonicalize(self):
|
||||
ret = InternetCanonicalizeUrl("foo bar")
|
||||
self.assertEqual(ret, "foo%20bar")
|
||||
|
||||
def testLongCanonicalize(self):
|
||||
# a 4k URL causes the underlying API to request a bigger buffer"
|
||||
big = "x" * 2048
|
||||
ret = InternetCanonicalizeUrl(big + " " + big)
|
||||
self.assertEqual(ret, big + "%20" + big)
|
||||
|
||||
|
||||
class TestNetwork(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.hi = InternetOpen("test", INTERNET_OPEN_TYPE_DIRECT, None, None, 0)
|
||||
|
||||
def tearDown(self):
|
||||
self.hi.Close()
|
||||
|
||||
def testPythonDotOrg(self):
|
||||
hdl = InternetOpenUrl(
|
||||
self.hi, "http://www.python.org", None, INTERNET_FLAG_EXISTING_CONNECT
|
||||
)
|
||||
chunks = []
|
||||
while 1:
|
||||
chunk = InternetReadFile(hdl, 1024)
|
||||
if not chunk:
|
||||
break
|
||||
chunks.append(chunk)
|
||||
data = str2bytes("").join(chunks)
|
||||
assert data.find(str2bytes("Python")) > 0, repr(
|
||||
data
|
||||
) # This must appear somewhere on the main page!
|
||||
|
||||
def testFtpCommand(self):
|
||||
# ftp.python.org doesn't exist. ftp.gnu.org is what Python's urllib
|
||||
# test code uses.
|
||||
# (As of 2020 it doesn't! Unsurprisingly, it's difficult to find a good
|
||||
# test server. This test sometimes works, but often doesn't - so handle
|
||||
# failure here as a "skip")
|
||||
try:
|
||||
hcon = InternetConnect(
|
||||
self.hi,
|
||||
"ftp.gnu.org",
|
||||
INTERNET_INVALID_PORT_NUMBER,
|
||||
None,
|
||||
None, # username/password
|
||||
INTERNET_SERVICE_FTP,
|
||||
0,
|
||||
0,
|
||||
)
|
||||
try:
|
||||
hftp = FtpCommand(hcon, True, FTP_TRANSFER_TYPE_ASCII, "NLST", 0)
|
||||
try:
|
||||
print("Connected - response info is", InternetGetLastResponseInfo())
|
||||
got = InternetReadFile(hftp, 2048)
|
||||
print("Read", len(got), "bytes")
|
||||
finally:
|
||||
hftp.Close()
|
||||
finally:
|
||||
hcon.Close()
|
||||
except error as e:
|
||||
raise TestSkipped(e)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
testmain()
|
24
lib/win32/test/test_win32net.py
Normal file
24
lib/win32/test/test_win32net.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
import unittest
|
||||
|
||||
import win32net
|
||||
import win32netcon
|
||||
|
||||
|
||||
class TestCase(unittest.TestCase):
|
||||
def testGroupsGoodResume(self, server=None):
|
||||
res = 0
|
||||
level = 0 # setting it to 1 will provide more detailed info
|
||||
while True:
|
||||
(user_list, total, res) = win32net.NetGroupEnum(server, level, res)
|
||||
for i in user_list:
|
||||
pass
|
||||
if not res:
|
||||
break
|
||||
|
||||
def testGroupsBadResume(self, server=None):
|
||||
res = 1 # Can't pass this first time round.
|
||||
self.assertRaises(win32net.error, win32net.NetGroupEnum, server, 0, res)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
153
lib/win32/test/test_win32pipe.py
Normal file
153
lib/win32/test/test_win32pipe.py
Normal file
|
@ -0,0 +1,153 @@
|
|||
import threading
|
||||
import time
|
||||
import unittest
|
||||
|
||||
import pywintypes
|
||||
import win32con
|
||||
import win32event
|
||||
import win32file
|
||||
import win32pipe
|
||||
import winerror
|
||||
from pywin32_testutil import str2bytes # py3k-friendly helper
|
||||
|
||||
|
||||
class PipeTests(unittest.TestCase):
|
||||
pipename = "\\\\.\\pipe\\python_test_pipe"
|
||||
|
||||
def _serverThread(self, pipe_handle, event, wait_time):
|
||||
# just do one connection and terminate.
|
||||
hr = win32pipe.ConnectNamedPipe(pipe_handle)
|
||||
self.assertTrue(
|
||||
hr in (0, winerror.ERROR_PIPE_CONNECTED), "Got error code 0x%x" % (hr,)
|
||||
)
|
||||
hr, got = win32file.ReadFile(pipe_handle, 100)
|
||||
self.assertEqual(got, str2bytes("foo\0bar"))
|
||||
time.sleep(wait_time)
|
||||
win32file.WriteFile(pipe_handle, str2bytes("bar\0foo"))
|
||||
pipe_handle.Close()
|
||||
event.set()
|
||||
|
||||
def startPipeServer(self, event, wait_time=0):
|
||||
openMode = win32pipe.PIPE_ACCESS_DUPLEX
|
||||
pipeMode = win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT
|
||||
|
||||
sa = pywintypes.SECURITY_ATTRIBUTES()
|
||||
sa.SetSecurityDescriptorDacl(1, None, 0)
|
||||
|
||||
pipe_handle = win32pipe.CreateNamedPipe(
|
||||
self.pipename,
|
||||
openMode,
|
||||
pipeMode,
|
||||
win32pipe.PIPE_UNLIMITED_INSTANCES,
|
||||
0,
|
||||
0,
|
||||
2000,
|
||||
sa,
|
||||
)
|
||||
|
||||
threading.Thread(
|
||||
target=self._serverThread, args=(pipe_handle, event, wait_time)
|
||||
).start()
|
||||
|
||||
def testCallNamedPipe(self):
|
||||
event = threading.Event()
|
||||
self.startPipeServer(event)
|
||||
|
||||
got = win32pipe.CallNamedPipe(
|
||||
self.pipename, str2bytes("foo\0bar"), 1024, win32pipe.NMPWAIT_WAIT_FOREVER
|
||||
)
|
||||
self.assertEqual(got, str2bytes("bar\0foo"))
|
||||
event.wait(5)
|
||||
self.assertTrue(event.isSet(), "Pipe server thread didn't terminate")
|
||||
|
||||
def testTransactNamedPipeBlocking(self):
|
||||
event = threading.Event()
|
||||
self.startPipeServer(event)
|
||||
open_mode = win32con.GENERIC_READ | win32con.GENERIC_WRITE
|
||||
|
||||
hpipe = win32file.CreateFile(
|
||||
self.pipename,
|
||||
open_mode,
|
||||
0, # no sharing
|
||||
None, # default security
|
||||
win32con.OPEN_EXISTING,
|
||||
0, # win32con.FILE_FLAG_OVERLAPPED,
|
||||
None,
|
||||
)
|
||||
|
||||
# set to message mode.
|
||||
win32pipe.SetNamedPipeHandleState(
|
||||
hpipe, win32pipe.PIPE_READMODE_MESSAGE, None, None
|
||||
)
|
||||
|
||||
hr, got = win32pipe.TransactNamedPipe(hpipe, str2bytes("foo\0bar"), 1024, None)
|
||||
self.assertEqual(got, str2bytes("bar\0foo"))
|
||||
event.wait(5)
|
||||
self.assertTrue(event.isSet(), "Pipe server thread didn't terminate")
|
||||
|
||||
def testTransactNamedPipeBlockingBuffer(self):
|
||||
# Like testTransactNamedPipeBlocking, but a pre-allocated buffer is
|
||||
# passed (not really that useful, but it exercises the code path)
|
||||
event = threading.Event()
|
||||
self.startPipeServer(event)
|
||||
open_mode = win32con.GENERIC_READ | win32con.GENERIC_WRITE
|
||||
|
||||
hpipe = win32file.CreateFile(
|
||||
self.pipename,
|
||||
open_mode,
|
||||
0, # no sharing
|
||||
None, # default security
|
||||
win32con.OPEN_EXISTING,
|
||||
0, # win32con.FILE_FLAG_OVERLAPPED,
|
||||
None,
|
||||
)
|
||||
|
||||
# set to message mode.
|
||||
win32pipe.SetNamedPipeHandleState(
|
||||
hpipe, win32pipe.PIPE_READMODE_MESSAGE, None, None
|
||||
)
|
||||
|
||||
buffer = win32file.AllocateReadBuffer(1024)
|
||||
hr, got = win32pipe.TransactNamedPipe(
|
||||
hpipe, str2bytes("foo\0bar"), buffer, None
|
||||
)
|
||||
self.assertEqual(got, str2bytes("bar\0foo"))
|
||||
event.wait(5)
|
||||
self.assertTrue(event.isSet(), "Pipe server thread didn't terminate")
|
||||
|
||||
def testTransactNamedPipeAsync(self):
|
||||
event = threading.Event()
|
||||
overlapped = pywintypes.OVERLAPPED()
|
||||
overlapped.hEvent = win32event.CreateEvent(None, 0, 0, None)
|
||||
self.startPipeServer(event, 0.5)
|
||||
open_mode = win32con.GENERIC_READ | win32con.GENERIC_WRITE
|
||||
|
||||
hpipe = win32file.CreateFile(
|
||||
self.pipename,
|
||||
open_mode,
|
||||
0, # no sharing
|
||||
None, # default security
|
||||
win32con.OPEN_EXISTING,
|
||||
win32con.FILE_FLAG_OVERLAPPED,
|
||||
None,
|
||||
)
|
||||
|
||||
# set to message mode.
|
||||
win32pipe.SetNamedPipeHandleState(
|
||||
hpipe, win32pipe.PIPE_READMODE_MESSAGE, None, None
|
||||
)
|
||||
|
||||
buffer = win32file.AllocateReadBuffer(1024)
|
||||
hr, got = win32pipe.TransactNamedPipe(
|
||||
hpipe, str2bytes("foo\0bar"), buffer, overlapped
|
||||
)
|
||||
self.assertEqual(hr, winerror.ERROR_IO_PENDING)
|
||||
nbytes = win32file.GetOverlappedResult(hpipe, overlapped, True)
|
||||
got = buffer[:nbytes]
|
||||
self.assertEqual(got, str2bytes("bar\0foo"))
|
||||
event.wait(5)
|
||||
self.assertTrue(event.isSet(), "Pipe server thread didn't terminate")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
24
lib/win32/test/test_win32print.py
Normal file
24
lib/win32/test/test_win32print.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Tests (scarce) for win32print module
|
||||
|
||||
import unittest
|
||||
|
||||
import win32print as wprn
|
||||
|
||||
|
||||
class Win32PrintTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.printer_idx = 0
|
||||
self.printer_levels_all = list(range(1, 10))
|
||||
self.local_printers = wprn.EnumPrinters(wprn.PRINTER_ENUM_LOCAL, None, 1)
|
||||
|
||||
def test_printer_levels_read_dummy(self):
|
||||
if not self.local_printers:
|
||||
print("Test didn't run (no local printers)!")
|
||||
return
|
||||
ph = wprn.OpenPrinter(self.local_printers[self.printer_idx][2])
|
||||
for level in self.printer_levels_all:
|
||||
wprn.GetPrinter(ph, level)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
18
lib/win32/test/test_win32profile.py
Normal file
18
lib/win32/test/test_win32profile.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
"""Test win32profile"""
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import win32profile
|
||||
|
||||
|
||||
class Tester(unittest.TestCase):
|
||||
def test_environment(self):
|
||||
os.environ["FOO"] = "bar=baz"
|
||||
env = win32profile.GetEnvironmentStrings()
|
||||
assert "FOO" in env
|
||||
assert env["FOO"] == "bar=baz"
|
||||
assert os.environ["FOO"] == "bar=baz"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
70
lib/win32/test/test_win32rcparser.py
Normal file
70
lib/win32/test/test_win32rcparser.py
Normal file
|
@ -0,0 +1,70 @@
|
|||
import os
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import win32con
|
||||
import win32rcparser
|
||||
|
||||
|
||||
class TestParser(unittest.TestCase):
|
||||
def setUp(self):
|
||||
rc_file = os.path.join(os.path.dirname(__file__), "win32rcparser", "test.rc")
|
||||
self.resources = win32rcparser.Parse(rc_file)
|
||||
|
||||
def testStrings(self):
|
||||
for sid, expected in (
|
||||
("IDS_TEST_STRING4", "Test 'single quoted' string"),
|
||||
("IDS_TEST_STRING1", 'Test "quoted" string'),
|
||||
("IDS_TEST_STRING3", 'String with single " quote'),
|
||||
("IDS_TEST_STRING2", "Test string"),
|
||||
):
|
||||
got = self.resources.stringTable[sid].value
|
||||
self.assertEqual(got, expected)
|
||||
|
||||
def testStandardIds(self):
|
||||
for idc in "IDOK IDCANCEL".split():
|
||||
correct = getattr(win32con, idc)
|
||||
self.assertEqual(self.resources.names[correct], idc)
|
||||
self.assertEqual(self.resources.ids[idc], correct)
|
||||
|
||||
def testTabStop(self):
|
||||
d = self.resources.dialogs["IDD_TEST_DIALOG2"]
|
||||
tabstop_names = ["IDC_EDIT1", "IDOK"] # should have WS_TABSTOP
|
||||
tabstop_ids = [self.resources.ids[name] for name in tabstop_names]
|
||||
notabstop_names = ["IDC_EDIT2"] # should have WS_TABSTOP
|
||||
notabstop_ids = [self.resources.ids[name] for name in notabstop_names]
|
||||
num_ok = 0
|
||||
for cdef in d[1:]: # skip dlgdef
|
||||
# print cdef
|
||||
cid = cdef[2]
|
||||
style = cdef[-2]
|
||||
styleex = cdef[-1]
|
||||
if cid in tabstop_ids:
|
||||
self.assertEqual(style & win32con.WS_TABSTOP, win32con.WS_TABSTOP)
|
||||
num_ok += 1
|
||||
elif cid in notabstop_ids:
|
||||
self.assertEqual(style & win32con.WS_TABSTOP, 0)
|
||||
num_ok += 1
|
||||
self.assertEqual(num_ok, len(tabstop_ids) + len(notabstop_ids))
|
||||
|
||||
|
||||
class TestGenerated(TestParser):
|
||||
def setUp(self):
|
||||
# don't call base!
|
||||
rc_file = os.path.join(os.path.dirname(__file__), "win32rcparser", "test.rc")
|
||||
py_file = tempfile.mktemp("test_win32rcparser.py")
|
||||
try:
|
||||
win32rcparser.GenerateFrozenResource(rc_file, py_file)
|
||||
py_source = open(py_file).read()
|
||||
finally:
|
||||
if os.path.isfile(py_file):
|
||||
os.unlink(py_file)
|
||||
|
||||
# poor-man's import :)
|
||||
globs = {}
|
||||
exec(py_source, globs, globs)
|
||||
self.resources = globs["FakeParser"]()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
27
lib/win32/test/test_win32timezone.py
Normal file
27
lib/win32/test/test_win32timezone.py
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Test module for win32timezone
|
||||
|
||||
import doctest
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
import win32timezone
|
||||
|
||||
|
||||
class Win32TimeZoneTest(unittest.TestCase):
|
||||
def testWin32TZ(self):
|
||||
# On 3.7 and later, the repr() for datetime objects changed to use kwargs - eg,
|
||||
# eg, `datetime.timedelta(0, 10800)` is now `datetime.timedelta(seconds=10800)`.
|
||||
# So we just skip the tests on 3.5 and 3.6
|
||||
if sys.version_info < (3, 7):
|
||||
from pywin32_testutil import TestSkipped
|
||||
|
||||
raise TestSkipped(
|
||||
"The repr() for datetime objects makes this test fail in 3.5 and 3.6"
|
||||
)
|
||||
|
||||
failed, total = doctest.testmod(win32timezone, verbose=False)
|
||||
self.assertFalse(failed)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
369
lib/win32/test/test_win32trace.py
Normal file
369
lib/win32/test/test_win32trace.py
Normal file
|
@ -0,0 +1,369 @@
|
|||
import os
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
import unittest
|
||||
|
||||
import win32trace
|
||||
from pywin32_testutil import TestSkipped
|
||||
|
||||
if __name__ == "__main__":
|
||||
this_file = sys.argv[0]
|
||||
else:
|
||||
this_file = __file__
|
||||
|
||||
|
||||
def SkipIfCI():
|
||||
# This test often fails in CI, probably when it is being run multiple times
|
||||
# (ie, for different Python versions)
|
||||
# Github actions always have a `CI` variable.
|
||||
if "CI" in os.environ:
|
||||
raise TestSkipped("We skip this test on CI")
|
||||
|
||||
|
||||
def CheckNoOtherReaders():
|
||||
win32trace.write("Hi")
|
||||
time.sleep(0.05)
|
||||
if win32trace.read() != "Hi":
|
||||
# Reset everything so following tests still fail with this error!
|
||||
win32trace.TermRead()
|
||||
win32trace.TermWrite()
|
||||
raise RuntimeError(
|
||||
"An existing win32trace reader appears to be "
|
||||
"running - please stop this process and try again"
|
||||
)
|
||||
|
||||
|
||||
class TestInitOps(unittest.TestCase):
|
||||
def setUp(self):
|
||||
SkipIfCI()
|
||||
# clear old data
|
||||
win32trace.InitRead()
|
||||
win32trace.read()
|
||||
win32trace.TermRead()
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
win32trace.TermRead()
|
||||
except win32trace.error:
|
||||
pass
|
||||
try:
|
||||
win32trace.TermWrite()
|
||||
except win32trace.error:
|
||||
pass
|
||||
|
||||
def testInitTermRead(self):
|
||||
self.assertRaises(win32trace.error, win32trace.read)
|
||||
win32trace.InitRead()
|
||||
result = win32trace.read()
|
||||
self.assertEqual(result, "")
|
||||
win32trace.TermRead()
|
||||
self.assertRaises(win32trace.error, win32trace.read)
|
||||
|
||||
win32trace.InitRead()
|
||||
self.assertRaises(win32trace.error, win32trace.InitRead)
|
||||
win32trace.InitWrite()
|
||||
self.assertRaises(win32trace.error, win32trace.InitWrite)
|
||||
win32trace.TermWrite()
|
||||
win32trace.TermRead()
|
||||
|
||||
def testInitTermWrite(self):
|
||||
self.assertRaises(win32trace.error, win32trace.write, "Hei")
|
||||
win32trace.InitWrite()
|
||||
win32trace.write("Johan Galtung")
|
||||
win32trace.TermWrite()
|
||||
self.assertRaises(win32trace.error, win32trace.write, "Hei")
|
||||
|
||||
def testTermSematics(self):
|
||||
win32trace.InitWrite()
|
||||
win32trace.write("Ta da")
|
||||
|
||||
# if we both Write and Read are terminated at the same time,
|
||||
# we lose the data as the win32 object is closed. Note that
|
||||
# if another writer is running, we do *not* lose the data - so
|
||||
# test for either the correct data or an empty string
|
||||
win32trace.TermWrite()
|
||||
win32trace.InitRead()
|
||||
self.assertTrue(win32trace.read() in ("Ta da", ""))
|
||||
win32trace.TermRead()
|
||||
|
||||
# we keep the data because we init read before terminating write
|
||||
win32trace.InitWrite()
|
||||
win32trace.write("Ta da")
|
||||
win32trace.InitRead()
|
||||
win32trace.TermWrite()
|
||||
self.assertEqual("Ta da", win32trace.read())
|
||||
win32trace.TermRead()
|
||||
|
||||
|
||||
class BasicSetupTearDown(unittest.TestCase):
|
||||
def setUp(self):
|
||||
SkipIfCI()
|
||||
win32trace.InitRead()
|
||||
# If any other writers are running (even if not actively writing),
|
||||
# terminating the module will *not* close the handle, meaning old data
|
||||
# will remain. This can cause other tests to fail.
|
||||
win32trace.read()
|
||||
win32trace.InitWrite()
|
||||
|
||||
def tearDown(self):
|
||||
win32trace.TermWrite()
|
||||
win32trace.TermRead()
|
||||
|
||||
|
||||
class TestModuleOps(BasicSetupTearDown):
|
||||
def testRoundTrip(self):
|
||||
win32trace.write("Syver Enstad")
|
||||
syverEnstad = win32trace.read()
|
||||
self.assertEqual("Syver Enstad", syverEnstad)
|
||||
|
||||
def testRoundTripUnicode(self):
|
||||
win32trace.write("\xa9opyright Syver Enstad")
|
||||
syverEnstad = win32trace.read()
|
||||
# str objects are always returned in py2k (latin-1 encoding was used
|
||||
# on unicode objects)
|
||||
self.assertEqual("\xa9opyright Syver Enstad", syverEnstad)
|
||||
|
||||
def testBlockingRead(self):
|
||||
win32trace.write("Syver Enstad")
|
||||
self.assertEqual("Syver Enstad", win32trace.blockingread())
|
||||
|
||||
def testBlockingReadUnicode(self):
|
||||
win32trace.write("\xa9opyright Syver Enstad")
|
||||
# str objects are always returned in py2k (latin-1 encoding was used
|
||||
# on unicode objects)
|
||||
self.assertEqual("\xa9opyright Syver Enstad", win32trace.blockingread())
|
||||
|
||||
def testFlush(self):
|
||||
win32trace.flush()
|
||||
|
||||
|
||||
class TestTraceObjectOps(BasicSetupTearDown):
|
||||
def testInit(self):
|
||||
win32trace.TermRead()
|
||||
win32trace.TermWrite()
|
||||
traceObject = win32trace.GetTracer()
|
||||
self.assertRaises(win32trace.error, traceObject.read)
|
||||
self.assertRaises(win32trace.error, traceObject.write, "")
|
||||
win32trace.InitRead()
|
||||
win32trace.InitWrite()
|
||||
self.assertEqual("", traceObject.read())
|
||||
traceObject.write("Syver")
|
||||
|
||||
def testFlush(self):
|
||||
traceObject = win32trace.GetTracer()
|
||||
traceObject.flush()
|
||||
|
||||
def testIsatty(self):
|
||||
tracer = win32trace.GetTracer()
|
||||
assert tracer.isatty() == False
|
||||
|
||||
def testRoundTrip(self):
|
||||
traceObject = win32trace.GetTracer()
|
||||
traceObject.write("Syver Enstad")
|
||||
self.assertEqual("Syver Enstad", traceObject.read())
|
||||
|
||||
|
||||
class WriterThread(threading.Thread):
|
||||
def run(self):
|
||||
self.writeCount = 0
|
||||
for each in range(self.BucketCount):
|
||||
win32trace.write(str(each))
|
||||
self.writeCount = self.BucketCount
|
||||
|
||||
def verifyWritten(self):
|
||||
return self.writeCount == self.BucketCount
|
||||
|
||||
|
||||
class TestMultipleThreadsWriting(unittest.TestCase):
|
||||
# FullBucket is the thread count
|
||||
FullBucket = 50
|
||||
BucketCount = 9 # buckets must be a single digit number (ie. less than 10)
|
||||
|
||||
def setUp(self):
|
||||
SkipIfCI()
|
||||
WriterThread.BucketCount = self.BucketCount
|
||||
win32trace.InitRead()
|
||||
win32trace.read() # clear any old data.
|
||||
win32trace.InitWrite()
|
||||
CheckNoOtherReaders()
|
||||
self.threads = [WriterThread() for each in range(self.FullBucket)]
|
||||
self.buckets = list(range(self.BucketCount))
|
||||
for each in self.buckets:
|
||||
self.buckets[each] = 0
|
||||
|
||||
def tearDown(self):
|
||||
win32trace.TermRead()
|
||||
win32trace.TermWrite()
|
||||
|
||||
def areBucketsFull(self):
|
||||
bucketsAreFull = True
|
||||
for each in self.buckets:
|
||||
assert each <= self.FullBucket, each
|
||||
if each != self.FullBucket:
|
||||
bucketsAreFull = False
|
||||
break
|
||||
return bucketsAreFull
|
||||
|
||||
def read(self):
|
||||
while 1:
|
||||
readString = win32trace.blockingread()
|
||||
for ch in readString:
|
||||
integer = int(ch)
|
||||
count = self.buckets[integer]
|
||||
assert count != -1
|
||||
self.buckets[integer] = count + 1
|
||||
if self.buckets[integer] == self.FullBucket:
|
||||
if self.areBucketsFull():
|
||||
return
|
||||
|
||||
def testThreads(self):
|
||||
for each in self.threads:
|
||||
each.start()
|
||||
self.read()
|
||||
for each in self.threads:
|
||||
each.join()
|
||||
for each in self.threads:
|
||||
assert each.verifyWritten()
|
||||
assert self.areBucketsFull()
|
||||
|
||||
|
||||
class TestHugeChunks(unittest.TestCase):
|
||||
# BiggestChunk is the size where we stop stressing the writer
|
||||
BiggestChunk = 2**16 # 256k should do it.
|
||||
|
||||
def setUp(self):
|
||||
SkipIfCI()
|
||||
win32trace.InitRead()
|
||||
win32trace.read() # clear any old data
|
||||
win32trace.InitWrite()
|
||||
|
||||
def testHugeChunks(self):
|
||||
data = "*" * 1023 + "\n"
|
||||
while len(data) <= self.BiggestChunk:
|
||||
win32trace.write(data)
|
||||
data = data + data
|
||||
# If we made it here, we passed.
|
||||
|
||||
def tearDown(self):
|
||||
win32trace.TermRead()
|
||||
win32trace.TermWrite()
|
||||
|
||||
|
||||
import win32event
|
||||
import win32process
|
||||
|
||||
|
||||
class TraceWriteProcess:
|
||||
def __init__(self, threadCount):
|
||||
self.exitCode = -1
|
||||
self.threadCount = threadCount
|
||||
|
||||
def start(self):
|
||||
procHandle, threadHandle, procId, threadId = win32process.CreateProcess(
|
||||
None, # appName
|
||||
'python.exe "%s" /run_test_process %s %s'
|
||||
% (this_file, self.BucketCount, self.threadCount),
|
||||
None, # process security
|
||||
None, # thread security
|
||||
0, # inherit handles
|
||||
win32process.NORMAL_PRIORITY_CLASS,
|
||||
None, # new environment
|
||||
None, # Current directory
|
||||
win32process.STARTUPINFO(), # startup info
|
||||
)
|
||||
self.processHandle = procHandle
|
||||
|
||||
def join(self):
|
||||
win32event.WaitForSingleObject(self.processHandle, win32event.INFINITE)
|
||||
self.exitCode = win32process.GetExitCodeProcess(self.processHandle)
|
||||
|
||||
def verifyWritten(self):
|
||||
return self.exitCode == 0
|
||||
|
||||
|
||||
class TestOutofProcess(unittest.TestCase):
|
||||
BucketCount = 9
|
||||
FullBucket = 50
|
||||
|
||||
def setUp(self):
|
||||
SkipIfCI()
|
||||
win32trace.InitRead()
|
||||
TraceWriteProcess.BucketCount = self.BucketCount
|
||||
self.setUpWriters()
|
||||
self.buckets = list(range(self.BucketCount))
|
||||
for each in self.buckets:
|
||||
self.buckets[each] = 0
|
||||
|
||||
def tearDown(self):
|
||||
win32trace.TermRead()
|
||||
|
||||
def setUpWriters(self):
|
||||
self.processes = []
|
||||
# 5 processes, quot threads in each process
|
||||
quot, remainder = divmod(self.FullBucket, 5)
|
||||
for each in range(5):
|
||||
self.processes.append(TraceWriteProcess(quot))
|
||||
if remainder:
|
||||
self.processes.append(TraceWriteProcess(remainder))
|
||||
|
||||
def areBucketsFull(self):
|
||||
bucketsAreFull = True
|
||||
for each in self.buckets:
|
||||
assert each <= self.FullBucket, each
|
||||
if each != self.FullBucket:
|
||||
bucketsAreFull = False
|
||||
break
|
||||
return bucketsAreFull
|
||||
|
||||
def read(self):
|
||||
while 1:
|
||||
readString = win32trace.blockingread()
|
||||
for ch in readString:
|
||||
integer = int(ch)
|
||||
count = self.buckets[integer]
|
||||
assert count != -1
|
||||
self.buckets[integer] = count + 1
|
||||
if self.buckets[integer] == self.FullBucket:
|
||||
if self.areBucketsFull():
|
||||
return
|
||||
|
||||
def testProcesses(self):
|
||||
for each in self.processes:
|
||||
each.start()
|
||||
self.read()
|
||||
for each in self.processes:
|
||||
each.join()
|
||||
for each in self.processes:
|
||||
assert each.verifyWritten()
|
||||
assert self.areBucketsFull()
|
||||
|
||||
|
||||
def _RunAsTestProcess():
|
||||
# Run as an external process by the main tests.
|
||||
WriterThread.BucketCount = int(sys.argv[2])
|
||||
threadCount = int(sys.argv[3])
|
||||
threads = [WriterThread() for each in range(threadCount)]
|
||||
win32trace.InitWrite()
|
||||
for t in threads:
|
||||
t.start()
|
||||
for t in threads:
|
||||
t.join()
|
||||
for t in threads:
|
||||
if not t.verifyWritten():
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if sys.argv[1:2] == ["/run_test_process"]:
|
||||
_RunAsTestProcess()
|
||||
sys.exit(0)
|
||||
# If some other win32traceutil reader is running, these tests fail
|
||||
# badly (as the other reader sometimes sees the output!)
|
||||
win32trace.InitRead()
|
||||
win32trace.InitWrite()
|
||||
CheckNoOtherReaders()
|
||||
# reset state so test env is back to normal
|
||||
win32trace.TermRead()
|
||||
win32trace.TermWrite()
|
||||
unittest.main()
|
175
lib/win32/test/test_win32wnet.py
Normal file
175
lib/win32/test/test_win32wnet.py
Normal file
|
@ -0,0 +1,175 @@
|
|||
import unittest
|
||||
|
||||
import netbios
|
||||
import win32api
|
||||
import win32wnet
|
||||
from pywin32_testutil import str2bytes
|
||||
|
||||
RESOURCE_CONNECTED = 0x00000001
|
||||
RESOURCE_GLOBALNET = 0x00000002
|
||||
RESOURCE_REMEMBERED = 0x00000003
|
||||
RESOURCE_RECENT = 0x00000004
|
||||
RESOURCE_CONTEXT = 0x00000005
|
||||
RESOURCETYPE_ANY = 0x00000000
|
||||
RESOURCETYPE_DISK = 0x00000001
|
||||
RESOURCETYPE_PRINT = 0x00000002
|
||||
RESOURCETYPE_RESERVED = 0x00000008
|
||||
RESOURCETYPE_UNKNOWN = 0xFFFFFFFF
|
||||
RESOURCEUSAGE_CONNECTABLE = 0x00000001
|
||||
RESOURCEUSAGE_CONTAINER = 0x00000002
|
||||
RESOURCEDISPLAYTYPE_GENERIC = 0x00000000
|
||||
RESOURCEDISPLAYTYPE_DOMAIN = 0x00000001
|
||||
RESOURCEDISPLAYTYPE_SERVER = 0x00000002
|
||||
RESOURCEDISPLAYTYPE_SHARE = 0x00000003
|
||||
|
||||
|
||||
NETRESOURCE_attributes = [
|
||||
("dwScope", int),
|
||||
("dwType", int),
|
||||
("dwDisplayType", int),
|
||||
("dwUsage", int),
|
||||
("lpLocalName", str),
|
||||
("lpRemoteName", str),
|
||||
("lpComment", str),
|
||||
("lpProvider", str),
|
||||
]
|
||||
|
||||
NCB_attributes = [
|
||||
("Command", int),
|
||||
("Retcode", int),
|
||||
("Lsn", int),
|
||||
("Num", int),
|
||||
# ("Bufflen", int), - read-only
|
||||
("Callname", str),
|
||||
("Name", str),
|
||||
("Rto", int),
|
||||
("Sto", int),
|
||||
("Lana_num", int),
|
||||
("Cmd_cplt", int),
|
||||
("Event", int),
|
||||
("Post", int),
|
||||
]
|
||||
|
||||
|
||||
class TestCase(unittest.TestCase):
|
||||
def testGetUser(self):
|
||||
self.assertEqual(win32api.GetUserName(), win32wnet.WNetGetUser())
|
||||
|
||||
def _checkItemAttributes(self, item, attrs):
|
||||
for attr, typ in attrs:
|
||||
val = getattr(item, attr)
|
||||
if typ is int:
|
||||
self.assertTrue(
|
||||
type(val) in (int,), "Attr %r has value %r" % (attr, val)
|
||||
)
|
||||
new_val = val + 1
|
||||
elif typ is str:
|
||||
if val is not None:
|
||||
# on py2k, must be string or unicode. py3k must be string or bytes.
|
||||
self.assertTrue(
|
||||
type(val) in (str, str), "Attr %r has value %r" % (attr, val)
|
||||
)
|
||||
new_val = val + " new value"
|
||||
else:
|
||||
new_val = "new value"
|
||||
else:
|
||||
self.fail("Don't know what %s is" % (typ,))
|
||||
# set the attribute just to make sure we can.
|
||||
setattr(item, attr, new_val)
|
||||
|
||||
def testNETRESOURCE(self):
|
||||
nr = win32wnet.NETRESOURCE()
|
||||
self._checkItemAttributes(nr, NETRESOURCE_attributes)
|
||||
|
||||
def testWNetEnumResource(self):
|
||||
handle = win32wnet.WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, None)
|
||||
try:
|
||||
while 1:
|
||||
items = win32wnet.WNetEnumResource(handle, 0)
|
||||
if len(items) == 0:
|
||||
break
|
||||
for item in items:
|
||||
self._checkItemAttributes(item, NETRESOURCE_attributes)
|
||||
finally:
|
||||
handle.Close()
|
||||
|
||||
def testNCB(self):
|
||||
ncb = win32wnet.NCB()
|
||||
self._checkItemAttributes(ncb, NCB_attributes)
|
||||
|
||||
def testNetbios(self):
|
||||
# taken from the demo code in netbios.py
|
||||
ncb = win32wnet.NCB()
|
||||
ncb.Command = netbios.NCBENUM
|
||||
la_enum = netbios.LANA_ENUM()
|
||||
ncb.Buffer = la_enum
|
||||
rc = win32wnet.Netbios(ncb)
|
||||
self.assertEqual(rc, 0)
|
||||
for i in range(la_enum.length):
|
||||
ncb.Reset()
|
||||
ncb.Command = netbios.NCBRESET
|
||||
ncb.Lana_num = netbios.byte_to_int(la_enum.lana[i])
|
||||
rc = Netbios(ncb)
|
||||
self.assertEqual(rc, 0)
|
||||
ncb.Reset()
|
||||
ncb.Command = netbios.NCBASTAT
|
||||
ncb.Lana_num = byte_to_int(la_enum.lana[i])
|
||||
ncb.Callname = str2bytes("* ") # ensure bytes on py2x and 3k
|
||||
adapter = netbios.ADAPTER_STATUS()
|
||||
ncb.Buffer = adapter
|
||||
Netbios(ncb)
|
||||
# expect 6 bytes in the mac address.
|
||||
self.assertTrue(len(adapter.adapter_address), 6)
|
||||
|
||||
def iterConnectableShares(self):
|
||||
nr = win32wnet.NETRESOURCE()
|
||||
nr.dwScope = RESOURCE_GLOBALNET
|
||||
nr.dwUsage = RESOURCEUSAGE_CONTAINER
|
||||
nr.lpRemoteName = "\\\\" + win32api.GetComputerName()
|
||||
|
||||
handle = win32wnet.WNetOpenEnum(RESOURCE_GLOBALNET, RESOURCETYPE_ANY, 0, nr)
|
||||
while 1:
|
||||
items = win32wnet.WNetEnumResource(handle, 0)
|
||||
if len(items) == 0:
|
||||
break
|
||||
for item in items:
|
||||
if item.dwDisplayType == RESOURCEDISPLAYTYPE_SHARE:
|
||||
yield item
|
||||
|
||||
def findUnusedDriveLetter(self):
|
||||
existing = [
|
||||
x[0].lower() for x in win32api.GetLogicalDriveStrings().split("\0") if x
|
||||
]
|
||||
handle = win32wnet.WNetOpenEnum(RESOURCE_REMEMBERED, RESOURCETYPE_DISK, 0, None)
|
||||
try:
|
||||
while 1:
|
||||
items = win32wnet.WNetEnumResource(handle, 0)
|
||||
if len(items) == 0:
|
||||
break
|
||||
xtra = [i.lpLocalName[0].lower() for i in items if i.lpLocalName]
|
||||
existing.extend(xtra)
|
||||
finally:
|
||||
handle.Close()
|
||||
for maybe in "defghijklmnopqrstuvwxyz":
|
||||
if maybe not in existing:
|
||||
return maybe
|
||||
self.fail("All drive mappings are taken?")
|
||||
|
||||
def testAddConnection(self):
|
||||
localName = self.findUnusedDriveLetter() + ":"
|
||||
for share in self.iterConnectableShares():
|
||||
share.lpLocalName = localName
|
||||
win32wnet.WNetAddConnection2(share)
|
||||
win32wnet.WNetCancelConnection2(localName, 0, 0)
|
||||
break
|
||||
|
||||
def testAddConnectionOld(self):
|
||||
localName = self.findUnusedDriveLetter() + ":"
|
||||
for share in self.iterConnectableShares():
|
||||
win32wnet.WNetAddConnection2(share.dwType, localName, share.lpRemoteName)
|
||||
win32wnet.WNetCancelConnection2(localName, 0, 0)
|
||||
break
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
230
lib/win32/test/testall.py
Normal file
230
lib/win32/test/testall.py
Normal file
|
@ -0,0 +1,230 @@
|
|||
import os
|
||||
import re
|
||||
import sys
|
||||
import traceback
|
||||
import unittest
|
||||
|
||||
import pywin32_testutil
|
||||
|
||||
# A list of demos that depend on user-interface of *any* kind. Tests listed
|
||||
# here are not suitable for unattended testing.
|
||||
ui_demos = """GetSaveFileName print_desktop win32cred_demo win32gui_demo
|
||||
win32gui_dialog win32gui_menu win32gui_taskbar
|
||||
win32rcparser_demo winprocess win32console_demo
|
||||
win32clipboard_bitmapdemo
|
||||
win32gui_devicenotify
|
||||
NetValidatePasswordPolicy""".split()
|
||||
# Other demos known as 'bad' (or at least highly unlikely to work)
|
||||
# cerapi: no CE module is built (CE via pywin32 appears dead)
|
||||
# desktopmanager: hangs (well, hangs for 60secs or so...)
|
||||
# EvtSubscribe_*: must be run together:
|
||||
# SystemParametersInfo: a couple of the params cause markh to hang, and there's
|
||||
# no great reason to adjust (twice!) all those system settings!
|
||||
bad_demos = """cerapi desktopmanager win32comport_demo
|
||||
EvtSubscribe_pull EvtSubscribe_push
|
||||
SystemParametersInfo
|
||||
""".split()
|
||||
|
||||
argvs = {
|
||||
"rastest": ("-l",),
|
||||
}
|
||||
|
||||
no_user_interaction = True
|
||||
|
||||
# re to pull apart an exception line into the exception type and the args.
|
||||
re_exception = re.compile("([a-zA-Z0-9_.]*): (.*)$")
|
||||
|
||||
|
||||
def find_exception_in_output(data):
|
||||
have_traceback = False
|
||||
for line in data.splitlines():
|
||||
line = line.decode("ascii") # not sure what the correct encoding is...
|
||||
if line.startswith("Traceback ("):
|
||||
have_traceback = True
|
||||
continue
|
||||
if line.startswith(" "):
|
||||
continue
|
||||
if have_traceback:
|
||||
# first line not starting with a space since the traceback.
|
||||
# must be the exception!
|
||||
m = re_exception.match(line)
|
||||
if m:
|
||||
exc_type, args = m.groups()
|
||||
# get hacky - get the *real* exception object from the name.
|
||||
bits = exc_type.split(".", 1)
|
||||
if len(bits) > 1:
|
||||
mod = __import__(bits[0])
|
||||
exc = getattr(mod, bits[1])
|
||||
else:
|
||||
# probably builtin
|
||||
exc = eval(bits[0])
|
||||
else:
|
||||
# hrm - probably just an exception with no args
|
||||
try:
|
||||
exc = eval(line.strip())
|
||||
args = "()"
|
||||
except:
|
||||
return None
|
||||
# try and turn the args into real args.
|
||||
try:
|
||||
args = eval(args)
|
||||
except:
|
||||
pass
|
||||
if not isinstance(args, tuple):
|
||||
args = (args,)
|
||||
# try and instantiate the exception.
|
||||
try:
|
||||
ret = exc(*args)
|
||||
except:
|
||||
ret = None
|
||||
return ret
|
||||
# apparently not - keep looking...
|
||||
have_traceback = False
|
||||
|
||||
|
||||
class TestRunner:
|
||||
def __init__(self, argv):
|
||||
self.argv = argv
|
||||
self.__name__ = "Test Runner for cmdline {}".format(argv)
|
||||
|
||||
def __call__(self):
|
||||
import subprocess
|
||||
|
||||
p = subprocess.Popen(
|
||||
self.argv, stdout=subprocess.PIPE, stderr=subprocess.STDOUT
|
||||
)
|
||||
output, _ = p.communicate()
|
||||
rc = p.returncode
|
||||
|
||||
if rc:
|
||||
base = os.path.basename(self.argv[1])
|
||||
# See if we can detect and reconstruct an exception in the output.
|
||||
reconstituted = find_exception_in_output(output)
|
||||
if reconstituted is not None:
|
||||
raise reconstituted
|
||||
raise AssertionError(
|
||||
"%s failed with exit code %s. Output is:\n%s" % (base, rc, output)
|
||||
)
|
||||
|
||||
|
||||
def get_demo_tests():
|
||||
import win32api
|
||||
|
||||
ret = []
|
||||
demo_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "Demos"))
|
||||
assert os.path.isdir(demo_dir), demo_dir
|
||||
for name in os.listdir(demo_dir):
|
||||
base, ext = os.path.splitext(name)
|
||||
if base in ui_demos and no_user_interaction:
|
||||
continue
|
||||
# Skip any other files than .py and bad tests in any case
|
||||
if ext != ".py" or base in bad_demos:
|
||||
continue
|
||||
argv = (sys.executable, os.path.join(demo_dir, base + ".py")) + argvs.get(
|
||||
base, ()
|
||||
)
|
||||
ret.append(
|
||||
unittest.FunctionTestCase(
|
||||
TestRunner(argv), description="win32/demos/" + name
|
||||
)
|
||||
)
|
||||
return ret
|
||||
|
||||
|
||||
def import_all():
|
||||
# Some hacks for import order - dde depends on win32ui
|
||||
try:
|
||||
import win32ui
|
||||
except ImportError:
|
||||
pass # 'what-ev-a....'
|
||||
|
||||
import win32api
|
||||
|
||||
dir = os.path.dirname(win32api.__file__)
|
||||
num = 0
|
||||
is_debug = os.path.basename(win32api.__file__).endswith("_d")
|
||||
for name in os.listdir(dir):
|
||||
base, ext = os.path.splitext(name)
|
||||
# handle `modname.cp310-win_amd64.pyd` etc
|
||||
base = base.split(".")[0]
|
||||
if (
|
||||
(ext == ".pyd")
|
||||
and name != "_winxptheme.pyd"
|
||||
and (
|
||||
is_debug
|
||||
and base.endswith("_d")
|
||||
or not is_debug
|
||||
and not base.endswith("_d")
|
||||
)
|
||||
):
|
||||
try:
|
||||
__import__(base)
|
||||
except:
|
||||
print("FAILED to import", name)
|
||||
raise
|
||||
num += 1
|
||||
|
||||
|
||||
def suite():
|
||||
# Loop over all .py files here, except me :)
|
||||
try:
|
||||
me = __file__
|
||||
except NameError:
|
||||
me = sys.argv[0]
|
||||
me = os.path.abspath(me)
|
||||
files = os.listdir(os.path.dirname(me))
|
||||
suite = unittest.TestSuite()
|
||||
suite.addTest(unittest.FunctionTestCase(import_all))
|
||||
for file in files:
|
||||
base, ext = os.path.splitext(file)
|
||||
if ext == ".py" and os.path.basename(me) != file:
|
||||
try:
|
||||
mod = __import__(base)
|
||||
except:
|
||||
print("FAILED to import test module %r" % base)
|
||||
traceback.print_exc()
|
||||
continue
|
||||
if hasattr(mod, "suite"):
|
||||
test = mod.suite()
|
||||
else:
|
||||
test = unittest.defaultTestLoader.loadTestsFromModule(mod)
|
||||
suite.addTest(test)
|
||||
for test in get_demo_tests():
|
||||
suite.addTest(test)
|
||||
return suite
|
||||
|
||||
|
||||
class CustomLoader(pywin32_testutil.TestLoader):
|
||||
def loadTestsFromModule(self, module):
|
||||
return self.fixupTestsForLeakTests(suite())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="Test runner for PyWin32/win32")
|
||||
parser.add_argument(
|
||||
"-no-user-interaction",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="(This is now the default - use `-user-interaction` to include them)",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
"-user-interaction",
|
||||
action="store_true",
|
||||
help="Include tests which require user interaction",
|
||||
)
|
||||
|
||||
parsed_args, remains = parser.parse_known_args()
|
||||
|
||||
if parsed_args.no_user_interaction:
|
||||
print(
|
||||
"Note: -no-user-interaction is now the default, run with `-user-interaction` to include them."
|
||||
)
|
||||
|
||||
no_user_interaction = not parsed_args.user_interaction
|
||||
|
||||
sys.argv = [sys.argv[0]] + remains
|
||||
|
||||
pywin32_testutil.testmain(testLoader=CustomLoader())
|
BIN
lib/win32/test/win32rcparser/python.bmp
Normal file
BIN
lib/win32/test/win32rcparser/python.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 778 B |
BIN
lib/win32/test/win32rcparser/python.ico
Normal file
BIN
lib/win32/test/win32rcparser/python.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 766 B |
46
lib/win32/test/win32rcparser/test.h
Normal file
46
lib/win32/test/win32rcparser/test.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by test.rc
|
||||
//
|
||||
#define IDS_TEST_STRING1 51
|
||||
#define IDS_TEST_STRING2 52
|
||||
#define IDS_TEST_STRING3 53
|
||||
#define IDS_TEST_STRING4 54
|
||||
#define IDS_TEST_STRING5 55
|
||||
#define IDS_TEST_STRING6 56
|
||||
#define IDS_TEST_STRING7 57
|
||||
#define IDD_TEST_DIALOG1 101
|
||||
#define IDD_TEST_DIALOG2 102
|
||||
#define IDB_PYTHON 103
|
||||
#define IDI_PYTHON 105
|
||||
#define IDD_TEST_DIALOG3 105
|
||||
#define IDC_EDIT1 1000
|
||||
#define IDC_CHECK1 1001
|
||||
#define IDC_EDIT2 1001
|
||||
#define IDC_COMBO1 1002
|
||||
#define IDC_SPIN1 1003
|
||||
#define IDC_PROGRESS1 1004
|
||||
#define IDC_SLIDER1 1005
|
||||
#define IDC_LIST1 1006
|
||||
#define IDC_TREE1 1007
|
||||
#define IDC_TAB1 1008
|
||||
#define IDC_ANIMATE1 1009
|
||||
#define IDC_RICHEDIT1 1010
|
||||
#define IDC_DATETIMEPICKER1 1011
|
||||
#define IDC_MONTHCALENDAR1 1012
|
||||
#define IDC_SCROLLBAR1 1013
|
||||
#define IDC_SCROLLBAR2 1014
|
||||
#define IDC_LIST2 1015
|
||||
#define IDC_HELLO 1016
|
||||
#define IDC_HELLO2 1017
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 107
|
||||
#define _APS_NEXT_COMMAND_VALUE 40002
|
||||
#define _APS_NEXT_CONTROL_VALUE 1018
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
216
lib/win32/test/win32rcparser/test.rc
Normal file
216
lib/win32/test/win32rcparser/test.rc
Normal file
|
@ -0,0 +1,216 @@
|
|||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "test.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "afxres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (Australia) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENA)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"test.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""afxres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_TEST_DIALOG1 DIALOG DISCARDABLE 0, 0, 186, 95
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Test Dialog"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,129,7,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14
|
||||
ICON IDI_PYTHON,IDC_STATIC,142,47,21,20
|
||||
LTEXT "An icon",IDC_STATIC,140,70,34,9
|
||||
END
|
||||
|
||||
IDD_TEST_DIALOG2 DIALOG DISCARDABLE 0, 0, 186, 95
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Test Dialog"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "OK",IDOK,129,7,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14,NOT WS_TABSTOP
|
||||
CONTROL 103,IDC_STATIC,"Static",SS_BITMAP,139,49,32,32
|
||||
LTEXT "A bitmap",IDC_STATIC,135,72,34,9
|
||||
EDITTEXT IDC_EDIT1,59,7,59,14,ES_AUTOHSCROLL
|
||||
EDITTEXT IDC_EDIT2,59,31,60,15,ES_AUTOHSCROLL | NOT WS_TABSTOP
|
||||
LTEXT "Tabstop",IDC_STATIC,7,9,43,10
|
||||
LTEXT "Not Tabstop",IDC_STATIC,7,33,43,10
|
||||
END
|
||||
|
||||
IDD_TEST_DIALOG3 DIALOGEX 0, 0, 232, 310
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Dialog"
|
||||
FONT 8, "MS Sans Serif", 0, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Frame",IDC_STATIC,7,7,218,41
|
||||
LTEXT "Left Static",IDC_STATIC,16,17,73,11
|
||||
EDITTEXT IDC_EDIT1,103,15,112,12,ES_AUTOHSCROLL
|
||||
LTEXT "Right Static",IDC_STATIC,16,30,73,11,0,WS_EX_RIGHT
|
||||
CONTROL "",IDC_RICHEDIT1,"RICHEDIT",ES_AUTOHSCROLL | WS_BORDER |
|
||||
WS_TABSTOP,103,31,113,14
|
||||
CONTROL "Check1",IDC_CHECK1,"Button",BS_AUTOCHECKBOX |
|
||||
WS_TABSTOP,7,52,68,12
|
||||
COMBOBOX IDC_COMBO1,85,52,82,35,CBS_DROPDOWNLIST | CBS_SORT |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
CONTROL "Spin1",IDC_SPIN1,"msctls_updown32",UDS_ARROWKEYS,7,71,
|
||||
14,22
|
||||
CONTROL "Progress1",IDC_PROGRESS1,"msctls_progress32",WS_BORDER,
|
||||
39,72,153,13
|
||||
SCROLLBAR IDC_SCROLLBAR2,207,55,13,57,SBS_VERT
|
||||
CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH |
|
||||
TBS_NOTICKS | WS_TABSTOP,35,91,159,7
|
||||
SCROLLBAR IDC_SCROLLBAR1,37,102,155,11
|
||||
CONTROL "Tab1",IDC_TAB1,"SysTabControl32",0x0,7,120,217,43
|
||||
CONTROL "Animate1",IDC_ANIMATE1,"SysAnimate32",WS_BORDER |
|
||||
WS_TABSTOP,7,171,46,42
|
||||
CONTROL "List1",IDC_LIST1,"SysListView32",WS_BORDER | WS_TABSTOP,
|
||||
63,171,53,43
|
||||
CONTROL "Tree1",IDC_TREE1,"SysTreeView32",WS_BORDER | WS_TABSTOP,
|
||||
126,171,50,43
|
||||
CONTROL "MonthCalendar1",IDC_MONTHCALENDAR1,"SysMonthCal32",
|
||||
MCS_NOTODAY | WS_TABSTOP,7,219,140,84
|
||||
CONTROL "DateTimePicker1",IDC_DATETIMEPICKER1,"SysDateTimePick32",
|
||||
DTS_RIGHTALIGN | WS_TABSTOP,174,221,51,15
|
||||
DEFPUSHBUTTON "OK",IDOK,175,289,50,14
|
||||
PUSHBUTTON "Hello",IDC_HELLO,175,271,50,14
|
||||
PUSHBUTTON "Hello",IDC_HELLO2,175,240,50,26,BS_ICON
|
||||
LISTBOX IDC_LIST2,184,171,40,45,LBS_SORT | LBS_NOINTEGRALHEIGHT |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO DISCARDABLE
|
||||
BEGIN
|
||||
IDD_TEST_DIALOG1, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 179
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 88
|
||||
END
|
||||
|
||||
IDD_TEST_DIALOG2, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 179
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 88
|
||||
END
|
||||
|
||||
IDD_TEST_DIALOG3, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 225
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 303
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_PYTHON ICON DISCARDABLE "python.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Bitmap
|
||||
//
|
||||
|
||||
IDB_PYTHON BITMAP DISCARDABLE "python.bmp"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog Info
|
||||
//
|
||||
|
||||
IDD_TEST_DIALOG3 DLGINIT
|
||||
BEGIN
|
||||
IDC_COMBO1, 0x403, 6, 0
|
||||
0x7449, 0x6d65, 0x0031,
|
||||
IDC_COMBO1, 0x403, 6, 0
|
||||
0x7449, 0x6d65, 0x0032,
|
||||
0
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_TEST_STRING1 "Test ""quoted"" string"
|
||||
IDS_TEST_STRING2 "Test string"
|
||||
IDS_TEST_STRING3 "String with single "" quote"
|
||||
IDS_TEST_STRING4 "Test 'single quoted' string"
|
||||
END
|
||||
|
||||
#endif // English (Australia) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue