rims 0.2.8 → 0.2.9

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.
@@ -232,7 +232,7 @@ module RIMS
232
232
  @mail_store = mail_store
233
233
  @folder = folder
234
234
  @charset_aliases = charset_aliases
235
- @charset_convert_options = charset_convert_options
235
+ @charset_convert_options = charset_convert_options || {}
236
236
  @charset = nil
237
237
  @mail_cache = Hash.new{|hash, uid|
238
238
  if (msg_txt = @mail_store.msg_text(@folder.mbox_id, uid)) then
@@ -269,7 +269,7 @@ module RIMS
269
269
  if (string.encoding == @charset) then
270
270
  string
271
271
  else
272
- string.encode(@charset, @charset_convert_options)
272
+ string.encode(@charset, **@charset_convert_options)
273
273
  end
274
274
  end
275
275
  private :encode_charset
@@ -118,6 +118,7 @@ module RIMS
118
118
  # daemon:
119
119
  # daemonize: true
120
120
  # debug: false
121
+ # umask: 0037
121
122
  # status_file: rims.pid
122
123
  # server_polling_interval_seconds: 3
123
124
  # server_privileged_user: nobody
@@ -418,6 +419,10 @@ module RIMS
418
419
  end
419
420
  end
420
421
 
422
+ def daemon_umask
423
+ @config.dig('daemon', 'umask') || 0037
424
+ end
425
+
421
426
  def status_file
422
427
  file_path = @config.dig('daemon', 'status_file') || 'rims.pid'
423
428
  file_path = Pathname(file_path)
@@ -799,16 +804,16 @@ module RIMS
799
804
  using Logger::JointPlus
800
805
 
801
806
  def setup(server, daemon: false)
802
- file_logger_params = @config.make_file_logger_params
803
- logger = Logger.new(*file_logger_params)
807
+ *file_logger_params, file_logger_opts = @config.make_file_logger_params
808
+ logger = Logger.new(*file_logger_params, **file_logger_opts)
804
809
 
805
- stdout_logger_params = @config.make_stdout_logger_params
810
+ *stdout_logger_params, stdout_logger_opts = @config.make_stdout_logger_params
806
811
  unless (daemon && @config.daemonize?) then
807
- logger += Logger.new(*stdout_logger_params)
812
+ logger += Logger.new(*stdout_logger_params, **stdout_logger_opts)
808
813
  end
809
814
 
810
- protocol_logger_params = @config.make_protocol_logger_params
811
- protocol_logger = Logger.new(*protocol_logger_params)
815
+ *protocol_logger_params, protocol_logger_opts = @config.make_protocol_logger_params
816
+ protocol_logger = Logger.new(*protocol_logger_params, **protocol_logger_opts)
812
817
 
813
818
  logger.info('preload libraries.')
814
819
  Riser.preload
@@ -892,17 +897,17 @@ module RIMS
892
897
  file_logger_params[1..-2].each_with_index do |value, i|
893
898
  logger.info("file logging parameter: shift_args[#{i}]=#{value}")
894
899
  end
895
- for name, value in file_logger_params[-1]
900
+ for name, value in file_logger_opts
896
901
  logger.info("file logging parameter: #{name}=#{value}")
897
902
  end
898
- for name, value in stdout_logger_params[-1]
903
+ for name, value in stdout_logger_opts
899
904
  logger.info("stdout logging parameter: #{name}=#{value}")
900
905
  end
901
906
  logger.info("protocol logging parameter: path=#{protocol_logger_params[0]}")
902
907
  protocol_logger_params[1..-2].each_with_index do |value, i|
903
908
  logger.info("protocol logging parameter: shift_args[#{i}]=#{value}")
904
909
  end
905
- for name, value in protocol_logger_params[-1]
910
+ for name, value in protocol_logger_opts
906
911
  logger.info("protocol logging parameter: #{name}=#{value}")
907
912
  end
908
913
  logger.info("listen address: #{server_socket.local_address.inspect_sockaddr}")
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  module RIMS
4
- VERSION = '0.2.8'
4
+ VERSION = '0.2.9'
5
5
  MAILBOX_DATA_STRUCTURE_VERSION = 'mailbox.2'
6
6
  end
7
7
 
@@ -78,6 +78,8 @@ task :imap_append do
78
78
  end
79
79
  end
80
80
 
81
+ CLOBBER.include('imap_append')
82
+
81
83
  desc 'run server'
82
84
  task :run_server do
83
85
  run_server_conf('imap_server', USER_CONF, *%w[ -v debug -l debug --imap-host=localhost --imap-port=14300 ]) do
@@ -85,7 +87,7 @@ task :run_server do
85
87
  end
86
88
  end
87
89
 
88
- CLOBBER.include('imap_append')
90
+ CLOBBER.include('imap_server')
89
91
 
90
92
  # Local Variables:
91
93
  # mode: Ruby
@@ -27,7 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.required_ruby_version = '>= 2.0.0'
28
28
 
29
29
  spec.add_runtime_dependency 'rims-rfc822', '>= 0.2.2'
30
- spec.add_runtime_dependency 'riser', '>= 0.1.11'
30
+ spec.add_runtime_dependency 'riser', '>= 0.1.12'
31
31
  spec.add_runtime_dependency 'logger-joint'
32
32
  spec.add_development_dependency 'bundler'
33
33
  spec.add_development_dependency 'rake'
@@ -119,6 +119,7 @@ module RIMS::Test
119
119
  '--no-daemonize' => [ %W[ -f #{BASE_DIR}/config.yml --no-daemonize ] ],
120
120
  '--daemon-debug' => [ %W[ -f #{BASE_DIR}/config.yml --daemon-debug ] ],
121
121
  '--no-daemon-debug' => [ %W[ -f #{BASE_DIR}/config.yml --no-daemon-debug ] ],
122
+ '--daemon-umask' => [ %W[ -f #{BASE_DIR}/config.yml --daemon-umask=0022 ] ],
122
123
  '--status-file' => [ %W[ -f #{BASE_DIR}/config.yml --status-file=status.yml ] ],
123
124
  '--privilege-user' => [ %W[ -f #{BASE_DIR}/config.yml --privilege-user=#{Process::UID.eid} ] ],
124
125
  '--privilege-group' => [ %W[ -f #{BASE_DIR}/config.yml --privilege-group=#{Process::GID.eid} ] ],
@@ -55,7 +55,8 @@ module RIMS::Test
55
55
  pub1.publish('msg1')
56
56
  pub2.publish('msg2')
57
57
 
58
- error = assert_raise(RuntimeError) { pub3.publish('msg3') }
58
+ error = assert_raise(RIMS::ServerResponseChannelPublishError) { pub3.publish('msg3') }
59
+ pp error, error.optional_data if $DEBUG
59
60
  assert_match(/detached/, error.message)
60
61
 
61
62
  assert_equal(%w[ msg2 ], sub1.enum_for(:fetch).to_a)
@@ -5,6 +5,18 @@ require 'test/unit'
5
5
 
6
6
  module RIMS::Test
7
7
  class TestError < Test::Unit::TestCase
8
+ def test_optional_data
9
+ error = RIMS::Error.new('test', foo: 1, bar: '2')
10
+ assert_equal('test', error.message)
11
+ assert_equal({ foo: 1, bar: '2' }, error.optional_data)
12
+ end
13
+
14
+ def test_no_optional_data
15
+ error = RIMS::Error.new('test')
16
+ assert_equal('test', error.message)
17
+ assert_predicate(error.optional_data, :empty?)
18
+ end
19
+
8
20
  def test_trace_error_chain
9
21
  exception = assert_raise(RuntimeError) {
10
22
  begin
@@ -32,6 +44,26 @@ module RIMS::Test
32
44
  'error level 0'
33
45
  ], errors.map(&:message))
34
46
  end
47
+
48
+ def test_optional_data_block
49
+ count = 0
50
+ error = RIMS::Error.new('test', foo: 1, bar: '2')
51
+ RIMS::Error.optional_data(error) do |e, data|
52
+ count += 1
53
+ assert_equal(error, e)
54
+ assert_equal({ foo: 1, bar: '2' }, data)
55
+ end
56
+ assert_equal(1, count)
57
+ end
58
+
59
+ data('not a RIMS::Error' => StandardError.new('test'),
60
+ 'no optional data' => RIMS::Error.new('test'))
61
+ def test_no_optional_data_block(data)
62
+ error = data
63
+ RIMS::Error.optional_data(error) do |e, data|
64
+ flunk
65
+ end
66
+ end
35
67
  end
36
68
  end
37
69
 
@@ -51,7 +51,7 @@ module RIMS::Test
51
51
  assert_equal('write-lock wait timeout', error.message)
52
52
  end
53
53
 
54
- def calculate_threa_work_seconds
54
+ def calculate_thread_work_seconds
55
55
  t0 = Time.now
56
56
  1000.times{|i| i.succ }
57
57
  t1 = Time.now
@@ -60,10 +60,10 @@ module RIMS::Test
60
60
 
61
61
  wait_seconds
62
62
  end
63
- private :calculate_threa_work_seconds
63
+ private :calculate_thread_work_seconds
64
64
 
65
65
  def test_read_write_lock_multithread
66
- lock_wait_seconds = calculate_threa_work_seconds
66
+ lock_wait_seconds = calculate_thread_work_seconds
67
67
 
68
68
  count = 0
69
69
  read_thread_num = 10
@@ -116,7 +116,7 @@ module RIMS::Test
116
116
  def test_write_lock_timeout_detach
117
117
  logger = Logger.new(STDOUT)
118
118
  logger.level = ($DEBUG) ? Logger::DEBUG : Logger::FATAL
119
- wait_seconds = calculate_threa_work_seconds
119
+ wait_seconds = calculate_thread_work_seconds
120
120
 
121
121
  t_list = []
122
122
  assert_nil(RIMS::ReadWriteLock.write_lock_timeout_detach(wait_seconds, wait_seconds * 2, logger: logger ) {|timeout_seconds|
@@ -127,6 +127,7 @@ module RIMS::Test
127
127
  cmd_name, cmd_args, cmd_client_output = parse_imap_command(tag, imap_command_message)
128
128
  normalized_cmd_name = RIMS::Protocol::Decoder.imap_command_normalize(cmd_name)
129
129
  cmd_id = RIMS::Protocol::Decoder::IMAP_CMDs[normalized_cmd_name] or flunk("not a imap command: #{cmd_name}")
130
+ cmd_kw_args = {}
130
131
 
131
132
  input = nil
132
133
  output = nil
@@ -146,32 +147,29 @@ module RIMS::Test
146
147
  cmd_args = inout_args + cmd_args
147
148
  end
148
149
  unless (uid.nil?) then
149
- cmd_args += [ { uid: uid } ]
150
+ cmd_kw_args[:uid] = uid
150
151
  end
151
152
 
152
153
  block_call = 0
153
154
  ret_val = nil
154
155
 
156
+ response_message = cmd_client_output.b
155
157
  pp [ :debug_imap_command, imap_command_message, cmd_id, cmd_args ] if $DEBUG
156
- @decoder.__send__(cmd_id, tag, *cmd_args) {|responses|
158
+ @decoder.__send__(cmd_id, tag, *cmd_args, **cmd_kw_args) {|response|
157
159
  block_call += 1
158
- response_message = cmd_client_output.b
159
- if (output) then
160
+ if (block_call == 1 && output) then
160
161
  response_message << output.string
161
162
  end
162
- for response in responses
163
- if (response != :flush) then
164
- response_message << response
165
- end
163
+ if (response != :flush) then
164
+ response_message << response
166
165
  end
167
- response_lines = StringIO.new(response_message, 'r').each_line
168
- ret_val = yield(response_lines)
169
- assert_raise(StopIteration) { response_lines.next }
170
166
  }
167
+ response_lines = StringIO.new(response_message, 'r').each_line
168
+ ret_val = yield(response_lines)
169
+ assert_raise(StopIteration) { response_lines.next }
171
170
  if (client_input_text) then
172
171
  pp input.string, output.string if $DEBUG
173
172
  end
174
- assert_equal(1, block_call, 'IMAP command block should be called only once.')
175
173
 
176
174
  @decoder = @decoder.next_decoder
177
175
 
@@ -1966,7 +1964,7 @@ module RIMS::Test
1966
1964
  }
1967
1965
 
1968
1966
  assert_imap_command('SELECT INBOX') {|assert|
1969
- assert.skip_while{|line| line =~ /^\* /}
1967
+ assert.skip_while{|line| line =~ /^\* / }
1970
1968
  assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
1971
1969
  }
1972
1970
 
@@ -5215,7 +5213,7 @@ module RIMS::Test
5215
5213
  }
5216
5214
 
5217
5215
  assert_imap_command('SELECT INBOX') {|assert|
5218
- assert.skip_while{|line| line =~ /^\* /}
5216
+ assert.skip_while{|line| line =~ /^\* / }
5219
5217
  assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
5220
5218
  }
5221
5219
 
@@ -5242,7 +5240,7 @@ module RIMS::Test
5242
5240
  }
5243
5241
 
5244
5242
  assert_imap_command('EXAMINE INBOX') {|assert|
5245
- assert.skip_while{|line| line =~ /^\* /}
5243
+ assert.skip_while{|line| line =~ /^\* / }
5246
5244
  assert.equal("#{tag} OK [READ-ONLY] EXAMINE completed")
5247
5245
  }
5248
5246
 
@@ -5303,7 +5301,7 @@ module RIMS::Test
5303
5301
  }
5304
5302
 
5305
5303
  assert_imap_command('SELECT INBOX') {|assert|
5306
- assert.skip_while{|line| line =~ /^\* /}
5304
+ assert.skip_while{|line| line =~ /^\* / }
5307
5305
  assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
5308
5306
  }
5309
5307
 
@@ -5349,7 +5347,7 @@ module RIMS::Test
5349
5347
  }
5350
5348
 
5351
5349
  assert_imap_command('EXAMINE INBOX') {|assert|
5352
- assert.skip_while{|line| line =~ /^\* /}
5350
+ assert.skip_while{|line| line =~ /^\* / }
5353
5351
  assert.equal("#{tag} OK [READ-ONLY] EXAMINE completed")
5354
5352
  }
5355
5353
 
@@ -5730,7 +5728,7 @@ module RIMS::Test
5730
5728
  }
5731
5729
 
5732
5730
  assert_imap_command('SELECT INBOX') {|assert|
5733
- assert.skip_while{|line| line =~ /^\* /}
5731
+ assert.skip_while{|line| line =~ /^\* / }
5734
5732
  assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
5735
5733
  }
5736
5734
 
@@ -5754,7 +5752,7 @@ module RIMS::Test
5754
5752
  }
5755
5753
 
5756
5754
  assert_imap_command('SELECT INBOX') {|assert|
5757
- assert.skip_while{|line| line =~ /^\* /}
5755
+ assert.skip_while{|line| line =~ /^\* / }
5758
5756
  assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
5759
5757
  }
5760
5758
 
@@ -5778,7 +5776,7 @@ module RIMS::Test
5778
5776
  }
5779
5777
 
5780
5778
  assert_imap_command('SELECT INBOX') {|assert|
5781
- assert.skip_while{|line| line =~ /^\* /}
5779
+ assert.skip_while{|line| line =~ /^\* / }
5782
5780
  assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
5783
5781
  }
5784
5782
 
@@ -5806,7 +5804,7 @@ module RIMS::Test
5806
5804
  }
5807
5805
 
5808
5806
  assert_imap_command('SELECT INBOX') {|assert|
5809
- assert.skip_while{|line| line =~ /^\* /}
5807
+ assert.skip_while{|line| line =~ /^\* / }
5810
5808
  assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
5811
5809
  }
5812
5810
 
@@ -5839,10 +5837,8 @@ module RIMS::Test
5839
5837
  }
5840
5838
 
5841
5839
  another_decoder = make_decoder
5842
- another_writer = proc{|res|
5843
- for line in res
5844
- p line if $DEBUG
5845
- end
5840
+ another_writer = proc{|response|
5841
+ p response if $DEBUG
5846
5842
  }
5847
5843
 
5848
5844
  another_decoder.login('tag', 'foo', 'open_sesame', &another_writer)
@@ -6117,10 +6113,8 @@ module RIMS::Test
6117
6113
  }
6118
6114
 
6119
6115
  another_decoder = make_decoder
6120
- another_writer = proc{|res|
6121
- for line in res
6122
- p line if $DEBUG
6123
- end
6116
+ another_writer = proc{|response|
6117
+ p response if $DEBUG
6124
6118
  }
6125
6119
 
6126
6120
  another_decoder.login('tag', 'foo', 'open_sesame', &another_writer)
@@ -6212,7 +6206,7 @@ module RIMS::Test
6212
6206
  end
6213
6207
 
6214
6208
  assert_imap_command('SELECT INBOX') {|assert|
6215
- assert.skip_while{|line| line =~ /^\* /}
6209
+ assert.skip_while{|line| line =~ /^\* / }
6216
6210
  assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
6217
6211
  }
6218
6212
 
@@ -6293,7 +6287,7 @@ module RIMS::Test
6293
6287
  end
6294
6288
 
6295
6289
  assert_imap_command('SELECT INBOX') {|assert|
6296
- assert.skip_while{|line| line =~ /^\* /}
6290
+ assert.skip_while{|line| line =~ /^\* / }
6297
6291
  assert.equal("#{tag} OK [READ-WRITE] SELECT completed")
6298
6292
  }
6299
6293
 
@@ -6341,7 +6335,7 @@ module RIMS::Test
6341
6335
 
6342
6336
  def test_charset_convert_options_stream
6343
6337
  use_imap_stream_decode_engine
6344
- test_charset_aliases
6338
+ test_charset_convert_options
6345
6339
  end
6346
6340
  end
6347
6341
 
@@ -6365,6 +6359,93 @@ module RIMS::Test
6365
6359
  assert_equal(%w[ foo INBOX ], RIMS::Protocol::Decoder.decode_delivery_target_mailbox(encoded_mbox_name))
6366
6360
  end
6367
6361
  end
6362
+
6363
+ class ProtocolDecoderBulkResponseTest < Test::Unit::TestCase
6364
+ def setup
6365
+ limit_count = 10
6366
+ limit_size = 100
6367
+ @res = RIMS::Protocol::Decoder::BulkResponse.new(limit_count, limit_size)
6368
+ end
6369
+
6370
+ data('empty' => [ 0, 0, [] ],
6371
+ '1' => [ 1, 3, %w[ foo ] ],
6372
+ '2' => [ 2, 6, %w[ foo bar ] ],
6373
+ '3' => [ 3, 11, %w[ foo bar baaaz ] ])
6374
+ def test_add(data)
6375
+ expected_count, expected_size, response_list = data
6376
+
6377
+ assert_equal(0, @res.count)
6378
+ assert_equal(0, @res.size)
6379
+
6380
+ for response in response_list
6381
+ @res << response
6382
+ end
6383
+
6384
+ assert_equal(expected_count, @res.count)
6385
+ assert_equal(expected_size, @res.size)
6386
+ end
6387
+
6388
+ def test_emtpy?
6389
+ assert_true(@res.empty?)
6390
+ end
6391
+
6392
+ def test_not_empty?
6393
+ @res << 'foo'
6394
+ assert_false(@res.empty?)
6395
+ end
6396
+
6397
+ data('count: boundary' => %w[ 1 2 3 4 5 6 7 8 9 0 ],
6398
+ 'count: over' => %w[ 1 2 3 4 5 6 7 8 9 0 a ],
6399
+ 'size: boundary' => [ 'x' * 50, 'y' * 50 ],
6400
+ 'size: over' => [ 'x' * 50, 'y' * 50, 'z' ],
6401
+ 'count,size: boundary' => %w[ 1 2 3 4 5 6 7 8 9 0 ].map{|s| s * 10 },
6402
+ 'count,size: over' => %w[ 1 2 3 4 5 6 7 8 9 0 ].map{|s| s * 10 } + %w[ a ])
6403
+ def test_full?(data)
6404
+ response_list = data
6405
+ for response in response_list
6406
+ @res << response
6407
+ end
6408
+ assert_true(@res.full?)
6409
+ end
6410
+
6411
+ data('empty' => [],
6412
+ 'under' => %w[ foo bar baz ],
6413
+ 'count: boundary' => %w[ 1 2 3 4 5 6 7 8 9 ],
6414
+ 'size: boundary' => [ 'x' * 50, 'y' * 49 ])
6415
+ def test_not_full?(data)
6416
+ response_list = data
6417
+ for response in response_list
6418
+ @res << response
6419
+ end
6420
+ assert_false(@res.full?)
6421
+ end
6422
+
6423
+ def test_flush
6424
+ @res << 'foo'
6425
+ @res << 'bar'
6426
+ r1 = @res.flush
6427
+ assert_equal('foo' + 'bar', r1.join(''), 'responses may be joined.')
6428
+ assert_true(@res.empty?)
6429
+ assert_false(@res.full?)
6430
+
6431
+ @res << 'baz'
6432
+ r2 = @res.flush
6433
+ assert_equal('baz', r2.join(''), 'responses may be joined.')
6434
+ assert_true(@res.empty?)
6435
+ assert_false(@res.full?)
6436
+
6437
+ assert_not_equal(r1, r2)
6438
+ end
6439
+
6440
+ def test_flush_joined
6441
+ for c in ('a'..).first(10)
6442
+ @res << c
6443
+ end
6444
+ assert_equal([ ('a'..).first(10).join('') ], @res.flush)
6445
+ assert_true(@res.empty?)
6446
+ assert_false(@res.full?)
6447
+ end
6448
+ end
6368
6449
  end
6369
6450
 
6370
6451
  # Local Variables: