sys-proctable 0.7.6 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +1 -0
  4. data/CHANGES +165 -0
  5. data/MANIFEST +33 -41
  6. data/README +115 -135
  7. data/Rakefile +94 -0
  8. data/benchmarks/bench_ps.rb +21 -0
  9. data/doc/top.txt +5 -11
  10. data/examples/example_ps.rb +20 -0
  11. data/lib/aix/sys/proctable.rb +458 -0
  12. data/lib/darwin/sys/proctable.rb +363 -0
  13. data/lib/freebsd/sys/proctable.rb +363 -0
  14. data/lib/linux/sys/proctable.rb +314 -0
  15. data/lib/linux/sys/proctable/cgroup_entry.rb +50 -0
  16. data/lib/linux/sys/proctable/smaps.rb +118 -0
  17. data/lib/sunos/sys/proctable.rb +456 -0
  18. data/lib/sys-proctable.rb +1 -0
  19. data/lib/sys-top.rb +1 -0
  20. data/lib/sys/proctable.rb +18 -0
  21. data/lib/sys/proctable/version.rb +6 -0
  22. data/lib/sys/top.rb +28 -19
  23. data/lib/windows/sys/proctable.rb +208 -0
  24. data/spec/sys_proctable_aix_spec.rb +328 -0
  25. data/spec/sys_proctable_all_spec.rb +89 -0
  26. data/spec/sys_proctable_darwin_spec.rb +120 -0
  27. data/spec/sys_proctable_freebsd_spec.rb +210 -0
  28. data/spec/sys_proctable_linux_spec.rb +310 -0
  29. data/spec/sys_proctable_sunos_spec.rb +316 -0
  30. data/spec/sys_proctable_windows_spec.rb +317 -0
  31. data/spec/sys_top_spec.rb +51 -0
  32. data/sys-proctable.gemspec +38 -0
  33. metadata +140 -64
  34. metadata.gz.sig +0 -0
  35. data/doc/freebsd.txt +0 -90
  36. data/doc/hpux.txt +0 -77
  37. data/doc/linux.txt +0 -85
  38. data/doc/solaris.txt +0 -99
  39. data/doc/windows.txt +0 -122
  40. data/ext/extconf.rb +0 -98
  41. data/ext/sunos/sunos.c +0 -374
  42. data/ext/sunos/sunos.h +0 -177
  43. data/ext/version.h +0 -2
  44. data/test/tc_all.rb +0 -59
  45. data/test/tc_freebsd.rb +0 -45
  46. data/test/tc_hpux.rb +0 -49
  47. data/test/tc_kvm_bsd.rb +0 -31
  48. data/test/tc_linux.rb +0 -45
  49. data/test/tc_sunos.rb +0 -52
  50. data/test/tc_top.rb +0 -26
  51. data/test/tc_windows.rb +0 -40
  52. data/test/test_memleak.rb +0 -54
@@ -0,0 +1 @@
1
+ require_relative 'sys/proctable'
@@ -0,0 +1 @@
1
+ require 'sys/top'
@@ -0,0 +1,18 @@
1
+ require 'rbconfig'
2
+
3
+ case RbConfig::CONFIG['host_os']
4
+ when /aix/i
5
+ require_relative '../aix/sys/proctable'
6
+ when /darwin/i
7
+ require_relative '../darwin/sys/proctable'
8
+ when /freebsd/i
9
+ require_relative '../freebsd/sys/proctable'
10
+ when /linux/i
11
+ require_relative '../linux/sys/proctable'
12
+ when /sunos|solaris/i
13
+ require_relative '../sunos/sys/proctable'
14
+ when /mswin|win32|dos|cygwin|mingw|windows/i
15
+ require_relative '../windows/sys/proctable'
16
+ else
17
+ raise "Unsupported platform"
18
+ end
@@ -0,0 +1,6 @@
1
+ module Sys
2
+ class ProcTable
3
+ # The version of the sys-proctable library
4
+ VERSION = '1.2.0'.freeze
5
+ end
6
+ end
@@ -1,23 +1,32 @@
1
- require "sys/proctable"
1
+ require 'sys/proctable'
2
+
3
+ # The Sys module serves as a namespace only
2
4
  module Sys
