vcs 0.1 → 0.2.148

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 (132) hide show
  1. data/Rakefile +17 -3
  2. data/bin/vcs +57 -34
  3. data/doc/jamis.rb +564 -0
  4. data/ruby_ex/abstract.rb +254 -0
  5. data/ruby_ex/abstract_node.rb +85 -0
  6. data/ruby_ex/algorithms/simulated_annealing.rb +140 -0
  7. data/ruby_ex/array_each_pair.rb +18 -0
  8. data/ruby_ex/ask.rb +101 -0
  9. data/ruby_ex/attributed_class.rb +302 -0
  10. data/ruby_ex/cache.rb +373 -0
  11. data/ruby_ex/checkout.rb +12 -0
  12. data/ruby_ex/choose.rb +271 -0
  13. data/ruby_ex/commands.rb +18 -0
  14. data/ruby_ex/commands/command.rb +401 -0
  15. data/ruby_ex/commands/datas.rb +16 -0
  16. data/ruby_ex/commands/datas/data.rb +33 -0
  17. data/ruby_ex/commands/datas/factory.rb +66 -0
  18. data/ruby_ex/commands/factory.rb +66 -0
  19. data/ruby_ex/commands/helpers.rb +67 -0
  20. data/ruby_ex/commands/pipe.rb +64 -0
  21. data/ruby_ex/commands/runners.rb +17 -0
  22. data/ruby_ex/commands/runners/exec.rb +49 -0
  23. data/ruby_ex/commands/runners/fork.rb +97 -0
  24. data/ruby_ex/commands/runners/runner.rb +107 -0
  25. data/ruby_ex/commands/seq.rb +27 -0
  26. data/ruby_ex/config_file.rb +96 -0
  27. data/ruby_ex/const_regexp.rb +59 -0
  28. data/ruby_ex/daemon.rb +134 -0
  29. data/ruby_ex/diff.rb +667 -0
  30. data/ruby_ex/dlogger.rb +62 -0
  31. data/ruby_ex/drb/dispatcher.rb +252 -0
  32. data/ruby_ex/drb/dispatcher_server_test.rb +29 -0
  33. data/ruby_ex/drb/drb_observable.rb +97 -0
  34. data/ruby_ex/drb/drb_observable_pool.rb +27 -0
  35. data/ruby_ex/drb/drb_service.rb +43 -0
  36. data/ruby_ex/drb/drb_undumped_attributes.rb +55 -0
  37. data/ruby_ex/drb/drb_undumped_indexed_object.rb +54 -0
  38. data/ruby_ex/drb/insecure_protected_methods.rb +103 -0
  39. data/ruby_ex/drb/session_client_test.rb +40 -0
  40. data/ruby_ex/drb/session_manager.rb +246 -0
  41. data/ruby_ex/drb/session_server.rb +53 -0
  42. data/ruby_ex/dtime.rb +143 -0
  43. data/ruby_ex/dumpable_proc.rb +63 -0
  44. data/ruby_ex/exception.rb +32 -0
  45. data/ruby_ex/filetype.rb +229 -0
  46. data/ruby_ex/fileutils_ex.rb +44 -0
  47. data/ruby_ex/fold.rb +58 -0
  48. data/ruby_ex/generate_id.rb +44 -0
  49. data/ruby_ex/hookable.rb +262 -0
  50. data/ruby_ex/hooker.rb +54 -0
  51. data/ruby_ex/inactive_timeout.rb +137 -0
  52. data/ruby_ex/indexed_node.rb +66 -0
  53. data/ruby_ex/io_marshal.rb +100 -0
  54. data/ruby_ex/ioo.rb +194 -0
  55. data/ruby_ex/labeled_node.rb +63 -0
  56. data/ruby_ex/logger_observer.rb +23 -0
  57. data/ruby_ex/md5sum.rb +66 -0
  58. data/ruby_ex/mktemp.rb +208 -0
  59. data/ruby_ex/module/attr_once.rb +36 -0
  60. data/ruby_ex/module/autoload_tree.rb +75 -0
  61. data/ruby_ex/module/hierarchy.rb +335 -0
  62. data/ruby_ex/module/instance_method_visibility.rb +73 -0
  63. data/ruby_ex/module_ex.rb +11 -0
  64. data/ruby_ex/node.rb +80 -0
  65. data/ruby_ex/object_monitor.rb +145 -0
  66. data/ruby_ex/object_monitor_activity.rb +33 -0
  67. data/ruby_ex/observable.rb +140 -0
  68. data/ruby_ex/observable_pool.rb +293 -0
  69. data/ruby_ex/orderedhash.rb +252 -0
  70. data/ruby_ex/pathname_ex.rb +152 -0
  71. data/ruby_ex/pp_hierarchy.rb +29 -0
  72. data/ruby_ex/pseudo_cache.rb +190 -0
  73. data/ruby_ex/queue.rb +56 -0
  74. data/ruby_ex/random_generators.rb +25 -0
  75. data/ruby_ex/random_generators/random_generator.rb +31 -0
  76. data/ruby_ex/random_generators/ruby.rb +23 -0
  77. data/ruby_ex/safe_eval.rb +348 -0
  78. data/ruby_ex/sendmail.rb +215 -0
  79. data/ruby_ex/service_manager.rb +121 -0
  80. data/ruby_ex/session/administrable.rb +120 -0
  81. data/ruby_ex/session/client.rb +153 -0
  82. data/ruby_ex/session/const.rb +18 -0
  83. data/ruby_ex/session/dispatcher.rb +184 -0
  84. data/ruby_ex/session/error.rb +21 -0
  85. data/ruby_ex/session/fetchable.rb +57 -0
  86. data/ruby_ex/session/fetcher.rb +62 -0
  87. data/ruby_ex/session/hookable.rb +26 -0
  88. data/ruby_ex/session/profile.rb +110 -0
  89. data/ruby_ex/session/server.rb +582 -0
  90. data/ruby_ex/session/test/administrable_test.rb +337 -0
  91. data/ruby_ex/session/test/basic_test.rb +523 -0
  92. data/ruby_ex/session/test/dispatcher_test.rb +409 -0
  93. data/ruby_ex/session/test/fetchable_test.rb +119 -0
  94. data/ruby_ex/session/test/sub_server_test.rb +188 -0
  95. data/ruby_ex/shuffle.rb +30 -0
  96. data/ruby_ex/spring.rb +136 -0
  97. data/ruby_ex/spring_set.rb +137 -0
  98. data/ruby_ex/string_ex.rb +28 -0
  99. data/ruby_ex/symtbl.rb +106 -0
  100. data/ruby_ex/synflow.rb +474 -0
  101. data/ruby_ex/test/unit/ui/yaml/testrunner.rb +164 -0
  102. data/ruby_ex/thread_mutex.rb +10 -0
  103. data/ruby_ex/timeout_ex.rb +81 -0
  104. data/ruby_ex/top_down.rb +73 -0
  105. data/ruby_ex/trace.rb +26 -0
  106. data/ruby_ex/uri/druby.rb +81 -0
  107. data/ruby_ex/uri/file.rb +65 -0
  108. data/ruby_ex/uri/ftp_ex.rb +37 -0
  109. data/ruby_ex/uri/http_ex.rb +43 -0
  110. data/ruby_ex/uri/ssh.rb +92 -0
  111. data/ruby_ex/uri/svn.rb +118 -0
  112. data/ruby_ex/uri_ex.rb +45 -0
  113. data/ruby_ex/verbose_object.rb +30 -0
  114. data/ruby_ex/version.rb +66 -0
  115. data/ruby_ex/yaml/basenode_ext.rb +63 -0
  116. data/ruby_ex/yaml/chop_header.rb +23 -0
  117. data/ruby_ex/yaml/transform.rb +449 -0
  118. data/ruby_ex/yaml/yregexpath.rb +76 -0
  119. data/src/changelog.rb +28 -18
  120. data/src/conflict.rb +20 -0
  121. data/src/diff.rb +18 -0
  122. data/src/diffstat.rb +9 -3
  123. data/src/last_changed_date.rb +18 -0
  124. data/src/mail.rb +33 -65
  125. data/src/message.rb +15 -9
  126. data/src/mycommit.rb +29 -14
  127. data/src/news.rb +24 -3
  128. data/src/status.rb +17 -0
  129. data/src/svn.rb +2 -2
  130. data/src/vcs.rb +24 -3
  131. metadata +124 -5
  132. data/lrdetools.rb +0 -12
