mongoid 7.0.4 → 7.0.10
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/LICENSE +1 -0
- data/README.md +3 -2
- data/Rakefile +26 -0
- data/lib/mongoid.rb +2 -1
- 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/atomic.rb +13 -3
- data/lib/mongoid/atomic/paths/embedded.rb +1 -1
- data/lib/mongoid/attributes.rb +28 -20
- data/lib/mongoid/attributes/dynamic.rb +15 -14
- data/lib/mongoid/clients/sessions.rb +20 -4
- data/lib/mongoid/config/environment.rb +21 -8
- data/lib/mongoid/criteria.rb +7 -1
- data/lib/mongoid/criteria/modifiable.rb +13 -2
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
- data/lib/mongoid/criteria/queryable/extensions/time.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +12 -0
- data/lib/mongoid/criteria/queryable/key.rb +67 -8
- data/lib/mongoid/criteria/queryable/mergeable.rb +5 -4
- data/lib/mongoid/criteria/queryable/selectable.rb +3 -4
- data/lib/mongoid/criteria/queryable/selector.rb +9 -31
- data/lib/mongoid/extensions/hash.rb +4 -2
- data/lib/mongoid/extensions/regexp.rb +1 -1
- data/lib/mongoid/extensions/string.rb +2 -2
- data/lib/mongoid/fields.rb +2 -1
- data/lib/mongoid/matchable.rb +14 -15
- data/lib/mongoid/matchable/all.rb +4 -3
- data/lib/mongoid/matchable/default.rb +71 -24
- 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/positional.rb +1 -1
- data/lib/mongoid/query_cache.rb +24 -11
- data/lib/mongoid/validatable/macros.rb +1 -1
- data/lib/mongoid/validatable/uniqueness.rb +1 -1
- data/lib/mongoid/version.rb +2 -1
- data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -1
- data/spec/README.md +18 -0
- data/spec/app/models/delegating_patient.rb +16 -0
- data/spec/integration/app_spec.rb +192 -0
- data/spec/integration/associations/embedded_spec.rb +62 -0
- data/spec/integration/criteria/date_field_spec.rb +41 -0
- data/spec/integration/criteria/time_with_zone_spec.rb +32 -0
- data/spec/integration/document_spec.rb +22 -0
- data/spec/integration/matchable_spec.rb +680 -0
- data/spec/lite_spec_helper.rb +15 -5
- data/spec/mongoid/association/embedded/embeds_many_models.rb +53 -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/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/attributes/dynamic_spec.rb +153 -0
- data/spec/mongoid/attributes_spec.rb +19 -7
- data/spec/mongoid/clients/factory_spec.rb +2 -2
- data/spec/mongoid/clients/options_spec.rb +4 -4
- data/spec/mongoid/clients/sessions_spec.rb +20 -7
- data/spec/mongoid/clients/transactions_spec.rb +36 -15
- data/spec/mongoid/clients_spec.rb +2 -2
- data/spec/mongoid/contextual/atomic_spec.rb +20 -10
- data/spec/mongoid/contextual/geo_near_spec.rb +12 -2
- data/spec/mongoid/contextual/map_reduce_spec.rb +20 -5
- data/spec/mongoid/contextual/mongo_spec.rb +76 -53
- data/spec/mongoid/criteria/modifiable_spec.rb +59 -10
- data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +54 -0
- 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/key_spec.rb +48 -6
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +762 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +5 -224
- data/spec/mongoid/criteria/queryable/selector_spec.rb +37 -0
- data/spec/mongoid/criteria_spec.rb +7 -2
- data/spec/mongoid/document_fields_spec.rb +88 -0
- data/spec/mongoid/document_persistence_context_spec.rb +33 -0
- data/spec/mongoid/indexable_spec.rb +6 -4
- data/spec/mongoid/matchable/default_spec.rb +10 -3
- 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 +62 -8
- data/spec/mongoid/relations/proxy_spec.rb +1 -1
- data/spec/mongoid/scopable_spec.rb +2 -1
- data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
- data/spec/mongoid/tasks/database_spec.rb +1 -1
- data/spec/mongoid/validatable/uniqueness_spec.rb +33 -6
- data/spec/spec_helper.rb +4 -37
- data/spec/support/child_process_helper.rb +76 -0
- data/spec/support/cluster_config.rb +158 -0
- data/spec/support/constraints.rb +201 -30
- data/spec/support/expectations.rb +17 -3
- data/spec/support/spec_config.rb +12 -4
- metadata +490 -454
- metadata.gz.sig +0 -0
|
@@ -796,20 +796,47 @@ describe Mongoid::Validatable::UniquenessValidator do
|
|
|
796
796
|
end
|
|
797
797
|
end
|
|
798
798
|
|
|
799
|
-
context "when a range
|
|
799
|
+
context "when a range condition is provided" do
|
|
800
800
|
|
|
801
801
|
before do
|
|
802
|
-
Dictionary.validates_uniqueness_of(:name,
|
|
803
|
-
|
|
804
|
-
Dictionary.create(name: "French-English", year: 1960)
|
|
802
|
+
Dictionary.validates_uniqueness_of(:name,
|
|
803
|
+
conditions: -> { Dictionary.where(:year.gte => 1900, :year.lt => 2000) })
|
|
805
804
|
end
|
|
806
805
|
|
|
807
806
|
after do
|
|
808
807
|
Dictionary.reset_callbacks(:validate)
|
|
809
808
|
end
|
|
810
809
|
|
|
811
|
-
|
|
812
|
-
|
|
810
|
+
context 'when multiple documents would match the condition' do
|
|
811
|
+
it "prevents creation of new document" do
|
|
812
|
+
Dictionary.create!(name: "French-English", year: 1950)
|
|
813
|
+
|
|
814
|
+
expect do
|
|
815
|
+
Dictionary.create!(name: "French-English", year: 1960)
|
|
816
|
+
end.to raise_error(Mongoid::Errors::Validations, /Name is already taken/)
|
|
817
|
+
|
|
818
|
+
expect(Dictionary.all.size).to eq(1)
|
|
819
|
+
end
|
|
820
|
+
end
|
|
821
|
+
|
|
822
|
+
context 'when only new document would match the condition' do
|
|
823
|
+
it 'creates the new document' do
|
|
824
|
+
Dictionary.create!(name: "French-English", year: 950)
|
|
825
|
+
expect do
|
|
826
|
+
Dictionary.create!(name: "French-English", year: 1950)
|
|
827
|
+
end.not_to raise_error
|
|
828
|
+
end
|
|
829
|
+
end
|
|
830
|
+
|
|
831
|
+
context 'when only existing document matches the condition' do
|
|
832
|
+
it 'creates the new document' do
|
|
833
|
+
pending 'https://jira.mongodb.org/browse/MONGOID-4815'
|
|
834
|
+
|
|
835
|
+
Dictionary.create!(name: "French-English", year: 1950)
|
|
836
|
+
expect do
|
|
837
|
+
Dictionary.create!(name: "French-English", year: 950)
|
|
838
|
+
end.not_to raise_error
|
|
839
|
+
end
|
|
813
840
|
end
|
|
814
841
|
end
|
|
815
842
|
|
data/spec/spec_helper.rb
CHANGED
|
@@ -31,6 +31,7 @@ end
|
|
|
31
31
|
require 'support/authorization'
|
|
32
32
|
require 'support/expectations'
|
|
33
33
|
require 'support/macros'
|
|
34
|
+
require 'support/cluster_config'
|
|
34
35
|
require 'support/constraints'
|
|
35
36
|
|
|
36
37
|
# Give MongoDB time to start up on the travis ci environment.
|
|
@@ -74,42 +75,6 @@ CONFIG = {
|
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
def non_legacy_server?
|
|
78
|
-
Mongoid::Clients.default.cluster.servers.first.features.write_command_enabled?
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def testing_replica_set?
|
|
82
|
-
Mongoid::Clients.default.cluster.replica_set?
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def collation_supported?
|
|
86
|
-
Mongoid::Clients.default.cluster.next_primary.features.collation_enabled?
|
|
87
|
-
end
|
|
88
|
-
alias :decimal128_supported? :collation_supported?
|
|
89
|
-
|
|
90
|
-
def array_filters_supported?
|
|
91
|
-
Mongoid::Clients.default.cluster.next_primary.features.array_filters_enabled?
|
|
92
|
-
end
|
|
93
|
-
alias :sessions_supported? :array_filters_supported?
|
|
94
|
-
|
|
95
|
-
def testing_geo_near?
|
|
96
|
-
$geo_near_enabled ||= (Mongoid::Clients.default
|
|
97
|
-
.command(serverStatus: 1)
|
|
98
|
-
.first['version'] < '4.1')
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def transactions_supported?
|
|
102
|
-
Mongoid::Clients.default.cluster.next_primary.features.transactions_enabled?
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def testing_transactions?
|
|
106
|
-
transactions_supported? && testing_replica_set?
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
def testing_locally?
|
|
110
|
-
!(ENV['CI'] == 'travis')
|
|
111
|
-
end
|
|
112
|
-
|
|
113
78
|
# Set the database that the spec suite connects to.
|
|
114
79
|
Mongoid.configure do |config|
|
|
115
80
|
config.load_configuration(CONFIG)
|
|
@@ -164,7 +129,9 @@ RSpec.configure do |config|
|
|
|
164
129
|
|
|
165
130
|
# Drop all collections and clear the identity map before each spec.
|
|
166
131
|
config.before(:each) do
|
|
167
|
-
|
|
132
|
+
cluster = Mongoid.default_client.cluster
|
|
133
|
+
# Older drivers do not have a #connected? method
|
|
134
|
+
if cluster.respond_to?(:connected?) && !cluster.connected?
|
|
168
135
|
Mongoid.default_client.reconnect
|
|
169
136
|
end
|
|
170
137
|
Mongoid.default_client.collections.each do |coll|
|
|
@@ -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
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
|
|
4
|
+
require 'singleton'
|
|
5
|
+
|
|
6
|
+
class ClusterConfig
|
|
7
|
+
include Singleton
|
|
8
|
+
|
|
9
|
+
def single_server?
|
|
10
|
+
determine_cluster_config
|
|
11
|
+
@single_server
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def replica_set_name
|
|
15
|
+
determine_cluster_config
|
|
16
|
+
@replica_set_name
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def server_version
|
|
20
|
+
determine_cluster_config
|
|
21
|
+
@server_version
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def short_server_version
|
|
25
|
+
server_version.split('.')[0..1].join('.')
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def fcv
|
|
29
|
+
determine_cluster_config
|
|
30
|
+
@fcv
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Per https://jira.mongodb.org/browse/SERVER-39052, working with FCV
|
|
34
|
+
# in sharded topologies is annoying. Also, FCV doesn't exist in servers
|
|
35
|
+
# less than 3.4. This method returns FCV on 3.4+ servers when in single
|
|
36
|
+
# or RS topologies, and otherwise returns the major.minor server version.
|
|
37
|
+
def fcv_ish
|
|
38
|
+
if server_version >= '3.4' && topology != :sharded
|
|
39
|
+
fcv
|
|
40
|
+
else
|
|
41
|
+
if short_server_version == '4.1'
|
|
42
|
+
'4.2'
|
|
43
|
+
else
|
|
44
|
+
short_server_version
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def primary_address
|
|
50
|
+
determine_cluster_config
|
|
51
|
+
@primary_address
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def primary_address_str
|
|
55
|
+
determine_cluster_config
|
|
56
|
+
@primary_address.seed
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def primary_address_host
|
|
60
|
+
both = primary_address_str
|
|
61
|
+
both.split(':').first
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def primary_address_port
|
|
65
|
+
both = primary_address_str
|
|
66
|
+
both.split(':')[1] || 27017
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def primary_description
|
|
70
|
+
determine_cluster_config
|
|
71
|
+
@primary_description
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Try running a command on the admin database to see if the mongod was
|
|
75
|
+
# started with auth.
|
|
76
|
+
def auth_enabled?
|
|
77
|
+
if @auth_enabled.nil?
|
|
78
|
+
@auth_enabled = begin
|
|
79
|
+
basic_client.use(:admin).command(getCmdLineOpts: 1).first["argv"].include?("--auth")
|
|
80
|
+
rescue => e
|
|
81
|
+
e.message =~ /(not authorized)|(unauthorized)|(no users authenticated)|(requires authentication)/
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
@auth_enabled
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def topology
|
|
88
|
+
determine_cluster_config
|
|
89
|
+
@topology
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def storage_engine
|
|
93
|
+
@storage_engine ||= begin
|
|
94
|
+
# 2.6 does not have wired tiger
|
|
95
|
+
if short_server_version == '2.6'
|
|
96
|
+
:mmapv1
|
|
97
|
+
else
|
|
98
|
+
client = ClientRegistry.instance.global_client('root_authorized')
|
|
99
|
+
if topology == :sharded
|
|
100
|
+
shards = client.use(:admin).command(listShards: 1).first
|
|
101
|
+
shard = shards['shards'].first
|
|
102
|
+
address_str = shard['host'].sub(/\A.*\//, '').sub(/,.*/, '')
|
|
103
|
+
client = ClusterTools.instance.direct_client(address_str,
|
|
104
|
+
SpecConfig.instance.test_options.merge(SpecConfig.instance.auth_options).merge(connect: :direct))
|
|
105
|
+
end
|
|
106
|
+
rv = client.use(:admin).command(serverStatus: 1).first
|
|
107
|
+
rv = rv['storageEngine']['name']
|
|
108
|
+
rv_map = {
|
|
109
|
+
'wiredTiger' => :wired_tiger,
|
|
110
|
+
'mmapv1' => :mmapv1,
|
|
111
|
+
}
|
|
112
|
+
rv_map[rv] || rv
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
private
|
|
118
|
+
|
|
119
|
+
def determine_cluster_config
|
|
120
|
+
return if @primary_address
|
|
121
|
+
|
|
122
|
+
# Run all commands to figure out the cluster configuration from the same
|
|
123
|
+
# client. This is somewhat wasteful when running a single test, but reduces
|
|
124
|
+
# test runtime for the suite overall because all commands are sent on the
|
|
125
|
+
# same connection rather than each command connecting to the cluster by
|
|
126
|
+
# itself.
|
|
127
|
+
client = Mongoid::Clients.default
|
|
128
|
+
|
|
129
|
+
primary = client.cluster.next_primary
|
|
130
|
+
@primary_address = primary.address
|
|
131
|
+
@primary_description = primary.description
|
|
132
|
+
@replica_set_name = client.cluster.topology.replica_set_name
|
|
133
|
+
|
|
134
|
+
@topology ||= begin
|
|
135
|
+
topology = client.cluster.topology.class.name.sub(/.*::/, '')
|
|
136
|
+
topology = topology.gsub(/([A-Z])/) { |match| '_' + match.downcase }.sub(/\A_/, '')
|
|
137
|
+
if topology =~ /\Areplica_set/
|
|
138
|
+
topology = 'replica_set'
|
|
139
|
+
end
|
|
140
|
+
topology.to_sym
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
@single_server = client.cluster.send(:servers_list).length == 1
|
|
144
|
+
|
|
145
|
+
@server_version = client.database.command(buildInfo: 1).first['version']
|
|
146
|
+
|
|
147
|
+
if @topology != :sharded && short_server_version >= '3.4'
|
|
148
|
+
rv = client.use(:admin).command(getParameter: 1, featureCompatibilityVersion: 1).first['featureCompatibilityVersion']
|
|
149
|
+
@fcv = rv['version'] || rv
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def basic_client
|
|
154
|
+
# Do not cache the result here so that if the client gets closed,
|
|
155
|
+
# client registry reconnects it in subsequent tests
|
|
156
|
+
ClientRegistry.instance.global_client('basic')
|
|
157
|
+
end
|
|
158
|
+
end
|
data/spec/support/constraints.rb
CHANGED
|
@@ -1,12 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
|
|
1
4
|
module Constraints
|
|
2
5
|
RAILS_VERSION = ActiveSupport.version.to_s.split('.')[0..1].join('.').freeze
|
|
3
6
|
|
|
7
|
+
def require_driver_query_cache
|
|
8
|
+
before(:all) do
|
|
9
|
+
if !defined?(Mongo::QueryCache)
|
|
10
|
+
skip "Driver version #{Mongo::VERSION} does not support query cache"
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def require_mongoid_query_cache
|
|
16
|
+
before (:all) do
|
|
17
|
+
if defined?(Mongo::QueryCache)
|
|
18
|
+
skip "Mongoid uses the driver query cache in driver versions that support it"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
4
23
|
def min_rails_version(version)
|
|
5
|
-
unless version =~
|
|
24
|
+
unless version =~ /\A\d+\.\d+\z/
|
|
6
25
|
raise ArgumentError, "Version can only be major.minor: #{version}"
|
|
7
26
|
end
|
|
8
27
|
|
|
9
|
-
before do
|
|
28
|
+
before(:all) do
|
|
10
29
|
if version > RAILS_VERSION
|
|
11
30
|
skip "Rails version #{version} or higher required, we have #{RAILS_VERSION}"
|
|
12
31
|
end
|
|
@@ -14,11 +33,11 @@ module Constraints
|
|
|
14
33
|
end
|
|
15
34
|
|
|
16
35
|
def max_rails_version(version)
|
|
17
|
-
unless version =~
|
|
36
|
+
unless version =~ /\A\d+\.\d+\z/
|
|
18
37
|
raise ArgumentError, "Version can only be major.minor: #{version}"
|
|
19
38
|
end
|
|
20
39
|
|
|
21
|
-
before do
|
|
40
|
+
before(:all) do
|
|
22
41
|
if version < RAILS_VERSION
|
|
23
42
|
skip "Rails version #{version} or lower required, we have #{RAILS_VERSION}"
|
|
24
43
|
end
|
|
@@ -26,11 +45,11 @@ module Constraints
|
|
|
26
45
|
end
|
|
27
46
|
|
|
28
47
|
def min_server_version(version)
|
|
29
|
-
unless version =~
|
|
48
|
+
unless version =~ /\A\d+\.\d+\z/
|
|
30
49
|
raise ArgumentError, "Version can only be major.minor: #{version}"
|
|
31
50
|
end
|
|
32
51
|
|
|
33
|
-
before do
|
|
52
|
+
before(:all) do
|
|
34
53
|
if version > ClusterConfig.instance.server_version
|
|
35
54
|
skip "Server version #{version} or higher required, we have #{ClusterConfig.instance.server_version}"
|
|
36
55
|
end
|
|
@@ -38,11 +57,11 @@ module Constraints
|
|
|
38
57
|
end
|
|
39
58
|
|
|
40
59
|
def max_server_version(version)
|
|
41
|
-
unless version =~
|
|
60
|
+
unless version =~ /\A\d+\.\d+\z/
|
|
42
61
|
raise ArgumentError, "Version can only be major.minor: #{version}"
|
|
43
62
|
end
|
|
44
63
|
|
|
45
|
-
before do
|
|
64
|
+
before(:all) do
|
|
46
65
|
if version < ClusterConfig.instance.short_server_version
|
|
47
66
|
skip "Server version #{version} or lower required, we have #{ClusterConfig.instance.server_version}"
|
|
48
67
|
end
|
|
@@ -50,18 +69,14 @@ module Constraints
|
|
|
50
69
|
end
|
|
51
70
|
|
|
52
71
|
def require_topology(*topologies)
|
|
53
|
-
|
|
54
|
-
|
|
72
|
+
invalid_topologies = topologies - [:single, :replica_set, :sharded]
|
|
73
|
+
|
|
55
74
|
unless invalid_topologies.empty?
|
|
56
75
|
raise ArgumentError, "Invalid topologies requested: #{invalid_topologies.join(', ')}"
|
|
57
76
|
end
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if topology =~ /^replica_set/
|
|
62
|
-
topology = 'replica_set'
|
|
63
|
-
end
|
|
64
|
-
unless topologies.include?(topology)
|
|
77
|
+
|
|
78
|
+
before(:all) do
|
|
79
|
+
unless topologies.include?(topology = ClusterConfig.instance.topology)
|
|
65
80
|
skip "Topology #{topologies.join(' or ')} required, we have #{topology}"
|
|
66
81
|
end
|
|
67
82
|
end
|
|
@@ -69,32 +84,188 @@ module Constraints
|
|
|
69
84
|
|
|
70
85
|
def max_example_run_time(timeout)
|
|
71
86
|
around do |example|
|
|
72
|
-
TimeoutInterrupt.timeout(timeout) do
|
|
87
|
+
TimeoutInterrupt.timeout(timeout, TimeoutInterrupt::Error.new("Test execution terminated after #{timeout} seconds")) do
|
|
73
88
|
example.run
|
|
74
89
|
end
|
|
75
90
|
end
|
|
76
91
|
end
|
|
77
92
|
|
|
78
93
|
def require_transaction_support
|
|
79
|
-
|
|
80
|
-
|
|
94
|
+
before(:all) do
|
|
95
|
+
case ClusterConfig.instance.topology
|
|
96
|
+
when :single
|
|
97
|
+
skip 'Transactions tests require a replica set (4.0+) or a sharded cluster (4.2+)'
|
|
98
|
+
when :replica_set
|
|
99
|
+
unless ClusterConfig.instance.server_version >= '4.0'
|
|
100
|
+
skip 'Transactions tests in a replica set topology require server 4.0+'
|
|
101
|
+
end
|
|
102
|
+
when :sharded
|
|
103
|
+
unless ClusterConfig.instance.server_version >= '4.2'
|
|
104
|
+
skip 'Transactions tests in a sharded cluster topology require server 4.2+'
|
|
105
|
+
end
|
|
106
|
+
else
|
|
107
|
+
raise NotImplementedError
|
|
108
|
+
end
|
|
109
|
+
end
|
|
81
110
|
end
|
|
82
111
|
|
|
83
|
-
def
|
|
84
|
-
before do
|
|
85
|
-
|
|
86
|
-
|
|
112
|
+
def require_tls
|
|
113
|
+
before(:all) do
|
|
114
|
+
unless SpecConfig.instance.ssl?
|
|
115
|
+
skip "SSL not enabled"
|
|
87
116
|
end
|
|
88
|
-
|
|
89
|
-
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def require_no_tls
|
|
121
|
+
before(:all) do
|
|
122
|
+
if SpecConfig.instance.ssl?
|
|
123
|
+
skip "SSL enabled"
|
|
90
124
|
end
|
|
91
125
|
end
|
|
92
126
|
end
|
|
93
127
|
|
|
94
|
-
def
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
128
|
+
def require_local_tls
|
|
129
|
+
require_tls
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def require_no_retry_writes
|
|
133
|
+
before(:all) do
|
|
134
|
+
if SpecConfig.instance.retry_writes?
|
|
135
|
+
skip "Retry writes is enabled"
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def require_compression
|
|
141
|
+
before(:all) do
|
|
142
|
+
if SpecConfig.instance.compressors.nil?
|
|
143
|
+
skip "Compression is not enabled"
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def require_no_compression
|
|
149
|
+
before(:all) do
|
|
150
|
+
if SpecConfig.instance.compressors
|
|
151
|
+
skip "Compression is enabled"
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def ruby_version_gte(version)
|
|
157
|
+
before(:all) do
|
|
158
|
+
if RUBY_VERSION < version
|
|
159
|
+
skip "Ruby version #{version} or higher required"
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def ruby_version_lt(version)
|
|
165
|
+
before(:all) do
|
|
166
|
+
if RUBY_VERSION >= version
|
|
167
|
+
skip "Ruby version less than #{version} required"
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def require_auth
|
|
173
|
+
before(:all) do
|
|
174
|
+
unless ENV['AUTH'] == 'auth' || SpecConfig.instance.user || ClusterConfig.instance.auth_enabled?
|
|
175
|
+
skip "Auth required"
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def require_no_auth
|
|
181
|
+
before(:all) do
|
|
182
|
+
if ENV['AUTH'] == 'auth' || SpecConfig.instance.user || ClusterConfig.instance.auth_enabled?
|
|
183
|
+
skip "Auth not allowed"
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def require_no_x509_auth
|
|
189
|
+
before(:all) do
|
|
190
|
+
if SpecConfig.instance.x509_auth?
|
|
191
|
+
skip "X.509 auth not allowed"
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# Can the driver specify a write concern that won't be overridden?
|
|
197
|
+
# (mongos 4.0+ overrides the write concern)
|
|
198
|
+
def require_set_write_concern
|
|
199
|
+
before(:all) do
|
|
200
|
+
if ClusterConfig.instance.topology == :sharded && ClusterConfig.instance.short_server_version >= '4.0'
|
|
201
|
+
skip "mongos 4.0+ overrides write concern"
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def require_multi_shard
|
|
207
|
+
before(:all) do
|
|
208
|
+
if ClusterConfig.instance.topology == :sharded && SpecConfig.instance.addresses.length == 1
|
|
209
|
+
skip 'Test requires a minimum of two shards if run in sharded topology'
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def require_no_multi_shard
|
|
215
|
+
before(:all) do
|
|
216
|
+
if ClusterConfig.instance.topology == :sharded && SpecConfig.instance.addresses.length > 1
|
|
217
|
+
skip 'Test requires a single shard if run in sharded topology'
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def require_wired_tiger
|
|
223
|
+
before(:all) do
|
|
224
|
+
if ClusterConfig.instance.storage_engine != :wired_tiger
|
|
225
|
+
skip 'Test requires WiredTiger storage engine'
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def require_wired_tiger_on_36
|
|
231
|
+
before(:all) do
|
|
232
|
+
if ClusterConfig.instance.short_server_version >= '3.6'
|
|
233
|
+
if ClusterConfig.instance.storage_engine != :wired_tiger
|
|
234
|
+
skip 'Test requires WiredTiger storage engine on 3.6+ servers'
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def require_mmapv1
|
|
241
|
+
before(:all) do
|
|
242
|
+
if ClusterConfig.instance.storage_engine != :mmapv1
|
|
243
|
+
skip 'Test requires MMAPv1 storage engine'
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def require_enterprise
|
|
249
|
+
before(:all) do
|
|
250
|
+
unless ClusterConfig.instance.enterprise?
|
|
251
|
+
skip 'Test requires enterprise build of MongoDB'
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Integration tests for SRV polling require internet connectivity to
|
|
257
|
+
# look up SRV records and a sharded cluster configured on default port on
|
|
258
|
+
# localhost (localhost:27017, localhost:27018).
|
|
259
|
+
def require_default_port_deployment
|
|
260
|
+
# Because the DNS records at test1.test.build.10gen.cc point to
|
|
261
|
+
# localhost:27017 & localhost:27018, the test suite must have been
|
|
262
|
+
# configured to use these addresses
|
|
263
|
+
before(:all) do
|
|
264
|
+
have_default_port = SpecConfig.instance.addresses.any? do |address|
|
|
265
|
+
%w(127.0.0.1 127.0.0.1:27017 localhost localhost:27017).include?(address)
|
|
266
|
+
end
|
|
267
|
+
unless have_default_port
|
|
268
|
+
skip 'This test requires the test suite to be configured for localhost:27017'
|
|
98
269
|
end
|
|
99
270
|
end
|
|
100
271
|
end
|