3
- class Top
4
- VERSION = "1.0.1"
5
- WINDOWS = PLATFORM.match("mswin")
6
5
 
7
- def self.top(num=10, field="pctcpu")
8
- # Sort by pid on Windows by default
9
- if WINDOWS && field == "pctcpu"
10
- field = "pid"
11
- end
12
-
13
- # Linux does not have a pctcpu field yet
14
- if RUBY_PLATFORM =~ /linux/ && field == "pctcpu"
15
- field = "pid"
16
- end
17
-
18
- Sys::ProcTable.ps.sort{ |a,b|
19
- b.send(field) <=> a.send(field)
20
- }[0..num-1]
6
+ # The Top class serves as a toplevel name for the 'top' method.
7
+ class Top
8
+
9
+ # The version of the sys-top library
10
+ VERSION = '1.0.5'.freeze
11
+
12
+ # Returns an array of Struct::ProcTableStruct elements containing up
13
+ # to +num+ elements, sorted by +field+. The default number of elements
14
+ # is 10, while the default field is 'pctcpu'.
15
+ #
16
+ # Exception: the default sort field is 'pid' on AIX, Darwin and Windows.
17
+ #
18
+ def self.top(num=10, field='pctcpu')
19
+ field = field.to_s if field.is_a?(Symbol)
20
+
21
+ aix = RbConfig::CONFIG['host_os'] =~ /aix/i
22
+ darwin = RbConfig::CONFIG['host_os'] =~ /darwin/i
23
+
24
+ # Sort by pid on Windows and AIX by default
25
+ if (File::ALT_SEPARATOR || aix || darwin) && field == 'pctcpu'
26
+ field = 'pid'
21
27
  end
22
- end
28
+
29
+ Sys::ProcTable.ps.sort_by{ |obj| obj.send(field) || '' }[0..num-1]
30
+ end
31
+ end
23
32
  end