@@ -0,0 +1,188 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
2
+ # Author: Nicolas Despres <polrop@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: polrop $
6
+ # $Id: sub_server_test.rb 68 2004-12-07 10:51:28Z polrop $
7
+
8
+
9
+ #
10
+ # Client/Server basic test suite
11
+ #
12
+ if defined? TEST_MODE or $0 == __FILE__
13
+
14
+ if RUBY_VERSION >= '1.9.0'
15
+
16
+
17
+ require 'test/unit/ui/yaml/testrunner'
18
+ require 'session/server'
19
+ require 'session/administrable'
20
+ require 'session/client'
21
+
22
+
23
+ module Session
24
+
25
+ module Test
26
+
27
+ class SubServerTest < ::Test::Unit::TestCase
28
+
29
+ class MyServer < Session::Server
30
+ include Administrable
31
+
32
+ # protected
33
+ # def request_testme(sid, profile, test_obj)
34
+ # ret = test_obj.run
35
+ # return test_obj, ret
36
+ # end
37
+
38
+ end
39
+
40
+ def setup
41
+ unless @srv_pid = fork # son
42
+ $stderr = File.open('/dev/null')
43
+ @opts = MyServer::OPTS
44
+ @opts[:usrdb] = MyServer::USRDB
45
+ @opts[:max_usr] = 2
46
+ @opts[:wipeout_delay] = 2
47
+ @srv = MyServer.new(@opts)
48
+ DRb.start_service('druby://localhost:42000', @srv)
49
+ DRb.thread.join
50
+ exit(0)
51
+ end
52
+ end
53
+
54
+ def teardown
55
+ Process.kill('TERM', @srv_pid)
56
+ Process.waitpid(@srv_pid)
57
+ end
58
+
59
+ #
60
+ # Tests
61
+ #
62
+ def test_detach
63
+ clt = nil
64
+ assert_nothing_raised do
65
+ clt = Client.new('druby://localhost:42000',
66
+ 'admin',
67
+ 'admin'.crypt(Const::SALT_KEY))
68
+ end
69
+ assert_not_nil(clt)
70
+ assert(! clt.online?, 'clt online 1')
71
+ assert_equal('data', clt.ping('data'))
72
+ assert(clt.logout)
73
+ end
74
+
75
+ def test_sub_server
76
+ clt = nil
77
+ assert_nothing_raised do
78
+ clt = Client.new('druby://localhost:42000',
79
+ 'admin',
80
+ 'admin'.crypt(Const::SALT_KEY), true)
81
+ end
82
+ assert_not_nil(clt)
83
+ uri = clt.start_sub_server(nil, MyServer) { true }
84
+ assert_not_equal(clt.local_uri, uri)
85
+ assert_not_equal(clt.uri, uri)
86
+ assert_equal(1, clt.sessions.size)
87
+ assert_not_nil(clt.sessions[clt.sid])
88
+ clients = clt.profile[:dispatcher].select_all
89
+ assert_equal(1, clients.size)
90
+ client = clients.first
91
+ assert_equal(uri, client.uri)
92
+ assert_equal(1, client.request(:sessions).size)
93
+ assert_not_equal(client.request(:sessions), clt.sessions)
94
+ assert_not_nil(client.request(:sessions)[client.sid])
95
+
96
+ sub_clt = nil
97
+ assert_nothing_raised do
98
+ sub_clt = Client.new(uri,
99
+ 'admin',
100
+ 'admin'.crypt(Const::SALT_KEY))
101
+ end
102
+ assert_not_nil(sub_clt)
103
+ assert_equal(uri, sub_clt.uri)
104
+ assert_equal(2, sub_clt.sessions.size)
105
+ assert_equal(2, client.request(:sessions).size)
106
+ assert_not_nil(client.request(:sessions)[sub_clt.sid])
107
+ assert_not_nil(sub_clt.sessions[client.sid])
108
+
109
+ assert(clt.logout)
110
+ end
111
+
112
+ def test_kill_and_sub_server
113
+ clt = nil
114
+ assert_nothing_raised do
115
+ clt = Client.new('druby://localhost:42000',
116
+ 'admin',
117
+ 'admin'.crypt(Const::SALT_KEY))
118
+ end
119
+ assert_not_nil(clt)
120
+ uri = clt.start_sub_server(nil) {}
121
+ pid = clt.pid
122
+ sub_pid = clt.request_at(uri, :pid)
123
+ assert_not_equal($$, pid)
124
+ assert_not_equal(sub_pid, pid)
125
+ assert_not_equal($$, sub_pid)
126
+ assert_equal(@srv_pid, pid)
127
+
128
+ assert_raises(Errno::EADDRINUSE) do
129
+ clt.start_sub_server(uri)
130
+ end
131
+ stat = clt.stop_sub_server(uri)
132
+ assert_equal(sub_pid, stat.pid)
133
+ assert_equal(0, stat.exitstatus)
134
+ assert_nil(stat.termsig)
135
+ assert_raises(Errno::ESRCH) do
136
+ Process.kill('KILL', sub_pid)
137
+ end
138
+
139
+ new_uri = clt.start_sub_server(uri)
140
+ assert_equal(uri, new_uri)
141
+ new_sub_pid = clt.request_at(uri, :pid)
142
+ assert_not_equal(sub_pid, new_sub_pid)
143
+
144
+ assert_equal(1, Process.kill('KILL', new_sub_pid))
145
+
146
+ stat = clt.stop_sub_server(uri)
147
+ assert_equal(new_sub_pid, stat.pid)
148
+ assert_equal(nil, stat.exitstatus)
149
+ assert_equal(9, stat.termsig)
150
+
151
+ clt.start_sub_server(nil) {}
152
+ clt.start_sub_server(nil) {}
153
+ assert(clt.logout)
154
+ end
155
+
156
+ def test_request_at
157
+ clt = nil
158
+ assert_nothing_raised do
159
+ clt = Client.new('druby://localhost:42000',
160
+ 'admin',
161
+ 'admin'.crypt(Const::SALT_KEY))
162
+ end
163
+ assert_not_nil(clt)
164
+ uri = clt.start_sub_server(nil) {}
165
+ sub_pid = clt.request_at(uri, :pid)
166
+ assert_raises(Session::RequestError) do
167
+ clt.request_at(uri, :toto)
168
+ end
169
+ assert_equal(sub_pid, clt.stop_sub_server(uri).pid)
170
+ assert(clt.logout)
171
+ end
172
+
173
+ #
174
+ # Utilities
175
+ #
176
+
177
+ end # class SubServerTest
178
+
179
+ end # module Test
180
+
181
+ end # module Session
182
+
183
+ else
184
+ STDERR.puts('need ruby1.9')
185
+ end
186
+
187
+
188
+ end
@@ -0,0 +1,30 @@
1
+ # Author:: Nicolas Pouillard <ertai@lrde.epita.fr>.
2
+ # Copyright:: Copyright (c) 2005 Nicolas Pouillard. All rights reserved.
3
+ # License:: GNU General Public License (GPL).
4
+ # Revision:: $Id: shuffle.rb 220 2005-05-09 12:28:26Z ertai $
5
+
6
+ class Array
7
+
8
+ def shuffle! ( generator=nil )
9
+ n = size
10
+ n.times do |i|
11
+ swap!(i, n.choose(generator))
12
+ end
13
+ self
14
+ end
15
+
16
+ def shuffle ( generator=nil )
17
+ dup.shuffle!(generator)
18
+ end
19
+
20
+ def swap! ( i, j )
21
+ self[i], self[j] = self[j], self[i]
22
+ end
23
+
24
+ def swap ( i, j )
25
+ dup.swap!(i, j)
26
+ end
27
+
28
+ end # class Array
29
+
30
+
@@ -0,0 +1,136 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
2
+ # Author: Nicolas Despres <polrop@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: ertai $
6
+ # $Id: spring.rb 53 2004-12-02 22:24:03Z ertai $
7
+
8
+
9
+ require 'thread'
10
+ require 'observer'
11
+
12
+
13
+ class Spring
14
+
15
+ include Observable
16
+
17
+ GET = :get
18
+ SIGN_UP = :sign_up
19
+
20
+ def initialize(*items)
21
+ @q = *items
22
+ @mutex = Mutex.new
23
+ @collecter = []
24
+ end
25
+
26
+ def get(collecter_id)
27
+ @mutex.synchronize do
28
+ if @collecter.include?(collecter_id)
29
+ item = @q.shift
30
+ changed(true)
31
+ notify_observers(self.object_id, GET, collecter_id)
32
+ return item
33
+ end
34
+ end
35
+ end
36
+
37
+ def size
38
+ @mutex.synchronize { return @q.size }
39
+ end
40
+ alias length size
41
+
42
+ def empty?
43
+ @mutex.synchronize { return @q.empty? }
44
+ end
45
+
46
+ def sign_up(collecter_id)
47
+ @mutex.synchronize do
48
+ unless @collecter.include?(collecter_id)
49
+ @collecter << collecter_id
50
+ changed(true)
51
+ notify_observers(self.object_id, SIGN_UP, collecter_id)
52
+ return nil
53
+ end
54
+ end
55
+ end
56
+
57
+ def num_collecter
58
+ @mutex.synchronize { @collecter.length }
59
+ end
60
+
61
+ end # class Spring
62
+
63
+
64
+ #
65
+ # Unit test suite
66
+ #
67
+ if defined? TEST_MODE or $0 == __FILE__
68
+
69
+
70
+ require 'test/unit/ui/yaml/testrunner'
71
+
72
+
73
+ class SpringTest < Test::Unit::TestCase
74
+
75
+ class Obs
76
+
77
+ attr_reader :updated, :msg_seq
78
+
79
+ def initialize(s_id, msg_seq, t_id, spring_test_instance)
80
+ @s_id = s_id
81
+ @msg_seq = msg_seq
82
+ @t_id = t_id
83
+ @updated = false
84
+ @spring_test_instance = spring_test_instance
85
+ end
86
+
87
+ def update(s_id, msg, t_id)
88
+ @updated = true
89
+ @spring_test_instance.test_update(@s_id,
90
+ @msg_seq,
91
+ @t_id,
92
+ s_id,
93
+ msg,
94
+ t_id)
95
+ end
96
+
97
+ end
98
+
99
+ #
100
+ # tests
101
+ #
102
+ def test_simple
103
+ s = Spring.new('hello', 'world')
104
+ q = Queue.new
105
+ thread = Thread.new do
106
+ s.add_observer(q.get)
107
+ assert_equal(2, s.size)
108
+ assert_equal(2, s.length)
109
+ assert_nil(s.get(thread.object_id))
110
+ s.sign_up(thread.object_id)
111
+ assert_equal(1, s.num_collecter)
112
+ assert_equal('hello', s.get(thread.object_id))
113
+ assert_equal('world', s.get(thread.object_id))
114
+ end
115
+ o = Obs.new(s.object_id,
116
+ [Spring::SIGN_UP, Spring::GET, Spring::GET],
117
+ thread.object_id,
118
+ self)
119
+ q.put(o)
120
+ thread.join
121
+ assert_equal(true, o.updated, 'not visited at all')
122
+ assert_equal([], o.msg_seq)
123
+ end
124
+
125
+ # tools
126
+
127
+ def test_update(r_s_id, r_msg, r_t_id, s_id, msg, t_id)
128
+ assert_equal(r_t_id, t_id, 'bad collecter id')
129
+ assert_equal(r_s_id, s_id, 'bad spring id')
130
+ assert_equal(r_msg.shift, msg, 'bad message')
131
+ end
132
+
133
+ end # class SpringTest
134
+
135
+
136
+ end
@@ -0,0 +1,137 @@
1
+ # Copyright: Copyright (c) 2004 Nicolas Despres. All rights reserved.
2
+ # Author: Nicolas Despres <polrop@lrde.epita.fr>.
3
+ # License: Gnu General Public License.
4
+
5
+ # $LastChangedBy: ertai $
6
+ # $Id: spring_set.rb 186 2005-04-03 00:07:45Z ertai $
7
+
8
+
9
+ require 'spring'
10
+
11
+
12
+ class SpringSet
13
+
14
+ def initialize(*springs)
15
+ @springs = {}
16
+ springs.flatten.each do |s|
17
+ @springs[s.object_id] = {
18
+ :spring => s,
19
+ :num_collecter => s.num_collecter,
20
+ :size => s.size
21
+ }
22
+ s.add_observer(self)
23
+ end
24
+ end
25
+
26
+ def update(spring_id, msg, collecter_id)
27
+ case msg
28
+ when Spring::SIGN_UP
29
+ @springs[spring_id][:num_collecter] += 1
30
+ when Spring::GET
31
+ @springs[spring_id][:size] -= 1 if @springs[spring_id][:size] > 0
32
+ end
33
+ end
34
+
35
+ def get_most_free
36
+ calc_stat(:num_collecter) { |a, b| a < b }
37
+ end
38
+
39
+ def get_most_busy
40
+ calc_stat(:num_collecter) { |a, b| a > b }
41
+ end
42
+
43
+ def get_most_full
44
+ calc_stat(:size) { |a, b| a > b }
45
+ end
46
+
47
+ def get_most_empty
48
+ calc_stat(:size) { |a, b| a < b }
49
+ end
50
+
51
+ def size
52
+ @springs.size
53
+ end
54
+
55
+ alias length size
56
+
57
+ def num_collecter(spring_id)
58
+ @springs[spring_id][:num_collecter]
59
+ end
60
+
61
+ def spring_size(spring_id)
62
+ @springs[spring_id][:size]
63
+ end
64
+
65
+ alias spring_length spring_size
66
+
67
+ def each
68
+ @springs.values.each { |v| yield(v[:spring]) }
69
+ end
70
+
71
+ protected
72
+ def calc_stat(field, &cmp)
73
+ spring = nil
74
+ @springs.values.each do |s|
75
+ if spring.nil? or cmp[s[field], spring[field]]
76
+ spring = s
77
+ end
78
+ end
79
+ return spring[:spring]
80
+ end
81
+
82
+ end # class SpringSet
83
+
84
+
85
+ #
86
+ # Unit test suite
87
+ #
88
+ if defined? TEST_MODE or $0 == __FILE__
89
+
90
+
91
+ require 'test/unit/ui/yaml/testrunner'
92
+
93
+
94
+ class SpringSetTest < Test::Unit::TestCase
95
+
96
+ #
97
+ # tests
98
+ #
99
+ def test_simple
100
+ s1 = Spring.new('hello', 'world')
101
+ s2 = Spring.new('bonjour', 'tout', 'monde')
102
+ s = SpringSet.new(s1, s2)
103
+ assert_equal(s1.num_collecter, s.num_collecter(s1.object_id))
104
+ assert_equal(s2.num_collecter, s.num_collecter(s2.object_id))
105
+ assert_equal(s1.size, s.spring_size(s1.object_id))
106
+ assert_equal(s2.length, s.spring_length(s2.object_id))
107
+ thread = Thread.new do
108
+ sleep(0.0001)
109
+ assert_equal(2, s.size)
110
+ assert_equal(2, s.length)
111
+ assert_equal(s2, s.get_most_full)
112
+ assert_equal(s1, s.get_most_empty)
113
+ s1.sign_up(thread.object_id)
114
+ assert_equal(s1.num_collecter, s.num_collecter(s1.object_id))
115
+ assert_equal(s1, s.get_most_busy)
116
+ assert_equal(s2, s.get_most_free)
117
+ s2.sign_up(thread.object_id)
118
+ assert_equal(s2.num_collecter, s.num_collecter(s2.object_id), 'bad num collecter')
119
+ assert_equal('bonjour', s2.get(thread.object_id))
120
+ assert_equal(s2.size, s.spring_size(s2.object_id), 'bad size')
121
+ assert_equal('tout', s2.get(thread.object_id))
122
+ assert_equal(s2.size, s.spring_size(s2.object_id))
123
+ assert_equal('monde', s2.get(thread.object_id))
124
+ assert_equal(s2.size, s.spring_size(s2.object_id))
125
+ assert_equal(nil, s2.get(thread.object_id))
126
+ assert_equal(s2.size, s.spring_size(s2.object_id))
127
+ assert_equal(0, s.spring_size(s2.object_id))
128
+ assert_equal(s1, s.get_most_full)
129
+ assert_equal(s2, s.get_most_empty)
130
+ end
131
+ thread.join
132
+ end
133
+
134
+ end # class SpringSetTest
135
+
136
+
137
+ end