rims 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
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: