sys-proctable 0.7.6 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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