rims 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/ChangeLog +379 -0
  4. data/Gemfile +11 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +566 -0
  7. data/Rakefile +29 -0
  8. data/bin/rims +11 -0
  9. data/lib/rims.rb +45 -0
  10. data/lib/rims/auth.rb +133 -0
  11. data/lib/rims/cksum_kvs.rb +68 -0
  12. data/lib/rims/cmd.rb +809 -0
  13. data/lib/rims/daemon.rb +338 -0
  14. data/lib/rims/db.rb +793 -0
  15. data/lib/rims/error.rb +23 -0
  16. data/lib/rims/gdbm_kvs.rb +76 -0
  17. data/lib/rims/hash_kvs.rb +66 -0
  18. data/lib/rims/kvs.rb +101 -0
  19. data/lib/rims/lock.rb +151 -0
  20. data/lib/rims/mail_store.rb +663 -0
  21. data/lib/rims/passwd.rb +251 -0
  22. data/lib/rims/pool.rb +88 -0
  23. data/lib/rims/protocol.rb +71 -0
  24. data/lib/rims/protocol/decoder.rb +1469 -0
  25. data/lib/rims/protocol/parser.rb +1114 -0
  26. data/lib/rims/rfc822.rb +456 -0
  27. data/lib/rims/server.rb +567 -0
  28. data/lib/rims/test.rb +391 -0
  29. data/lib/rims/version.rb +11 -0
  30. data/load_test/Rakefile +93 -0
  31. data/rims.gemspec +38 -0
  32. data/test/test_auth.rb +174 -0
  33. data/test/test_cksum_kvs.rb +121 -0
  34. data/test/test_config.rb +533 -0
  35. data/test/test_daemon_status_file.rb +169 -0
  36. data/test/test_daemon_waitpid.rb +72 -0
  37. data/test/test_db.rb +602 -0
  38. data/test/test_db_recovery.rb +732 -0
  39. data/test/test_error.rb +97 -0
  40. data/test/test_gdbm_kvs.rb +32 -0
  41. data/test/test_hash_kvs.rb +116 -0
  42. data/test/test_lock.rb +161 -0
  43. data/test/test_mail_store.rb +750 -0
  44. data/test/test_passwd.rb +203 -0
  45. data/test/test_protocol.rb +91 -0
  46. data/test/test_protocol_auth.rb +121 -0
  47. data/test/test_protocol_decoder.rb +6490 -0
  48. data/test/test_protocol_fetch.rb +994 -0
  49. data/test/test_protocol_request.rb +332 -0
  50. data/test/test_protocol_search.rb +974 -0
  51. data/test/test_rfc822.rb +696 -0
  52. metadata +174 -0
