| Server IP : 123.56.80.60 / Your IP : 216.73.216.33 Web Server : Apache/2.4.54 (Win32) OpenSSL/1.1.1s PHP/7.4.33 mod_fcgid/2.3.10-dev System : Windows NT iZhx3sob14hnz7Z 10.0 build 14393 (Windows Server 2016) i586 User : SYSTEM ( 0) PHP Version : 7.4.33 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/Program Files/python/Scripts/ |
Upload File : |
"""Unit tests for WMI modules
Some tests are optional, since they rely on remote machines and
usernames / passwords. To enable these, copy wmitest.master.ini
to wmitest.ini and set the parameters you have available.
The watcher tests spawn temporary processes and temporary
logical drives. These may get left behind.
"""
#
# TODO:
# - Test for negative timezone
# - Test for share name with embedded single quote
#
import os, sys
import datetime
try:
import ConfigParser
except ImportError:
import configparser as ConfigParser
import operator
try:
import Queue
except ImportError:
import queue as Queue
try:
next
except NameError:
def next(iterator): return iterator.next()
import subprocess
import tempfile
import threading
import time
import unittest
import warnings
try:
import _winreg
except ImportError:
import winreg as _winreg
import pythoncom
import win32api
import win32con
import win32file
import wmi
ini = ConfigParser.SafeConfigParser()
ini.read(["wmitest.master.ini", "wmitest.ini"])
settings = {}
if ini.has_section("settings"):
settings.update(ini.items("settings"))
excludes = [i.strip() for i in settings.get("excludes", "").split(",")]
COMPUTERS = [None, "."]
if "machine" in settings:
COMPUTERS.append(settings['machine'])
IMPERSONATION_LEVELS = [None, "identify", "impersonate", "delegate"]
AUTHENTICATION_LEVELS = [None, "default", "none", "connect", "call", "pkt", "pktintegrity", "pktprivacy"]
AUTHORITIES = [None]
if set(["domain", "machine"]) <= set(settings):
#~ AUTHORITIES.append("kerberos:%s" % settings['domain'])
AUTHORITIES.append("ntlmdomain:%s" % settings['domain'])
PRIVILEGES = [None, ['security', '!shutdown']]
NAMESPACES = [None, "root/cimv2", "default"]
class TestBasicConnections(unittest.TestCase):
def test_basic_connection(self):
"Check that a standard connection works"
self.assert_(wmi.WMI())
def test_remote_connection(self):
"Check that a remote connection works, if specified"
if "machine" in settings:
self.assert_(wmi.WMI(settings['machine']))
else:
warnings.warn("Skipping test_remote_connection")
def test_simple_moniker(self):
"Check that a simple moniker works"
self.assert_(wmi.WMI(moniker="winmgmts:"))
def test_moniker_with_class(self):
"Check that specifying a class in moniker works"
c0 = wmi.WMI().Win32_ComputerSystem
c1 = wmi.WMI(moniker="winmgmts:Win32_ComputerSystem")
self.assert_(c0 == c1)
def test_moniker_with_instance(self):
"Check that specifying an instance in the moniker works"
for c0 in wmi.WMI().Win32_ComputerSystem():
break
c1 = wmi.WMI(moniker='winmgmts:Win32_ComputerSystem.Name="%s"' % c0.Name)
self.assert_(c0 == c1)
def test_impersonation_levels(self):
"Check that specifying an impersonation level works"
for impersonation in IMPERSONATION_LEVELS:
self.assert_(wmi.WMI(impersonation_level=impersonation))
def test_authentication_levels(self):
"Check that specifying an authentication level works"
for authentication in AUTHENTICATION_LEVELS:
try:
c = wmi.WMI(authentication_level=authentication)
except wmi.x_access_denied:
warnings.warn("Access denied for authentication level %s" % authentication)
else:
self.assert_(c)
def test_authority(self):
"Check that specifying an authority works"
for authority in AUTHORITIES:
self.assert_(wmi.WMI(authority=authority))
def test_privileges(self):
"Check that specifying privileges works"
for privileges in PRIVILEGES:
self.assert_(wmi.WMI(privileges=privileges))
def test_namespace(self):
"Check that specifying a namespace works"
for namespace in NAMESPACES:
self.assert_(wmi.WMI(namespace=namespace))
def test_suffix(self):
"Check that a suffix returns the class of that name"
self.assert_(wmi.WMI(namespace="DEFAULT", suffix="StdRegProv") == wmi.WMI(namespace="DEFAULT").StdRegProv)
def test_user_password(self):
"Check that username & password are passed through for a remote connection"
if set(["machine", "user", "password"]) <= set(settings):
self.assert_(wmi.WMI(computer=settings['machine'], user=settings['user'], password=settings['password']))
else:
warnings.warn("Skipping test_user_password because no machine, user or password")
def test_too_much_authentication(self):
"Check that user/password plus privs / suffix raises exception"
self.assertRaises(wmi.x_wmi_authentication, wmi.WMI, computer='***', user="***", password="***", privileges=["***"])
self.assertRaises(wmi.x_wmi_authentication, wmi.WMI, computer='***', user="***", password="***", suffix="***")
def test_user_password_with_impersonation_level(self):
"Check that an impersonation level works with a username / password"
if not(set(["machine", "user", "password"]) <= set(settings)):
warnings.warn("Skipping test_user_password_with_impersonation_level because no machine, user or password")
else:
self.assert_(
wmi.WMI(
computer=settings['machine'],
user=settings['user'],
password=settings['password'],
impersonation_level="impersonate"
)
)
def test_user_password_with_invalid_impersonation_level(self):
"Check that an impersonation level works with a username / password"
if not(set(["machine", "user", "password"]) <= set(settings)):
warnings.warn("Skipping test_user_password_with_invalid_impersonation_level because no machine, user or password")
else:
self.assertRaises(
wmi.x_wmi_authentication,
wmi.WMI,
computer=settings['machine'],
user=settings['user'],
password=settings['password'],
impersonation_level="***"
)
def test_user_password_with_authentication_level(self):
"Check that an invalid impersonation level raises x_wmi_authentication"
if not(set(["machine", "user", "password"]) <= set(settings)):
warnings.warn("Skipping test_user_password_with_authentication_level because no machine, user or password")
else:
self.assert_(
wmi.WMI(
computer=settings['machine'],
user=settings['user'],
password=settings['password'],
authentication_level="pktIntegrity"
)
)
def test_user_password_with_invalid_authentication_level(self):
"Check that an invalid authentication level raises x_wmi_authentication"
if not(set(["machine", "user", "password"]) <= set(settings)):
warnings.warn("Skipping test_user_password_with_invalid_authentication_level because no machine, user or password")
else:
self.assertRaises(
wmi.x_wmi_authentication,
wmi.WMI,
computer=settings['machine'],
user=settings['user'],
password=settings['password'],
authentication_level="***"
)
def test_local_user_password(self):
"Check that user/password for local connection raises exception"
self.assertRaises(wmi.x_wmi_authentication, wmi.WMI, user="***", password="***")
def test_find_classes(self):
"Check ability to switch class scan on and off"
self.assert_(wmi.WMI(find_classes=True)._classes)
self.assertFalse(wmi.WMI(find_classes=False)._classes)
def test_find_classes_false(self):
"By default, don't scan for classes but load them on demand"
self.assertFalse(wmi.WMI()._classes)
self.assert_(wmi.WMI().classes)
def test_classes_acts_as_list(self):
self.assert_(wmi.WMI().classes.index)
def test_classes_acts_as_dict(self):
self.assert_(wmi.WMI().classes.keys)
class TestThreadedConnection(unittest.TestCase):
def test_initialised_thread(self):
"""A WMI connection in a thread which has been initialised for COM
should succeed.
"""
def f(q):
pythoncom.CoInitialize()
try:
try:
wmi.WMI()
except:
q.put(False)
else:
q.put(True)
finally:
pythoncom.CoUninitialize()
q = Queue.Queue()
threading.Thread(target=f, args=(q,)).start()
self.assert_(q.get())
def test_uninitialised_thread(self):
"""A WMI connection in a thread which has not been initialised
for COM should fail with a wmi-specific exception.
"""
def f(q):
try:
wmi.WMI()
except wmi.x_wmi_uninitialised_thread:
q.put(True)
except:
q.put(False)
else:
q.put(False)
q = Queue.Queue()
threading.Thread(target=f, args=(q,)).start()
self.assert_(q.get())
class TestMoniker(unittest.TestCase):
def test_moniker(self):
"""Look at all possible options for moniker construction and pass
them through to a WMI connector
"""
for computer in COMPUTERS:
if computer in (None, "."):
local_authorities = [None]
else:
local_authorities = AUTHORITIES
for impersonation_level in IMPERSONATION_LEVELS:
for authentication_level in AUTHENTICATION_LEVELS:
for authority in local_authorities:
for privileges in PRIVILEGES:
for namespace in NAMESPACES:
moniker = wmi.construct_moniker(
computer=computer,
impersonation_level=impersonation_level,
authority=authority,
privileges=privileges,
namespace=namespace
)
self.assert_(wmi.WMI(moniker=moniker), "Moniker failed: %s" % moniker)
def test_moniker_root_namespace(self):
"Check that namespace is prefixed by root if needed"
self.assertEquals(wmi.construct_moniker(namespace="default"), "winmgmts:root/default")
self.assertEquals(wmi.construct_moniker(namespace="root/default"), "winmgmts:root/default")
class TestFunctions(unittest.TestCase):
times = [
((2000, 1, 1), "20000101******.******+***"),
((2000, 1, 1, 10, 0, 0), "20000101100000.******+***"),
((2000, 1, 1, 10, 0, 0, 100), "20000101100000.000100+***"),
((2000, 1, 1, 10, 0, 0, 100, "GMT"), "20000101100000.000100+GMT")
]
def test_signed_to_unsigned(self):
tests = [
(0, 0),
(-1, 0xffffffff),
(+1, 1),
(0x7fffffff, 0x7fffffff),
(-0x7fffffff, 0x80000001)
]
for signed, unsigned in tests:
self.assertEquals(wmi.signed_to_unsigned(signed), unsigned)
def test_from_1601(self):
"Check conversion from 100-ns intervals since 1601(!)"
self.assertEquals(wmi.from_1601(0), datetime.datetime(1601, 1, 1))
self.assertEquals(wmi.from_1601(24 * 60 * 60 * 10 * 1000 * 1000), datetime.datetime(1601, 1, 2))
def test_from_time(self):
"Check conversion from time-tuple to time-string"
for t, s in self.times:
self.assertEquals(wmi.from_time(*t), s)
def test_to_time(self):
"Check conversion from time-string to time-tuple"
for t, s in self.times:
t = tuple(list(t) +([None] * 8))[:8]
self.assertEquals(wmi.to_time(s), t)
def test_get_wmi_type(self):
"Check that namespace, class & instance are identified correctly"
self.assertEquals(wmi.get_wmi_type(wmi.WMI()), "namespace")
self.assertEquals(wmi.get_wmi_type(wmi.WMI().Win32_ComputerSystem), "class")
for i in wmi.WMI().Win32_ComputerSystem():
self.assertEquals(wmi.get_wmi_type(i), "instance")
def test_registry(self):
"""Convenience Registry function is identical to picking
the StdRegProv class out of the DEFAULT namespace"""
self.assertEquals(wmi.Registry(), wmi.WMI(namespace="DEFAULT").StdRegProv)
class TestWMI(unittest.TestCase):
def setUp(self):
self.connection = wmi.WMI(namespace="root/cimv2", find_classes=False)
self.logical_disks = set(self.connection.Win32_LogicalDisk())
class TestNamespace(TestWMI):
def test_subclasses_of_simple(self):
self.assert_("Win32_ComputerSystem" in self.connection.subclasses_of())
def test_subclasses_of_subtree(self):
self.assert_("Win32_Desktop" in self.connection.subclasses_of("CIM_Setting"))
def test_subclasses_of_pattern(self):
self.assert_(set(["Win32_LogicalDisk", "Win32_MappedLogicalDisk"]) <= set(self.connection.subclasses_of("CIM_LogicalDevice", "Win32_.*Disk")))
def test_instances(self):
self.assertEquals(self.logical_disks, set(self.connection.instances("Win32_LogicalDisk")))
def test_new(self):
"Check this is an alias for the new method of the equivalent class"
self.assertEquals(self.connection.new("Win32_Process")._instance_of, self.connection.Win32_Process)
def test_query(self):
self.assertEquals(self.logical_disks, set(self.connection.query("SELECT * FROM Win32_LogicalDisk")))
def test_ipython_attributes_with_find_classes(self):
connection = wmi.WMI(find_classes=True)
self.assertEquals(sorted(connection._getAttributeNames()), sorted(i for i in connection.classes if not i.startswith("__")))
def test_getattr(self):
"Check that WMI classes are returned by attribute access on their namespace"
connection = wmi.WMI(find_classes=True)
for c in list(connection.classes)[:5]:
wmi_class = getattr(connection, c)
self.assert_(isinstance(wmi_class, wmi._wmi_class))
self.assertEquals(wmi_class._class_name, c)
def test_watch_for(self):
"""Check that the watch_for method returns a watcher. The watcher itself
will be tested elsewhere.
"""
watcher = self.connection.watch_for(
wmi_class="Win32_Process"
)
self.assert_(isinstance(watcher, wmi._wmi_watcher))
class TestClass(TestWMI):
def test_class_from_namespace(self):
self.assert_(self.connection.Win32_ComputerSystem._namespace is self.connection)
def test_class_without_namespace(self):
wmi_class = wmi.GetObject("winmgmts:Win32_ComputerSystem")
self.assert_(wmi._wmi_class(None, wmi_class)._namespace)
def test_query(self):
self.assertEquals(
set(self.connection.Win32_ComputerSystem.query()),
set(self.connection.query("SELECT * FROM Win32_ComputerSystem"))
)
def test_query_with_where(self):
this_drive = os.getcwd()[:2]
for drive in self.connection.Win32_LogicalDisk(Name=this_drive):
self.assertEquals(drive.Name, this_drive)
def test_query_with_fields(self):
this_drive = os.getcwd()[:2]
properties = set(["MediaType"])
self.assert_("Name" not in properties)
for drive in self.connection.Win32_LogicalDisk(properties, Name=this_drive):
self.assertEquals(set(drive.properties), set(properties))
self.assert_(drive.MediaType)
self.assertRaises(AttributeError, getattr, drive, "Name")
def test_watch_for(self):
"""Check that the watch_for method returns a watcher. The watcher itself
will be tested elsewhere.
"""
watcher = self.connection.Win32_Process.watch_for()
self.assert_(isinstance(watcher, wmi._wmi_watcher))
def test_instances(self):
self.assertEquals(
set(self.connection.Win32_LogicalDisk()),
set(self.connection.Win32_LogicalDisk.instances())
)
def test_new(self):
process = self.connection.Win32_Process.new()
self.assertEquals(wmi.get_wmi_type(process), "instance")
self.assertEquals(process._instance_of, self.connection.Win32_process)
class TestWatcher(TestWMI):
def new_letter(self):
return \
set("%s:" % chr(i) for i in range(ord('A'), 1 + ord('Z'))).\
difference(d.DeviceID for d in self.connection.Win32_LogicalDisk()).\
pop()
@staticmethod
def create(new_letter):
#~ print("about to create drive with letter", new_letter)
here = os.path.dirname(os.path.abspath(__file__))
win32file.DefineDosDevice(0, new_letter, here)
try:
#
# This sleep is needed for the WMI pollster to react
#
time.sleep(2)
finally:
win32file.DefineDosDevice(2, new_letter, here)
def test_creation(self):
try:
new_letter = self.new_letter()
except KeyError:
warnings.warn("Unable to find a spare drive letter to map.")
return
watcher = self.connection.Win32_LogicalDisk.watch_for(
notification_type="Creation",
DeviceID=new_letter
)
t = threading.Timer(2, self.create,(new_letter,))
t.start()
found_disk = watcher(timeout_ms=20000)
self.assert_(isinstance(found_disk, wmi._wmi_object))
self.assertEqual(found_disk.Caption, new_letter)
t.join()
def test_event_with_no_params(self):
try:
new_letter = self.new_letter()
except KeyError:
warnings.warn("Unable to find a spare drive letter to map.")
return
#
# This watcher will return *any* logical disk with some activity. To
# make sure there is at least some, we'll create a new logical disk
# but there's no guarantee that this will be the one returned, as
# activity on, eg, the C: drive will be enough to trigger the event.
#
watcher = self.connection.Win32_LogicalDisk.watch_for()
t = threading.Timer(2, self.create,(new_letter,))
t.start()
found_disk = watcher(timeout_ms=20000)
self.assert_(isinstance(found_disk, wmi._wmi_object))
self.assertEqual(found_disk.path().Class, "Win32_LogicalDisk")
t.join()
def test_valid_notification_types(self):
for notification_type in ['operation', 'modification', 'creation', 'deletion']:
self.assert_(self.connection.Win32_LogicalDisk.watch_for(notification_type=notification_type))
def test_invalid_notification_types(self):
self.assertRaises(wmi.x_wmi, self.connection.Win32_LogicalDisk.watch_for, notification_type="***")
def do_not_test_extrinsic_event(self):
#
# This doesn't seem implementable at the moment
# as a test. I can't find a reproducible extrinsic
# event except for Win32_DeviceChangeEvent and that
# one would require someone to, eg, plug in / unplug
# a USB stick.
#
# It looks as though Win32_ProcessStartTrace should work
# and it does on my laptop; just not on my desktop.
#
def _create(queue):
queue.put(subprocess.Popen([sys.executable, "-c", "import time; time.sleep(10)"]))
watcher = self.connection.Win32_ProcessStartTrace.watch_for(
fields=["*"]##,
#~ ProcessName=os.path.basename(sys.executable)
)
q = Queue.Queue()
t = threading.Timer(2, _create,(q,))
try:
t.start()
found_process = watcher(timeout_ms=20000)
spawned_process = q.get_nowait()
self.assert_(isinstance(found_process, wmi._wmi_event))
self.assertEqual(int(found_process.ProcessID), spawned_process.pid)
finally:
t.cancel()
class TestMethods(TestWMI):
def test_exists(self):
"Check that a well-known method is available by attribute"
self.assert_(self.connection.Win32_Process.Create)
def test_params(self):
"Check that the names and arrayness of params are picked up when not arrays"
self.assertEquals(
[(n, False) for n in ["CommandLine", "CurrentDirectory", "ProcessStartupInformation"]],
self.connection.Win32_Process.Create.in_parameter_names
)
self.assertEquals(
[("ProcessId", False),("ReturnValue", False)],
self.connection.Win32_Process.Create.out_parameter_names
)
def test_positional_params(self):
dir = tempfile.mkdtemp()
filename = "abc.txt"
contents = str(datetime.datetime.now())
handle, result = self.connection.Win32_Process.Create(
"cmd /c echo %s > %s" %(contents, filename),
dir,
self.connection.Win32_ProcessStartup.new(ShowWindow=0)
)
time.sleep(0.5)
with open(os.path.join(dir, filename)) as f:
self.assertEqual(f.read(), contents + " \n")
def test_named_params(self):
dir = tempfile.mkdtemp()
filename = "abc.txt"
contents = str(datetime.datetime.now())
handle, result = self.connection.Win32_Process.Create(
ProcessStartupInformation=self.connection.Win32_ProcessStartup.new(ShowWindow=0),
CurrentDirectory=dir,
CommandLine="cmd /c echo %s > %s" %(contents, filename)
)
time.sleep(0.5)
with open(os.path.join(dir, filename)) as f:
self.assertEqual(f.read(), contents + " \n")
def test_in_params_with_array(self):
"Check that the names and arrayness of params are picked up when arrays"
self.assertEquals(
[("DNSServerSearchOrder", True)],
self.connection.Win32_NetworkAdapterConfiguration.SetDNSServerSearchOrder.in_parameter_names
)
def test_instance_methods_are_distinct(self):
"""Check that the methods of difference instances of a class are distinct.
This caused a problem when calling .Terminate on one process killed another.
"""
methods = [d.Reset for d in self.logical_disks]
for i in range(len(methods)-1):
self.assertNotEqual(methods[i], methods[i+1])
def test_call_from_class(self):
"Check that a method can be called from a class"
self.assert_(self.connection.Win32_Process.Create(
CommandLine=sys.executable + " -c pass",
ProcessStartupInformation=self.connection.Win32_ProcessStartup.new(ShowWindow=0)
))
def test_call_from_instance(self):
"Check that a method can be called from an instance"
handle, _ = self.connection.Win32_Process.Create(
CommandLine=sys.executable,
ProcessStartupInformation=self.connection.Win32_ProcessStartup.new(ShowWindow=0)
)
result = 1
for p in self.connection.Win32_Process(Handle=handle):
result, = p.Terminate()
self.assertEqual(result, 0)
class TestProperties(TestWMI):
def test_access(self):
"Check that all properties are available as attributes"
for d in self.logical_disks:
break
for p in d.ole_object.Properties_:
self.assertEqual(p.Value, getattr(d, p.Name))
def test_attribute_passthrough(self):
"Check that unknown attributes are passed through to the underlying object"
for d in self.logical_disks:
break
#
# Can't rely on the COM Objects testing identical or equal;
# have to check their values and their emptiness.
#
self.assert_(d.Properties_)
self.assert_(d.ole_object.Properties_)
self.assertEqual(
[p.Value for p in d.Properties_],
[p.Value for p in d.ole_object.Properties_]
)
def test_settable(self):
"Check that a writeable property can be written"
name = str(time.time()).split(".")[0]
old_value = "***"
new_value = "!!!"
username = win32api.GetUserNameEx(win32con.NameSamCompatible)
self.assert_(not self.connection.Win32_Environment(Name=name, UserName=username))
self.connection.Win32_Environment.new(Name=name, UserName=username, VariableValue=old_value).put()
for envvar in self.connection.Win32_Environment(Name=name, UserName=username):
self.assertEqual(envvar.VariableValue, old_value)
envvar.VariableValue = new_value
try:
for envvar in self.connection.Win32_Environment(Name=name, UserName=username):
self.assertEqual(envvar.VariableValue, new_value)
finally:
for envvar in self.connection.Win32_Environment(Name=name, UserName=username):
envvar.VariableValue = None
class TestInstances(TestWMI):
def test_hashable(self):
"Ensure instances are hashable so can be used in a set/dict"
self.assert_(dict.fromkeys(self.logical_disks))
def test_equalable(self):
"Ensure instances compare equal"
self.assertEqual(self.logical_disks, self.logical_disks)
def test_not_equal_to_anything_else(self):
"Ensure WMI instances are not equal to non-WMI instances"
for d in self.logical_disks:
break
self.assertNotEqual(d, d.Caption)
def test_sortable(self):
"Ensure instances sort by full path/key"
self.assertEqual(
sorted(self.logical_disks),
sorted(self.logical_disks, key=operator.attrgetter("DeviceID"))
)
def test_references(self):
"Ensure that associations are special-cased to return wrapped objects"
for d in self.logical_disks:
break
for r in d.references("Win32_LogicalDiskRootDirectory"):
self.assert_(r.is_association)
self.assertEqual(r.GroupComponent, d)
self.assert_(isinstance(r.GroupComponent, wmi._wmi_object))
self.assert_(isinstance(r.PartComponent, wmi._wmi_object))
def test_associators(self):
"Ensure that associators are returned by association / result"
for d in self.logical_disks:
if d.DeviceID == os.path.abspath(__file__)[:2]:
break
else:
raise RuntimeError("Unable to find the logical drive corresponding to this file")
root_dir = d.associators(wmi_association_class="Win32_LogicalDiskRootDirectory")[0]
self.assertEqual(root_dir.Name.lower(), d.Name.lower() + "\\".lower())
root_dir = d.associators(wmi_result_class="Win32_Directory")[0]
self.assertEqual(root_dir.Name.lower(), d.Name.lower() + "\\")
def test_derivation(self):
"Check that derivation mimics WMI-provided Derivation_ property"
for d in self.logical_disks:
break
self.assertEqual(d.derivation(), d.ole_object.Derivation_)
def test_keys(self):
"Check that the readonly keys property returns the keys for an object"
self.assertEqual(self.connection.Win32_LogicalDisk.keys, ['DeviceID'])
self.assertEqual(next(iter(self.logical_disks)).keys, ['DeviceID'])
class TestInstanceCreation(TestWMI):
def test_create_instance(self):
self.assert_(isinstance(self.connection.Win32_ProcessStartup.new(ShowWindow=2), wmi._wmi_object))
class TestAssociations(TestWMI):
def test_all_properties_available(self):
#
# An association can contain not only the associated
# classes but also extra information as well. Ensure
# that both types of data are correctly handled.
#
for q in self.connection.Win32_DiskQuota():
for p in q.properties:
try:
getattr(q, p)
except wmi.x_wmi:
assert False, "Error getting %s from %s" % (p, q)
else:
assert True
if __name__ == '__main__':
unittest.main()