Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: pylib/mozrunner/qijo.py

Issue 6183003: Added third_party python libraries that are needed for browser testing. (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/third_party/
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pylib/mozrunner/killableprocess.py ('k') | pylib/mozrunner/winprocess.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 from ctypes import c_void_p, POINTER, sizeof, Structure, windll, WinError, WINFU NCTYPE, addressof, c_size_t, c_ulong
2 from ctypes.wintypes import BOOL, BYTE, DWORD, HANDLE, LARGE_INTEGER
3
4 LPVOID = c_void_p
5 LPDWORD = POINTER(DWORD)
6 SIZE_T = c_size_t
7 ULONG_PTR = POINTER(c_ulong)
8
9 # A ULONGLONG is a 64-bit unsigned integer.
10 # Thus there are 8 bytes in a ULONGLONG.
11 # XXX why not import c_ulonglong ?
12 ULONGLONG = BYTE * 8
13
14 class IO_COUNTERS(Structure):
15 # The IO_COUNTERS struct is 6 ULONGLONGs.
16 # TODO: Replace with non-dummy fields.
17 _fields_ = [('dummy', ULONGLONG * 6)]
18
19 class JOBOBJECT_BASIC_ACCOUNTING_INFORMATION(Structure):
20 _fields_ = [('TotalUserTime', LARGE_INTEGER),
21 ('TotalKernelTime', LARGE_INTEGER),
22 ('ThisPeriodTotalUserTime', LARGE_INTEGER),
23 ('ThisPeriodTotalKernelTime', LARGE_INTEGER),
24 ('TotalPageFaultCount', DWORD),
25 ('TotalProcesses', DWORD),
26 ('ActiveProcesses', DWORD),
27 ('TotalTerminatedProcesses', DWORD)]
28
29 class JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION(Structure):
30 _fields_ = [('BasicInfo', JOBOBJECT_BASIC_ACCOUNTING_INFORMATION),
31 ('IoInfo', IO_COUNTERS)]
32
33 # see http://msdn.microsoft.com/en-us/library/ms684147%28VS.85%29.aspx
34 class JOBOBJECT_BASIC_LIMIT_INFORMATION(Structure):
35 _fields_ = [('PerProcessUserTimeLimit', LARGE_INTEGER),
36 ('PerJobUserTimeLimit', LARGE_INTEGER),
37 ('LimitFlags', DWORD),
38 ('MinimumWorkingSetSize', SIZE_T),
39 ('MaximumWorkingSetSize', SIZE_T),
40 ('ActiveProcessLimit', DWORD),
41 ('Affinity', ULONG_PTR),
42 ('PriorityClass', DWORD),
43 ('SchedulingClass', DWORD)
44 ]
45
46 # see http://msdn.microsoft.com/en-us/library/ms684156%28VS.85%29.aspx
47 class JOBOBJECT_EXTENDED_LIMIT_INFORMATION(Structure):
48 _fields_ = [('BasicLimitInformation', JOBOBJECT_BASIC_LIMIT_INFORMATION),
49 ('IoInfo', IO_COUNTERS),
50 ('ProcessMemoryLimit', SIZE_T),
51 ('JobMemoryLimit', SIZE_T),
52 ('PeakProcessMemoryUsed', SIZE_T),
53 ('PeakJobMemoryUsed', SIZE_T)]
54
55 # XXX Magical numbers like 8 should be documented
56 JobObjectBasicAndIoAccountingInformation = 8
57
58 # ...like magical number 9 comes from
59 # http://community.flexerasoftware.com/archive/index.php?t-181670.html
60 # I wish I had a more canonical source
61 JobObjectExtendedLimitInformation = 9
62
63 class JobObjectInfo(object):
64 mapping = { 'JobObjectBasicAndIoAccountingInformation': 8,
65 'JobObjectExtendedLimitInformation': 9
66 }
67 structures = { 8: JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION,
68 9: JOBOBJECT_EXTENDED_LIMIT_INFORMATION
69 }
70 def __init__(self, _class):
71 if isinstance(_class, basestring):
72 assert _class in self.mapping, 'Class should be one of %s; you gave %s' % (self.mapping, _class)
73 _class = self.mapping[_class]
74 assert _class in self.structures, 'Class should be one of %s; you gave % s' % (self.structures, _class)
75 self.code = _class
76 self.info = self.structures[_class]()
77
78
79 QueryInformationJobObjectProto = WINFUNCTYPE(
80 BOOL, # Return type
81 HANDLE, # hJob
82 DWORD, # JobObjectInfoClass
83 LPVOID, # lpJobObjectInfo
84 DWORD, # cbJobObjectInfoLength
85 LPDWORD # lpReturnLength
86 )
87
88 QueryInformationJobObjectFlags = (
89 (1, 'hJob'),
90 (1, 'JobObjectInfoClass'),
91 (1, 'lpJobObjectInfo'),
92 (1, 'cbJobObjectInfoLength'),
93 (1, 'lpReturnLength', None)
94 )
95
96 _QueryInformationJobObject = QueryInformationJobObjectProto(
97 ('QueryInformationJobObject', windll.kernel32),
98 QueryInformationJobObjectFlags
99 )
100
101 class SubscriptableReadOnlyStruct(object):
102 def __init__(self, struct):
103 self._struct = struct
104
105 def _delegate(self, name):
106 result = getattr(self._struct, name)
107 if isinstance(result, Structure):
108 return SubscriptableReadOnlyStruct(result)
109 return result
110
111 def __getitem__(self, name):
112 match = [fname for fname, ftype in self._struct._fields_
113 if fname == name]
114 if match:
115 return self._delegate(name)
116 raise KeyError(name)
117
118 def __getattr__(self, name):
119 return self._delegate(name)
120
121 def QueryInformationJobObject(hJob, JobObjectInfoClass):
122 jobinfo = JobObjectInfo(JobObjectInfoClass)
123 result = _QueryInformationJobObject(
124 hJob=hJob,
125 JobObjectInfoClass=jobinfo.code,
126 lpJobObjectInfo=addressof(jobinfo.info),
127 cbJobObjectInfoLength=sizeof(jobinfo.info)
128 )
129 if not result:
130 raise WinError()
131 return SubscriptableReadOnlyStruct(jobinfo.info)
132
133 def test_qijo():
134 from killableprocess import Popen
135
136 popen = Popen('c:\\windows\\notepad.exe')
137
138 try:
139 result = QueryInformationJobObject(0, 8)
140 raise AssertionError('throw should occur')
141 except WindowsError, e:
142 pass
143
144 try:
145 result = QueryInformationJobObject(0, 1)
146 raise AssertionError('throw should occur')
147 except NotImplementedError, e:
148 pass
149
150 result = QueryInformationJobObject(popen._job, 8)
151 if result['BasicInfo']['ActiveProcesses'] != 1:
152 raise AssertionError('expected ActiveProcesses to be 1')
153 popen.kill()
154
155 result = QueryInformationJobObject(popen._job, 8)
156 if result.BasicInfo.ActiveProcesses != 0:
157 raise AssertionError('expected ActiveProcesses to be 0')
158
159 if __name__ == '__main__':
160 print "testing."
161 test_qijo()
162 print "success!"
OLDNEW
« no previous file with comments | « pylib/mozrunner/killableprocess.py ('k') | pylib/mozrunner/winprocess.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698