@@ -0,0 +1,38 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'rims/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "rims"
9
+ spec.version = RIMS::VERSION
10
+ spec.authors = ["TOKI Yoshinori"]
11
+ spec.email = ["toki@freedom.ne.jp"]
12
+ spec.summary = %q{RIMS is Ruby IMap Server}
13
+ spec.description = <<-'EOF'
14
+ RIMS is Ruby IMap Server.
15
+ This gem provides a complete IMAP server by itself. The IMAP
16
+ server can run as a daemon, mailboxes are provided and messages
17
+ can be delivered to them.
18
+ EOF
19
+ spec.homepage = "https://github.com/y10k/rims"
20
+ spec.license = "MIT"
21
+
22
+ spec.files = `git ls-files`.split($/)
23
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
24
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
25
+ spec.require_paths = ["lib"]
26
+
27
+ spec.required_ruby_version = '>= 2.0.0'
28
+
29
+ spec.add_development_dependency "bundler"
30
+ spec.add_development_dependency "rake"
31
+ spec.add_development_dependency "test-unit"
32
+ spec.add_development_dependency "rdoc"
33
+ end
34
+
35
+ # Local Variables:
36
+ # mode: Ruby
37
+ # indent-tabs-mode: nil
38
+ # End:
@@ -0,0 +1,174 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'pp' if $DEBUG
4
+ require 'rims'
5
+ require 'test/unit'
6
+
7
+ module RIMS::Test
8
+ class AuthenticationTest < Test::Unit::TestCase
9
+ include RIMS::Test::PseudoAuthenticationUtility
10
+
11
+ def setup
12
+ src_time = Time.at(1404046689)
13
+ random_seed = 70100924388646298230620504594645040907
14
+
15
+ @time_source = make_pseudo_time_source(src_time)
16
+ @random_string_source = make_pseudo_random_string_source(random_seed)
17
+
18
+ @username = 'foo'
19
+ @password = 'open_sesame'
20
+
21
+ @auth = RIMS::Authentication.new(time_source: make_pseudo_time_source(src_time),
22
+ random_string_source: make_pseudo_random_string_source(random_seed))
23
+ @auth.entry(@username, @password)
24
+ end
25
+
26
+ def test_unique_user_id
27
+ id1 = RIMS::Authentication.unique_user_id(@username)
28
+ assert_instance_of(String, id1)
29
+ assert_true(id1.frozen?)
30
+ refute(id1.empty?)
31
+
32
+ id2 = RIMS::Authentication.unique_user_id(@username)
33
+ assert_instance_of(String, id2)
34
+ assert_true(id2.frozen?)
35
+ refute(id2.empty?)
36
+
37
+ id3 = RIMS::Authentication.unique_user_id(@username.succ)
38
+ assert_instance_of(String, id3)
39
+ assert_true(id3.frozen?)
40
+ refute(id3.empty?)
41
+
42
+ assert(id2.bytesize == id1.bytesize)
43
+ assert(id3.bytesize == id1.bytesize)
44
+
45
+ assert(id2 == id1)
46
+ assert(id3 != id1)
47
+
48
+ pp [ id1, id2, id3 ] if $DEBUG
49
+ end
50
+
51
+ def test_user?
52
+ assert_equal(true, (@auth.user? @username))
53
+ assert_equal(false, (@auth.user? @username.succ))
54
+ end
55
+
56
+ def test_authenticate_login
57
+ assert_equal(@username, @auth.authenticate_login(@username, @password))
58
+ assert_nil(@auth.authenticate_login(@username, @password.succ))
59
+ assert_nil(@auth.authenticate_login(@username.succ, @password))
60
+ end
61
+
62
+ def test_authenticate_plain
63
+ authz_id = @username
64
+ authc_id = @username
65
+
66
+ assert_equal(@username, @auth.authenticate_plain([ authz_id, authc_id, @password ].join("\0")))
67
+ assert_nil(@auth.authenticate_plain([ authz_id.succ, authc_id, @password ].join("\0")))
68
+ assert_nil(@auth.authenticate_plain([ authz_id, authc_id.succ, @password ].join("\0")))
69
+ assert_nil(@auth.authenticate_plain([ authz_id, authc_id, @password.succ ].join("\0")))
70
+
71
+ assert_equal(@username, @auth.authenticate_plain([ '', authc_id, @password ].join("\0")))
72
+ assert_nil(@auth.authenticate_plain([ '', authc_id.succ, @password ].join("\0")))
73
+ assert_nil(@auth.authenticate_plain([ '', authc_id, @password.succ ].join("\0")))
74
+
75
+ assert_nil(@auth.authenticate_plain([ authz_id, '', @password ].join("\0")))
76
+ end
77
+
78
+ def test_make_time_source
79
+ time_source = RIMS::Authentication.make_time_source
80
+
81
+ t1 = time_source.call
82
+ assert_instance_of(Time, t1)
83
+
84
+ begin
85
+ t2 = time_source.call
86
+ assert_instance_of(Time, t2)
87
+ end until (t2 != t1)
88
+
89
+ assert(t1 < t2)
90
+ end
91
+
92
+ def test_pseudo_make_time_source
93
+ t1 = @time_source.call
94
+ assert_instance_of(Time, t1)
95
+
96
+ begin
97
+ t2 = @time_source.call
98
+ assert_instance_of(Time, t2)
99
+ end until (t2 != t1)
100
+
101
+ assert(t1 < t2)
102
+ end
103
+
104
+ def test_make_random_string_source
105
+ random_string_source = RIMS::Authentication.make_random_string_source
106
+
107
+ s1 = random_string_source.call
108
+ assert_instance_of(String, s1)
109
+ refute(s1.empty?)
110
+
111
+ s2 = random_string_source.call
112
+ assert_instance_of(String, s2)
113
+ refute(s2.empty?)
114
+
115
+ assert(s1.bytesize == s2.bytesize)
116
+ assert(s1 != s2)
117
+ end
118
+
119
+ def test_pseudo_make_random_string_source
120
+ s1 = @random_string_source.call
121
+ assert_instance_of(String, s1)
122
+ refute(s1.empty?)
123
+
124
+ s2 = @random_string_source.call
125
+ assert_instance_of(String, s2)
126
+ refute(s2.empty?)
127
+
128
+ assert(s1.bytesize == s2.bytesize)
129
+ assert(s1 != s2)
130
+ end
131
+
132
+ def test_cram_md5_server_challenge_data_class_method
133
+ s1 = RIMS::Authentication.cram_md5_server_challenge_data('rims', @time_source, @random_string_source)
134
+ assert_instance_of(String, s1)
135
+ refute(s1.empty?)
136
+
137
+ s2 = RIMS::Authentication.cram_md5_server_challenge_data('rims', @time_source, @random_string_source)
138
+ assert_instance_of(String, s2)
139
+ refute(s2.empty?)
140
+
141
+ assert(s1 != s2)
142
+ end
143
+
144
+ def test_cram_md5_server_challenge_data
145
+ assert_equal(RIMS::Authentication.cram_md5_server_challenge_data('rims', @time_source, @random_string_source), @auth.cram_md5_server_challenge_data)
146
+ assert_equal(RIMS::Authentication.cram_md5_server_challenge_data('rims', @time_source, @random_string_source), @auth.cram_md5_server_challenge_data)
147
+ assert_equal(RIMS::Authentication.cram_md5_server_challenge_data('rims', @time_source, @random_string_source), @auth.cram_md5_server_challenge_data)
148
+ assert_equal(RIMS::Authentication.cram_md5_server_challenge_data('rims', @time_source, @random_string_source), @auth.cram_md5_server_challenge_data)
149
+ assert_equal(RIMS::Authentication.cram_md5_server_challenge_data('rims', @time_source, @random_string_source), @auth.cram_md5_server_challenge_data)
150
+ end
151
+
152
+ def cram_md5_client_response(username, password, server_challenge_data)
153
+ "#{username} #{RIMS::Authentication.hmac_md5_hexdigest(password, server_challenge_data)}"
154
+ end
155
+ private :cram_md5_client_response
156
+
157
+ def test_authenticate_cram_md5
158
+ server_challenge_data = @auth.cram_md5_server_challenge_data
159
+ assert_equal(@username, @auth.authenticate_cram_md5(server_challenge_data,
160
+ cram_md5_client_response(@username, @password, server_challenge_data)))
161
+ assert_nil(@auth.authenticate_cram_md5(server_challenge_data,
162
+ cram_md5_client_response(@username.succ, @password, server_challenge_data)))
163
+ assert_nil(@auth.authenticate_cram_md5(server_challenge_data,
164
+ cram_md5_client_response(@username, @password.succ, server_challenge_data)))
165
+ assert_nil(@auth.authenticate_cram_md5(server_challenge_data,
166
+ cram_md5_client_response(@username, @password, server_challenge_data.succ)))
167
+ end
168
+ end
169
+ end
170
+
171
+ # Local Variables:
172
+ # mode: Ruby
173
+ # indent-tabs-mode: nil
174
+ # End:
@@ -0,0 +1,121 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'pp' if $DEBUG
4
+ require 'rims'
5
+ require 'test/unit'
6
+
7
+ module RIMS::Test
8
+ class Checksum_KeyValueStoreTest < Test::Unit::TestCase
9
+ def setup
10
+ @db = {}
11
+ @builder = RIMS::KeyValueStore::FactoryBuilder.new
12
+ @builder.open{|name| RIMS::Hash_KeyValueStore.new(@db) }
13
+ @builder.use(RIMS::Checksum_KeyValueStore)
14
+ @kvs = @builder.factory.call('test')
15
+ end
16
+
17
+ def teardown
18
+ pp @db if $DEBUG
19
+ end
20
+
21
+ def test_store_fetch
22
+ assert_nil(@db['foo'])
23
+ assert_nil(@kvs['foo'])
24
+
25
+ assert_equal('apple', (@kvs['foo'] = 'apple'))
26
+
27
+ assert_not_nil('apple', @db['foo'])
28
+ assert_equal('apple', @kvs['foo'])
29
+ end
30
+
31
+ def test_delete
32
+ assert_nil(@kvs.delete('foo'))
33
+
34
+ @kvs['foo'] = 'apple'
35
+ assert_equal('apple', @kvs.delete('foo'))
36
+
37
+ assert_nil(@db['foo'])
38
+ assert_nil(@kvs['foo'])
39
+ end
40
+
41
+ def test_key?
42
+ assert_equal(false, (@db.key? 'foo'))
43
+ assert_equal(false, (@kvs.key? 'foo'))
44
+
45
+ @kvs['foo'] = 'apple'
46
+ assert_equal(true, (@db.key? 'foo'))
47
+ assert_equal(true, (@kvs.key? 'foo'))
48
+
49
+ @kvs.delete('foo')
50
+ assert_equal(false, (@db.key? 'foo'))
51
+ assert_equal(false, (@kvs.key? 'foo'))
52
+ end
53
+
54
+ def test_each_key
55
+ assert_equal(%w[], @db.each_key.to_a)
56
+ assert_equal(%w[], @kvs.each_key.to_a)
57
+
58
+ @kvs['foo'] = 'apple'
59
+ assert_equal(%w[ foo ], @db.each_key.to_a)
60
+ assert_equal(%w[ foo ], @kvs.each_key.to_a)
61
+ assert_equal(%w[ apple ], @kvs.each_value.to_a)
62
+ assert_equal([ %w[ foo apple ] ], @kvs.each_pair.to_a)
63
+
64
+ @kvs['bar'] = 'banana'
65
+ assert_equal(%w[ foo bar ], @db.each_key.to_a)
66
+ assert_equal(%w[ foo bar ], @kvs.each_key.to_a)
67
+ assert_equal(%w[ apple banana ], @kvs.each_value.to_a)
68
+ assert_equal([ %w[ foo apple ], %w[ bar banana ] ], @kvs.each_pair.to_a)
69
+
70
+ @kvs['baz'] = 'orange'
71
+ assert_equal(%w[ foo bar baz ], @db.each_key.to_a)
72
+ assert_equal(%w[ foo bar baz ], @kvs.each_key.to_a)
73
+ assert_equal(%w[ apple banana orange ], @kvs.each_value.to_a)
74
+ assert_equal([ %w[ foo apple ], %w[ bar banana ], %w[ baz orange ] ], @kvs.each_pair.to_a)
75
+
76
+ @kvs.delete('bar')
77
+ assert_equal(%w[ foo baz ], @db.each_key.to_a)
78
+ assert_equal(%w[ foo baz ], @kvs.each_key.to_a)
79
+ assert_equal(%w[ apple orange ], @kvs.each_value.to_a)
80
+ assert_equal([ %w[ foo apple ], %w[ baz orange ] ], @kvs.each_pair.to_a)
81
+ end
82
+
83
+ def test_sync
84
+ @kvs.sync
85
+ end
86
+
87
+ def test_close
88
+ @kvs.close
89
+
90
+ # nil exception
91
+ assert_raise(NoMethodError) { @kvs['foo'] }
92
+ assert_raise(NoMethodError) { @kvs['foo'] = 'apple' }
93
+ assert_raise(NoMethodError) { @kvs.delete('foo') }
94
+ assert_raise(NoMethodError) { @kvs.key? 'foo' }
95
+ assert_raise(NoMethodError) { @kvs.each_key.to_a }
96
+ assert_raise(NoMethodError) { @kvs.each_value.to_a }
97
+ assert_raise(NoMethodError) { @kvs.each_pair.to_a }
98
+ end
99
+
100
+ def test_destroy
101
+ @kvs.destroy
102
+ end
103
+
104
+ def test_checksum_error
105
+ @kvs['foo'] = 'Hello world.'
106
+ assert_equal('Hello world.', @kvs['foo'])
107
+
108
+ s = @db['foo']
109
+ @db['foo'] = s.chop
110
+ assert_raise(RuntimeError) { @kvs['foo'] }
111
+
112
+ @db['foo'] = 'Hello world.'
113
+ assert_raise(RuntimeError) { @kvs['foo'] }
114
+ end
115
+ end
116
+ end
117
+
118
+ # Local Variables:
119
+ # mode: Ruby
120
+ # indent-tabs-mode: nil
121
+ # End:
@@ -0,0 +1,533 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require 'digest'
4
+ require 'fileutils'
5
+ require 'logger'
6
+ require 'pp' if $DEBUG
7
+ require 'rims'
8
+ require 'socket'
9
+ require 'test/unit'
10
+ require 'yaml'
11
+
12
+ module RIMS::Test
13
+ class ConfigTest < Test::Unit::TestCase
14
+ def setup
15
+ @base_dir = 'dummy_test_base_dir'
16
+ end
17
+
18
+ def teardown
19
+ FileUtils.rm_rf(@base_dir)
20
+ end
21
+
22
+ def assert_load_from_base_dir(conf_params)
23
+ conf = RIMS::Config.new
24
+ conf.load_config_from_base_dir(conf_params, @base_dir)
25
+ yield(conf)
26
+ end
27
+ private :assert_load_from_base_dir
28
+
29
+ def assert_config(conf_params)
30
+ conf = RIMS::Config.new
31
+ conf.load(base_dir: @base_dir)
32
+ conf.load(conf_params)
33
+ yield(conf)
34
+ end
35
+ private :assert_config
36
+
37
+ def assert_logging_params(conf_params, expected_params)
38
+ assert_config(conf_params) {|conf|
39
+ assert_equal(expected_params, conf.logging_params, 'logging_params')
40
+ assert_equal({}, conf.through_server_params, 'throuth_server_params')
41
+ }
42
+ end
43
+ private :assert_logging_params
44
+
45
+ def assert_key_value_store_params(db_type, conf_params, expected_params)
46
+ assert_config(conf_params) {|conf|
47
+ assert_equal(expected_params, conf.key_value_store_params(db_type), 'key_value_store_params')
48
+ assert_equal({}, conf.through_server_params, 'throuth_server_params')
49
+ }
50
+ end
51
+ private :assert_key_value_store_params
52
+
53
+ def assert_build_authentication(conf_params)
54
+ assert_config(conf_params) {|conf|
55
+ yield(conf.build_authentication)
56
+ assert_equal({}, conf.through_server_params, 'throuth_server_params')
57
+ }
58
+ end
59
+ private :assert_build_authentication
60
+
61
+ def assert_privilege_params(conf_params, expected_params)
62
+ assert_config(conf_params) {|conf|
63
+ if ((expected_params.is_a? Class) && (expected_params <= Exception)) then
64
+ assert_raise(expected_params) { conf.setup_privilege_params }
65
+ else
66
+ conf.setup_privilege_params
67
+ assert_equal(expected_params, conf.through_server_params)
68
+ end
69
+ }
70
+ end
71
+ private :assert_privilege_params
72
+
73
+ def test_load_from_base_dir
74
+ assert_load_from_base_dir({}) {|conf|
75
+ assert_equal(@base_dir, conf.base_dir)
76
+ assert_equal({}, conf.through_server_params)
77
+ }
78
+
79
+ assert_load_from_base_dir({ ip_addr: '192.168.0.1' }) {|conf|
80
+ assert_equal(@base_dir, conf.base_dir)
81
+ assert_equal({ ip_addr: '192.168.0.1' }, conf.through_server_params)
82
+ }
83
+
84
+ assert_load_from_base_dir({ base_dir: 'foo' }) {|conf|
85
+ assert_equal(File.join(@base_dir, 'foo'), conf.base_dir)
86
+ assert_equal({}, conf.through_server_params)
87
+ }
88
+
89
+ assert_load_from_base_dir({ base_dir: 'foo', ip_addr: '192.168.0.1' }) {|conf|
90
+ assert_equal(File.join(@base_dir, 'foo'), conf.base_dir)
91
+ assert_equal({ ip_addr: '192.168.0.1' }, conf.through_server_params)
92
+ }
93
+
94
+ assert_load_from_base_dir({ base_dir: '/foo' }) {|conf|
95
+ assert_equal('/foo', conf.base_dir)
96
+ assert_equal({}, conf.through_server_params)
97
+ }
98
+
99
+ assert_load_from_base_dir({ base_dir: '/foo', ip_addr: '192.168.0.1' }) {|conf|
100
+ assert_equal('/foo', conf.base_dir)
101
+ assert_equal({ ip_addr: '192.168.0.1' }, conf.through_server_params)
102
+ }
103
+ end
104
+
105
+ def test_load_libraries
106
+ assert(! $LOADED_FEATURES.any?{|name| name =~ /prime/})
107
+ fork{
108
+ begin
109
+ assert_config(load_libraries: %w[ prime ]) {|conf|
110
+ conf.setup_load_libraries
111
+ assert($LOADED_FEATURES.any?{|name| name =~ /prime/})
112
+ }
113
+ rescue
114
+ exit!(1)
115
+ end
116
+ exit!(0)
117
+ }
118
+ Process.wait
119
+ assert_equal(0, $?.exitstatus)
120
+ end
121
+
122
+ def test_logging_params
123
+ assert_logging_params({}, {
124
+ log_file: File.join(@base_dir, 'imap.log'),
125
+ log_level: Logger::INFO,
126
+ log_opt_args: [],
127
+ log_stdout: Logger::INFO
128
+ })
129
+
130
+ assert_logging_params({ log_level: 'debug' }, {
131
+ log_file: File.join(@base_dir, 'imap.log'),
132
+ log_level: Logger::DEBUG,
133
+ log_opt_args: [],
134
+ log_stdout: Logger::INFO
135
+ })
136
+
137
+ assert_logging_params({ log_level: 'info' }, {
138
+ log_file: File.join(@base_dir, 'imap.log'),
139
+ log_level: Logger::INFO,
140
+ log_opt_args: [],
141
+ log_stdout: Logger::INFO
142
+ })
143
+
144
+ assert_logging_params({ log_level: 'warn' }, {
145
+ log_file: File.join(@base_dir, 'imap.log'),
146
+ log_level: Logger::WARN,
147
+ log_opt_args: [],
148
+ log_stdout: Logger::INFO
149
+ })
150
+
151
+ assert_logging_params({ log_level: 'error' }, {
152
+ log_file: File.join(@base_dir, 'imap.log'),
153
+ log_level: Logger::ERROR,
154
+ log_opt_args: [],
155
+ log_stdout: Logger::INFO
156
+ })
157
+
158
+ assert_logging_params({ log_stdout: 'debug' }, {
159
+ log_file: File.join(@base_dir, 'imap.log'),
160
+ log_level: Logger::INFO,
161
+ log_opt_args: [],
162
+ log_stdout: Logger::DEBUG
163
+ })
164
+
165
+ assert_logging_params({ log_stdout: 'info' }, {
166
+ log_file: File.join(@base_dir, 'imap.log'),
167
+ log_level: Logger::INFO,
168
+ log_opt_args: [],
169
+ log_stdout: Logger::INFO
170
+ })
171
+
172
+ assert_logging_params({ log_stdout: 'warn' }, {
173
+ log_file: File.join(@base_dir, 'imap.log'),
174
+ log_level: Logger::INFO,
175
+ log_opt_args: [],
176
+ log_stdout: Logger::WARN
177
+ })
178
+
179
+ assert_logging_params({ log_stdout: 'error' }, {
180
+ log_file: File.join(@base_dir, 'imap.log'),
181
+ log_level: Logger::INFO,
182
+ log_opt_args: [],
183
+ log_stdout: Logger::ERROR
184
+ })
185
+
186
+ assert_logging_params({ log_file: 'server.log' }, {
187
+ log_file: File.join(@base_dir, 'server.log'),
188
+ log_level: Logger::INFO,
189
+ log_opt_args: [],
190
+ log_stdout: Logger::INFO
191
+ })
192
+
193
+ assert_logging_params({ log_file: 'foo/bar/server.log' }, {
194
+ log_file: File.join(@base_dir, 'foo/bar/server.log'),
195
+ log_level: Logger::INFO,
196
+ log_opt_args: [],
197
+ log_stdout: Logger::INFO
198
+ })
199
+
200
+ assert_logging_params({ log_file: '/var/rims/server.log' }, {
201
+ log_file: '/var/rims/server.log',
202
+ log_level: Logger::INFO,
203
+ log_opt_args: [],
204
+ log_stdout: Logger::INFO
205
+ })
206
+
207
+ assert_logging_params({ log_shift_age: 'daily' }, {
208
+ log_file: File.join(@base_dir, 'imap.log'),
209
+ log_level: Logger::INFO,
210
+ log_opt_args: [ 'daily' ],
211
+ log_stdout: Logger::INFO
212
+ })
213
+
214
+ assert_logging_params({ log_shift_size: 1024**2 }, {
215
+ log_file: File.join(@base_dir, 'imap.log'),
216
+ log_level: Logger::INFO,
217
+ log_opt_args: [ 1, 1024**2 ],
218
+ log_stdout: Logger::INFO
219
+ })
220
+
221
+ assert_logging_params({ log_shift_age: 10,
222
+ log_shift_size: 1024**2
223
+ }, {
224
+ log_file: File.join(@base_dir, 'imap.log'),
225
+ log_level: Logger::INFO,
226
+ log_opt_args: [ 10, 1024**2 ],
227
+ log_stdout: Logger::INFO
228
+ })
229
+ end
230
+
231
+ def test_key_value_store_params
232
+ assert_key_value_store_params(:meta_key_value_store, {}, {
233
+ origin_key_value_store: RIMS::GDBM_KeyValueStore,
234
+ origin_config: {},
235
+ middleware_key_value_store_list: [ RIMS::Checksum_KeyValueStore ]
236
+ })
237
+
238
+ assert_key_value_store_params(:meta_key_value_store, {
239
+ meta_key_value_store: {
240
+ 'plug_in' => 'gdbm'
241
+ }
242
+ }, {
243
+ origin_key_value_store: RIMS::GDBM_KeyValueStore,
244
+ origin_config: {},
245
+ middleware_key_value_store_list: [ RIMS::Checksum_KeyValueStore ]
246
+ })
247
+
248
+ assert_key_value_store_params(:meta_key_value_store, {
249
+ meta_key_value_store: {
250
+ 'plug_in' => 'gdbm',
251
+ 'configuration' => { 'foo' => 'bar' }
252
+ }
253
+ }, {
254
+ origin_key_value_store: RIMS::GDBM_KeyValueStore,
255
+ origin_config: { 'foo' => 'bar' },
256
+ middleware_key_value_store_list: [ RIMS::Checksum_KeyValueStore ]
257
+ })
258
+
259
+ FileUtils.mkdir_p(@base_dir)
260
+ IO.write(File.join(@base_dir, 'config.yml'), { 'foo' => 'bar' }.to_yaml)
261
+
262
+ assert_key_value_store_params(:meta_key_value_store, {
263
+ meta_key_value_store: {
264
+ 'plug_in' => 'gdbm',
265
+ 'configuration_file' => 'config.yml'
266
+ }
267
+ }, {
268
+ origin_key_value_store: RIMS::GDBM_KeyValueStore,
269
+ origin_config: { 'foo' => 'bar' },
270
+ middleware_key_value_store_list: [ RIMS::Checksum_KeyValueStore ]
271
+ })
272
+
273
+ assert_key_value_store_params(:meta_key_value_store, {
274
+ meta_key_value_store: {
275
+ 'use_checksum' => true
276
+ }
277
+ }, {
278
+ origin_key_value_store: RIMS::GDBM_KeyValueStore,
279
+ origin_config: {},
280
+ middleware_key_value_store_list: [ RIMS::Checksum_KeyValueStore ]
281
+ })
282
+
283
+ assert_key_value_store_params(:meta_key_value_store, {
284
+ meta_key_value_store: {
285
+ 'use_checksum' => false
286
+ }
287
+ }, {
288
+ origin_key_value_store: RIMS::GDBM_KeyValueStore,
289
+ origin_config: {},
290
+ middleware_key_value_store_list: []
291
+ })
292
+
293
+ # for backward compatibility
294
+ assert_key_value_store_params(:meta_key_value_store, { key_value_store_type: 'gdbm' }, {
295
+ origin_key_value_store: RIMS::GDBM_KeyValueStore,
296
+ origin_config: {},
297
+ middleware_key_value_store_list: [ RIMS::Checksum_KeyValueStore ]
298
+ })
299
+
300
+ # for backward compatibility
301
+ assert_key_value_store_params(:meta_key_value_store, { use_key_value_store_checksum: true }, {
302
+ origin_key_value_store: RIMS::GDBM_KeyValueStore,
303
+ origin_config: {},
304
+ middleware_key_value_store_list: [ RIMS::Checksum_KeyValueStore ]
305
+ })
306
+
307
+ # for backward compatibility
308
+ assert_key_value_store_params(:meta_key_value_store, { use_key_value_store_checksum: false }, {
309
+ origin_key_value_store: RIMS::GDBM_KeyValueStore,
310
+ origin_config: {},
311
+ middleware_key_value_store_list: []
312
+ })
313
+ end
314
+
315
+ def test_build_authentication
316
+ username = 'foo'
317
+ password = 'open_sesame'
318
+ salt = "\x8F\x16\x63\x6D\x21\xE0\x0F\x3D"
319
+
320
+ assert_build_authentication({ username: username, password: password }) {|auth|
321
+ assert_equal(Socket.gethostname, auth.hostname, 'hostname')
322
+ assert(auth.authenticate_login(username, password), 'user')
323
+ refute(auth.authenticate_login(username.succ, password), 'mismatch username')
324
+ refute(auth.authenticate_login(username, password.succ), 'mismatch password')
325
+ }
326
+
327
+ assert_build_authentication({ username: username, password: password, hostname: 'rims-test' }) {|auth|
328
+ assert_equal('rims-test', auth.hostname, 'hostname')
329
+ assert(auth.authenticate_login(username, password), 'user')
330
+ refute(auth.authenticate_login(username.succ, password), 'mismatch username')
331
+ refute(auth.authenticate_login(username, password.succ), 'mismatch password')
332
+ }
333
+
334
+ assert_build_authentication({ user_list: [
335
+ { 'user' => username, 'pass' => password },
336
+ { 'user' => username.succ, 'pass' => password.succ }
337
+ ]
338
+ }) {|auth|
339
+ assert(auth.authenticate_login(username, password), 'user 1')
340
+ assert(auth.authenticate_login(username.succ, password.succ), 'user 2')
341
+ refute(auth.authenticate_login(username.succ.succ, password.succ.succ), 'user 3')
342
+ }
343
+
344
+ assert_build_authentication({ username: username, password: password,
345
+ user_list: [
346
+ { 'user' => username.succ, 'pass' => password.succ }
347
+ ]
348
+ }) {|auth|
349
+ assert(auth.authenticate_login(username, password), 'user 1')
350
+ assert(auth.authenticate_login(username.succ, password.succ), 'user 2')
351
+ refute(auth.authenticate_login(username.succ.succ, password.succ.succ), 'user 3')
352
+ }
353
+
354
+ assert_build_authentication({ authentication: [
355
+ { 'plug_in' => 'plain',
356
+ 'configuration' => [
357
+ { 'user' => username, 'pass' => password }
358
+ ]
359
+ }
360
+ ]
361
+ }) {|auth|
362
+ assert(auth.authenticate_login(username, password), 'user')
363
+ refute(auth.authenticate_login(username.succ, password), 'mismatch username')
364
+ refute(auth.authenticate_login(username, password.succ), 'mismatch password')
365
+ }
366
+
367
+ assert_build_authentication({ authentication: [
368
+ { 'plug_in' => 'hash',
369
+ 'configuration' => [
370
+ { 'user' => username,
371
+ 'hash' => RIMS::Password::HashSource.make_entry(Digest::SHA256, 1000, salt, password).to_s
372
+ }
373
+ ]
374
+ }
375
+ ]
376
+ }) {|auth|
377
+ assert(auth.authenticate_login(username, password), 'user')
378
+ refute(auth.authenticate_login(username.succ, password), 'mismatch username')
379
+ refute(auth.authenticate_login(username, password.succ), 'mismatch password')
380
+ }
381
+
382
+ FileUtils.mkdir_p(@base_dir)
383
+ IO.write(File.join(@base_dir, 'passwd.yml'), [
384
+ { 'user' => username, 'pass' => password }
385
+ ].to_yaml)
386
+
387
+ assert_build_authentication({ authentication: [
388
+ { 'plug_in' => 'plain',
389
+ 'configuration_file' => 'passwd.yml'
390
+ }
391
+ ]
392
+ }) {|auth|
393
+ assert(auth.authenticate_login(username, password), 'user')
394
+ refute(auth.authenticate_login(username.succ, password), 'mismatch username')
395
+ refute(auth.authenticate_login(username, password.succ), 'mismatch password')
396
+ }
397
+
398
+ IO.write(File.join(@base_dir, 'passwd.yml'), [
399
+ { 'user' => username,
400
+ 'hash' => RIMS::Password::HashSource.make_entry(Digest::SHA256, 1000, salt, password).to_s
401
+ }
402
+ ].to_yaml)
403
+
404
+ assert_build_authentication({ authentication: [
405
+ { 'plug_in' => 'hash',
406
+ 'configuration_file' => 'passwd.yml'
407
+ }
408
+ ]
409
+ }) {|auth|
410
+ assert(auth.authenticate_login(username, password), 'user')
411
+ refute(auth.authenticate_login(username.succ, password), 'mismatch username')
412
+ refute(auth.authenticate_login(username, password.succ), 'mismatch password')
413
+ }
414
+ end
415
+
416
+ def test_setup_privilege_params
417
+ assert_privilege_params({}, {
418
+ process_privilege_uid: 65534,
419
+ process_privilege_gid: 65534
420
+ })
421
+
422
+ assert_privilege_params({ process_privilege_user: 'root',
423
+ process_privilege_group: '0'
424
+ }, {
425
+ process_privilege_uid: 0,
426
+ process_privilege_gid: 0
427
+ })
428
+
429
+ assert_privilege_params({ process_privilege_user: 0,
430
+ process_privilege_group: 0
431
+ }, {
432
+ process_privilege_uid: 0,
433
+ process_privilege_gid: 0
434
+ })
435
+
436
+ assert_privilege_params({ process_privilege_user: 'detarame',
437
+ process_privilege_group: 0
438
+ },
439
+ ArgumentError)
440
+
441
+ assert_privilege_params({ process_privilege_user: 0,
442
+ process_privilege_group: :detarame
443
+ },
444
+ TypeError)
445
+ end
446
+ end
447
+
448
+ class ConfigPathUtilTest < Test::Unit::TestCase
449
+ def setup
450
+ @base_dir = "dummy_test_base_dir.#{$$}"
451
+ FileUtils.rm_rf(@base_dir) if (File.directory? @base_dir)
452
+ end
453
+
454
+ def teardown
455
+ FileUtils.rm_rf(@base_dir) unless $DEBUG
456
+ end
457
+
458
+ def test_load_plug_in_configuration
459
+ assert_equal({},RIMS::Config.load_plug_in_configuration(@base_dir, {}))
460
+ assert_equal({ 'foo' => 'bar' },
461
+ RIMS::Config.load_plug_in_configuration(@base_dir,
462
+ { 'configuration' => { 'foo' => 'bar' } }))
463
+
464
+ FileUtils.mkdir_p(@base_dir)
465
+ IO.write(File.join(@base_dir, 'config.yml'), { 'foo' => 'bar' }.to_yaml)
466
+ assert_equal({ 'foo' => 'bar' },
467
+ RIMS::Config.load_plug_in_configuration(@base_dir,
468
+ { 'configuration_file' => 'config.yml' }))
469
+
470
+ assert_raise(RuntimeError) {
471
+ RIMS::Config.load_plug_in_configuration(@base_dir, {
472
+ 'configuration' => { 'foo' => 'bar' },
473
+ 'configuration_file' => 'config.yml'
474
+ })
475
+ }
476
+ end
477
+
478
+ def test_mkdir_from_base_dir
479
+ target_dir = File.join(@base_dir, 'foo', 'bar')
480
+ Dir.mkdir(@base_dir)
481
+
482
+ refute(File.directory? target_dir)
483
+ assert_equal(target_dir, RIMS::Config.mkdir_from_base_dir(@base_dir, %w[ foo bar ]))
484
+ assert(File.directory? target_dir)
485
+ end
486
+
487
+ def test_mkdir_from_base_dir_already_exist_dir
488
+ target_dir = File.join(@base_dir, 'foo', 'bar')
489
+ FileUtils.mkdir_p(target_dir)
490
+
491
+ assert(File.directory? target_dir)
492
+ assert_nil(RIMS::Config.mkdir_from_base_dir(@base_dir, %w[ foo bar ]))
493
+ assert(File.directory? target_dir)
494
+ end
495
+
496
+ def test_mkdir_from_base_dir_already_exist_file
497
+ target_dir = File.join(@base_dir, 'foo', 'bar')
498
+ FileUtils.mkdir_p(File.dirname(target_dir))
499
+ FileUtils.touch(target_dir)
500
+
501
+ assert(File.file? target_dir)
502
+ assert_raise(RuntimeError) {
503
+ RIMS::Config.mkdir_from_base_dir(@base_dir, %w[ foo bar ])
504
+ }
505
+ assert(File.file? target_dir)
506
+ end
507
+
508
+ def test_mkdir_from_base_dir_not_exist_base_dir
509
+ refute(File.directory? @base_dir)
510
+ assert_raise(RuntimeError) {
511
+ RIMS::Config.mkdir_from_base_dir(@base_dir, %w[ foo bar ])
512
+ }
513
+ refute(File.directory? @base_dir)
514
+ end
515
+
516
+ def test_make_key_value_store_path_name_list
517
+ assert_equal([ 'v1', 'ab', 'c' ],
518
+ RIMS::Config.make_key_value_store_path_name_list('v1', 'abc'))
519
+ assert_equal([ 'v1', 'e3', 'b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855' ],
520
+ RIMS::Config.make_key_value_store_path_name_list('v1', 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'))
521
+ assert_equal([ 'v1', 'e3', 'b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', 'meta_db' ],
522
+ RIMS::Config.make_key_value_store_path_name_list('v1', 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', db_name: 'meta_db'))
523
+
524
+ assert_raise(ArgumentError) { RIMS::Config.make_key_value_store_path_name_list('v1', '') }
525
+ assert_raise(ArgumentError) { RIMS::Config.make_key_value_store_path_name_list('v1', 'ab') }
526
+ end
527
+ end
528
+ end
529
+
530
+ # Local Variables:
531
+ # mode: Ruby
532
+ # indent-tabs-mode: nil
533
+ # End: