rims 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  module RIMS
4
- VERSION = '0.2.2'
4
+ VERSION = '0.2.3'
5
5
  MAILBOX_DATA_STRUCTURE_VERSION = 'mailbox.2'
6
6
  end
7
7
 
@@ -26,6 +26,8 @@ Gem::Specification.new do |spec|
26
26
 
27
27
  spec.required_ruby_version = '>= 2.0.0'
28
28
 
29
+ spec.add_runtime_dependency "riser", '>= 0.1.7'
30
+ spec.add_runtime_dependency "logger-joint"
29
31
  spec.add_development_dependency "bundler"
30
32
  spec.add_development_dependency "rake"
31
33
  spec.add_development_dependency "test-unit"
@@ -0,0 +1,999 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'fileutils'
4
+ require 'logger'
5
+ require 'net/imap'
6
+ require 'open3'
7
+ require 'pathname'
8
+ require 'pp' if $DEBUG
9
+ require 'rims'
10
+ require 'set'
11
+ require 'test/unit'
12
+ require 'time'
13
+ require 'timeout'
14
+ require 'yaml'
15
+
16
+ module RIMS::Test
17
+ class CommandTest < Test::Unit::TestCase
18
+ include Timeout
19
+
20
+ BASE_DIR = 'cmd_base_dir'
21
+
22
+ def setup
23
+ @base_dir = Pathname(BASE_DIR)
24
+ @base_dir.mkpath
25
+ end
26
+
27
+ def teardown
28
+ @base_dir.rmtree
29
+ end
30
+
31
+ def test_rims_no_args
32
+ stdout, stderr, status = Open3.capture3('rims')
33
+ pp [ stdout, stderr, status ] if $DEBUG
34
+
35
+ assert_equal(1, status.exitstatus)
36
+ assert(! stdout.empty?)
37
+ assert_equal('', stderr)
38
+ end
39
+
40
+ def test_help
41
+ stdout, stderr, status = Open3.capture3('rims', 'help')
42
+ pp [ stdout, stderr, status ] if $DEBUG
43
+
44
+ assert_equal(0, status.exitstatus)
45
+ assert(! stdout.empty?)
46
+ assert_not_match(/debug/, stdout)
47
+ assert_equal('', stderr)
48
+
49
+ stdout, stderr, status = Open3.capture3('rims', 'help', '--show-debug-command')
50
+ pp [ stdout, stderr, status ] if $DEBUG
51
+
52
+ assert_equal(0, status.exitstatus)
53
+ assert(! stdout.empty?)
54
+ assert_match(/debug/, stdout)
55
+ assert_equal('', stderr)
56
+ end
57
+
58
+ def test_version
59
+ stdout, stderr, status = Open3.capture3('rims', 'version')
60
+ pp [ stdout, stderr, status ] if $DEBUG
61
+
62
+ assert_equal(0, status.exitstatus)
63
+ assert_equal(RIMS::VERSION, stdout.chomp)
64
+ assert_equal('', stderr)
65
+ end
66
+
67
+ data('-f' => [ %W[ -f #{BASE_DIR}/config.yml ] ],
68
+ '--config-yaml' => [ %W[ --config-yaml #{BASE_DIR}/config.yml ] ],
69
+ '-r' => [ %W[ -f #{BASE_DIR}/config.yml -r prime ] ],
70
+ '--required-feature' => [ %W[ -f #{BASE_DIR}/config.yml --required-feature=prime ] ],
71
+ '-d,--passwd-file' => [ %W[ -d #{BASE_DIR} --passwd-file=plain:passwd.yml ] ],
72
+ '--base-dir,--passwd-file' => [ %W[ --base-dir=#{BASE_DIR} --passwd-file=plain:passwd.yml ] ],
73
+ '--log-file' => [ %W[ -f #{BASE_DIR}/config.yml --log-file=server.log ] ],
74
+ '-l' => [ %W[ -f #{BASE_DIR}/config.yml -l debug ] ],
75
+ '--log-level' => [ %W[ -f #{BASE_DIR}/config.yml --log-level=debug ] ],
76
+ '--log-shift-age' => [ %W[ -f #{BASE_DIR}/config.yml --log-shift-age=10 ] ],
77
+ '--log-shift-daily' => [ %W[ -f #{BASE_DIR}/config.yml --log-shift-age-daily ] ],
78
+ '--log-shift-weekly' => [ %W[ -f #{BASE_DIR}/config.yml --log-shift-age-weekly ] ],
79
+ '--log-shift-monthly' => [ %W[ -f #{BASE_DIR}/config.yml --log-shift-age-monthly ] ],
80
+ '--log-shift-size' => [ %W[ -f #{BASE_DIR}/config.yml --log-shift-size=1048576 ] ],
81
+ '-v' => [ %W[ -f #{BASE_DIR}/config.yml -v debug ] ],
82
+ '--log-stdout' => [ %W[ -f #{BASE_DIR}/config.yml --log-stdout=debug ] ],
83
+ '--protocol-log-file' => [ %W[ -f #{BASE_DIR}/config.yml --protocol-log-file=imap.log ] ],
84
+ '-p' => [ %W[ -f #{BASE_DIR}/config.yml -p info ] ],
85
+ '--protocol-log-level' => [ %W[ -f #{BASE_DIR}/config.yml --protocol-log-level=info ] ],
86
+ '--protocol-log-shift-age' => [ %W[ -f #{BASE_DIR}/config.yml --protocol-log-shift-age=10 ] ],
87
+ '--protocol-log-shift-age-daily' => [ %W[ -f #{BASE_DIR}/config.yml --protocol-log-shift-age-daily ] ],
88
+ '--protocol-log-shift-age-weekly' => [ %W[ -f #{BASE_DIR}/config.yml --protocol-log-shift-age-weekly ] ],
89
+ '--protocol-log-shift-age-monthly' => [ %W[ -f #{BASE_DIR}/config.yml --protocol-log-shift-age-monthly ] ],
90
+ '--protocol-log-shift-size' => [ %W[ -f #{BASE_DIR}/config.yml --protocol-log-shift-size=1048576 ] ],
91
+ '--daemonize' => [ %W[ -f #{BASE_DIR}/config.yml --daemonize ] ],
92
+ '--no-daemonize' => [ %W[ -f #{BASE_DIR}/config.yml --no-daemonize ] ],
93
+ '--daemon-debug' => [ %W[ -f #{BASE_DIR}/config.yml --daemon-debug ] ],
94
+ '--no-daemon-debug' => [ %W[ -f #{BASE_DIR}/config.yml --no-daemon-debug ] ],
95
+ '--status-file' => [ %W[ -f #{BASE_DIR}/config.yml --status-file=status.yml ] ],
96
+ '--privilege-user' => [ %W[ -f #{BASE_DIR}/config.yml --privilege-user=#{Process::UID.eid} ] ],
97
+ '--privilege-group' => [ %W[ -f #{BASE_DIR}/config.yml --privilege-group=#{Process::GID.eid} ] ],
98
+ '-s' => [ %W[ -f #{BASE_DIR}/config.yml -s localhost:1430 ] ],
99
+ '--listen' => [ %W[ -f #{BASE_DIR}/config.yml --listen=localhost:1430 ] ],
100
+ '--accept-polling-timeout' => [ %W[ -f #{BASE_DIR}/config.yml --accept-polling-timeout=0.1 ] ],
101
+ '--thread-num' => [ %W[ -f #{BASE_DIR}/config.yml --thread-num=4 ] ],
102
+ '--thread-queue-size' => [ %W[ -f #{BASE_DIR}/config.yml --thread-queue-size=128 ] ],
103
+ '--thread-queue-polling-timeout' => [ %W[ -f #{BASE_DIR}/config.yml --thread-queue-polling-timeout=0.1 ] ],
104
+ '--send-buffer-limit' => [ %W[ -f #{BASE_DIR}/config.yml --send-buffer-limit=131072 ] ],
105
+ '--read-lock-timeout' => [ %W[ -f #{BASE_DIR}/config.yml --read-lock-timeout=10 ] ],
106
+ '--write-lock-timeout' => [ %W[ -f #{BASE_DIR}/config.yml --write-lock-timeout=10 ] ],
107
+ '--clenup-write-lock-timeout' => [ %W[ -f #{BASE_DIR}/config.yml --write-lock-timeout=5 ] ],
108
+ '--meta-kvs-type' => [ %W[ -f #{BASE_DIR}/config.yml --meta-kvs-type=gdbm ] ],
109
+ '--meta-kvs-config' => [ %W[ -f #{BASE_DIR}/config.yml --meta-kvs-config={} ] ],
110
+ '--use-meta-kvs-checksum' => [ %W[ -f #{BASE_DIR}/config.yml --use-meta-kvs-checksum ] ],
111
+ '--no-use-meta-kvs-checksum' => [ %W[ -f #{BASE_DIR}/config.yml --no-use-meta-kvs-checksum ] ],
112
+ '--text-kvs-type' => [ %W[ -f #{BASE_DIR}/config.yml --text-kvs-type=gdbm ] ],
113
+ '--text-kvs-config' => [ %W[ -f #{BASE_DIR}/config.yml --text-kvs-config={} ] ],
114
+ '--use-text-kvs-checksum' => [ %W[ -f #{BASE_DIR}/config.yml --use-text-kvs-checksum ] ],
115
+ '--no-use-text-kvs-checksum' => [ %W[ -f #{BASE_DIR}/config.yml --no-use-text-kvs-checksum ] ],
116
+ '--auth-hostname' => [ %W[ -f #{BASE_DIR}/config.yml --auth-hostname=imap.example.com ] ],
117
+ '--passwd-config' => [ %W[ -d #{BASE_DIR} --passwd-config=plain:[{"user":"foo","pass":"foo"}] ] ],
118
+ '--mail-delivery-user' => [ %W[ -f #{BASE_DIR}/config.yml --mail-delivery-user=postman ] ],
119
+
120
+ # deplicated options
121
+ 'deplicated:--imap-host' => [ %W[ -f #{BASE_DIR}/config.yml --imap-host=localhost ], true ],
122
+ 'deplicated:--imap-port' => [ %W[ -f #{BASE_DIR}/config.yml --imap-port=1430 ], true ],
123
+ 'deplicated:--ip-addr' => [ %W[ -f #{BASE_DIR}/config.yml --ip-addr=0.0.0.0 ], true ],
124
+ 'deplicated:--ip-port' => [ %W[ -f #{BASE_DIR}/config.yml --ip-port=1430 ], true ],
125
+ 'deplicated:--kvs-type' => [ %W[ -f #{BASE_DIR}/config.yml --kvs-type=gdbm ], true ],
126
+ 'deplicated:--use-kvs-cksum' => [ %W[ -f #{BASE_DIR}/config.yml --use-kvs-cksum ], true ],
127
+ 'deplicated:--no-use-kvs-cksum' => [ %W[ -f #{BASE_DIR}/config.yml --no-use-kvs-cksum ], true ],
128
+ 'deplicated:-u,-w' => [ %W[ -d #{BASE_DIR} -u foo -w foo ], true ],
129
+ 'deplicated:--username,--password' => [ %W[ -d #{BASE_DIR} --username=foo --password=foo ], true ])
130
+ def test_server(data)
131
+ options, deplicated = data
132
+
133
+ (@base_dir + 'passwd.yml').write([ { 'user' => 'foo', 'pass' => 'foo' } ].to_yaml)
134
+ (@base_dir + 'config.yml').write({ 'authentication' => {
135
+ 'password_sources' => [
136
+ { 'type' => 'plain',
137
+ 'configuration_file' => 'passwd.yml'
138
+ }
139
+ ]
140
+ }
141
+ }.to_yaml)
142
+
143
+ Open3.popen3('rims', 'server', *options) {|stdin, stdout, stderr, wait_thread|
144
+ begin
145
+ stdout_thread = Thread.new{
146
+ result = stdout.read
147
+ puts [ :stdout, result ].pretty_inspect if $DEBUG
148
+ result
149
+ }
150
+ stderr_thread = Thread.new{
151
+ result = stderr.read
152
+ puts [ :stderr, result ].pretty_inspect if $DEBUG
153
+ result
154
+ }
155
+
156
+ imap = timeout(10) {
157
+ begin
158
+ Net::IMAP.new('localhost', 1430)
159
+ rescue SystemCallError
160
+ sleep(0.1)
161
+ retry
162
+ end
163
+ }
164
+ begin
165
+ imap.noop
166
+ imap.login('foo', 'foo')
167
+ imap.noop
168
+ imap.append('INBOX', 'HALO')
169
+ imap.select('INBOX')
170
+ imap.noop
171
+ assert_equal([ 1 ], imap.search([ '*' ]))
172
+ fetch_list = imap.fetch(1, %w[ RFC822 ])
173
+ assert_equal([ 'HALO' ], fetch_list.map{|f| f.attr['RFC822'] })
174
+ imap.logout
175
+ ensure
176
+ imap.disconnect
177
+ end
178
+ ensure
179
+ Process.kill(:TERM, wait_thread.pid)
180
+ stdout_result = stdout_thread.value if stdout_thread
181
+ stderr_result = stderr_thread.value if stderr_thread
182
+ end
183
+
184
+ server_status = wait_thread.value
185
+ pp server_status if $DEBUG
186
+ assert_equal(0, server_status.exitstatus)
187
+
188
+ assert(! stdout_result.empty?)
189
+ if (deplicated) then
190
+ assert_match(/^warning:/, stderr_result)
191
+ else
192
+ assert_equal('', stderr_result)
193
+ end
194
+ }
195
+ end
196
+
197
+ def test_daemon_status_stopped
198
+ stdout, stderr, status = Open3.capture3('rims', 'daemon', 'status', '-d', @base_dir.to_s)
199
+ pp [ stdout, stderr, status ] if $DEBUG
200
+ assert_match(/stopped/, stdout)
201
+ assert_equal('', stderr)
202
+ assert_equal(1, status.exitstatus)
203
+
204
+ %w[ -v --verbose ].each do |option|
205
+ stdout, stderr, status = Open3.capture3('rims', 'daemon', option, 'status', '-d', @base_dir.to_s, "status verbose option: #{option}")
206
+ pp [ stdout, stderr, status ] if $DEBUG
207
+ assert_match(/stopped/, stdout)
208
+ assert_equal('', stderr)
209
+ assert_equal(1, status.exitstatus)
210
+ end
211
+
212
+ %w[ -q --quiet ].each do |option|
213
+ stdout, stderr, status = Open3.capture3('rims', 'daemon', option, 'status', '-d', @base_dir.to_s, "status quiet option: #{option}")
214
+ pp [ stdout, stderr, status ] if $DEBUG
215
+ assert_equal('', stdout)
216
+ assert_equal('', stderr)
217
+ assert_equal(1, status.exitstatus)
218
+ end
219
+
220
+ stdout, stderr, status = Open3.capture3('rims', 'daemon', '--status-code', 'status', '-d', @base_dir.to_s)
221
+ pp [ stdout, stderr, status ] if $DEBUG
222
+ assert_match(/stopped/, stdout)
223
+ assert_equal('', stderr)
224
+ assert_equal(1, status.exitstatus)
225
+
226
+ stdout, stderr, status = Open3.capture3('rims', 'daemon', '--no-status-code', 'status', '-d', @base_dir.to_s)
227
+ pp [ stdout, stderr, status ] if $DEBUG
228
+ assert_match(/stopped/, stdout)
229
+ assert_equal('', stderr)
230
+ assert_equal(0, status.exitstatus)
231
+ end
232
+
233
+ def test_daemon_run
234
+ # need for riser 0.1.7 or later to close stdin/stdout/stderr of daemon process
235
+ stdout, stderr, status = Open3.capture3('rims', 'daemon', 'start', '-d', @base_dir.to_s, '--passwd-config=plain:[{"user":"foo","pass":"foo"}]')
236
+ begin
237
+ pp [ stdout, stderr, status ] if $DEBUG
238
+ assert_equal('', stdout)
239
+ assert_equal('', stderr)
240
+ assert_equal(0, status.exitstatus)
241
+
242
+ imap = timeout(10) {
243
+ begin
244
+ Net::IMAP.new('localhost', 1430)
245
+ rescue SystemCallError
246
+ sleep(0.1)
247
+ retry
248
+ end
249
+ }
250
+ begin
251
+ imap.noop
252
+ imap.login('foo', 'foo')
253
+ imap.noop
254
+ imap.append('INBOX', 'HALO')
255
+ imap.select('INBOX')
256
+ imap.noop
257
+ assert_equal([ 1 ], imap.search([ '*' ]))
258
+ fetch_list = imap.fetch(1, %w[ RFC822 ])
259
+ assert_equal([ 'HALO' ], fetch_list.map{|f| f.attr['RFC822'] })
260
+ imap.logout
261
+ ensure
262
+ imap.disconnect
263
+ end
264
+
265
+ stdout, stderr, status = Open3.capture3('rims', 'daemon', 'status', '-d', @base_dir.to_s)
266
+ pp [ stdout, stderr, status ] if $DEBUG
267
+ assert_match(/running/, stdout)
268
+ assert_equal('', stderr)
269
+ assert_equal(0, status.exitstatus)
270
+
271
+ %w[ -v --verbose ].each do |option|
272
+ stdout, stderr, status = Open3.capture3('rims', 'daemon', option, 'status', '-d', @base_dir.to_s, "status verbose option: #{option}")
273
+ pp [ stdout, stderr, status ] if $DEBUG
274
+ assert_match(/running/, stdout)
275
+ assert_equal('', stderr)
276
+ assert_equal(0, status.exitstatus)
277
+ end
278
+
279
+ %w[ -q --quiet ].each do |option|
280
+ stdout, stderr, status = Open3.capture3('rims', 'daemon', option, 'status', '-d', @base_dir.to_s, "status quiet option: #{option}")
281
+ pp [ stdout, stderr, status ] if $DEBUG
282
+ assert_equal('', stdout)
283
+ assert_equal('', stderr)
284
+ assert_equal(0, status.exitstatus)
285
+ end
286
+
287
+ stdout, stderr, status = Open3.capture3('rims', 'daemon', '--status-code', 'status', '-d', @base_dir.to_s)
288
+ pp [ stdout, stderr, status ] if $DEBUG
289
+ assert_match(/running/, stdout)
290
+ assert_equal('', stderr)
291
+ assert_equal(0, status.exitstatus)
292
+
293
+ stdout, stderr, status = Open3.capture3('rims', 'daemon', '--no-status-code', 'status', '-d', @base_dir.to_s)
294
+ pp [ stdout, stderr, status ] if $DEBUG
295
+ assert_match(/running/, stdout)
296
+ assert_equal('', stderr)
297
+ assert_equal(0, status.exitstatus)
298
+ ensure
299
+ stdout, stderr, status = Open3.capture3('rims', 'daemon', 'stop', '-d', @base_dir.to_s)
300
+ pp [ stdout, stderr, status ] if $DEBUG
301
+ end
302
+ assert_equal('', stdout)
303
+ assert_equal('', stderr)
304
+ assert_equal(0, status.exitstatus)
305
+ end
306
+
307
+ tls_dir = Pathname(__FILE__).parent.parent / "tls"
308
+ TLS_CA_CERT = tls_dir / 'ca.cert'
309
+ TLS_SERVER_CERT = tls_dir / 'server_localhost.cert'
310
+ TLS_SERVER_PKEY = tls_dir / 'server.priv_key'
311
+
312
+ unless ([ TLS_CA_CERT, TLS_SERVER_CERT, TLS_SERVER_PKEY ].all?(&:file?)) then
313
+ warn("warning: do `rake test_cert:make' to create TLS private key file and TLS certificate file for test.")
314
+ end
315
+
316
+ def run_server(use_ssl: false, optional: {})
317
+ config = {
318
+ logging: {
319
+ file: { level: 'debug' },
320
+ stdout: { level: 'debug' },
321
+ protocol: { level: 'info' }
322
+ },
323
+ server: {
324
+ listen: 'localhost:1430'
325
+ },
326
+ authentication: {
327
+ password_sources: [
328
+ { type: 'plain',
329
+ configuration: [
330
+ { user: 'foo', pass: 'foo' },
331
+ { user: '#postman', pass: '#postman' }
332
+ ]
333
+ }
334
+ ]
335
+ },
336
+ authorization: {
337
+ mail_delivery_user: '#postman'
338
+ }
339
+ }
340
+
341
+ if (use_ssl) then
342
+ FileUtils.cp(TLS_SERVER_PKEY.to_s, @base_dir.to_s)
343
+ FileUtils.cp(TLS_SERVER_CERT.to_s, @base_dir.to_s)
344
+ config.update({ openssl: {
345
+ ssl_context: %Q{
346
+ _.cert = X509::Certificate.new((base_dir / #{TLS_SERVER_CERT.basename.to_s.dump}).read)
347
+ _.key = PKey.read((base_dir / #{TLS_SERVER_PKEY.basename.to_s.dump}).read)
348
+ }
349
+ }
350
+ })
351
+ end
352
+
353
+ config.update(optional)
354
+
355
+ config_path = @base_dir + 'config.yml'
356
+ config_path.write(RIMS::Service::Configuration.stringify_symbol(config).to_yaml)
357
+
358
+ Open3.popen3('rims', 'server', '-f', config_path.to_s) {|stdin, stdout, stderr, wait_thread|
359
+ begin
360
+ stdout_thread = Thread.new{
361
+ result = stdout.read
362
+ puts [ :stdout, result ].pretty_inspect if $DEBUG
363
+ result
364
+ }
365
+ stderr_thread = Thread.new{
366
+ result = stderr.read
367
+ puts [ :stderr, result ].pretty_inspect if $DEBUG
368
+ result
369
+ }
370
+
371
+ imap = timeout(10) {
372
+ begin
373
+ Net::IMAP.new('localhost', 1430, use_ssl, TLS_CA_CERT.to_s)
374
+ rescue SystemCallError
375
+ sleep(0.1)
376
+ retry
377
+ end
378
+ }
379
+ begin
380
+ imap.noop
381
+ ret_val = yield(imap)
382
+ imap.logout
383
+ ensure
384
+ imap.disconnect
385
+ end
386
+ ensure
387
+ Process.kill(:TERM, wait_thread.pid)
388
+ stdout_thread.join if stdout_thread
389
+ stderr_thread.join if stderr_thread
390
+ end
391
+
392
+ server_status = wait_thread.value
393
+ pp server_status if $DEBUG
394
+ assert_equal(0, server_status.exitstatus)
395
+
396
+ ret_val
397
+ }
398
+ end
399
+ private :run_server
400
+
401
+ data('-f' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml ] ],
402
+ '--config-yaml' => [ false, 10, %W[ --config-yaml=#{BASE_DIR}/postman.yml ] ],
403
+ '-v' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml -v ] ],
404
+ '--verbose' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --verbose ] ],
405
+ '--no-verbose' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --no-verbose ] ],
406
+ '-n' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml -n localhost ] ],
407
+ '--host' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --host=localhost ] ],
408
+ '-o' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml -o 1430 ] ],
409
+ '--port' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --port=1430 ] ],
410
+ '-s,--ca-cert' => [ true, 10, %W[ -f #{BASE_DIR}/postman.yml -s --ca-cert=#{TLS_CA_CERT} ] ],
411
+ '-s,--ssl-params' => [ true, 10, %W[ -f #{BASE_DIR}/postman.yml -s --ssl-params={"ca_file":#{TLS_CA_CERT.to_s.dump}} ] ],
412
+ '--use-ssl,--ca-cert' => [ true, 10, %W[ -f #{BASE_DIR}/postman.yml --use-ssl --ca-cert=#{TLS_CA_CERT} ] ],
413
+ '--use-ssl,--ssl-params' => [ true, 10, %W[ -f #{BASE_DIR}/postman.yml --use-ssl --ssl-params={"ca_file":#{TLS_CA_CERT.to_s.dump}} ] ],
414
+ '--no-use-ssl' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --no-use-ssl ] ],
415
+ '-u' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml -u #postman ] ],
416
+ '--username' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --username #postman ] ],
417
+ '-w' => [ false, 10, %W[ -w #postman ] ],
418
+ '--password' => [ false, 10, %W[ --password=#postman ] ],
419
+ '--auth-type=login' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --auth-type=login ] ],
420
+ '--auth-type=plain' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --auth-type=plain ] ],
421
+ '--auth-type=cram-md5' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --auth-type=cram-md5 ] ],
422
+ '-m' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml -m INBOX ] ],
423
+ '--mailbox' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --mailbox=INBOX ] ],
424
+ '--store-flag-answered' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --store-flag-answered ], [ :Answered ] ],
425
+ '--store-flag-flagged' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --store-flag-flagged ], [ :Flagged ] ],
426
+ '--store-flag-deleted' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --store-flag-deleted ], [ :Deleted ] ],
427
+ '--store-flag-seen' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --store-flag-seen ], [ :Seen ] ],
428
+ '--store-flag-draft' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --store-flag-draft ], [ :Draft ] ],
429
+ '--store-flag-all' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --store-flag-answered
430
+ --store-flag-flagged
431
+ --store-flag-deleted
432
+ --store-flag-seen
433
+ --store-flag-draft ], [ :Answered, :Flagged, :Deleted, :Seen, :Draft ] ],
434
+ '--no-store-flag-answered' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --no-store-flag-answered ], [] ],
435
+ '--no-store-flag-flagged' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --no-store-flag-flagged ], [] ],
436
+ '--no-store-flag-deleted' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --no-store-flag-deleted ], [] ],
437
+ '--no-store-flag-seen' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --no-store-flag-seen ], [] ],
438
+ '--no-store-flag-draft' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --no-store-flag-draft ], [] ],
439
+ '--look-for-date=servertime' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --look-for-date=servertime ] ],
440
+ '--look-for-date=localtime' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --look-for-date=localtime ] ],
441
+ '--look-for-date=filetime' => [ false, Time.parse('Mon, 01 Apr 2019 12:00:00 +0900'), %W[ -f #{BASE_DIR}/postman.yml --look-for-date=filetime ] ],
442
+ '--look-for-date=mailheader' => [ false, Time.parse('Mon, 01 Apr 2019 09:00:00 +0900'), %W[ -f #{BASE_DIR}/postman.yml --look-for-date=mailheader ] ],
443
+ '--imap-debug' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --imap-debug ] ],
444
+ '--no-imap-debug' => [ false, 10, %W[ -f #{BASE_DIR}/postman.yml --no-imap-debug ] ])
445
+ def test_post_mail(data)
446
+ use_ssl, expected_date, options, expected_flags = data
447
+
448
+ config = @base_dir + 'postman.yml'
449
+ config.write({ 'password' => '#postman' }.to_yaml)
450
+
451
+ message = <<-'EOF'
452
+ From: foo@mail.example.com
453
+ To: bar@mail.example.com
454
+ Subject: HALO
455
+ Date: Mon, 01 Apr 2019 09:00:00 +0900
456
+
457
+ Hello world.
458
+ EOF
459
+
460
+ message_path = @base_dir + 'message.txt'
461
+ message_path.write(message)
462
+
463
+ t = Time.parse('Mon, 01 Apr 2019 12:00:00 +0900')
464
+ message_path.utime(t, t)
465
+
466
+ run_server(use_ssl: use_ssl) {|imap|
467
+ stdout, stderr, status = Open3.capture3('rims', 'post-mail', *options, 'foo', message_path.to_s)
468
+ pp [ stdout, stderr, status ] if $DEBUG
469
+ assert_equal(0, status.exitstatus)
470
+
471
+ imap.login('foo', 'foo')
472
+ imap.examine('INBOX') # for read-only
473
+ fetch_list = imap.fetch(1, %w[ RFC822 INTERNALDATE FLAGS ])
474
+ assert_equal(1, fetch_list.length)
475
+ assert_equal(message, fetch_list[0].attr['RFC822'])
476
+
477
+ internal_date = Time.parse(fetch_list[0].attr['INTERNALDATE'])
478
+ case (expected_date)
479
+ when Time
480
+ assert_equal(expected_date, internal_date)
481
+ when Integer
482
+ t = Time.now
483
+ delta_t = expected_date
484
+ assert(((t - delta_t)..t).cover? internal_date)
485
+ else
486
+ flunk
487
+ end
488
+
489
+ flags = [ :Recent ].to_set
490
+ flags += expected_flags if expected_flags
491
+ assert_equal(flags, fetch_list[0].attr['FLAGS'].to_set)
492
+ }
493
+ end
494
+
495
+ data('-f' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml ] ],
496
+ '--config-yaml' => [ false, 10, %W[ --config-yaml=#{BASE_DIR}/append.yml ] ],
497
+ '-v' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml -v ] ],
498
+ '--verbose' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --verbose ] ],
499
+ '--no-verbose' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --no-verbose ] ],
500
+ '-n' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml -n localhost ] ],
501
+ '--host' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --host=localhost ] ],
502
+ '-o' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml -o 1430 ] ],
503
+ '--port' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --port=1430 ] ],
504
+ '-s,--ca-cert' => [ true, 10, %W[ -f #{BASE_DIR}/append.yml -s --ca-cert=#{TLS_CA_CERT} ] ],
505
+ '-s,--ssl-params' => [ true, 10, %W[ -f #{BASE_DIR}/append.yml -s --ssl-params={"ca_file":#{TLS_CA_CERT.to_s.dump}} ] ],
506
+ '--use-ssl,--ca-cert' => [ true, 10, %W[ -f #{BASE_DIR}/append.yml --use-ssl --ca-cert=#{TLS_CA_CERT} ] ],
507
+ '--use-ssl,--ssl-params' => [ true, 10, %W[ -f #{BASE_DIR}/append.yml --use-ssl --ssl-params={"ca_file":#{TLS_CA_CERT.to_s.dump}} ] ],
508
+ '--no-use-ssl' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --no-use-ssl ] ],
509
+ '-u,-w,-o' => [ false, 10, %W[ -u foo -w foo -o 1430 ] ],
510
+ '--username,--password,--port' => [ false, 10, %W[ --username=foo --password=foo --port=1430 ] ],
511
+ '--auth-type=login' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --auth-type=login ] ],
512
+ '--auth-type=plain' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --auth-type=plain ] ],
513
+ '--auth-type=cram-md5' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --auth-type=cram-md5 ] ],
514
+ '-m' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml -m INBOX ] ],
515
+ '--mailbox' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --mailbox=INBOX ] ],
516
+ '--store-flag-answered' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --store-flag-answered ], [ :Answered ] ],
517
+ '--store-flag-flagged' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --store-flag-flagged ], [ :Flagged ] ],
518
+ '--store-flag-deleted' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --store-flag-deleted ], [ :Deleted ] ],
519
+ '--store-flag-seen' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --store-flag-seen ], [ :Seen ] ],
520
+ '--store-flag-draft' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --store-flag-draft ], [ :Draft ] ],
521
+ '--store-flag-all' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --store-flag-answered
522
+ --store-flag-flagged
523
+ --store-flag-deleted
524
+ --store-flag-seen
525
+ --store-flag-draft ], [ :Answered, :Flagged, :Deleted, :Seen, :Draft ] ],
526
+ '--no-store-flag-answered' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --no-store-flag-answered ], [] ],
527
+ '--no-store-flag-flagged' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --no-store-flag-flagged ], [] ],
528
+ '--no-store-flag-deleted' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --no-store-flag-deleted ], [] ],
529
+ '--no-store-flag-seen' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --no-store-flag-seen ], [] ],
530
+ '--no-store-flag-draft' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --no-store-flag-draft ], [] ],
531
+ '--look-for-date=servertime' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --look-for-date=servertime ] ],
532
+ '--look-for-date=localtime' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --look-for-date=localtime ] ],
533
+ '--look-for-date=filetime' => [ false, Time.parse('Mon, 01 Apr 2019 12:00:00 +0900'), %W[ -f #{BASE_DIR}/append.yml --look-for-date=filetime ] ],
534
+ '--look-for-date=mailheader' => [ false, Time.parse('Mon, 01 Apr 2019 09:00:00 +0900'), %W[ -f #{BASE_DIR}/append.yml --look-for-date=mailheader ] ],
535
+ '--imap-debug' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --imap-debug ] ],
536
+ '--no-imap-debug' => [ false, 10, %W[ -f #{BASE_DIR}/append.yml --no-imap-debug ] ])
537
+ def test_imap_append(data)
538
+ use_ssl, expected_date, options, expected_flags = data
539
+
540
+ config = @base_dir + 'append.yml'
541
+ config.write({ 'imap_port' => 1430,
542
+ 'username' => 'foo',
543
+ 'password' => 'foo'
544
+ }.to_yaml)
545
+
546
+ message = <<-'EOF'
547
+ From: foo@mail.example.com
548
+ To: bar@mail.example.com
549
+ Subject: HALO
550
+ Date: Mon, 01 Apr 2019 09:00:00 +0900
551
+
552
+ Hello world.
553
+ EOF
554
+
555
+ message_path = @base_dir + 'message.txt'
556
+ message_path.write(message)
557
+
558
+ t = Time.parse('Mon, 01 Apr 2019 12:00:00 +0900')
559
+ message_path.utime(t, t)
560
+
561
+ run_server(use_ssl: use_ssl) {|imap|
562
+ stdout, stderr, status = Open3.capture3('rims', 'imap-append', *options, message_path.to_s)
563
+ pp [ stdout, stderr, status ] if $DEBUG
564
+ assert_equal(0, status.exitstatus)
565
+
566
+ imap.login('foo', 'foo')
567
+ imap.examine('INBOX') # for read-only
568
+ fetch_list = imap.fetch(1, %w[ RFC822 INTERNALDATE FLAGS ])
569
+ assert_equal(1, fetch_list.length)
570
+ assert_equal(message, fetch_list[0].attr['RFC822'])
571
+
572
+ internal_date = Time.parse(fetch_list[0].attr['INTERNALDATE'])
573
+ case (expected_date)
574
+ when Time
575
+ assert_equal(expected_date, internal_date)
576
+ when Integer
577
+ t = Time.now
578
+ delta_t = expected_date
579
+ assert(((t - delta_t)..t).cover? internal_date)
580
+ else
581
+ flunk
582
+ end
583
+
584
+ flags = [ :Recent ].to_set
585
+ flags += expected_flags if expected_flags
586
+ assert_equal(flags, fetch_list[0].attr['FLAGS'].to_set)
587
+ }
588
+ end
589
+
590
+ data('default' => [ true, true, false, %w[] ],
591
+ '-r' => [ true, true, false, %w[ -r prime ] ],
592
+ '--required-feature' => [ true, true, false, %w[ --required-feature=prime ] ],
593
+ '--kvs-type' => [ true, true, false, %w[ --kvs-type=gdbm ] ],
594
+ '--use-kvs-checksum' => [ true, true, false, %w[ --use-kvs-checksum ] ],
595
+ '--no-use-kvs-checksum' => [ true, true, false, %w[ --no-use-kvs-checksum ],
596
+ { storage:
597
+ { meta_key_value_store:
598
+ { use_checksum:
599
+ false
600
+ }
601
+ }
602
+ }
603
+ ],
604
+ '-v' => [ true, true, false, %w[ -v ] ],
605
+ '--verbose' => [ true, true, false, %w[ --verbose ] ],
606
+ '--no-verbose' => [ false, true, false, %w[ --no-verbose ] ],
607
+ '--quiet' => [ false, true, false, %w[ --quiet ] ],
608
+ '--no-quiet' => [ true, true, false, %w[ --no-quiet ] ],
609
+ '--return-flag-exit-code' => [ true, true, false, %w[ --return-flag-exit-code ] ],
610
+ '--no-return-flag-exit-code' => [ true, false, false, %w[ --no-return-flag-exit-code ] ],
611
+
612
+ # deplicated options
613
+ 'deplicated:--load-library' => [ true, true, true, %w[ --load-library=prime ] ],
614
+ 'deplicated:--use-kvs-cksum' => [ true, true, true, %w[ --use-kvs-cksum ] ],
615
+ 'deplicated:--no-use-kvs-cksum' => [ true, true, true, %w[ --no-use-kvs-cksum ],
616
+ { storage:
617
+ { meta_key_value_store:
618
+ { use_checksum:
619
+ false
620
+ }
621
+ }
622
+ }
623
+ ])
624
+ def test_mbox_dirty_flag_true(data)
625
+ expected_stdout, expected_status, deplicated, options, config = data
626
+
627
+ run_server(optional: config || {}) {|imap|
628
+ imap.login('foo', 'foo')
629
+ imap.select('INBOX')
630
+ }
631
+
632
+ svc_conf = RIMS::Service::Configuration.new
633
+ svc_conf.load(base_dir: @base_dir.to_s)
634
+ foo_mbox_path = svc_conf.make_key_value_store_path(RIMS::MAILBOX_DATA_STRUCTURE_VERSION,
635
+ RIMS::Authentication.unique_user_id('foo'))
636
+
637
+ stdout, stderr, status = Open3.capture3('rims', 'mbox-dirty-flag', '--quiet', '--enable-dirty-flag', foo_mbox_path.to_s)
638
+ assert_equal('', stdout)
639
+ assert_equal('', stderr)
640
+ assert_equal(1, status.exitstatus)
641
+
642
+ stdout, stderr, status = Open3.capture3('rims', 'mbox-dirty-flag', *options, foo_mbox_path.to_s)
643
+ pp [ stdout, stderr, status ] if $DEBUG
644
+ if (expected_stdout) then
645
+ assert_match(/dirty flag is true/, stdout)
646
+ else
647
+ assert_equal('', stdout)
648
+ end
649
+ if (deplicated) then
650
+ assert_match(/warning/, stderr)
651
+ else
652
+ assert_equal('', stderr)
653
+ end
654
+ if (expected_status) then
655
+ assert_equal(1, status.exitstatus)
656
+ else
657
+ assert_equal(0, status.exitstatus)
658
+ end
659
+ end
660
+
661
+ data('default' => [ true, true, false, %w[] ],
662
+ '-r' => [ true, true, false, %w[ -r prime ] ],
663
+ '--required-feature' => [ true, true, false, %w[ --required-feature=prime ] ],
664
+ '--kvs-type' => [ true, true, false, %w[ --kvs-type=gdbm ] ],
665
+ '--use-kvs-checksum' => [ true, true, false, %w[ --use-kvs-checksum ] ],
666
+ '--no-use-kvs-checksum' => [ true, true, false, %w[ --no-use-kvs-checksum ],
667
+ { storage:
668
+ { meta_key_value_store:
669
+ { use_checksum:
670
+ false
671
+ }
672
+ }
673
+ }
674
+ ],
675
+ '-v' => [ true, true, false, %w[ -v ] ],
676
+ '--verbose' => [ true, true, false, %w[ --verbose ] ],
677
+ '--no-verbose' => [ false, true, false, %w[ --no-verbose ] ],
678
+ '--quiet' => [ false, true, false, %w[ --quiet ] ],
679
+ '--no-quiet' => [ true, true, false, %w[ --no-quiet ] ],
680
+ '--return-flag-exit-code' => [ true, true, false, %w[ --return-flag-exit-code ] ],
681
+ '--no-return-flag-exit-code' => [ true, false, false, %w[ --no-return-flag-exit-code ] ],
682
+
683
+ # deplicated options
684
+ 'deplicated:--load-library' => [ true, true, true, %w[ --load-library=prime ] ],
685
+ 'deplicated:--use-kvs-cksum' => [ true, true, true, %w[ --use-kvs-cksum ] ],
686
+ 'deplicated:--no-use-kvs-cksum' => [ true, true, true, %w[ --no-use-kvs-cksum ],
687
+ { storage:
688
+ { meta_key_value_store:
689
+ { use_checksum:
690
+ false
691
+ }
692
+ }
693
+ }
694
+ ])
695
+ def test_mbox_dirty_flag_false(data)
696
+ expected_stdout, expected_status, deplicated, options, config = data
697
+
698
+ run_server(optional: config || {}) {|imap|
699
+ imap.login('foo', 'foo')
700
+ imap.select('INBOX')
701
+ }
702
+
703
+ svc_conf = RIMS::Service::Configuration.new
704
+ svc_conf.load(base_dir: @base_dir.to_s)
705
+ foo_mbox_path = svc_conf.make_key_value_store_path(RIMS::MAILBOX_DATA_STRUCTURE_VERSION,
706
+ RIMS::Authentication.unique_user_id('foo'))
707
+
708
+ stdout, stderr, status = Open3.capture3('rims', 'mbox-dirty-flag', *options, foo_mbox_path.to_s)
709
+ pp [ stdout, stderr, status ] if $DEBUG
710
+ if (expected_stdout) then
711
+ assert_match(/dirty flag is false/, stdout)
712
+ else
713
+ assert_equal('', stdout)
714
+ end
715
+ if (deplicated) then
716
+ assert_match(/warning/, stderr)
717
+ else
718
+ assert_equal('', stderr)
719
+ end
720
+ if (expected_status) then
721
+ assert_equal(0, status.exitstatus)
722
+ else
723
+ assert_equal(0, status.exitstatus)
724
+ end
725
+ end
726
+
727
+ data('default' => [ true, true, false, %w[] ],
728
+ '-r' => [ true, true, false, %w[ -r prime ] ],
729
+ '--required-feature' => [ true, true, false, %w[ --required-feature=prime ] ],
730
+ '--kvs-type' => [ true, true, false, %w[ --kvs-type=gdbm ] ],
731
+ '--use-kvs-checksum' => [ true, true, false, %w[ --use-kvs-checksum ] ],
732
+ '--no-use-kvs-checksum' => [ true, true, false, %w[ --no-use-kvs-checksum ],
733
+ { storage:
734
+ { meta_key_value_store:
735
+ { use_checksum:
736
+ false
737
+ }
738
+ }
739
+ }
740
+ ],
741
+ '-v' => [ true, true, false, %w[ -v ] ],
742
+ '--verbose' => [ true, true, false, %w[ --verbose ] ],
743
+ '--no-verbose' => [ false, true, false, %w[ --no-verbose ] ],
744
+ '--quiet' => [ false, true, false, %w[ --quiet ] ],
745
+ '--no-quiet' => [ true, true, false, %w[ --no-quiet ] ],
746
+ '--return-flag-exit-code' => [ true, true, false, %w[ --return-flag-exit-code ] ],
747
+ '--no-return-flag-exit-code' => [ true, false, false, %w[ --no-return-flag-exit-code ] ],
748
+
749
+ # deplicated options
750
+ 'deplicated:--load-library' => [ true, true, true, %w[ --load-library=prime ] ],
751
+ 'deplicated:--use-kvs-cksum' => [ true, true, true, %w[ --use-kvs-cksum ] ],
752
+ 'deplicated:--no-use-kvs-cksum' => [ true, true, true, %w[ --no-use-kvs-cksum ],
753
+ { storage:
754
+ { meta_key_value_store:
755
+ { use_checksum:
756
+ false
757
+ }
758
+ }
759
+ }
760
+ ])
761
+ def test_mbox_dirty_flag_enable(data)
762
+ expected_stdout, expected_status, deplicated, options, config = data
763
+
764
+ run_server(optional: config || {}) {|imap|
765
+ imap.login('foo', 'foo')
766
+ imap.select('INBOX')
767
+ }
768
+
769
+ svc_conf = RIMS::Service::Configuration.new
770
+ svc_conf.load(base_dir: @base_dir.to_s)
771
+ foo_mbox_path = svc_conf.make_key_value_store_path(RIMS::MAILBOX_DATA_STRUCTURE_VERSION,
772
+ RIMS::Authentication.unique_user_id('foo'))
773
+
774
+ stdout, stderr, status = Open3.capture3('rims', 'mbox-dirty-flag', '--enable-dirty-flag', *options, foo_mbox_path.to_s)
775
+ pp [ stdout, stderr, status ] if $DEBUG
776
+ if (expected_stdout) then
777
+ assert_match(/dirty flag is true/, stdout)
778
+ else
779
+ assert_equal('', stdout)
780
+ end
781
+ if (deplicated) then
782
+ assert_match(/warning/, stderr)
783
+ else
784
+ assert_equal('', stderr)
785
+ end
786
+ if (expected_status) then
787
+ assert_equal(1, status.exitstatus)
788
+ else
789
+ assert_equal(0, status.exitstatus)
790
+ end
791
+
792
+ stdout, stderr, status = Open3.capture3('rims', 'mbox-dirty-flag', '--quiet', '--return-flag-exit-code', foo_mbox_path.to_s)
793
+ assert_equal('', stdout)
794
+ assert_equal('', stderr)
795
+ assert_equal(1, status.exitstatus)
796
+ end
797
+
798
+ data('default' => [ true, true, false, %w[] ],
799
+ '-r' => [ true, true, false, %w[ -r prime ] ],
800
+ '--required-feature' => [ true, true, false, %w[ --required-feature=prime ] ],
801
+ '--kvs-type' => [ true, true, false, %w[ --kvs-type=gdbm ] ],
802
+ '--use-kvs-checksum' => [ true, true, false, %w[ --use-kvs-checksum ] ],
803
+ '--no-use-kvs-checksum' => [ true, true, false, %w[ --no-use-kvs-checksum ],
804
+ { storage:
805
+ { meta_key_value_store:
806
+ { use_checksum:
807
+ false
808
+ }
809
+ }
810
+ }
811
+ ],
812
+ '-v' => [ true, true, false, %w[ -v ] ],
813
+ '--verbose' => [ true, true, false, %w[ --verbose ] ],
814
+ '--no-verbose' => [ false, true, false, %w[ --no-verbose ] ],
815
+ '--quiet' => [ false, true, false, %w[ --quiet ] ],
816
+ '--no-quiet' => [ true, true, false, %w[ --no-quiet ] ],
817
+ '--return-flag-exit-code' => [ true, true, false, %w[ --return-flag-exit-code ] ],
818
+ '--no-return-flag-exit-code' => [ true, false, false, %w[ --no-return-flag-exit-code ] ],
819
+
820
+ # deplicated options
821
+ 'deplicated:--load-library' => [ true, true, true, %w[ --load-library=prime ] ],
822
+ 'deplicated:--use-kvs-cksum' => [ true, true, true, %w[ --use-kvs-cksum ] ],
823
+ 'deplicated:--no-use-kvs-cksum' => [ true, true, true, %w[ --no-use-kvs-cksum ],
824
+ { storage:
825
+ { meta_key_value_store:
826
+ { use_checksum:
827
+ false
828
+ }
829
+ }
830
+ }
831
+ ])
832
+ def test_mbox_dirty_flag_disable(data)
833
+ expected_stdout, expected_status, deplicated, options, config = data
834
+
835
+ run_server(optional: config || {}) {|imap|
836
+ imap.login('foo', 'foo')
837
+ imap.select('INBOX')
838
+ }
839
+
840
+ svc_conf = RIMS::Service::Configuration.new
841
+ svc_conf.load(base_dir: @base_dir.to_s)
842
+ foo_mbox_path = svc_conf.make_key_value_store_path(RIMS::MAILBOX_DATA_STRUCTURE_VERSION,
843
+ RIMS::Authentication.unique_user_id('foo'))
844
+
845
+ stdout, stderr, status = Open3.capture3('rims', 'mbox-dirty-flag', '--quiet', '--return-flag-exit-code', '--enable-dirty-flag', foo_mbox_path.to_s)
846
+ assert_equal('', stdout)
847
+ assert_equal('', stderr)
848
+ assert_equal(1, status.exitstatus)
849
+
850
+ stdout, stderr, status = Open3.capture3('rims', 'mbox-dirty-flag', '--disable-dirty-flag', *options, foo_mbox_path.to_s)
851
+ pp [ stdout, stderr, status ] if $DEBUG
852
+ if (expected_stdout) then
853
+ assert_match(/dirty flag is false/, stdout)
854
+ else
855
+ assert_equal('', stdout)
856
+ end
857
+ if (deplicated) then
858
+ assert_match(/warning/, stderr)
859
+ else
860
+ assert_equal('', stderr)
861
+ end
862
+ if (expected_status) then
863
+ assert_equal(0, status.exitstatus)
864
+ else
865
+ assert_equal(0, status.exitstatus)
866
+ end
867
+
868
+ stdout, stderr, status = Open3.capture3('rims', 'mbox-dirty-flag', '--quiet', '--return-flag-exit-code', foo_mbox_path.to_s)
869
+ assert_equal('', stdout)
870
+ assert_equal('', stderr)
871
+ assert_equal(0, status.exitstatus)
872
+ end
873
+
874
+ data('alice' => %w[ 2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90 alice ],
875
+ 'bob' => %w[ 81b637d8fcd2c6da6359e6963113a1170de795e4b725b84d1e0b4cfd9ec58ce9 bob ])
876
+ def test_unique_user_id(data)
877
+ expected_id, username = data
878
+ stdout, stderr, status = Open3.capture3('rims', 'unique-user-id', username)
879
+ assert_equal(expected_id, stdout.chomp)
880
+ assert_equal('', stderr)
881
+ assert_equal(0, status.exitstatus)
882
+ end
883
+
884
+ data('-f' => %W[ -f #{BASE_DIR}/config.yml ],
885
+ '--config-yaml' => %W[ --config-yaml=#{BASE_DIR}/config.yml ],
886
+ 'base_dir' => [ BASE_DIR ])
887
+ def test_show_user_mbox(args)
888
+ config_path = @base_dir + 'config.yml'
889
+ config_path.write({}.to_yaml)
890
+
891
+ svc_conf = RIMS::Service::Configuration.new
892
+ svc_conf.load(base_dir: @base_dir.to_s)
893
+ foo_mbox_path = svc_conf.make_key_value_store_path(RIMS::MAILBOX_DATA_STRUCTURE_VERSION,
894
+ RIMS::Authentication.unique_user_id('foo'))
895
+
896
+ stdout, stderr, status = Open3.capture3('rims', 'show-user-mbox', *args, 'foo')
897
+ pp [ stdout, stderr, status ] if $DEBUG
898
+ assert_equal(foo_mbox_path.to_s, stdout.chomp)
899
+ assert_equal('', stderr)
900
+ assert_equal(0, status.exitstatus)
901
+ end
902
+
903
+ data('default' => %w[],
904
+ 'MD5' => %w[ --hash-type=MD5 ],
905
+ 'RMD160' => %w[ --hash-type=RMD160 ],
906
+ 'SHA256' => %w[ --hash-type=SHA256 ],
907
+ 'SHA512' => %w[ --hash-type=SHA512 ],
908
+ 'strech' => %w[ --stretch-count=100000 ],
909
+ 'salt' => %w[ --salt-size=1024 ])
910
+ def test_pass_hash(options)
911
+ passwd_path = @base_dir + 'passwd_plain.yml'
912
+ passwd_path.write([ { 'user' => 'foo', 'pass' => 'open sesame' } ].to_yaml)
913
+
914
+ stdout, stderr, status = Open3.capture3('rims', 'pass-hash', *options, passwd_path.to_s)
915
+ pp [ stdout, stderr, status ] if $DEBUG
916
+ assert_equal('', stderr)
917
+ assert_equal(0, status.exitstatus)
918
+
919
+ passwd_hash = YAML.load(stdout)
920
+ hash_src = RIMS::Password::HashSource.build_from_conf(passwd_hash)
921
+ auth = RIMS::Authentication.new
922
+ auth.add_plug_in(hash_src)
923
+
924
+ logger = Logger.new(STDOUT)
925
+ logger.level = ($DEBUG) ? :debug : :unknown
926
+
927
+ auth.start_plug_in(logger)
928
+ assert_equal(true, (auth.user? 'foo'))
929
+ assert(auth.authenticate_login('foo', 'open sesame'))
930
+ auth.stop_plug_in(logger)
931
+ end
932
+
933
+ data('default' => [ true, false, %w[] ],
934
+ '-r' => [ true, false, %w[ -r prime ] ],
935
+ '--required-feature' => [ true, false, %w[ --required-feature=prime ] ],
936
+ '--kvs-type' => [ true, false, %w[ --kvs-type=gdbm ] ],
937
+ '--use-kvs-checksum' => [ true, false, %w[ --use-kvs-checksum ] ],
938
+ '--no-use-kvs-checksum' => [ true, false, %w[ --no-use-kvs-checksum ],
939
+ { storage: {
940
+ meta_key_value_store: {
941
+ use_checksum: false
942
+ }
943
+ }
944
+ }
945
+ ],
946
+ '--match-key:match' => [ true, false, %w[ --match-key=uid ] ],
947
+ '--match-key:no_match' => [ false, false, %w[ --match-key=nothing ] ],
948
+ '--dump-size' => [ true, false, %w[ --dump-size ] ],
949
+ '--no-dump-size' => [ true, false, %w[ --no-dump-size ] ],
950
+ '--dump-value' => [ true, false, %w[ --dump-value ] ],
951
+ '--no-dump-value' => [ true, false, %w[ --no-dump-value ] ],
952
+ '--marshal-restore' => [ true, false, %w[ --marshal-restore ] ],
953
+ '--no-marshal-restore' => [ true, false, %w[ --no-marshal-restore ] ],
954
+
955
+ # deplicated options
956
+ 'deplicated:--load-library' => [ true, true, %w[ --load-library=prime ] ],
957
+ 'deplicated:--use-kvs-cksum' => [ true, true, %w[ --use-kvs-cksum ] ],
958
+ 'deplicated:--no-use-kvs-cksum' => [ true, true, %w[ --no-use-kvs-cksum ],
959
+ { storage: {
960
+ meta_key_value_store: {
961
+ use_checksum: false
962
+ }
963
+ }
964
+ }
965
+ ])
966
+ def test_debug_dump_kvs(data)
967
+ expected_stdout, deplicated, options, config = data
968
+
969
+ run_server(optional: config || {}) {|imap|
970
+ imap.login('foo', 'foo')
971
+ imap.select('INBOX')
972
+ }
973
+
974
+ svc_conf = RIMS::Service::Configuration.new
975
+ svc_conf.load(base_dir: @base_dir.to_s)
976
+ foo_mbox_path = svc_conf.make_key_value_store_path(RIMS::MAILBOX_DATA_STRUCTURE_VERSION,
977
+ RIMS::Authentication.unique_user_id('foo'))
978
+
979
+ stdout, stderr, status = Open3.capture3('rims', 'debug-dump-kvs', *options, (foo_mbox_path + 'meta').to_s)
980
+ pp [ stdout, stderr, status ] if $DEBUG
981
+ if (expected_stdout) then
982
+ assert(! stdout.empty?)
983
+ else
984
+ assert_equal('', stdout)
985
+ end
986
+ if (deplicated) then
987
+ assert_match(/warning/, stderr)
988
+ else
989
+ assert_equal('', stderr)
990
+ end
991
+ assert_equal(0, status.exitstatus)
992
+ end
993
+ end
994
+ end
995
+
996
+ # Local Variables:
997
+ # mode: Ruby
998
+ # indent-tabs-mode: nil
999
+ # End: