mongoid 7.1.0 → 7.1.6
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/CHANGELOG.md +6 -6
- data/README.md +1 -1
- data/Rakefile +14 -5
- data/lib/config/locales/en.yml +5 -5
- data/lib/mongoid/association/accessors.rb +37 -2
- data/lib/mongoid/association/embedded/embeds_many.rb +2 -1
- data/lib/mongoid/association/embedded/embeds_one.rb +2 -1
- data/lib/mongoid/association/proxy.rb +1 -1
- data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -1
- data/lib/mongoid/association/referenced/belongs_to/eager.rb +38 -2
- data/lib/mongoid/association/referenced/eager.rb +29 -9
- data/lib/mongoid/association/referenced/has_one/proxy.rb +6 -1
- data/lib/mongoid/atomic.rb +13 -3
- data/lib/mongoid/clients/factory.rb +2 -2
- data/lib/mongoid/clients/options.rb +8 -8
- data/lib/mongoid/clients/sessions.rb +20 -4
- data/lib/mongoid/clients/storage_options.rb +5 -5
- data/lib/mongoid/config.rb +39 -9
- data/lib/mongoid/criteria.rb +23 -4
- data/lib/mongoid/criteria/modifiable.rb +2 -1
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +6 -6
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +12 -0
- data/lib/mongoid/criteria/queryable/mergeable.rb +75 -8
- data/lib/mongoid/criteria/queryable/pipeline.rb +3 -2
- data/lib/mongoid/criteria/queryable/selectable.rb +120 -13
- data/lib/mongoid/criteria/queryable/storable.rb +104 -99
- data/lib/mongoid/errors/eager_load.rb +2 -0
- data/lib/mongoid/errors/no_client_config.rb +2 -2
- data/lib/mongoid/errors/no_default_client.rb +1 -1
- data/lib/mongoid/extensions/hash.rb +4 -2
- data/lib/mongoid/extensions/regexp.rb +1 -1
- data/lib/mongoid/fields.rb +2 -1
- data/lib/mongoid/fields/validators/macro.rb +4 -1
- data/lib/mongoid/matchable/regexp.rb +2 -2
- data/lib/mongoid/persistable/pushable.rb +11 -2
- data/lib/mongoid/persistence_context.rb +6 -6
- data/lib/mongoid/query_cache.rb +61 -18
- data/lib/mongoid/serializable.rb +9 -3
- data/lib/mongoid/tasks/database.rb +38 -3
- data/lib/mongoid/validatable/uniqueness.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +32 -23
- data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -1
- data/spec/app/models/coding.rb +4 -0
- data/spec/app/models/coding/pull_request.rb +12 -0
- data/spec/app/models/delegating_patient.rb +16 -0
- data/spec/app/models/passport.rb +1 -0
- data/spec/app/models/person.rb +2 -0
- data/spec/app/models/phone.rb +1 -0
- data/spec/app/models/publication.rb +5 -0
- data/spec/app/models/publication/encyclopedia.rb +12 -0
- data/spec/app/models/publication/review.rb +14 -0
- data/spec/app/models/series.rb +1 -0
- data/spec/app/models/wiki_page.rb +1 -0
- data/spec/integration/app_spec.rb +254 -0
- data/spec/integration/associations/embedded_spec.rb +54 -0
- data/spec/integration/associations/embeds_many_spec.rb +24 -0
- data/spec/integration/associations/embeds_one_spec.rb +24 -0
- data/spec/integration/associations/has_many_spec.rb +76 -0
- data/spec/integration/associations/has_one_spec.rb +76 -0
- data/spec/integration/bson_regexp_raw_spec.rb +20 -0
- data/spec/integration/criteria/date_field_spec.rb +41 -0
- data/spec/integration/criteria/logical_spec.rb +13 -0
- data/spec/integration/document_spec.rb +22 -0
- data/spec/integration/shardable_spec.rb +20 -4
- data/spec/lite_spec_helper.rb +12 -4
- data/spec/mongoid/association/accessors_spec.rb +238 -63
- data/spec/mongoid/association/embedded/embeds_many_models.rb +19 -0
- data/spec/mongoid/association/embedded/embeds_many_spec.rb +10 -0
- data/spec/mongoid/association/embedded/embeds_one_spec.rb +0 -2
- data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +193 -10
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +140 -1
- data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +105 -0
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +2 -1
- data/spec/mongoid/clients/factory_spec.rb +8 -8
- data/spec/mongoid/clients/options_spec.rb +11 -11
- data/spec/mongoid/clients/sessions_spec.rb +8 -4
- data/spec/mongoid/clients/transactions_spec.rb +20 -8
- data/spec/mongoid/clients_spec.rb +2 -2
- data/spec/mongoid/contextual/atomic_spec.rb +22 -11
- data/spec/mongoid/contextual/geo_near_spec.rb +11 -2
- data/spec/mongoid/contextual/map_reduce_spec.rb +20 -5
- data/spec/mongoid/contextual/mongo_spec.rb +76 -53
- data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +7 -7
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +19 -7
- data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +28 -1
- data/spec/mongoid/criteria/queryable/mergeable_spec.rb +45 -12
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +1051 -392
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +52 -0
- data/spec/mongoid/criteria/queryable/storable_spec.rb +80 -2
- data/spec/mongoid/criteria_spec.rb +36 -2
- data/spec/mongoid/document_persistence_context_spec.rb +33 -0
- data/spec/mongoid/errors/no_client_config_spec.rb +2 -2
- data/spec/mongoid/errors/no_client_database_spec.rb +3 -3
- data/spec/mongoid/errors/no_client_hosts_spec.rb +3 -3
- data/spec/mongoid/fields_spec.rb +24 -1
- data/spec/mongoid/indexable_spec.rb +6 -4
- data/spec/mongoid/matchable/default_spec.rb +1 -1
- data/spec/mongoid/matchable/regexp_spec.rb +2 -2
- data/spec/mongoid/matchable_spec.rb +2 -2
- data/spec/mongoid/persistable/pushable_spec.rb +55 -1
- data/spec/mongoid/query_cache_spec.rb +77 -9
- data/spec/mongoid/relations/proxy_spec.rb +1 -1
- data/spec/mongoid/scopable_spec.rb +2 -1
- data/spec/mongoid/serializable_spec.rb +129 -18
- data/spec/mongoid/shardable_models.rb +1 -1
- data/spec/mongoid/shardable_spec.rb +2 -2
- data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
- data/spec/mongoid/tasks/database_spec.rb +1 -1
- data/spec/shared/LICENSE +20 -0
- data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
- data/spec/shared/lib/mrss/cluster_config.rb +211 -0
- data/spec/shared/lib/mrss/constraints.rb +312 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +175 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +149 -0
- data/spec/spec_helper.rb +2 -31
- data/spec/support/child_process_helper.rb +76 -0
- data/spec/support/cluster_config.rb +3 -3
- data/spec/support/constraints.rb +26 -10
- data/spec/support/expectations.rb +3 -1
- data/spec/support/helpers.rb +11 -0
- data/spec/support/session_registry.rb +50 -0
- data/spec/support/spec_config.rb +12 -4
- metadata +520 -473
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
autoload :JSON, 'json'
|
|
2
|
+
autoload :FileUtils, 'fileutils'
|
|
3
|
+
autoload :Find, 'find'
|
|
4
|
+
|
|
5
|
+
module Mrss
|
|
6
|
+
|
|
7
|
+
autoload :ChildProcessHelper, 'mrss/child_process_helper'
|
|
8
|
+
|
|
9
|
+
# Organizes and runs all of the tests in the test suite in batches.
|
|
10
|
+
#
|
|
11
|
+
# Organizing the tests in batches serves two purposes:
|
|
12
|
+
#
|
|
13
|
+
# 1. This allows running unit tests before integration tests, therefore
|
|
14
|
+
# in theory revealing failures quicker on average.
|
|
15
|
+
# 2. This allows running some tests that have high intermittent failure rate
|
|
16
|
+
# in their own test process.
|
|
17
|
+
#
|
|
18
|
+
# This class aggregates RSpec results after the test runs.
|
|
19
|
+
class SpecOrganizer
|
|
20
|
+
|
|
21
|
+
class BucketsNotPrioritized < StandardError
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def initialize(root: nil, classifiers:, priority_order:,
|
|
25
|
+
spec_root: nil, rspec_json_path: nil, rspec_all_json_path: nil
|
|
26
|
+
)
|
|
27
|
+
@spec_root = spec_root || File.join(root, 'spec')
|
|
28
|
+
@classifiers = classifiers
|
|
29
|
+
@priority_order = priority_order
|
|
30
|
+
@rspec_json_path = rspec_json_path || File.join(root, 'tmp/rspec.json')
|
|
31
|
+
@rspec_all_json_path = rspec_all_json_path || File.join(root, 'tmp/rspec-all.json')
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
attr_reader :spec_root, :classifiers, :priority_order
|
|
35
|
+
attr_reader :rspec_json_path, :rspec_all_json_path
|
|
36
|
+
|
|
37
|
+
def buckets
|
|
38
|
+
@buckets ||= {}.tap do |buckets|
|
|
39
|
+
Find.find(spec_root) do |path|
|
|
40
|
+
next unless File.file?(path)
|
|
41
|
+
next unless path =~ /_spec\.rb\z/
|
|
42
|
+
rel_path = path[(spec_root.length + 1)..path.length]
|
|
43
|
+
|
|
44
|
+
found = false
|
|
45
|
+
classifiers.each do |(regexp, category)|
|
|
46
|
+
if regexp =~ rel_path
|
|
47
|
+
buckets[category] ||= []
|
|
48
|
+
buckets[category] << File.join('spec', rel_path)
|
|
49
|
+
found = true
|
|
50
|
+
break
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
unless found
|
|
55
|
+
buckets[nil] ||= []
|
|
56
|
+
buckets[nil] << File.join('spec', rel_path)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end.freeze
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def ordered_buckets
|
|
63
|
+
@ordered_buckets ||= {}.tap do |ordered_buckets|
|
|
64
|
+
buckets = self.buckets.dup
|
|
65
|
+
priority_order.each do |category|
|
|
66
|
+
files = buckets.delete(category)
|
|
67
|
+
ordered_buckets[category] = files
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
if files = buckets.delete(nil)
|
|
71
|
+
ordered_buckets[nil] = files
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
unless buckets.empty?
|
|
75
|
+
raise BucketsNotPrioritized, "Some buckets were not prioritized: #{buckets.keys.map(&:to_s).join(', ')}"
|
|
76
|
+
end
|
|
77
|
+
end.freeze
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def run
|
|
81
|
+
FileUtils.rm_f(rspec_all_json_path)
|
|
82
|
+
|
|
83
|
+
failed = []
|
|
84
|
+
buckets = self.buckets.dup
|
|
85
|
+
|
|
86
|
+
priority_order.each do |category|
|
|
87
|
+
if files = buckets.delete(category)
|
|
88
|
+
unless run_files(category, files)
|
|
89
|
+
failed << category
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
if files = buckets.delete(nil)
|
|
94
|
+
unless run_files('remaining', files)
|
|
95
|
+
failed << 'remaining'
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
unless buckets.empty?
|
|
100
|
+
raise "Some buckets were not executed: #{buckets.keys.map(&:to_s).join(', ')}"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
if failed.any?
|
|
104
|
+
raise "The following buckets failed: #{failed.map(&:to_s).join(', ')}"
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def run_files(category, paths)
|
|
109
|
+
puts "Running #{category.to_s.gsub('_', ' ')} tests"
|
|
110
|
+
FileUtils.rm_f(rspec_json_path)
|
|
111
|
+
cmd = %w(rspec) + paths
|
|
112
|
+
|
|
113
|
+
begin
|
|
114
|
+
ChildProcessHelper.check_call(cmd)
|
|
115
|
+
ensure
|
|
116
|
+
if File.exist?(rspec_json_path)
|
|
117
|
+
if File.exist?(rspec_all_json_path)
|
|
118
|
+
merge_rspec_results
|
|
119
|
+
else
|
|
120
|
+
FileUtils.cp(rspec_json_path, rspec_all_json_path)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
true
|
|
126
|
+
rescue ChildProcessHelper::SpawnError
|
|
127
|
+
false
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def merge_rspec_results
|
|
131
|
+
all = JSON.parse(File.read(rspec_all_json_path))
|
|
132
|
+
new = JSON.parse(File.read(rspec_json_path))
|
|
133
|
+
all['examples'] += new.delete('examples')
|
|
134
|
+
new.delete('summary').each do |k, v|
|
|
135
|
+
all['summary'][k] += v
|
|
136
|
+
end
|
|
137
|
+
new.delete('version')
|
|
138
|
+
new.delete('summary_line')
|
|
139
|
+
unless new.empty?
|
|
140
|
+
raise "Unhandled rspec results keys: #{new.keys.join(', ')}"
|
|
141
|
+
end
|
|
142
|
+
# We do not merge summary lines, delete them from aggregated results
|
|
143
|
+
all.delete('summary_line')
|
|
144
|
+
File.open(rspec_all_json_path, 'w') do |f|
|
|
145
|
+
f << JSON.dump(all)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -31,6 +31,7 @@ end
|
|
|
31
31
|
|
|
32
32
|
require 'support/authorization'
|
|
33
33
|
require 'support/expectations'
|
|
34
|
+
require 'support/helpers'
|
|
34
35
|
require 'support/macros'
|
|
35
36
|
require 'support/cluster_config'
|
|
36
37
|
require 'support/constraints'
|
|
@@ -76,37 +77,6 @@ CONFIG = {
|
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
|
|
79
|
-
def non_legacy_server?
|
|
80
|
-
Mongoid::Clients.default.cluster.servers.first.features.write_command_enabled?
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def testing_replica_set?
|
|
84
|
-
Mongoid::Clients.default.cluster.replica_set?
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def collation_supported?
|
|
88
|
-
Mongoid::Clients.default.cluster.next_primary.features.collation_enabled?
|
|
89
|
-
end
|
|
90
|
-
alias :decimal128_supported? :collation_supported?
|
|
91
|
-
|
|
92
|
-
def array_filters_supported?
|
|
93
|
-
Mongoid::Clients.default.cluster.next_primary.features.array_filters_enabled?
|
|
94
|
-
end
|
|
95
|
-
alias :sessions_supported? :array_filters_supported?
|
|
96
|
-
|
|
97
|
-
def transactions_supported?
|
|
98
|
-
features = Mongoid::Clients.default.cluster.next_primary.features
|
|
99
|
-
features.respond_to?(:transactions_enabled?) && features.transactions_enabled?
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def testing_transactions?
|
|
103
|
-
transactions_supported? && if Gem::Version.new(ClusterConfig.instance.fcv_ish) >= Gem::Version.new('4.2')
|
|
104
|
-
%i(replica_set sharded).include?(ClusterConfig.instance.topology)
|
|
105
|
-
else
|
|
106
|
-
ClusterConfig.instance.topology == :replica_set
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
|
|
110
80
|
# Set the database that the spec suite connects to.
|
|
111
81
|
Mongoid.configure do |config|
|
|
112
82
|
config.load_configuration(CONFIG)
|
|
@@ -156,6 +126,7 @@ end
|
|
|
156
126
|
|
|
157
127
|
RSpec.configure do |config|
|
|
158
128
|
config.raise_errors_for_deprecations!
|
|
129
|
+
config.include(Helpers)
|
|
159
130
|
config.include(Mongoid::Expectations)
|
|
160
131
|
config.extend(Constraints)
|
|
161
132
|
config.extend(Mongoid::Macros)
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
|
|
4
|
+
autoload :ChildProcess, 'childprocess'
|
|
5
|
+
autoload :Tempfile, 'tempfile'
|
|
6
|
+
|
|
7
|
+
module ChildProcessHelper
|
|
8
|
+
module_function def call(cmd, env: nil, cwd: nil)
|
|
9
|
+
process = ChildProcess.new(*cmd)
|
|
10
|
+
process.io.inherit!
|
|
11
|
+
if cwd
|
|
12
|
+
process.cwd = cwd
|
|
13
|
+
end
|
|
14
|
+
if env
|
|
15
|
+
env.each do |k, v|
|
|
16
|
+
process.environment[k.to_s] = v
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
process.start
|
|
20
|
+
process.wait
|
|
21
|
+
process
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
module_function def check_call(cmd, env: nil, cwd: nil)
|
|
25
|
+
process = call(cmd, env: env, cwd: cwd)
|
|
26
|
+
unless process.exit_code == 0
|
|
27
|
+
raise "Failed to execute: #{cmd}"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
module_function def get_output(cmd, env: nil, cwd: nil)
|
|
32
|
+
process = ChildProcess.new(*cmd)
|
|
33
|
+
process.io.inherit!
|
|
34
|
+
if cwd
|
|
35
|
+
process.cwd = cwd
|
|
36
|
+
end
|
|
37
|
+
if env
|
|
38
|
+
env.each do |k, v|
|
|
39
|
+
process.environment[k.to_s] = v
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
output = ''
|
|
44
|
+
r, w = IO.pipe
|
|
45
|
+
|
|
46
|
+
begin
|
|
47
|
+
process.io.stdout = w
|
|
48
|
+
process.start
|
|
49
|
+
w.close
|
|
50
|
+
|
|
51
|
+
thread = Thread.new do
|
|
52
|
+
begin
|
|
53
|
+
loop do
|
|
54
|
+
output << r.readpartial(16384)
|
|
55
|
+
end
|
|
56
|
+
rescue EOFError
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
process.wait
|
|
61
|
+
thread.join
|
|
62
|
+
ensure
|
|
63
|
+
r.close
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
[process, output]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
module_function def check_output(*args)
|
|
70
|
+
process, output = get_output(*args)
|
|
71
|
+
unless process.exit_code == 0
|
|
72
|
+
raise "Failed to execute: #{args}"
|
|
73
|
+
end
|
|
74
|
+
output
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -99,7 +99,7 @@ class ClusterConfig
|
|
|
99
99
|
if topology == :sharded
|
|
100
100
|
shards = client.use(:admin).command(listShards: 1).first
|
|
101
101
|
shard = shards['shards'].first
|
|
102
|
-
address_str = shard['host'].sub(
|
|
102
|
+
address_str = shard['host'].sub(/\A.*\//, '').sub(/,.*/, '')
|
|
103
103
|
client = ClusterTools.instance.direct_client(address_str,
|
|
104
104
|
SpecConfig.instance.test_options.merge(SpecConfig.instance.auth_options).merge(connect: :direct))
|
|
105
105
|
end
|
|
@@ -133,8 +133,8 @@ class ClusterConfig
|
|
|
133
133
|
|
|
134
134
|
@topology ||= begin
|
|
135
135
|
topology = client.cluster.topology.class.name.sub(/.*::/, '')
|
|
136
|
-
topology = topology.gsub(/([A-Z])/) { |match| '_' + match.downcase }.sub(
|
|
137
|
-
if topology =~
|
|
136
|
+
topology = topology.gsub(/([A-Z])/) { |match| '_' + match.downcase }.sub(/\A_/, '')
|
|
137
|
+
if topology =~ /\Areplica_set/
|
|
138
138
|
topology = 'replica_set'
|
|
139
139
|
end
|
|
140
140
|
topology.to_sym
|
data/spec/support/constraints.rb
CHANGED
|
@@ -5,11 +5,11 @@ module Constraints
|
|
|
5
5
|
RAILS_VERSION = ActiveSupport.version.to_s.split('.')[0..1].join('.').freeze
|
|
6
6
|
|
|
7
7
|
def min_rails_version(version)
|
|
8
|
-
unless version =~
|
|
8
|
+
unless version =~ /\A\d+\.\d+\z/
|
|
9
9
|
raise ArgumentError, "Version can only be major.minor: #{version}"
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
before do
|
|
12
|
+
before(:all) do
|
|
13
13
|
if version > RAILS_VERSION
|
|
14
14
|
skip "Rails version #{version} or higher required, we have #{RAILS_VERSION}"
|
|
15
15
|
end
|
|
@@ -17,11 +17,11 @@ module Constraints
|
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def max_rails_version(version)
|
|
20
|
-
unless version =~
|
|
20
|
+
unless version =~ /\A\d+\.\d+\z/
|
|
21
21
|
raise ArgumentError, "Version can only be major.minor: #{version}"
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
before do
|
|
24
|
+
before(:all) do
|
|
25
25
|
if version < RAILS_VERSION
|
|
26
26
|
skip "Rails version #{version} or lower required, we have #{RAILS_VERSION}"
|
|
27
27
|
end
|
|
@@ -29,11 +29,11 @@ module Constraints
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def min_server_version(version)
|
|
32
|
-
unless version =~
|
|
32
|
+
unless version =~ /\A\d+\.\d+\z/
|
|
33
33
|
raise ArgumentError, "Version can only be major.minor: #{version}"
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
before do
|
|
36
|
+
before(:all) do
|
|
37
37
|
if version > ClusterConfig.instance.server_version
|
|
38
38
|
skip "Server version #{version} or higher required, we have #{ClusterConfig.instance.server_version}"
|
|
39
39
|
end
|
|
@@ -41,11 +41,11 @@ module Constraints
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def max_server_version(version)
|
|
44
|
-
unless version =~
|
|
44
|
+
unless version =~ /\A\d+\.\d+\z/
|
|
45
45
|
raise ArgumentError, "Version can only be major.minor: #{version}"
|
|
46
46
|
end
|
|
47
47
|
|
|
48
|
-
before do
|
|
48
|
+
before(:all) do
|
|
49
49
|
if version < ClusterConfig.instance.short_server_version
|
|
50
50
|
skip "Server version #{version} or lower required, we have #{ClusterConfig.instance.server_version}"
|
|
51
51
|
end
|
|
@@ -54,9 +54,11 @@ module Constraints
|
|
|
54
54
|
|
|
55
55
|
def require_topology(*topologies)
|
|
56
56
|
invalid_topologies = topologies - [:single, :replica_set, :sharded]
|
|
57
|
+
|
|
57
58
|
unless invalid_topologies.empty?
|
|
58
59
|
raise ArgumentError, "Invalid topologies requested: #{invalid_topologies.join(', ')}"
|
|
59
60
|
end
|
|
61
|
+
|
|
60
62
|
before(:all) do
|
|
61
63
|
unless topologies.include?(topology = ClusterConfig.instance.topology)
|
|
62
64
|
skip "Topology #{topologies.join(' or ')} required, we have #{topology}"
|
|
@@ -73,8 +75,22 @@ module Constraints
|
|
|
73
75
|
end
|
|
74
76
|
|
|
75
77
|
def require_transaction_support
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
before(:all) do
|
|
79
|
+
case ClusterConfig.instance.topology
|
|
80
|
+
when :single
|
|
81
|
+
skip 'Transactions tests require a replica set (4.0+) or a sharded cluster (4.2+)'
|
|
82
|
+
when :replica_set
|
|
83
|
+
unless ClusterConfig.instance.server_version >= '4.0'
|
|
84
|
+
skip 'Transactions tests in a replica set topology require server 4.0+'
|
|
85
|
+
end
|
|
86
|
+
when :sharded
|
|
87
|
+
unless ClusterConfig.instance.server_version >= '4.2'
|
|
88
|
+
skip 'Transactions tests in a sharded cluster topology require server 4.2+'
|
|
89
|
+
end
|
|
90
|
+
else
|
|
91
|
+
raise NotImplementedError
|
|
92
|
+
end
|
|
93
|
+
end
|
|
78
94
|
end
|
|
79
95
|
|
|
80
96
|
def require_tls
|
|
@@ -14,14 +14,16 @@ module Mongoid
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def expect_query(number)
|
|
17
|
+
rv = nil
|
|
17
18
|
RSpec::Mocks.with_temporary_scope do
|
|
18
19
|
if number > 0
|
|
19
20
|
expect_any_instance_of(connection_class).to receive(:command_started).exactly(number).times.and_call_original
|
|
20
21
|
else
|
|
21
22
|
expect_any_instance_of(connection_class).not_to receive(:command_started)
|
|
22
23
|
end
|
|
23
|
-
yield
|
|
24
|
+
rv = yield
|
|
24
25
|
end
|
|
26
|
+
rv
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
def expect_no_queries(&block)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
require 'singleton'
|
|
2
|
+
|
|
3
|
+
module Mongo
|
|
4
|
+
class Client
|
|
5
|
+
alias :get_session_without_tracking :get_session
|
|
6
|
+
|
|
7
|
+
def get_session(options = {})
|
|
8
|
+
get_session_without_tracking(options).tap do |session|
|
|
9
|
+
SessionRegistry.instance.register(session)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class Session
|
|
15
|
+
alias :end_session_without_tracking :end_session
|
|
16
|
+
|
|
17
|
+
def end_session
|
|
18
|
+
SessionRegistry.instance.unregister(self)
|
|
19
|
+
end_session_without_tracking
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class SessionRegistry
|
|
26
|
+
include Singleton
|
|
27
|
+
|
|
28
|
+
def initialize
|
|
29
|
+
@registry = {}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def register(session)
|
|
33
|
+
@registry[session.session_id] = session if session
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def unregister(session)
|
|
37
|
+
@registry.delete(session.session_id)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def verify_sessions_ended!
|
|
41
|
+
unless @registry.empty?
|
|
42
|
+
sessions = @registry.map { |_, session| session }
|
|
43
|
+
raise "Session registry contains live sessions: #{sessions.join(', ')}"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def clear_registry
|
|
48
|
+
@registry = {}
|
|
49
|
+
end
|
|
50
|
+
end
|