@@ -0,0 +1,208 @@
1
+ require 'win32ole'
2
+ require 'socket'
3
+ require 'date'
4
+ require 'sys/proctable/version'
5
+
6
+ # The Sys module serves as a namespace only
7
+ module Sys
8
+
9
+ # The ProcTable class encapsulates process table information
10
+ class ProcTable
11
+
12
+ # There is no constructor
13
+ private_class_method :new
14
+
15
+ # Error typically raised if one of the Sys::ProcTable methods fails
16
+ class Error < StandardError; end
17
+
18
+ # The comm field corresponds to the 'name' field. The 'cmdline' field
19
+ # is the CommandLine attribute on Windows XP or later, or the
20
+ # 'executable_path' field on Windows 2000 or earlier.
21
+ #
22
+ @fields = %w[
23
+ caption
24
+ cmdline
25
+ comm
26
+ creation_class_name
27
+ creation_date
28
+ cs_creation_class_name
29
+ cs_name
30
+ description
31
+ executable_path
32
+ execution_state
33
+ handle
34
+ handle_count
35
+ install_date
36
+ kernel_mode_time
37
+ maximum_working_set_size
38
+ minimum_working_set_size
39
+ name
40
+ os_creation_class_name
41
+ os_name
42
+ other_operation_count
43
+ other_transfer_count
44
+ page_faults
45
+ page_file_usage
46
+ ppid
47
+ peak_page_file_usage
48
+ peak_virtual_size
49
+ peak_working_set_size
50
+ priority
51
+ private_page_count
52
+ pid
53
+ quota_non_paged_pool_usage
54
+ quota_paged_pool_usage
55
+ quota_peak_non_paged_pool_usage
56
+ quota_peak_paged_pool_usage
57
+ read_operation_count
58
+ read_transfer_count
59
+ session_id
60
+ status
61
+ termination_date
62
+ thread_count
63
+ user_mode_time
64
+ virtual_size
65
+ windows_version
66
+ working_set_size
67
+ write_operation_count
68
+ write_transfer_count
69
+ ]
70
+
71
+ ProcTableStruct = Struct.new("ProcTableStruct", *@fields)
72
+
73
+ # call-seq:
74
+ # ProcTable.fields
75
+ #
76
+ # Returns an array of fields that each ProcTableStruct will contain. This
77
+ # may be useful if you want to know in advance what fields are available
78
+ # without having to perform at least one read of the /proc table.
79
+ #
80
+ def self.fields
81
+ @fields
82
+ end
83
+
84
+ # call-seq:
85
+ # ProcTable.ps(pid=nil)
86
+ # ProcTable.ps(pid=nil){ |ps| ... }
87
+ #
88
+ # In block form, yields a ProcTableStruct for each process entry that you
89
+ # have rights to. This method returns an array of ProcTableStruct's in
90
+ # non-block form.
91
+ #
92
+ # If a +pid+ is provided, then only a single ProcTableStruct is yielded or
93
+ # returned, or nil if no process information is found for that +pid+.
94
+ #
95
+ def self.ps(**kwargs)
96
+ pid = kwargs[:pid]
97
+ host = kwargs[:host] || Socket.gethostname
98
+
99
+ raise TypeError unless pid.kind_of?(Numeric) if pid
100
+
101
+ array = block_given? ? nil : []
102
+ struct = nil
103
+
104
+ begin
105
+ wmi = WIN32OLE.connect("winmgmts://#{host}/root/cimv2")
106
+ rescue WIN32OLERuntimeError => e
107
+ raise Error, e # Re-raise as ProcTable::Error
108
+ else
109
+ wmi.InstancesOf("Win32_Process").each{ |wproc|
110
+ if pid
111
+ next unless wproc.ProcessId == pid
112
+ end
113
+
114
+ # Some fields are added later, and so are nil initially
115
+ struct = ProcTableStruct.new(
116
+ wproc.Caption,
117
+ nil, # Added later, based on OS version
118
+ wproc.Name,
119
+ wproc.CreationClassName,
120
+ self.parse_ms_date(wproc.CreationDate),
121
+ wproc.CSCreationClassName,
122
+ wproc.CSName,
123
+ wproc.Description,
124
+ wproc.ExecutablePath,
125
+ wproc.ExecutionState,
126
+ wproc.Handle,
127
+ wproc.HandleCount,
128
+ self.parse_ms_date(wproc.InstallDate),
129
+ self.convert(wproc.KernelModeTime),
130
+ wproc.MaximumWorkingSetSize,
131
+ wproc.MinimumWorkingSetSize,
132
+ wproc.Name,
133
+ wproc.OSCreationClassName,
134
+ wproc.OSName,
135
+ self.convert(wproc.OtherOperationCount),
136
+ self.convert(wproc.OtherTransferCount),
137
+ wproc.PageFaults,
138
+ wproc.PageFileUsage,
139
+ wproc.ParentProcessId,
140
+ self.convert(wproc.PeakPageFileUsage),
141
+ self.convert(wproc.PeakVirtualSize),
142
+ self.convert(wproc.PeakWorkingSetSize),
143
+ wproc.Priority,
144
+ self.convert(wproc.PrivatePageCount),
145
+ wproc.ProcessId,
146
+ wproc.QuotaNonPagedPoolUsage,
147
+ wproc.QuotaPagedPoolUsage,
148
+ wproc.QuotaPeakNonPagedPoolUsage,
149
+ wproc.QuotaPeakPagedPoolUsage,
150
+ self.convert(wproc.ReadOperationCount),
151
+ self.convert(wproc.ReadTransferCount),
152
+ wproc.SessionId,
153
+ wproc.Status,
154
+ self.parse_ms_date(wproc.TerminationDate),
155
+ wproc.ThreadCount,
156
+ self.convert(wproc.UserModeTime),
157
+ self.convert(wproc.VirtualSize),
158
+ wproc.WindowsVersion,
159
+ self.convert(wproc.WorkingSetSize),
160
+ self.convert(wproc.WriteOperationCount),
161
+ self.convert(wproc.WriteTransferCount)
162
+ )
163
+
164
+ ###############################################################
165
+ # On Windows XP or later, set the cmdline to the CommandLine
166
+ # attribute. Otherwise, set it to the ExecutablePath
167
+ # attribute.
168
+ ###############################################################
169
+ if wproc.WindowsVersion.to_f < 5.1
170
+ struct.cmdline = wproc.ExecutablePath
171
+ else
172
+ struct.cmdline = wproc.CommandLine
173
+ end
174
+
175
+ struct.freeze # This is read-only data
176
+
177
+ if block_given?
178
+ yield struct
179
+ else
180
+ array << struct
181
+ end
182
+ }
183
+ end
184
+
185
+ pid ? struct : array
186
+ end
187
+
188
+ private
189
+
190
+ #######################################################################
191
+ # Converts a string in the format '20040703074625.015625-360' into a
192
+ # Ruby Time object.
193
+ #######################################################################
194
+ def self.parse_ms_date(str)
195
+ return if str.nil?
196
+ return DateTime.parse(str)
197
+ end
198
+
199
+ #####################################################################
200
+ # There is a bug in win32ole where uint64 types are returned as a
201
+ # String instead of a Fixnum. This method deals with that for now.
202
+ #####################################################################
203
+ def self.convert(str)
204
+ return nil if str.nil? # Return nil, not 0
205
+ return str.to_i
206
+ end
207
+ end
208
+ end
@@ -0,0 +1,328 @@
1
+ #######################################################################
2
+ # sys_proctable_aix_spec.rb
3
+ #
4
+ # Test suite for the AIX version of the sys-proctable library. You
5
+ # should run these tests via the 'rake test' task.
6
+ #######################################################################
7
+ require 'rspec'
8
+ require 'sys/proctable'
9
+ require_relative 'sys_proctable_all_spec'
10
+
11
+ describe Sys::ProcTable do
12
+ let(:fields){
13
+ %w[
14
+ addr argc argv bindpro cid clname cmd_args cmdline cwd egid environ
15
+ envp euid fd flag flag2 fname gid lwpid map nice nlwp onpro pgid pid
16
+ policy ppid pri psargs ptid rssize sid size sname start state time
17
+ ttydev uid wchan wtype s_ttydev
18
+ ]
19
+ }
20
+
21
+ let(:map_fields){
22
+ %w[size vaddr mapname off mflags pathoff alias gp s_mflags path]
23
+ }
24
+
25
+ before(:all) do
26
+ File.open('aix-child.rb', 'w') do |out|
27
+ out.puts 'trap("HUP") { exit }'
28
+ out.puts 'trap("TERM") { exit }'
29
+ out.puts 'sleep(60)'
30
+ end
31
+
32
+ @myenv = ENV.to_hash
33
+ @p1args = %w/aix-child.rb testing how well this works 1/
34
+ @p2args = %w/aix-child.rb testing how well this works 2/
35
+
36
+ @pid1 = fork do
37
+ exec('ruby', *@p1args)
38
+ end
39
+
40
+ @pid2 = fork do
41
+ exec('ruby', *@p2args)
42
+ end
43
+
44
+ sleep(2) # wait to make sure the above execs have completed in children
45
+
46
+
47
+ @p1info = ProcTable.ps(@pid1)
48
+ @p2info = ProcTable.ps.select { |e| e.pid == @pid2 }
49
+
50
+ if @p2info.size == 1
51
+ @p2info = @p2info[0]
52
+ else
53
+ $stderr.puts "expected a single process, have #{@p2info.size}"
54
+ exit 1
55
+ end
56
+ end
57
+
58
+ after(:all) do
59
+ Process.kill('TERM', @pid1)
60
+ Process.kill('TERM', @pid2)
61
+ File.unlink('aix-child.rb') rescue nil
62
+ end
63
+
64
+ context "fields singleton method" do
65
+ it "responds to a fields method" do
66
+ expect(described_class).to respond_to(:fields)
67
+ end
68
+
69
+ it "returns the expected results for the fields method" do
70
+ expect(described_class.fields).to be_kind_of(Array)
71
+ expect(described_class.fields).to eql(fields)
72
+ end
73
+ end
74
+
75
+ context "ProcTable::Struct members" do
76
+ it "contains a flag member and returns the expected value" do
77
+ expect(@p1info).to respond_to(:flag)
78
+ expect(@p1info.flag).to be_kind_of(Fixnum)
79
+ end
80
+
81
+ it "contains a flag2 member and returns the expected value" do
82
+ expect(@p1info).to respond_to(:flag2)
83
+ expect(@p1info.flag2).to be_kind_of(Fixnum)
84
+ end
85
+
86
+ it "contains a nlwp member and returns the expected value" do
87
+ expect(@p1info).to respond_to(:nlwp)
88
+ expect(@p1info.nlwp).to be_kind_of(Fixnum)
89
+ end
90
+
91
+ it "contains a uid member and returns the expected value" do
92
+ expect(@p1info).to respond_to(:uid)
93
+ expect(@p1info.uid).to be_kind_of(Integer)
94
+ expect(@p1info.uid).to eql(@p1info.uid)
95
+ end
96
+
97
+ it "contains a euid member and returns the expected value" do
98
+ expect(@p1info).to respond_to(:euid)
99
+ expect(@p1info.euid).to be_kind_of(Integer)
100
+ expect(@p1info.euid).to eql(@p1info.euid)
101
+ end
102
+
103
+ it "contains a gid member and returns the expected value" do
104
+ expect(@p1info).to respond_to(:gid)
105
+ expect(@p1info.gid).to be_kind_of(Integer)
106
+ expect(@p1info.gid).to eql(@p1info.gid)
107
+ end
108
+
109
+ it "contains a egid member and returns the expected value" do
110
+ expect(@p1info).to respond_to(:egid)
111
+ expect(@p1info.egid).to be_kind_of(Integer)
112
+ expect(@p1info.egid).to eql(@p1info.egid)
113
+ end
114
+
115
+ it "contains a pid member and returns the expected value" do
116
+ expect(@p1info).to respond_to(:pid)
117
+ expect(@p1info.pid).to be_kind_of(Integer)
118
+ expect(@p1info.pid).to eql(@p1info.pid)
119
+ end
120
+
121
+ it "contains a ppid member and returns the expected value" do
122
+ expect(@p1info).to respond_to(:ppid)
123
+ expect(@p1info.ppid).to be_kind_of(Integer)
124
+ expect(@p1info.ppid).to eql(@p1info.ppid)
125
+ end
126
+
127
+ it "contains a pgid member and returns the expected value" do
128
+ expect(@p1info).to respond_to(:pgid)
129
+ expect(@p1info.pgid).to be_kind_of(Integer)
130
+ expect(@p1info.pgid).to eql(@p1info.pgid)
131
+ end
132
+
133
+ it "contains a sid member and returns the expected value" do
134
+ expect(@p1info).to respond_to(:sid)
135
+ expect(@p1info.sid).to be_kind_of(Integer)
136
+ end
137
+
138
+ it "contains a ttydev member and returns the expected value" do
139
+ expect(@p1info).to respond_to(:ttydev)
140
+ expect(@p1info.ttydev).to be_kind_of(Integer)
141
+ end
142
+
143
+ it "contains a addr member and returns the expected value" do
144
+ expect(@p1info).to respond_to(:addr)
145
+ expect(@p1info.addr).to be_kind_of(Integer)
146
+ end
147
+
148
+ it "contains a size member and returns the expected value" do
149
+ expect(@p1info).to respond_to(:size)
150
+ expect(@p1info.size).to be_kind_of(Integer)
151
+ end
152
+
153
+ it "contains a rssize member and returns the expected value" do
154
+ expect(@p1info).to respond_to(:rssize)
155
+ expect(@p1info.rssize).to be_kind_of(Integer)
156
+ end
157
+
158
+ it "contains a start member and returns the expected value" do
159
+ expect(@p1info).to respond_to(:start)
160
+ expect(@p1info.start).to be_kind_of(Time)
161
+ end
162
+
163
+ it "contains a time member and returns the expected value" do
164
+ expect(@p1info).to respond_to(:time)
165
+ expect(@p1info.time).to be_kind_of(Time)
166
+ end
167
+
168
+ it "contains a cid member and returns the expected value" do
169
+ expect(@p1info).to respond_to(:cid)
170
+ expect(@p1info.cid).to be_kind_of(Fixnum)
171
+ end
172
+
173
+ it "contains an argc member and returns the expected value" do
174
+ expect(@p1info).to respond_to(:argc)
175
+ expect(@p1info.argc).to be_kind_of(Fixnum)
176
+ expect(@p1info.argc).to eql(@p1args.size + 1)
177
+ end
178
+
179
+ it "contains an argv member and returns the expected value" do
180
+ expect(@p1info).to respond_to(:argv)
181
+ expect(@p1info.argv).to be_kind_of(Integer)
182
+ end
183
+
184
+ it "contains an envp member and returns the expected value" do
185
+ expect(@p1info).to respond_to(:envp)
186
+ expect(@p1info.envp).to be_kind_of(Integer)
187
+ end
188
+
189
+ it "contains an fname member and returns the expected value" do
190
+ expect(@p1info).to respond_to(:fname)
191
+ expect(@p1info.fname).to be_kind_of(String)
192
+ end
193
+
194
+ it "contains an fname member and returns the expected value" do
195
+ expect(@p1info).to respond_to(:psargs)
196
+ expect(@p1info.psargs).to be_kind_of(String)
197
+ end
198
+
199
+ it "contains an lwpid member and returns the expected value" do
200
+ expect(@p1info).to respond_to(:lwpid)
201
+ expect(@p1info.lwpid).to be_kind_of(Integer)
202
+ end
203
+
204
+ it "contains a wchan member and returns the expected value" do
205
+ expect(@p1info).to respond_to(:wchan)
206
+ expect(@p1info.wchan).to be_kind_of(Integer)
207
+ end
208
+
209
+ it "contains a wtype member and returns the expected value" do
210
+ expect(@p1info).to respond_to(:wtype)
211
+ expect(@p1info.wchan).to be_kind_of(Fixnum)
212
+ end
213
+
214
+ it "contains a state member and returns the expected value" do
215
+ expect(@p1info).to respond_to(:state)
216
+ expect(@p1info.state).to be_kind_of(Fixnum)
217
+ end
218
+
219
+ it "contains an sname member and returns the expected value" do
220
+ expect(@p1info).to respond_to(:sname)
221
+ expect(@p1info.sname).to be_kind_of(String)
222
+ end
223
+
224
+ it "contains a nice member and returns the expected value" do
225
+ expect(@p1info).to respond_to(:nice)
226
+ expect(@p1info.nice).to be_kind_of(Fixnum)
227
+ end
228
+
229
+ it "contains a pri member and returns the expected value" do
230
+ expect(@p1info).to respond_to(:pri)
231
+ expect(@p1info.pri).to be_kind_of(Fixnum)
232
+ end
233
+
234
+ it "contains a policy member and returns the expected value" do
235
+ expect(@p1info).to respond_to(:policy)
236
+ expect(@p1info.policy).to be_kind_of(Fixnum)
237
+ end
238
+
239
+ it "contains a clname member and returns the expected value" do
240
+ expect(@p1info).to respond_to(:clname)
241
+ expect(@p1info.clname).to be_kind_of(String)
242
+ end
243
+
244
+ it "contains an onpro member and returns the expected value" do
245
+ expect(@p1info).to respond_to(:onpro)
246
+ expect(@p1info.onpro).to be_kind_of(Fixnum)
247
+ end
248
+
249
+ it "contains a bindpro member and returns the expected value" do
250
+ expect(@p1info).to respond_to(:bindpro)
251
+ expect(@p1info.bindpro).to be_kind_of(Fixnum)
252
+ end
253
+
254
+ it "contains a ptid member and returns the expected value" do
255
+ expect(@p1info).to respond_to(:ptid)
256
+ expect(@p1info.ptid).to be_kind_of(Fixnum)
257
+ end
258
+
259
+ it "contains a comm member and returns the expected value" do
260
+ expect(@p1info).to respond_to(:comm)
261
+ expect(@p1info.comm).to be_kind_of(String)
262
+ end
263
+
264
+ it "contains a fd member and returns the expected value" do
265
+ expect(@p1info).to respond_to(:fd)
266
+ expect(@p1info.fd).to be_kind_of(Array)
267
+ end
268
+
269
+ it "contains a cmd_args member and returns the expected value" do
270
+ expect(@p1info).to respond_to(:cmd_args)
271
+ expect(@p1info.cmd_args).to be_kind_of(Array)
272
+ expect(@p1info.cmd_args).to_eql(['ruby', @p1args].flatten)
273
+
274
+ expect(@p2info).to respond_to(:cmd_args)
275
+ expect(@p2info.cmd_args).to be_kind_of(Array)
276
+ expect(@p2info.cmd_args).to_eql(['ruby', @p2args].flatten)
277
+ end
278
+
279
+ it "contains an environ member and returns the expected value" do
280
+ expect(@p1info).to respond_to(:environ)
281
+ expect(@p1info.environ).to be_kind_of(Hash)
282
+ expect(@p1info.environ).to eql(@myenv)
283
+
284
+ expect(@p2info).to respond_to(:environ)
285
+ expect(@p2info.environ).to be_kind_of(Hash)
286
+ expect(@p2info.environ).to eql(@myenv)
287
+ end
288
+
289
+ it "contains a cmdline member and returns the expected value" do
290
+ expect(@p1info).to respond_to(:cmdline)
291
+ expect(@p1info.cmdline).to be_kind_of(String)
292
+ end
293
+
294
+ it "contains a cwd member and returns the expected value" do
295
+ expect(@p1info).to respond_to(:cwd)
296
+ expect(@p1info.cwd).to be_kind_of(String) if @p1info.cwd
297
+ end
298
+
299
+ it "contains a map member and returns the expected value" do
300
+ expect(@p1info).to respond_to(:map)
301
+ expect(@p1info.map).to be_kind_of(Array) if @p1info.map
302
+ end
303
+ end
304
+
305
+ context "Struct::ProcTableMapStruct" do
306
+ it "contains the expected members" do
307
+ expect(@p1info.map).to be_kind_of(Array)
308
+ expect(map_fields.sort).to eql(@p1info.map[0].members.sort)
309
+ end
310
+
311
+ it "has members of the expected type" do
312
+ expect(@p1info.map).to be_kind_of(Array)
313
+ p1info_map = @p1info.map
314
+
315
+ expect(p1info_map).to be_kind_of(Struct::ProcTableMapStruct)
316
+ expect(p1info_map.size).to be_kind_of(Integer)
317
+ expect(p1info_map.vaddr).to be_kind_of(Integer)
318
+ expect(p1info_map.mapname).to be_kind_of(String)
319
+ expect(p1info_map.off).to be_kind_of(Integer)
320
+ expect(p1info_map.mflags).to be_kind_of(Integer)
321
+ expect(p1info_map.s_mflags).to be_kind_of(String)
322
+ expect(p1info_map.pathoff).to be_kind_of(Integer)
323
+ expect(p1info_map.alias).to be_kind_of(Integer)
324
+ expect(p1info_map.gp).to be_kind_of(Integer)
325
+ expect(p1info_map.path).to be_kind_of(String)
326
+ end
327
+ end
328
+ end