mongo_test_server 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mongo_test_server.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 John Axel Eriksson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # MongoTestServer
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'mongo_test_server'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install mongo_test_server
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,3 @@
1
+ module MongoTestServer
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,209 @@
1
+ # coding: UTF-8
2
+ require 'mongo'
3
+ require 'fileutils'
4
+ require 'erb'
5
+ require 'yaml'
6
+ require 'tempfile'
7
+ require "mongo_test_server/version"
8
+
9
+ module MongoTestServer
10
+
11
+ class Mongod
12
+
13
+ class << self
14
+
15
+ def configure(options={}, &block)
16
+ options.each do |k,v|
17
+ server.send("#{k}=",v) if server.respond_to?("#{k}=")
18
+ end
19
+ yield(server) if block_given?
20
+ end
21
+
22
+ def server
23
+ @mongo_test_server ||= new
24
+ end
25
+
26
+ def start_server
27
+ unless @mongo_test_server.nil?
28
+ @mongo_test_server.start
29
+ else
30
+ puts "MongoTestServer not configured properly!"
31
+ end
32
+ end
33
+
34
+ def stop_server
35
+ unless @mongo_test_server.nil?
36
+ @mongo_test_server.stop
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ attr_writer :port
43
+ attr_writer :path
44
+ attr_writer :name
45
+ attr_reader :mongo_instance_id
46
+
47
+ def initialize(port=nil, name=nil, path=nil)
48
+ self.port = port
49
+ self.path = path
50
+ self.name = name
51
+ @mongo_process_or_thread = nil
52
+ @mongo_instance_id = "#{Time.now.to_i}_#{Random.new.rand(10000000000..90000000000)}"
53
+ @oplog_size = 200
54
+ @configured = true
55
+ self.started = false
56
+ end
57
+
58
+ def mongo_log
59
+ "#{mongo_dir}/mongo_log"
60
+ end
61
+
62
+ def port
63
+ @port ||= 27017
64
+ end
65
+
66
+ def path
67
+ @path ||= `which mongod`.chomp
68
+ end
69
+
70
+ def name
71
+ @name ||= "#{Random.new.rand(10000000000..90000000000)}"
72
+ end
73
+
74
+ def mongo_dir
75
+ @mongo_dir ||= "/tmp/#{self.name}_mongo_testserver_#{@mongo_instance_id}"
76
+ end
77
+
78
+ def mongo_cmd_line
79
+ "#{self.path} --port #{self.port} --dbpath #{self.mongo_dir} --noprealloc --nojournal --noauth --nohttpinterface --nssize 1 --oplogSize #{@oplog_size} --smallfiles --logpath #{self.mongo_log}"
80
+ end
81
+
82
+ def prepare
83
+ FileUtils.rm_rf self.mongo_dir
84
+ FileUtils.mkdir_p self.mongo_dir
85
+ end
86
+
87
+ def running?
88
+ pids = `ps ax | grep mongod | grep #{self.port} | grep #{self.mongo_dir} | grep -v grep | awk '{print \$1}'`.chomp
89
+ !pids.empty?
90
+ end
91
+
92
+ def started?
93
+ File.directory?(self.mongo_dir) && File.exists?("#{self.mongo_dir}/started")
94
+ end
95
+
96
+ def killed?
97
+ !File.directory?(self.mongo_dir) || File.exists?("#{self.mongo_dir}/killed")
98
+ end
99
+
100
+ def started=(running)
101
+ if File.directory?(self.mongo_dir)
102
+ running ? FileUtils.touch("#{self.mongo_dir}/started") : FileUtils.rm_f("#{self.mongo_dir}/started")
103
+ end
104
+ end
105
+
106
+ def killed=(killing)
107
+ if File.directory?(self.mongo_dir)
108
+ killing ? FileUtils.touch("#{self.mongo_dir}/killed") : FileUtils.rm_f("#{self.mongo_dir}/killed")
109
+ end
110
+ end
111
+
112
+ def error?
113
+ File.exists?("#{self.mongo_dir}/error")
114
+ end
115
+
116
+ def configured?
117
+ @configured
118
+ end
119
+
120
+ def start
121
+ unless started?
122
+ prepare
123
+ if RUBY_PLATFORM=='java'
124
+ @mongo_process_or_thread = Thread.new { run(mongo_cmd_line) }
125
+ else
126
+ @mongo_process_or_thread = fork { run(mongo_cmd_line) }
127
+ end
128
+ wait_until_ready
129
+ end
130
+ self
131
+ end
132
+
133
+ def run(command, *args)
134
+ error_file = Tempfile.new('error')
135
+ error_filepath = error_file.path
136
+ error_file.close
137
+ args = args.join(' ') rescue ''
138
+ command << " #{args}" unless args.empty?
139
+ result = `#{command} 2>"#{error_filepath}"`
140
+ unless killed? || $?.success?
141
+ error_message = <<-ERROR
142
+ <#{self.class.name}> Error executing command: #{command}
143
+ <#{self.class.name}> Result is: #{IO.binread(self.mongo_log)}
144
+ <#{self.class.name}> Error is: #{File.read(error_filepath)}
145
+ ERROR
146
+ File.open("#{self.mongo_dir}/error", 'w') do |f|
147
+ f << error_message
148
+ end
149
+ self.killed=true
150
+ end
151
+ result
152
+ end
153
+
154
+ def wait_until_ready
155
+ retries = 10
156
+ begin
157
+ self.started = true
158
+ c = Mongo::Connection.new("localhost", self.port)
159
+ c.close
160
+ rescue Exception => e
161
+ if retries>0 && !killed? && !error?
162
+ retries -= 1
163
+ sleep 0.5
164
+ retry
165
+ else
166
+ self.started = false
167
+ error_lines = []
168
+ error_lines << "<#{self.class.name}> cmd was: #{mongo_cmd_line}"
169
+ error_lines << "<#{self.class.name}> ERROR: Failed to connect to mongo database: #{e.message}"
170
+ IO.binread(self.mongo_log).split("\n").each do |line|
171
+ error_lines << "<#{self.class.name}> #{line}"
172
+ end
173
+ stop
174
+ raise Exception.new error_lines.join("\n")
175
+ end
176
+ end
177
+ end
178
+
179
+ def pids
180
+ pids = `ps ax | grep mongod | grep #{self.port} | grep #{self.mongo_dir} | grep -v grep | awk '{print \$1}'`.chomp
181
+ pids.split("\n").map {|p| (p.nil? || p=='') ? nil : p.to_i }
182
+ end
183
+
184
+ def stop
185
+ mongo_pids = pids
186
+ self.killed = true
187
+ self.started = false
188
+ mongo_pids.each { |ppid| `kill -9 #{ppid} 2> /dev/null` }
189
+ FileUtils.rm_rf self.mongo_dir
190
+ self
191
+ end
192
+
193
+ def mongoid_options(options={})
194
+ options = {host: "localhost", port: self.port, database: "#{self.name}_test_db", use_utc: false, use_activesupport_time_zone: true}.merge(options)
195
+ end
196
+
197
+ def mongoid_yml(options={})
198
+ options = mongoid_options(options)
199
+ mongo_conf_yaml = <<EOY
200
+ host: #{options[:host]}
201
+ port: #{options[:port]}
202
+ database : #{options[:database]}
203
+ use_utc: #{options[:use_utc]}
204
+ use_activesupport_time_zone: #{options[:use_activesupport_time_zone]}
205
+ EOY
206
+ end
207
+
208
+ end
209
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/mongo_test_server/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["John Axel Eriksson"]
6
+ gem.email = ["john@insane.se"]
7
+ gem.description = %q{Standalone mongo test server for use with rspec or other unit testing framework}
8
+ gem.summary = %q{Standalone mongo test server for use with rspec or other unit testing framework}
9
+ gem.homepage = ""
10
+
11
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
12
+ gem.files = `git ls-files`.split("\n")
13
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
14
+ gem.name = "mongo_test_server"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = MongoTestServer::VERSION
17
+
18
+ gem.add_dependency('mongo', '>=1.6.0')
19
+ unless RUBY_PLATFORM == 'java'
20
+ gem.add_development_dependency('bson_ext', '>=1.3.0')
21
+ end
22
+ gem.add_development_dependency "rspec", '>=2.6.0'
23
+
24
+ end
@@ -0,0 +1,124 @@
1
+ require 'spec_helper'
2
+
3
+ describe MongoTestServer::Mongod do
4
+
5
+ let(:port) { 11129 }
6
+ let(:bad_port) { 112233 }
7
+ let(:server_name) { "random_name_#{Random.new.rand(100000000..900000000)}"}
8
+ let(:path) { `which mongod`.chomp }
9
+ subject { MongoTestServer::Mongod.new(port, server_name, path)}
10
+ let(:server_same_port) { MongoTestServer::Mongod.new(port, server_name, path)}
11
+ let(:correct_mongoid_options) do
12
+ {
13
+ host: "localhost",
14
+ port: port,
15
+ database: "#{server_name}_test_db",
16
+ use_utc: false,
17
+ use_activesupport_time_zone: true
18
+ }
19
+ end
20
+ after(:each) do
21
+ subject.stop
22
+ server_same_port.stop
23
+ end
24
+
25
+ context "starting" do
26
+
27
+ it "should start" do
28
+ lambda { subject.start }.should_not raise_error
29
+ subject.started?.should be_true
30
+ end
31
+
32
+ it "should not complain if starting a started mongod" do
33
+ lambda { subject.start }.should_not raise_error
34
+ subject.started?.should be_true
35
+ lambda { subject.start }.should_not raise_error
36
+ end
37
+
38
+ it "should raise if something else is listening on the same port" do
39
+ server_same_port.start
40
+ subject.start.should raise_error
41
+ end
42
+
43
+ it "should raise if there is an error starting mongod" do
44
+ subject.port = bad_port ## port number is too high
45
+ lambda { subject.start }.should raise_error
46
+ end
47
+
48
+ end
49
+
50
+ context "mongoid config" do
51
+
52
+ it "should return correct mongoid options" do
53
+ subject.mongoid_options.should == correct_mongoid_options
54
+ end
55
+
56
+ it "should return correct mongoid options with requested changes" do
57
+ changed_mongoid_options = correct_mongoid_options.merge(use_utc: true, use_activesupport_time_zone: false)
58
+ subject.mongoid_options(use_utc: true, use_activesupport_time_zone: false).should == changed_mongoid_options
59
+ end
60
+
61
+ end
62
+
63
+ context "stopping" do
64
+
65
+ before(:each) do
66
+ subject.start
67
+ end
68
+
69
+ it "should stop a started mongod" do
70
+ subject.started?.should be_true
71
+ subject.stop
72
+ subject.started?.should be_false
73
+ subject.killed?.should be_true
74
+ subject.running?.should be_false
75
+ end
76
+
77
+ it "should not complain if stopping a stopped mongod" do
78
+ subject.started?.should be_true
79
+ subject.killed?.should be_false
80
+ subject.stop
81
+ subject.started?.should be_false
82
+ subject.killed?.should be_true
83
+ subject.running?.should be_false
84
+ lambda{ subject.stop }.should_not raise_error
85
+ end
86
+
87
+ it "should cleanup after itself" do
88
+ subject.started?.should be_true
89
+ File.directory?(subject.mongo_dir).should be_true
90
+ subject.stop
91
+ File.exists?(subject.mongo_dir).should be_false
92
+ end
93
+
94
+ end
95
+
96
+ context "MongoTestServer#configure" do
97
+
98
+ let(:name) { "somename" }
99
+ let(:port) { 33221 }
100
+ let(:path) { `which mongod`.chomp }
101
+
102
+ it "should configure a global mongod" do
103
+ MongoTestServer::Mongod.configure do |server|
104
+ server.name = name
105
+ server.port = port
106
+ server.path = path
107
+ end
108
+ server = MongoTestServer::Mongod.server
109
+ server.port.should == port
110
+ server.name.should == name
111
+ server.path.should == path
112
+ end
113
+
114
+ it "should configure a global mongod using options instead of block" do
115
+ MongoTestServer::Mongod.configure(port: (port+1), name: "someothername", path: path)
116
+ server = MongoTestServer::Mongod.server
117
+ server.port.should == (port+1)
118
+ server.name.should == "someothername"
119
+ server.path.should == path
120
+ end
121
+
122
+ end
123
+
124
+ end
@@ -0,0 +1,28 @@
1
+ # coding: UTF-8
2
+
3
+ require 'bundler/setup'
4
+ Bundler.require(:default, :development)
5
+ mongo_test_server_path = File.expand_path('./lib', File.dirname(__FILE__))
6
+ $:.unshift(mongo_test_server_path) if File.directory?(mongo_test_server_path) && !$:.include?(mongo_test_server_path)
7
+
8
+ require 'mongo_test_server'
9
+ require 'yaml'
10
+ require 'fileutils'
11
+
12
+ RSpec.configure do |config|
13
+ # == Mock Framework
14
+ #
15
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
16
+ #
17
+ # config.mock_with :mocha
18
+ # config.mock_with :flexmock
19
+ # config.mock_with :rr
20
+ config.mock_with :rspec
21
+
22
+ ## perhaps this should be removed as well
23
+ ## and done in Rakefile?
24
+ config.color_enabled = true
25
+
26
+ ## dont do this, do it in Rakefile instead
27
+ #config.formatter = 'd'
28
+ end
data/test.rb ADDED
@@ -0,0 +1,14 @@
1
+ # coding: UTF-8
2
+ require 'bundler/setup'
3
+
4
+ Bundler.require(:default)
5
+
6
+ mongo_test_server_path = File.expand_path('./lib', File.dirname(__FILE__))
7
+ $:.unshift(mongo_test_server_path) if File.directory?(mongo_test_server_path) && !$:.include?(mongo_test_server_path)
8
+
9
+ require 'mongo_test_server'
10
+
11
+ mongod = MongoTestServer::Mongod.configure(10203, 'testing_mongo')
12
+ mongod.start
13
+ sleep 10
14
+ mongod.stop
metadata ADDED
@@ -0,0 +1,92 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongo_test_server
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - John Axel Eriksson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-15 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mongo
16
+ requirement: &70365632511940 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.6.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70365632511940
25
+ - !ruby/object:Gem::Dependency
26
+ name: bson_ext
27
+ requirement: &70365632698560 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: 1.3.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70365632698560
36
+ - !ruby/object:Gem::Dependency
37
+ name: rspec
38
+ requirement: &70365632691840 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: 2.6.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70365632691840
47
+ description: Standalone mongo test server for use with rspec or other unit testing
48
+ framework
49
+ email:
50
+ - john@insane.se
51
+ executables: []
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - Gemfile
57
+ - LICENSE
58
+ - README.md
59
+ - Rakefile
60
+ - lib/mongo_test_server.rb
61
+ - lib/mongo_test_server/version.rb
62
+ - mongo_test_server.gemspec
63
+ - spec/mongo_test_server/mongo_test_server_spec.rb
64
+ - spec/spec_helper.rb
65
+ - test.rb
66
+ homepage: ''
67
+ licenses: []
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ! '>='
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 1.8.11
87
+ signing_key:
88
+ specification_version: 3
89
+ summary: Standalone mongo test server for use with rspec or other unit testing framework
90
+ test_files:
91
+ - spec/mongo_test_server/mongo_test_server_spec.rb
92
+ - spec/spec_helper.rb