tddium-sys-proctable 0.9.2-x86-darwin-10
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.
- data/CHANGES +294 -0
- data/MANIFEST +30 -0
- data/README +119 -0
- data/Rakefile +158 -0
- data/benchmarks/bench_ps.rb +21 -0
- data/doc/top.txt +47 -0
- data/examples/example_ps.rb +20 -0
- data/ext/darwin/extconf.rb +4 -0
- data/ext/darwin/sys/proctable.c +256 -0
- data/lib/sys/top.rb +32 -0
- data/sys-proctable.gemspec +42 -0
- data/test/test_sys_proctable_all.rb +85 -0
- data/test/test_sys_proctable_darwin.rb +213 -0
- metadata +99 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
########################################################################
|
2
|
+
# bench_ps.rb
|
3
|
+
#
|
4
|
+
# Benchmark program to show overall speed and compare the block form
|
5
|
+
# versus the non-block form. You should run this benchmark via the
|
6
|
+
# 'rake bench' Rake task.
|
7
|
+
########################################################################
|
8
|
+
require 'benchmark'
|
9
|
+
require 'sys/proctable'
|
10
|
+
|
11
|
+
MAX = 10
|
12
|
+
|
13
|
+
Benchmark.bm do |bench|
|
14
|
+
bench.report("Block form"){
|
15
|
+
MAX.times{ Sys::ProcTable.ps{} }
|
16
|
+
}
|
17
|
+
|
18
|
+
bench.report("Non-block form"){
|
19
|
+
MAX.times{ Sys::ProcTable.ps }
|
20
|
+
}
|
21
|
+
end
|
data/doc/top.txt
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
= Description
|
2
|
+
A simple 'top' interface for Ruby
|
3
|
+
|
4
|
+
= Prerequisites
|
5
|
+
Requires the "sys/proctable" package (which should be installed along
|
6
|
+
with this package).
|
7
|
+
|
8
|
+
= Synopsis
|
9
|
+
require "sys/top"
|
10
|
+
|
11
|
+
Sys::Top.top(5).each{ |ps|
|
12
|
+
p ps
|
13
|
+
}
|
14
|
+
|
15
|
+
= Constants
|
16
|
+
VERSION
|
17
|
+
Returns the version number of this package as a String.
|
18
|
+
|
19
|
+
= Class Methods
|
20
|
+
Sys::Top.top(number=10, field="pctcpu")
|
21
|
+
Returns an array of ProcTableStruct's. The size of the array (i.e. the
|
22
|
+
number of processes) that it returns is based on +number+, and sorted by
|
23
|
+
+pctcpu+. By default, the size and field values are 10 and "pctcpu",
|
24
|
+
respectively.
|
25
|
+
|
26
|
+
= Notes
|
27
|
+
Not all fields are available on all platforms. Please check your
|
28
|
+
platform specific documentation for which fields are available.
|
29
|
+
|
30
|
+
= Bugs
|
31
|
+
None that I'm aware of. Please log bug reports on the project page at
|
32
|
+
http://www.rubyforge.org/projects/sysutils
|
33
|
+
|
34
|
+
= License
|
35
|
+
Artistic 2.0
|
36
|
+
|
37
|
+
= Copyright
|
38
|
+
(C) 2004-2009 Daniel J. Berger
|
39
|
+
All Rights Reserved.
|
40
|
+
|
41
|
+
= Warranty
|
42
|
+
This package is provided "as is" and without any express or
|
43
|
+
implied warranties, including, without limitation, the implied
|
44
|
+
warranties of merchantability and fitness for a particular purpose.
|
45
|
+
|
46
|
+
= Author
|
47
|
+
Daniel J. Berger
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#######################################################################
|
2
|
+
# example_ps.rb
|
3
|
+
#
|
4
|
+
# Generic test program that demonstrates the use of ProcTable.ps. You
|
5
|
+
# can run this via the 'rake example' task.
|
6
|
+
#
|
7
|
+
# Modify as you see fit
|
8
|
+
#######################################################################
|
9
|
+
require 'sys/proctable'
|
10
|
+
include Sys
|
11
|
+
|
12
|
+
puts "VERSION: " + ProcTable::VERSION
|
13
|
+
sleep 2
|
14
|
+
|
15
|
+
ProcTable.ps{ |s|
|
16
|
+
ProcTable.fields.each{ |field|
|
17
|
+
puts "#{field}: " + s.send(field).to_s
|
18
|
+
}
|
19
|
+
puts '=' * 30
|
20
|
+
}
|
@@ -0,0 +1,256 @@
|
|
1
|
+
/**********************************************************************
|
2
|
+
* Mac OS X code for sys-proctable Ruby library. *
|
3
|
+
* *
|
4
|
+
* Date: 3-Mar-2006 (original submission date) *
|
5
|
+
* Author: David Felstead (david.felstead at gmail dot com) *
|
6
|
+
* Based on bsd.c by Daniel J. Berger (djberg96 at gmail dot com) *
|
7
|
+
*********************************************************************/
|
8
|
+
#include "ruby.h"
|
9
|
+
#include <sys/param.h>
|
10
|
+
#include <sys/stat.h>
|
11
|
+
#include <sys/sysctl.h>
|
12
|
+
#include <sys/types.h>
|
13
|
+
#include <sys/user.h>
|
14
|
+
#include <errno.h>
|
15
|
+
|
16
|
+
#define SYS_PROCTABLE_VERSION "0.9.1"
|
17
|
+
|
18
|
+
#define PROC_MIB_LEN 4
|
19
|
+
#define ARGS_MIB_LEN 3
|
20
|
+
#define ARGS_MAX_LEN 4096
|
21
|
+
VALUE cProcTableError, sProcStruct;
|
22
|
+
|
23
|
+
const char* fields[] = {
|
24
|
+
"pid", "ppid", "pgid", "ruid", "rgid", "comm", "state", "pctcpu", "oncpu",
|
25
|
+
"tnum", "tdev", "wmesg", "rtime", "priority", "usrpri", "nice", "cmdline",
|
26
|
+
"starttime", "maxrss", "ixrss", "idrss", "isrss", "minflt", "majflt",
|
27
|
+
"nswap", "inblock", "oublock", "msgsnd", "msgrcv", "nsignals", "nvcsw",
|
28
|
+
"nivcsw", "utime", "stime"
|
29
|
+
};
|
30
|
+
|
31
|
+
/*
|
32
|
+
* call-seq:
|
33
|
+
* ProcTable.ps(pid=nil)
|
34
|
+
* ProcTable.ps(pid=nil){ |ps| ... }
|
35
|
+
*
|
36
|
+
* In block form, yields a ProcTableStruct for each process entry that you
|
37
|
+
* have rights to. This method returns an array of ProcTableStruct's in
|
38
|
+
* non-block form.
|
39
|
+
*
|
40
|
+
* If a +pid+ is provided, then only a single ProcTableStruct is yielded or
|
41
|
+
* returned, or nil if no process information is found for that +pid+.
|
42
|
+
*/
|
43
|
+
static VALUE pt_ps(int argc, VALUE* argv, VALUE klass){
|
44
|
+
int err;
|
45
|
+
char state[8];
|
46
|
+
struct kinfo_proc* procs;
|
47
|
+
int count; /* Holds total number of processes */
|
48
|
+
int i = 0;
|
49
|
+
VALUE v_pid, v_tty_num, v_tty_dev, v_start_time;
|
50
|
+
VALUE v_pstruct = Qnil;
|
51
|
+
VALUE v_array = rb_ary_new();
|
52
|
+
size_t length;
|
53
|
+
char args[ARGS_MAX_LEN+1];
|
54
|
+
|
55
|
+
// Passed into sysctl call
|
56
|
+
static const int name_mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
|
57
|
+
|
58
|
+
rb_scan_args(argc, argv, "01", &v_pid);
|
59
|
+
|
60
|
+
// Get size of proc kproc buffer
|
61
|
+
err = sysctl( (int *) name_mib, PROC_MIB_LEN, NULL, &length, NULL, 0);
|
62
|
+
|
63
|
+
if(err == -1)
|
64
|
+
rb_raise(cProcTableError, strerror(errno));
|
65
|
+
|
66
|
+
// Populate the kproc buffer
|
67
|
+
procs = malloc(length);
|
68
|
+
|
69
|
+
if(procs == NULL)
|
70
|
+
rb_raise(cProcTableError, strerror(errno));
|
71
|
+
|
72
|
+
err = sysctl( (int *) name_mib, PROC_MIB_LEN, procs, &length, NULL, 0);
|
73
|
+
|
74
|
+
if(err == -1)
|
75
|
+
rb_raise(cProcTableError, strerror(errno));
|
76
|
+
|
77
|
+
// If we're here, we got our list
|
78
|
+
count = length / sizeof(struct kinfo_proc);
|
79
|
+
|
80
|
+
for(i = 0; i < count; i++) {
|
81
|
+
v_tty_num = Qnil;
|
82
|
+
v_tty_dev = Qnil;
|
83
|
+
v_start_time = Qnil;
|
84
|
+
|
85
|
+
// If a PID is provided, skip unless the PID matches
|
86
|
+
if( (!NIL_P(v_pid)) && (procs[i].kp_proc.p_pid != NUM2INT(v_pid)) )
|
87
|
+
continue;
|
88
|
+
|
89
|
+
*args = '\0';
|
90
|
+
|
91
|
+
/* Query the command line args */
|
92
|
+
/* TODO: Cmd line not working for now - fix */
|
93
|
+
|
94
|
+
/*args_mib[ARGS_MIB_LEN - 1] = procs[i].kp_proc.p_pid;
|
95
|
+
args_err = sysctl( (int *) args_mib, ARGS_MIB_LEN, args, &args_size, NULL, 0);
|
96
|
+
|
97
|
+
if(args_err >= 0) {
|
98
|
+
fprintf(stderr, "Ret: %d LEN: %d\n", err, args_size);
|
99
|
+
char *c;
|
100
|
+
for(c = args; c < args+args_size; c++)
|
101
|
+
if(*c == '\0') *c = ' ';
|
102
|
+
args[args_size] = '\0';
|
103
|
+
} else {
|
104
|
+
fprintf(stderr, "err: %s LEN: %d\n", strerror(errno), args_size);
|
105
|
+
}*/
|
106
|
+
|
107
|
+
// Get the start time of the process
|
108
|
+
v_start_time = rb_time_new(
|
109
|
+
procs[i].kp_proc.p_un.__p_starttime.tv_sec,
|
110
|
+
procs[i].kp_proc.p_un.__p_starttime.tv_usec
|
111
|
+
);
|
112
|
+
|
113
|
+
// Get the state of the process
|
114
|
+
switch(procs[i].kp_proc.p_stat)
|
115
|
+
{
|
116
|
+
case SIDL:
|
117
|
+
strcpy(state, "idle");
|
118
|
+
break;
|
119
|
+
case SRUN:
|
120
|
+
strcpy(state, "run");
|
121
|
+
break;
|
122
|
+
case SSLEEP:
|
123
|
+
strcpy(state, "sleep");
|
124
|
+
break;
|
125
|
+
case SSTOP:
|
126
|
+
strcpy(state, "stop");
|
127
|
+
break;
|
128
|
+
case SZOMB:
|
129
|
+
strcpy(state, "zombie");
|
130
|
+
break;
|
131
|
+
default:
|
132
|
+
strcpy(state, "unknown");
|
133
|
+
break;
|
134
|
+
}
|
135
|
+
|
136
|
+
// Get ttynum and ttydev. If ttynum is -1, there is no tty.
|
137
|
+
if(procs[i].kp_eproc.e_tdev != -1){
|
138
|
+
v_tty_num = INT2FIX(procs[i].kp_eproc.e_tdev),
|
139
|
+
v_tty_dev = rb_str_new2(devname(procs[i].kp_eproc.e_tdev, S_IFCHR));
|
140
|
+
}
|
141
|
+
|
142
|
+
v_pstruct = rb_struct_new(
|
143
|
+
sProcStruct,
|
144
|
+
INT2FIX(procs[i].kp_proc.p_pid),
|
145
|
+
INT2FIX(procs[i].kp_eproc.e_ppid),
|
146
|
+
INT2FIX(procs[i].kp_eproc.e_pgid),
|
147
|
+
INT2FIX(procs[i].kp_eproc.e_pcred.p_ruid),
|
148
|
+
INT2FIX(procs[i].kp_eproc.e_pcred.p_rgid),
|
149
|
+
rb_str_new2(procs[i].kp_proc.p_comm),
|
150
|
+
rb_str_new2(state),
|
151
|
+
rb_float_new(procs[i].kp_proc.p_pctcpu),
|
152
|
+
Qnil,
|
153
|
+
v_tty_num,
|
154
|
+
v_tty_dev,
|
155
|
+
rb_str_new2(procs[i].kp_eproc.e_wmesg),
|
156
|
+
INT2FIX(procs[i].kp_proc.p_rtime.tv_sec),
|
157
|
+
INT2FIX(procs[i].kp_proc.p_priority),
|
158
|
+
INT2FIX(procs[i].kp_proc.p_usrpri),
|
159
|
+
INT2FIX(procs[i].kp_proc.p_nice),
|
160
|
+
rb_str_new2(args),
|
161
|
+
v_start_time,
|
162
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_maxrss) : Qnil,
|
163
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_ixrss) : Qnil,
|
164
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_idrss) : Qnil,
|
165
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_isrss) : Qnil,
|
166
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_minflt) : Qnil,
|
167
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_majflt) : Qnil,
|
168
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nswap) : Qnil,
|
169
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_inblock) : Qnil,
|
170
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_oublock) : Qnil,
|
171
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_msgsnd) : Qnil,
|
172
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_msgrcv) : Qnil,
|
173
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nsignals) : Qnil,
|
174
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nvcsw) : Qnil,
|
175
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nivcsw) : Qnil,
|
176
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_utime.tv_sec) : Qnil,
|
177
|
+
(procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_stime.tv_sec) : Qnil
|
178
|
+
);
|
179
|
+
|
180
|
+
OBJ_FREEZE(v_pstruct); // This is read-only data
|
181
|
+
|
182
|
+
if(rb_block_given_p())
|
183
|
+
rb_yield(v_pstruct);
|
184
|
+
else
|
185
|
+
rb_ary_push(v_array, v_pstruct);
|
186
|
+
}
|
187
|
+
|
188
|
+
if(procs) free(procs);
|
189
|
+
|
190
|
+
if(!rb_block_given_p()){
|
191
|
+
if(NIL_P(v_pid))
|
192
|
+
return v_array;
|
193
|
+
else
|
194
|
+
return v_pstruct;
|
195
|
+
}
|
196
|
+
|
197
|
+
return Qnil;
|
198
|
+
}
|
199
|
+
|
200
|
+
/*
|
201
|
+
* call-seq:
|
202
|
+
* ProcTable.fields
|
203
|
+
*
|
204
|
+
* Returns an array of fields that each ProcTableStruct will contain. This
|
205
|
+
* may be useful if you want to know in advance what fields are available
|
206
|
+
* without having to perform at least one read of the /proc table.
|
207
|
+
*/
|
208
|
+
static VALUE pt_fields(VALUE klass){
|
209
|
+
VALUE v_array = rb_ary_new();
|
210
|
+
int size = sizeof(fields) / sizeof(fields[0]);
|
211
|
+
int i;
|
212
|
+
|
213
|
+
for(i = 0; i < size; i++)
|
214
|
+
rb_ary_push(v_array, rb_str_new2(fields[i]));
|
215
|
+
|
216
|
+
return v_array;
|
217
|
+
}
|
218
|
+
|
219
|
+
/*
|
220
|
+
* A Ruby interface for gathering process table information.
|
221
|
+
*/
|
222
|
+
void Init_proctable(){
|
223
|
+
VALUE mSys, cProcTable;
|
224
|
+
|
225
|
+
/* The Sys module serves as a namespace only */
|
226
|
+
mSys = rb_define_module("Sys");
|
227
|
+
|
228
|
+
/* The ProcTable class encapsulates process table information */
|
229
|
+
cProcTable = rb_define_class_under(mSys, "ProcTable", rb_cObject);
|
230
|
+
|
231
|
+
/* The Error class typically raised if any of the ProcTable methods fail */
|
232
|
+
cProcTableError = rb_define_class_under(cProcTable, "Error", rb_eStandardError);
|
233
|
+
|
234
|
+
/* Singleton methods */
|
235
|
+
|
236
|
+
rb_define_singleton_method(cProcTable, "ps", pt_ps, -1);
|
237
|
+
rb_define_singleton_method(cProcTable, "fields", pt_fields, 0);
|
238
|
+
|
239
|
+
/* There is no constructor */
|
240
|
+
rb_funcall(cProcTable, rb_intern("private_class_method"), 1, ID2SYM(rb_intern("new")));
|
241
|
+
|
242
|
+
/* Constants */
|
243
|
+
|
244
|
+
/* 0.9.1: The version of the sys-proctable library */
|
245
|
+
rb_define_const(cProcTable, "VERSION", rb_str_new2(SYS_PROCTABLE_VERSION));
|
246
|
+
|
247
|
+
/* Structs */
|
248
|
+
|
249
|
+
sProcStruct = rb_struct_define("ProcTableStruct","pid","ppid","pgid","ruid",
|
250
|
+
"rgid","comm","state","pctcpu","oncpu","tnum","tdev","wmesg",
|
251
|
+
"rtime", "priority","usrpri","nice","cmdline","starttime",
|
252
|
+
"maxrss","ixrss","idrss","isrss","minflt","majflt","nswap",
|
253
|
+
"inblock","oublock","msgsnd","msgrcv","nsignals","nvcsw","nivcsw",
|
254
|
+
"utime","stime", NULL
|
255
|
+
);
|
256
|
+
}
|
data/lib/sys/top.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'sys/proctable'
|
2
|
+
require 'rbconfig'
|
3
|
+
|
4
|
+
# The Sys module serves as a namespace only
|
5
|
+
module Sys
|
6
|
+
|
7
|
+
# The Top class serves as a toplevel name for the 'top' method.
|
8
|
+
class Top
|
9
|
+
|
10
|
+
# The version of the sys-top library
|
11
|
+
VERSION = '1.0.3'
|
12
|
+
|
13
|
+
# Returns an array of Struct::ProcTableStruct elements containing up
|
14
|
+
# to +num+ elements, sorted by +field+. The default number of elements
|
15
|
+
# is 10, while the default field is 'pctcpu'.
|
16
|
+
#
|
17
|
+
# Exception: the default sort field is 'pid' on Linux and Windows.
|
18
|
+
#
|
19
|
+
def self.top(num=10, field='pctcpu')
|
20
|
+
field = field.to_s if field.is_a?(Symbol)
|
21
|
+
|
22
|
+
windows = /mswin|win32|windows|dos|cygwin|mingw/i
|
23
|
+
|
24
|
+
# Sort by pid on Windows by default
|
25
|
+
if Config::CONFIG['host_os'].match(windows) && field == 'pctcpu'
|
26
|
+
field = 'pid'
|
27
|
+
end
|
28
|
+
|
29
|
+
Sys::ProcTable.ps.sort_by{ |obj| obj.send(field) || '' }[0..num-1]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rbconfig'
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = 'tddium-sys-proctable'
|
6
|
+
spec.version = '0.9.2'
|
7
|
+
spec.author = 'Daniel J. Berger'
|
8
|
+
spec.license = 'Artistic 2.0'
|
9
|
+
spec.email = 'info@tddium.com'
|
10
|
+
spec.homepage = 'http://www.rubyforge.org/projects/sysutils'
|
11
|
+
spec.platform = Gem::Platform::CURRENT
|
12
|
+
spec.summary = 'An interface for providing process table information'
|
13
|
+
spec.has_rdoc = true
|
14
|
+
spec.test_files = ['test/test_sys_proctable_all.rb']
|
15
|
+
|
16
|
+
# Additional files for your platform are added by the 'rake gem' task.
|
17
|
+
spec.files = [
|
18
|
+
'benchmarks/bench_ps.rb',
|
19
|
+
'examples/example_ps.rb',
|
20
|
+
'lib/sys/top.rb',
|
21
|
+
'CHANGES',
|
22
|
+
'MANIFEST',
|
23
|
+
'Rakefile',
|
24
|
+
'README',
|
25
|
+
'sys-proctable.gemspec'
|
26
|
+
]
|
27
|
+
|
28
|
+
spec.rubyforge_project = 'sysutils'
|
29
|
+
spec.extra_rdoc_files = ['CHANGES', 'README', 'MANIFEST', 'doc/top.txt']
|
30
|
+
|
31
|
+
spec.add_development_dependency('test-unit', '>= 2.1.2')
|
32
|
+
|
33
|
+
spec.description = <<-EOF
|
34
|
+
Testing a separate publish to see if I can get the mac install to work with bundler.
|
35
|
+
|
36
|
+
The sys-proctable library provides an interface for gathering information
|
37
|
+
about processes on your system, i.e. the process table. Most major
|
38
|
+
platforms are supported and, while different platforms may return
|
39
|
+
different information, the external interface is identical across
|
40
|
+
platforms.
|
41
|
+
EOF
|
42
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
#######################################################################
|
2
|
+
# test_sys_proctable_all.rb
|
3
|
+
#
|
4
|
+
# Test suite for methods common to all platforms. Generally speaking
|
5
|
+
# you should run this test case using the 'rake test' task.
|
6
|
+
#######################################################################
|
7
|
+
require 'rubygems'
|
8
|
+
gem 'test-unit'
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
require 'sys/proctable'
|
12
|
+
require 'rbconfig'
|
13
|
+
require 'test/test_sys_top'
|
14
|
+
include Sys
|
15
|
+
|
16
|
+
class TC_ProcTable_All < Test::Unit::TestCase
|
17
|
+
def self.startup
|
18
|
+
@@windows = Config::CONFIG['host_os'] =~ /windows|win32|msdos|mswin32|mingw|cygwin/i
|
19
|
+
end
|
20
|
+
|
21
|
+
def setup
|
22
|
+
@pid = @@windows ? 0 : 1
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_version
|
26
|
+
assert_equal('0.9.1', ProcTable::VERSION)
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_fields
|
30
|
+
assert_respond_to(ProcTable, :fields)
|
31
|
+
assert_nothing_raised{ ProcTable.fields }
|
32
|
+
assert_kind_of(Array, ProcTable.fields)
|
33
|
+
assert_kind_of(String, ProcTable.fields.first)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_ps
|
37
|
+
assert_respond_to(ProcTable, :ps)
|
38
|
+
assert_nothing_raised{ ProcTable.ps }
|
39
|
+
assert_nothing_raised{ ProcTable.ps{} }
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_ps_with_pid
|
43
|
+
assert_nothing_raised{ ProcTable.ps(0) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_ps_with_explicit_nil
|
47
|
+
assert_nothing_raised{ ProcTable.ps(nil) }
|
48
|
+
assert_kind_of(Array, ProcTable.ps(nil))
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_ps_return_value
|
52
|
+
assert_kind_of(Array, ProcTable.ps)
|
53
|
+
assert_kind_of(Struct::ProcTableStruct, ProcTable.ps(@pid))
|
54
|
+
assert_equal(nil, ProcTable.ps(999999999))
|
55
|
+
assert_equal(nil, ProcTable.ps(999999999){})
|
56
|
+
assert_equal(nil, ProcTable.ps{})
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_ps_returned_struct_is_frozen
|
60
|
+
assert_true(ProcTable.ps.first.frozen?)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_ps_expected_errors
|
64
|
+
assert_raises(TypeError){ ProcTable.ps('vim') }
|
65
|
+
omit_if(@@windows, 'ArgumentError check skipped on MS Windows')
|
66
|
+
assert_raises(ArgumentError){ ProcTable.ps(0, 'localhost') }
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_new_not_allowed
|
70
|
+
assert_raise(NoMethodError){ Sys::ProcTable.new }
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_error_class_defined
|
74
|
+
assert_not_nil(Sys::ProcTable::Error)
|
75
|
+
assert_kind_of(StandardError, Sys::ProcTable::Error.new)
|
76
|
+
end
|
77
|
+
|
78
|
+
def teardown
|
79
|
+
@pid = nil
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.teardown
|
83
|
+
@@windows = nil
|
84
|
+
end
|
85
|
+
end
|