Compare commits
97 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0752c8b593 | ||
|
|
07e2d97fbc | ||
|
|
f39bb1d092 | ||
|
|
105acca0d4 | ||
|
|
b552f4281d | ||
|
|
1ab1010737 | ||
|
|
1711789a79 | ||
|
|
96349e6eb5 | ||
|
|
72058227a2 | ||
|
|
6e30589695 | ||
|
|
5c46722a18 | ||
|
|
cb2858e0bf | ||
|
|
bfcb5e357a | ||
|
|
ed5dccdc3f | ||
|
|
4c2d1a88c1 | ||
|
|
f012132daf | ||
|
|
c19316e418 | ||
|
|
80cf806ce5 | ||
|
|
3a21ec0196 | ||
|
|
b9ab7e0621 | ||
|
|
7fbfcfba8c | ||
|
|
b11a874f54 | ||
|
|
b67afe29bc | ||
|
|
61cf4b85f6 | ||
|
|
e8e45c12ae | ||
|
|
a3210c8e07 | ||
|
|
e651e0fb73 | ||
|
|
540a68c3dd | ||
|
|
b64de30716 | ||
|
|
6389499b09 | ||
|
|
a7a144f40b | ||
|
|
5565001e7b | ||
|
|
ed1813b8f8 | ||
|
|
1e619e899f | ||
|
|
d9bc77ee50 | ||
|
|
68120a67d7 | ||
|
|
dfedaf8b08 | ||
|
|
88d1d469f9 | ||
|
|
70faecde6a | ||
|
|
7529ba0f4d | ||
|
|
e7960bb2b6 | ||
|
|
204f44d5f8 | ||
|
|
9efd09f83c | ||
|
|
ee6f6e2541 | ||
|
|
d5281e240a | ||
|
|
bef386bc14 | ||
|
|
2ecda906b9 | ||
|
|
88a553287a | ||
|
|
e59d00a732 | ||
|
|
e54239b3b9 | ||
|
|
896885c9e4 | ||
|
|
85f80aac4f | ||
|
|
029f51d0fd | ||
|
|
6dcfbb12c2 | ||
|
|
bcf597ce00 | ||
|
|
15179bd0a5 | ||
|
|
3f33ff2529 | ||
|
|
ba20ef3dc5 | ||
|
|
8177601e4a | ||
|
|
9a146cd40b | ||
|
|
186c06b297 | ||
|
|
9044a3fca9 | ||
|
|
a9f574de6a | ||
|
|
45334def42 | ||
|
|
bdb080651a | ||
|
|
aaa17b1ce6 | ||
|
|
300747bfbd | ||
|
|
a55aa86914 | ||
|
|
7182656291 | ||
|
|
6fc36be161 | ||
|
|
1b8cce4631 | ||
|
|
fdb19a9d6b | ||
|
|
a33ce8514c | ||
|
|
e51f8ac658 | ||
|
|
05de943c06 | ||
|
|
9963ece917 | ||
|
|
97af1fa552 | ||
|
|
0e14aad2be | ||
|
|
dc747348bf | ||
|
|
dbe8dde847 | ||
|
|
8aff699e9c | ||
|
|
0b9d92aa02 | ||
|
|
678cb635cc | ||
|
|
3994253fde | ||
|
|
e8fe6dc503 | ||
|
|
a7ffe65bd7 | ||
|
|
385ed43099 | ||
|
|
0f8edc6e87 | ||
|
|
d131ca7d6a | ||
|
|
6bc007607b | ||
|
|
23fe9f1a5d | ||
|
|
6166b5586f | ||
|
|
8a1030897a | ||
|
|
752daa3060 | ||
|
|
53adeef7db | ||
|
|
f34fbd1a04 | ||
|
|
e8d4c69970 |
@@ -654,9 +654,16 @@ env_vars.Add('MONGO_DISTNAME',
|
||||
help='Sets the version string to be used in dist archive naming',
|
||||
default='$MONGO_VERSION')
|
||||
|
||||
def validate_mongo_version(key, val, env):
|
||||
regex = r'^(\d+)\.(\d+)\.(\d+)-?((?:(rc)(\d+))?.*)?'
|
||||
if not re.match(regex, val):
|
||||
print("Invalid MONGO_VERSION '{}', or could not derive from version.json or git metadata. Please add a conforming MONGO_VERSION=x.y.z[-extra] as an argument to SCons".format(val))
|
||||
Exit(1)
|
||||
|
||||
env_vars.Add('MONGO_VERSION',
|
||||
help='Sets the version string for MongoDB',
|
||||
default=version_data['version'])
|
||||
default=version_data['version'],
|
||||
validator=validate_mongo_version)
|
||||
|
||||
env_vars.Add('MONGO_GIT_HASH',
|
||||
help='Sets the githash to store in the MongoDB version information',
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
driver:
|
||||
name: ec2
|
||||
region: us-east-1
|
||||
vpc_mode: true
|
||||
vpc_id: <%= ENV['KITCHEN_VPC'] %>
|
||||
subnet_id: <%= ENV['KITCHEN_SUBNET'] %>
|
||||
security_group_ids:
|
||||
- <%= ENV['KITCHEN_SECURITY_GROUP'] %>
|
||||
aws_ssh_key_id: <%= ENV['KITCHEN_SSH_KEY_ID'] %>
|
||||
interface: dns
|
||||
interface: private
|
||||
associate_public_ip: true
|
||||
|
||||
verifier:
|
||||
|
||||
@@ -87,6 +87,16 @@ if platform_family? 'suse'
|
||||
EOD
|
||||
end
|
||||
|
||||
%w(
|
||||
SLES12-Pool
|
||||
SLES12-Updates
|
||||
).each do |repo|
|
||||
execute "add #{repo}" do
|
||||
command "zypper addrepo --check --refresh --name \"#{repo}\" http://smt-ec2.susecloud.net/repo/SUSE/Products/SLE-SERVER/12/x86_64/product?credentials=SMT-http_smt-ec2_susecloud_net 'SMT-http_smt-ec2_susecloud_net:#{repo}'"
|
||||
not_if "zypper lr | grep #{repo}"
|
||||
end
|
||||
end
|
||||
|
||||
execute 'install mongod' do
|
||||
command 'zypper -n install `find . -name "*server*.rpm"`'
|
||||
cwd homedir
|
||||
|
||||
@@ -242,9 +242,7 @@ class Distro(object):
|
||||
else:
|
||||
raise Exception("unsupported build_os: %s" % build_os)
|
||||
elif self.n == 'debian':
|
||||
if build_os == 'debian71':
|
||||
return 'wheezy'
|
||||
elif build_os == 'debian81':
|
||||
if build_os == 'debian81':
|
||||
return 'jessie'
|
||||
else:
|
||||
raise Exception("unsupported build_os: %s" % build_os)
|
||||
@@ -261,7 +259,7 @@ class Distro(object):
|
||||
|
||||
def build_os(self, arch):
|
||||
"""Return the build os label in the binary package to download ("rhel55", "rhel62" and "rhel70"
|
||||
for redhat, "ubuntu1204" and "ubuntu1404" for Ubuntu, "debian71" for Debian), and "suse11"
|
||||
for redhat, "ubuntu1204" and "ubuntu1404" for Ubuntu, "debian81" for Debian), and "suse11"
|
||||
for SUSE)"""
|
||||
# Community builds only support amd64
|
||||
if arch not in ['x86_64', 'ppc64le']:
|
||||
@@ -276,7 +274,7 @@ class Distro(object):
|
||||
elif self.n == 'ubuntu':
|
||||
return [ "ubuntu1204", "ubuntu1404", "ubuntu1604", ]
|
||||
elif self.n == 'debian':
|
||||
return [ "debian71", "debian81" ]
|
||||
return [ "debian81" ]
|
||||
else:
|
||||
raise Exception("BUG: unsupported platform?")
|
||||
|
||||
@@ -457,12 +455,8 @@ def make_deb(distro, build_os, arch, spec, srcdir):
|
||||
sdir=setupdir(distro, build_os, arch, spec)
|
||||
if re.search("debian", distro.name()):
|
||||
os.unlink(sdir+"debian/mongod.upstart")
|
||||
if build_os == "debian71":
|
||||
os.link(sdir+"debian/init.d", sdir+"debian/%s%s-server.mongod.init" % (distro.pkgbase(), suffix))
|
||||
os.unlink(sdir+"debian/mongod.service")
|
||||
else:
|
||||
os.link(sdir+"debian/mongod.service", sdir+"debian/%s%s-server.mongod.service" % (distro.pkgbase(), suffix))
|
||||
os.unlink(sdir+"debian/init.d")
|
||||
os.link(sdir+"debian/mongod.service", sdir+"debian/%s%s-server.mongod.service" % (distro.pkgbase(), suffix))
|
||||
os.unlink(sdir+"debian/init.d")
|
||||
elif re.search("ubuntu", distro.name()):
|
||||
os.unlink(sdir+"debian/init.d")
|
||||
if build_os in ("ubuntu1204", "ubuntu1404", "ubuntu1410"):
|
||||
|
||||
@@ -4,9 +4,25 @@ selector:
|
||||
- jstests/aggregation/*.js
|
||||
- jstests/aggregation/bugs/*.js
|
||||
exclude_files:
|
||||
- jstests/aggregation/bugs/server18198.js # Uses a mocked mongo client to test read preference.
|
||||
- jstests/aggregation/mongos_slaveok.js # Majority read on secondary requires afterOpTime.
|
||||
- jstests/aggregation/testSlave.js # Majority read on secondary requires afterOpTime.
|
||||
# These test fail because afterOpTime is required to guarantee a secondary has advanced its
|
||||
# majority-committed snapshot.
|
||||
- jstests/aggregation/mongos_slaveok.js
|
||||
- jstests/aggregation/testSlave.js
|
||||
exclude_with_any_tags:
|
||||
##
|
||||
# The next three tags correspond to the special errors thrown by the
|
||||
# set_read_and_write_concerns.js override when it refuses to replace the readConcern or
|
||||
# writeConcern of a particular command. Above each tag are the message(s) that cause the tag to
|
||||
# be warranted.
|
||||
##
|
||||
# "Cowardly refusing to override read concern of command: ..."
|
||||
- assumes_read_concern_unchanged
|
||||
# "Cowardly refusing to override write concern of command: ..."
|
||||
- assumes_write_concern_unchanged
|
||||
# "Cowardly refusing to run test with overridden write concern when it uses a command that can
|
||||
# only perform w=1 writes: ..."
|
||||
- requires_collmod_command
|
||||
- requires_eval_command
|
||||
|
||||
executor:
|
||||
js_test:
|
||||
@@ -14,12 +30,18 @@ executor:
|
||||
shell_options:
|
||||
global_vars:
|
||||
TestData:
|
||||
defaultReadConcernLevel: majority
|
||||
enableMajorityReadConcern: ''
|
||||
eval: "var testingReplication = true; load('jstests/libs/override_methods/set_majority_read_and_write_concerns.js');"
|
||||
eval: >-
|
||||
var testingReplication = true;
|
||||
load('jstests/libs/override_methods/set_read_and_write_concerns.js');
|
||||
readMode: commands
|
||||
hooks:
|
||||
- class: ValidateCollections
|
||||
# The CheckReplDBHash hook waits until all operations have replicated to and have been applied
|
||||
# on the secondaries, so we run the ValidateCollections hook after it to ensure we're
|
||||
# validating the entire contents of the collection.
|
||||
- class: CheckReplDBHash
|
||||
- class: ValidateCollections
|
||||
fixture:
|
||||
class: ReplicaSetFixture
|
||||
mongod_options:
|
||||
|
||||
@@ -3,70 +3,48 @@ selector:
|
||||
roots:
|
||||
- jstests/core/*.js
|
||||
exclude_files:
|
||||
# Tests that won't work with an injected 'majority' readConcern
|
||||
# and/or an injected 'majority' writeConcern. Where a function is
|
||||
# listed the reason is we don't have a reliable solution to override
|
||||
# the write concern for that function.
|
||||
- jstests/core/batch_write_command*.js # these tests use various write concerns
|
||||
- jstests/core/bench_test*.js # benchRun() used for writes
|
||||
- jstests/core/capped_update.js # uses godinsert and can't run under replication.
|
||||
- jstests/core/crud_api.js # has specific w:0 tests
|
||||
- jstests/core/error2.js # db.eval() used
|
||||
- jstests/core/eval0.js # db.eval() used
|
||||
- jstests/core/eval1.js # db.eval() used
|
||||
- jstests/core/eval3.js # db.eval() used
|
||||
- jstests/core/eval4.js # db.eval() used
|
||||
- jstests/core/eval5.js # db.eval() used
|
||||
- jstests/core/eval6.js # db.eval() used
|
||||
- jstests/core/eval7.js # db.eval() used
|
||||
- jstests/core/eval9.js # db.eval() used
|
||||
- jstests/core/evala.js # db.eval() used
|
||||
- jstests/core/evalb.js # db.eval() used
|
||||
- jstests/core/evalc.js # db.eval() used
|
||||
- jstests/core/evald.js # db.eval() used
|
||||
- jstests/core/evale.js # db.eval() used
|
||||
- jstests/core/evalg.js # db.eval() used
|
||||
- jstests/core/eval_mr.js # db.eval() used
|
||||
- jstests/core/eval_nolock.js # db.eval() used
|
||||
- jstests/core/geo_s2cursorlimitskip.js # drops system.profile collection and counts ops.
|
||||
- jstests/core/js3.js # db.dbEval() used
|
||||
- jstests/core/js7.js # db.eval() used
|
||||
- jstests/core/js9.js # db.eval() used
|
||||
- jstests/core/mr_merge.js # mr temp tables aren't replicated
|
||||
- jstests/core/mr_merge2.js # mr temp tables aren't replicated
|
||||
- jstests/core/mr_outreduce.js # mr temp tables aren't replicated
|
||||
- jstests/core/mr_outreduce2.js # mr temp tables aren't replicated
|
||||
- jstests/core/opcounters_active.js # off by n problem with opcounters
|
||||
- jstests/core/opcounters_write_cmd.js # off by n problem with opcounters
|
||||
- jstests/core/profile1.js # system.profile not replicated
|
||||
- jstests/core/profile2.js # system.profile not replicated
|
||||
- jstests/core/profile3.js # system.profile not replicated
|
||||
- jstests/core/profile4.js # system.profile not replicated
|
||||
- jstests/core/profile5.js # system.profile not replicated
|
||||
- jstests/core/read_after_optime.js # verifies read after optime fails on standalone
|
||||
- jstests/core/remove8.js # db.eval() used
|
||||
- jstests/core/rename4.js # db.eval() used
|
||||
- jstests/core/shell1.js # tests setSlaveOk() variations on standalone mongod
|
||||
- jstests/core/shellkillop.js # db.eval() used
|
||||
- jstests/core/shell_writeconcern.js # checks write concern shell helpers
|
||||
- jstests/core/storefunc.js # db.eval() used
|
||||
- jstests/core/write_result.js # Tests invalid writeConcern, we shouldn't override.
|
||||
# Tests that need triaging & remediation | blacklist decision
|
||||
# Comments list possible problem point under review.
|
||||
- jstests/core/capped6.js # Uses captrunc test command.
|
||||
- jstests/core/convert_to_capped_nonexistant.js # Uses convertToCapped and captrunc command.
|
||||
- jstests/core/stages_delete.js # Uses stageDebug command for deletes.
|
||||
|
||||
# These tests are not expected to pass with replica-sets:
|
||||
- jstests/core/dbadmin.js
|
||||
- jstests/core/opcounters_write_cmd.js
|
||||
- jstests/core/read_after_optime.js
|
||||
- jstests/core/capped_update.js
|
||||
# These tests use benchRun(), which isn't configured to use the overridden writeConcern.
|
||||
- jstests/core/bench_test*.js
|
||||
exclude_with_any_tags:
|
||||
##
|
||||
# The next three tags correspond to the special errors thrown by the
|
||||
# set_read_and_write_concerns.js override when it refuses to replace the readConcern or
|
||||
# writeConcern of a particular command. Above each tag are the message(s) that cause the tag to
|
||||
# be warranted.
|
||||
##
|
||||
# "Cowardly refusing to override read concern of command: ..."
|
||||
- assumes_read_concern_unchanged
|
||||
# "Cowardly refusing to override write concern of command: ..."
|
||||
- assumes_write_concern_unchanged
|
||||
# "Cowardly refusing to run test with overridden write concern when it uses a command that can
|
||||
# only perform w=1 writes: ..."
|
||||
- requires_collmod_command
|
||||
- requires_eval_command
|
||||
|
||||
executor:
|
||||
js_test:
|
||||
config:
|
||||
shell_options:
|
||||
eval: "var testingReplication = true; load('jstests/libs/override_methods/set_majority_read_and_write_concerns.js');"
|
||||
global_vars:
|
||||
TestData:
|
||||
defaultReadConcernLevel: majority
|
||||
eval: >-
|
||||
var testingReplication = true;
|
||||
load('jstests/libs/override_methods/set_read_and_write_concerns.js');
|
||||
readMode: commands
|
||||
hooks:
|
||||
- class: ValidateCollections
|
||||
# The CheckReplDBHash hook waits until all operations have replicated to and have been applied
|
||||
# on the secondaries, so we run the ValidateCollections hook after it to ensure we're
|
||||
# validating the entire contents of the collection.
|
||||
- class: CheckReplDBHash
|
||||
- class: ValidateCollections
|
||||
- class: CleanEveryN
|
||||
n: 20
|
||||
fixture:
|
||||
class: ReplicaSetFixture
|
||||
mongod_options:
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
test_kind: js_test
|
||||
|
||||
selector:
|
||||
js_test:
|
||||
roots:
|
||||
- jstests/core/**/*.js
|
||||
exclude_files:
|
||||
# These tests are not expected to pass with replica-sets:
|
||||
- jstests/core/dbadmin.js
|
||||
- jstests/core/opcounters_write_cmd.js
|
||||
- jstests/core/read_after_optime.js
|
||||
- jstests/core/capped_update.js
|
||||
# These tests do not expect the mongo shell to be using a replica set connection string.
|
||||
- jstests/core/bench_test*.js
|
||||
- jstests/core/connection_string_validation.js
|
||||
# The bypass_doc_validation.js test runs an applyOps command that causes the primary to generate
|
||||
# an oplog entry without having applied the write. We skip this test to avoid causing a dbhash
|
||||
# mismatch.
|
||||
- jstests/core/bypass_doc_validation.js
|
||||
# These tests use DBCommandCursor which doesn't correctly route getMore and killCursors
|
||||
# commands to the original server the cursor was established on (prior to SERVER-23219).
|
||||
- jstests/core/find_getmore_bsonsize.js
|
||||
- jstests/core/find_getmore_cmd.js
|
||||
- jstests/core/getmore_cmd_maxtimems.js
|
||||
- jstests/core/kill_cursors.js
|
||||
- jstests/core/list_collections1.js
|
||||
- jstests/core/list_indexes.js
|
||||
# These tests attempt to read from the "system.profile" collection, which may be missing entries
|
||||
# if a write was performed on the primary of the replica set instead.
|
||||
- jstests/core/*profile*.js
|
||||
# The shellkillop.js test spawns a parallel shell without using startParallelShell() and
|
||||
# therefore doesn't inherit the w="majority" write concern when performing its writes.
|
||||
- jstests/core/shellkillop.js
|
||||
exclude_with_any_tags:
|
||||
##
|
||||
# The next three tags correspond to the special errors thrown by the
|
||||
# set_read_and_write_concerns.js override when it refuses to replace the readConcern or
|
||||
# writeConcern of a particular command. Above each tag are the message(s) that cause the tag to
|
||||
# be warranted.
|
||||
##
|
||||
# "Cowardly refusing to override read concern of command: ..."
|
||||
- assumes_read_concern_unchanged
|
||||
# "Cowardly refusing to override write concern of command: ..."
|
||||
- assumes_write_concern_unchanged
|
||||
# "Cowardly refusing to run test with overridden write concern when it uses a command that can
|
||||
# only perform w=1 writes: ..."
|
||||
- requires_collmod_command
|
||||
- requires_eval_command
|
||||
##
|
||||
# The next two tags corresponds to the special error thrown by the
|
||||
# set_read_preference_secondary.js override when it refuses to replace the readPreference of a
|
||||
# particular command. Above each tag are the message(s) that cause the tag to be warranted.
|
||||
##
|
||||
# "Cowardly refusing to override read preference of command: ..."
|
||||
# "Cowardly refusing to run test with overridden read preference when it reads from a
|
||||
# non-replicated collection: ..."
|
||||
- assumes_read_preference_unchanged
|
||||
# "Cowardly refusing to a run a test that starts a parallel shell because prior to MongoDB 3.4
|
||||
# replica set connections couldn't be used in it."
|
||||
- requires_parallel_shell
|
||||
|
||||
executor:
|
||||
js_test:
|
||||
config:
|
||||
shell_options:
|
||||
global_vars:
|
||||
TestData:
|
||||
defaultReadConcernLevel: local
|
||||
eval: >-
|
||||
testingReplication = true;
|
||||
load('jstests/libs/override_methods/set_read_and_write_concerns.js');
|
||||
load('jstests/libs/override_methods/set_read_preference_secondary.js');
|
||||
# We use --readMode=legacy because until MongoDB 3.4, DBCommandCursor wouldn't route the
|
||||
# getMore and killCursors operations to the original server the cursor was established on.
|
||||
readMode: legacy
|
||||
use_connection_string: true
|
||||
hooks:
|
||||
# The CheckReplDBHash hook waits until all operations have replicated to and have been applied
|
||||
# on the secondaries, so we run the ValidateCollections hook after it to ensure we're
|
||||
# validating the entire contents of the collection.
|
||||
- class: CheckReplDBHash
|
||||
- class: ValidateCollections
|
||||
- class: CleanEveryN
|
||||
n: 20
|
||||
fixture:
|
||||
class: ReplicaSetFixture
|
||||
mongod_options:
|
||||
set_parameters:
|
||||
enableTestCommands: 1
|
||||
# This suite requires w="majority" writes to be applied on all secondaries. By using a 2-node
|
||||
# replica set and having secondaries vote, the majority of the replica set is all nodes.
|
||||
num_nodes: 2
|
||||
voting_secondaries: true
|
||||
use_replica_set_connection_string: true
|
||||
@@ -115,7 +115,8 @@ def mongos_program(logger, executable=None, process_kwargs=None, **kwargs):
|
||||
return _process.Process(logger, args, **process_kwargs)
|
||||
|
||||
|
||||
def mongo_shell_program(logger, executable=None, filename=None, process_kwargs=None, **kwargs):
|
||||
def mongo_shell_program(logger, executable=None, connection_string=None, filename=None,
|
||||
process_kwargs=None, **kwargs):
|
||||
"""
|
||||
Returns a Process instance that starts a mongo shell with arguments
|
||||
constructed from 'kwargs'.
|
||||
@@ -181,9 +182,22 @@ def mongo_shell_program(logger, executable=None, filename=None, process_kwargs=N
|
||||
if config.SHELL_WRITE_MODE is not None:
|
||||
kwargs["writeMode"] = config.SHELL_WRITE_MODE
|
||||
|
||||
if connection_string is not None:
|
||||
# The --host and --port options are ignored by the mongo shell when an explicit connection
|
||||
# string is specified. We remove these options to avoid any ambiguity with what server the
|
||||
# logged mongo shell invocation will connect to.
|
||||
if "port" in kwargs:
|
||||
kwargs.pop("port")
|
||||
|
||||
if "host" in kwargs:
|
||||
kwargs.pop("host")
|
||||
|
||||
# Apply the rest of the command line arguments.
|
||||
_apply_kwargs(args, kwargs)
|
||||
|
||||
if connection_string is not None:
|
||||
args.append(connection_string)
|
||||
|
||||
# Have the mongos shell run the specified file.
|
||||
args.append(filename)
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@ Defines handlers for communicating with a buildlogger server.
|
||||
from __future__ import absolute_import
|
||||
|
||||
import functools
|
||||
import httplib
|
||||
import urllib2
|
||||
import json
|
||||
|
||||
from . import handlers
|
||||
from . import loggers
|
||||
@@ -131,6 +133,47 @@ def new_test_id(build_id, build_config, test_filename, test_command):
|
||||
return response["id"]
|
||||
|
||||
|
||||
class _LogsSplitter(object):
|
||||
"""Class with static methods used to split list of log lines into smaller batches."""
|
||||
|
||||
@staticmethod
|
||||
def split_logs(log_lines, max_size):
|
||||
"""
|
||||
Splits the log lines into batches of size less than or equal to max_size.
|
||||
|
||||
Args:
|
||||
log_lines: A list of log lines.
|
||||
max_size: The maximum size in bytes a batch of log lines can have in JSON.
|
||||
Returns:
|
||||
A list of list of log lines. Each item is a list is a list of log lines
|
||||
satisfying the size requirement.
|
||||
"""
|
||||
if not max_size:
|
||||
return [log_lines]
|
||||
|
||||
def line_size(line):
|
||||
"""
|
||||
Computes the encoded JSON size of a log line as part of an array.
|
||||
2 is added to each string size to account for the array representation of the logs,
|
||||
as each line is preceded by a '[' or a space and followed by a ',' or a ']'.
|
||||
"""
|
||||
return len(json.dumps(line, encoding="utf-8")) + 2
|
||||
|
||||
curr_logs = []
|
||||
curr_logs_size = 0
|
||||
split_logs = []
|
||||
for line in log_lines:
|
||||
size = line_size(line)
|
||||
if curr_logs_size + size > max_size:
|
||||
split_logs.append(curr_logs)
|
||||
curr_logs = []
|
||||
curr_logs_size = 0
|
||||
curr_logs.append(line)
|
||||
curr_logs_size += size
|
||||
split_logs.append(curr_logs)
|
||||
return split_logs
|
||||
|
||||
|
||||
class _BaseBuildloggerHandler(handlers.BufferedHandler):
|
||||
"""
|
||||
Base class of the buildlogger handler for the global logs and the
|
||||
@@ -138,8 +181,8 @@ class _BaseBuildloggerHandler(handlers.BufferedHandler):
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
build_id,
|
||||
build_config,
|
||||
endpoint,
|
||||
capacity=_SEND_AFTER_LINES,
|
||||
interval_secs=_SEND_AFTER_SECS):
|
||||
"""
|
||||
@@ -157,8 +200,9 @@ class _BaseBuildloggerHandler(handlers.BufferedHandler):
|
||||
username,
|
||||
password)
|
||||
|
||||
self.build_id = build_id
|
||||
self.endpoint = endpoint
|
||||
self.retry_buffer = []
|
||||
self.max_size = None
|
||||
|
||||
def process_record(self, record):
|
||||
"""
|
||||
@@ -177,12 +221,55 @@ class _BaseBuildloggerHandler(handlers.BufferedHandler):
|
||||
"""
|
||||
Convenience method for subclasses to use when making POST requests.
|
||||
"""
|
||||
|
||||
return self.http_handler.post(*args, **kwargs)
|
||||
|
||||
def _append_logs(self, log_lines):
|
||||
raise NotImplementedError("_append_logs must be implemented by _BaseBuildloggerHandler"
|
||||
" subclasses")
|
||||
"""
|
||||
Sends a POST request to the handlers endpoint with the logs that have been captured.
|
||||
|
||||
Returns:
|
||||
The number of log lines that have been successfully sent.
|
||||
"""
|
||||
lines_sent = 0
|
||||
for chunk in _LogsSplitter.split_logs(log_lines, self.max_size):
|
||||
chunk_lines_sent = self.__append_logs_chunk(chunk)
|
||||
lines_sent += chunk_lines_sent
|
||||
if chunk_lines_sent < len(chunk):
|
||||
# Not all lines have been sent. We stop here.
|
||||
break
|
||||
return lines_sent
|
||||
|
||||
def __append_logs_chunk(self, log_lines_chunk):
|
||||
"""
|
||||
Sends a log lines chunk, handles 413 Request Entity Too Large errors and retries
|
||||
if necessary.
|
||||
|
||||
Returns:
|
||||
The number of log lines that have been successfully sent.
|
||||
"""
|
||||
try:
|
||||
self.post(self.endpoint, data=log_lines_chunk)
|
||||
return len(log_lines_chunk)
|
||||
except urllib2.HTTPError as err:
|
||||
# Handle the "Request Entity Too Large" error, set the max size and retry.
|
||||
if err.code == httplib.REQUEST_ENTITY_TOO_LARGE:
|
||||
response_data = json.load(err, "utf-8")
|
||||
if isinstance(response_data, dict) and "max_size" in response_data:
|
||||
new_max_size = response_data["max_size"]
|
||||
if self.max_size and new_max_size >= self.max_size:
|
||||
loggers._BUILDLOGGER_FALLBACK.exception(
|
||||
"Received an HTTP 413 code, but already had max_size set")
|
||||
return 0
|
||||
loggers._BUILDLOGGER_FALLBACK.warning(
|
||||
"Received an HTTP 413 code, updating the request max_size to %s",
|
||||
new_max_size)
|
||||
self.max_size = new_max_size
|
||||
return self._append_logs(log_lines_chunk)
|
||||
loggers._BUILDLOGGER_FALLBACK.exception("Encountered an error.")
|
||||
return 0
|
||||
except:
|
||||
loggers._BUILDLOGGER_FALLBACK.exception("Encountered an error.")
|
||||
return 0
|
||||
|
||||
def _flush_buffer_with_lock(self, buf, close_called):
|
||||
"""
|
||||
@@ -196,9 +283,10 @@ class _BaseBuildloggerHandler(handlers.BufferedHandler):
|
||||
|
||||
self.retry_buffer.extend(buf)
|
||||
|
||||
if self._append_logs(self.retry_buffer):
|
||||
self.retry_buffer = []
|
||||
elif close_called:
|
||||
nb_sent = self._append_logs(self.retry_buffer)
|
||||
if nb_sent:
|
||||
self.retry_buffer = self.retry_buffer[nb_sent:]
|
||||
if close_called and self.retry_buffer:
|
||||
# Request to the buildlogger server returned an error, so use the fallback logger to
|
||||
# avoid losing the log messages entirely.
|
||||
for (_, message) in self.retry_buffer:
|
||||
@@ -215,29 +303,14 @@ class BuildloggerTestHandler(_BaseBuildloggerHandler):
|
||||
Buildlogger handler for the test logs.
|
||||
"""
|
||||
|
||||
def __init__(self, build_id, build_config, test_id, **kwargs):
|
||||
"""
|
||||
Initializes the buildlogger handler with the build id, test id,
|
||||
and credentials.
|
||||
"""
|
||||
|
||||
_BaseBuildloggerHandler.__init__(self, build_id, build_config, **kwargs)
|
||||
|
||||
self.test_id = test_id
|
||||
|
||||
@_log_on_error
|
||||
def _append_logs(self, log_lines):
|
||||
"""
|
||||
Sends a POST request to the APPEND_TEST_LOGS_ENDPOINT with the
|
||||
logs that have been captured.
|
||||
"""
|
||||
def __init__(self, build_config, build_id, test_id,
|
||||
capacity=_SEND_AFTER_LINES, interval_secs=_SEND_AFTER_SECS):
|
||||
"""Initializes the buildlogger handler with the credentials, build id, and test id."""
|
||||
endpoint = APPEND_TEST_LOGS_ENDPOINT % {
|
||||
"build_id": self.build_id,
|
||||
"test_id": self.test_id,
|
||||
"build_id": build_id,
|
||||
"test_id": test_id,
|
||||
}
|
||||
|
||||
response = self.post(endpoint, data=log_lines)
|
||||
return response is not None
|
||||
_BaseBuildloggerHandler.__init__(self, build_config, endpoint, capacity, interval_secs)
|
||||
|
||||
@_log_on_error
|
||||
def _finish_test(self, failed=False):
|
||||
@@ -245,12 +318,7 @@ class BuildloggerTestHandler(_BaseBuildloggerHandler):
|
||||
Sends a POST request to the APPEND_TEST_LOGS_ENDPOINT with the
|
||||
test status.
|
||||
"""
|
||||
endpoint = APPEND_TEST_LOGS_ENDPOINT % {
|
||||
"build_id": self.build_id,
|
||||
"test_id": self.test_id,
|
||||
}
|
||||
|
||||
self.post(endpoint, headers={
|
||||
self.post(self.endpoint, headers={
|
||||
"X-Sendlogs-Test-Done": "true",
|
||||
"X-Sendlogs-Test-Failed": "true" if failed else "false",
|
||||
})
|
||||
@@ -271,12 +339,8 @@ class BuildloggerGlobalHandler(_BaseBuildloggerHandler):
|
||||
Buildlogger handler for the global logs.
|
||||
"""
|
||||
|
||||
@_log_on_error
|
||||
def _append_logs(self, log_lines):
|
||||
"""
|
||||
Sends a POST request to the APPEND_GLOBAL_LOGS_ENDPOINT with
|
||||
the logs that have been captured.
|
||||
"""
|
||||
endpoint = APPEND_GLOBAL_LOGS_ENDPOINT % {"build_id": self.build_id}
|
||||
response = self.post(endpoint, data=log_lines)
|
||||
return response is not None
|
||||
def __init__(self, build_config, build_id,
|
||||
capacity=_SEND_AFTER_LINES, interval_secs=_SEND_AFTER_SECS):
|
||||
"""Initializes the buildlogger handler with the credentials and build id."""
|
||||
endpoint = APPEND_GLOBAL_LOGS_ENDPOINT % {"build_id": build_id}
|
||||
_BaseBuildloggerHandler.__init__(self, build_config, endpoint, capacity, interval_secs)
|
||||
|
||||
@@ -67,8 +67,8 @@ def apply_buildlogger_global_handler(logger, logging_config, build_id=None, buil
|
||||
log_format = logger_info.get("format", _DEFAULT_FORMAT)
|
||||
formatter = formatters.ISO8601Formatter(fmt=log_format)
|
||||
|
||||
handler = buildlogger.BuildloggerGlobalHandler(build_id,
|
||||
build_config,
|
||||
handler = buildlogger.BuildloggerGlobalHandler(build_config,
|
||||
build_id,
|
||||
**handler_info)
|
||||
handler.setFormatter(formatter)
|
||||
else:
|
||||
@@ -98,8 +98,8 @@ def apply_buildlogger_test_handler(logger,
|
||||
log_format = logger_info.get("format", _DEFAULT_FORMAT)
|
||||
formatter = formatters.ISO8601Formatter(fmt=log_format)
|
||||
|
||||
handler = buildlogger.BuildloggerTestHandler(build_id,
|
||||
build_config,
|
||||
handler = buildlogger.BuildloggerTestHandler(build_config,
|
||||
build_id,
|
||||
test_id,
|
||||
**handler_info)
|
||||
handler.setFormatter(formatter)
|
||||
|
||||
@@ -95,19 +95,23 @@ def parse_command_line():
|
||||
parser.add_option("--dbtest", dest="dbtest_executable", metavar="PATH",
|
||||
help="The path to the dbtest executable for resmoke to use.")
|
||||
|
||||
parser.add_option("--excludeWithAllTags", dest="exclude_with_all_tags", metavar="TAG1,TAG2",
|
||||
parser.add_option("--excludeWithAllTags", action="append", dest="exclude_with_all_tags",
|
||||
metavar="TAG1,TAG2",
|
||||
help=("Comma separated list of tags. Any jstest that contains all of the"
|
||||
" specified tags will be excluded from any suites that are run."))
|
||||
|
||||
parser.add_option("--excludeWithAnyTags", dest="exclude_with_any_tags", metavar="TAG1,TAG2",
|
||||
parser.add_option("--excludeWithAnyTags", action="append", dest="exclude_with_any_tags",
|
||||
metavar="TAG1,TAG2",
|
||||
help=("Comma separated list of tags. Any jstest that contains any of the"
|
||||
" specified tags will be excluded from any suites that are run."))
|
||||
|
||||
parser.add_option("--includeWithAllTags", dest="include_with_all_tags", metavar="TAG1,TAG2",
|
||||
parser.add_option("--includeWithAllTags", action="append", dest="include_with_all_tags",
|
||||
metavar="TAG1,TAG2",
|
||||
help=("Comma separated list of tags. For the jstest portion of the suite(s),"
|
||||
" only tests which have all of the specified tags will be run."))
|
||||
|
||||
parser.add_option("--includeWithAnyTags", dest="include_with_any_tags", metavar="TAG1,TAG2",
|
||||
parser.add_option("--includeWithAnyTags", action="append", dest="include_with_any_tags",
|
||||
metavar="TAG1,TAG2",
|
||||
help=("Comma separated list of tags. For the jstest portion of the suite(s),"
|
||||
" only tests which have at least one of the specified tags will be"
|
||||
" run."))
|
||||
|
||||
@@ -18,6 +18,7 @@ from . import utils
|
||||
from .utils import globstar
|
||||
from .utils import jscomment
|
||||
|
||||
|
||||
def _filter_cpp_tests(kind, root, include_files, exclude_files):
|
||||
"""
|
||||
Generic filtering logic for C++ tests that are sourced from a list
|
||||
@@ -32,16 +33,8 @@ def _filter_cpp_tests(kind, root, include_files, exclude_files):
|
||||
test_path = test_path.rstrip()
|
||||
tests.append(test_path)
|
||||
|
||||
(remaining, included, _) = _filter_by_filename(kind,
|
||||
tests,
|
||||
include_files,
|
||||
exclude_files)
|
||||
return list(_filter_by_filename(kind, tests, include_files, exclude_files))
|
||||
|
||||
if include_files:
|
||||
return list(included)
|
||||
elif exclude_files:
|
||||
return list(remaining)
|
||||
return tests
|
||||
|
||||
def filter_cpp_unit_tests(root="build/unittests.txt", include_files=None, exclude_files=None):
|
||||
"""
|
||||
@@ -112,93 +105,84 @@ def filter_jstests(roots,
|
||||
"""
|
||||
Filters out what jstests to run.
|
||||
"""
|
||||
|
||||
include_files = utils.default_if_none(include_files, [])
|
||||
exclude_files = utils.default_if_none(exclude_files, [])
|
||||
|
||||
# Command line options override the YAML options, and all should be defaulted to an empty list
|
||||
# if not specified.
|
||||
# Command line options are merged with YAML options.
|
||||
tags = {
|
||||
"exclude_with_all_tags": exclude_with_all_tags,
|
||||
"exclude_with_any_tags": exclude_with_any_tags,
|
||||
"include_with_all_tags": include_with_all_tags,
|
||||
"include_with_any_tags": include_with_any_tags,
|
||||
# The constructor for an empty set does not accept "None".
|
||||
"exclude_with_all_tags": set(utils.default_if_none(exclude_with_all_tags, [])),
|
||||
"exclude_with_any_tags": set(utils.default_if_none(exclude_with_any_tags, [])),
|
||||
"include_with_all_tags": set(utils.default_if_none(include_with_all_tags, [])),
|
||||
"include_with_any_tags": set(utils.default_if_none(include_with_any_tags, [])),
|
||||
}
|
||||
cmd_line_values = (
|
||||
|
||||
for name in tags:
|
||||
if not utils.is_string_set(tags[name]):
|
||||
raise TypeError("%s must be a YAML list of strings" % (name))
|
||||
|
||||
cmd_line_lists = (
|
||||
("exclude_with_all_tags", config.EXCLUDE_WITH_ALL_TAGS),
|
||||
("exclude_with_any_tags", config.EXCLUDE_WITH_ANY_TAGS),
|
||||
("include_with_all_tags", config.INCLUDE_WITH_ALL_TAGS),
|
||||
("include_with_any_tags", config.INCLUDE_WITH_ANY_TAGS),
|
||||
)
|
||||
for (tag_category, cmd_line_val) in cmd_line_values:
|
||||
if cmd_line_val is not None:
|
||||
|
||||
# Merge command line options with YAML options.
|
||||
for (tag_category, cmd_line_list) in cmd_line_lists:
|
||||
if cmd_line_list is not None:
|
||||
# Ignore the empty string when it is used as a tag. Specifying an empty string on the
|
||||
# command line allows a user to unset the list of tags specified in the YAML
|
||||
# configuration.
|
||||
tags[tag_category] = set([tag for tag in cmd_line_val.split(",") if tag != ""])
|
||||
else:
|
||||
tags[tag_category] = set(utils.default_if_none(tags[tag_category], []))
|
||||
# command line has no effect and allows a user to more easily synthesize a resmoke.py
|
||||
# invocation in their Evergreen project configuration.
|
||||
for cmd_line_tags in cmd_line_list:
|
||||
tags[tag_category] |= set(tag for tag in cmd_line_tags.split(",") if tag != "")
|
||||
|
||||
using_tags = 0
|
||||
for name in tags:
|
||||
if not utils.is_string_set(tags[name]):
|
||||
raise TypeError("%s must be a list of strings" % (name))
|
||||
if len(tags[name]) > 0:
|
||||
using_tags += 1
|
||||
|
||||
if using_tags > 1:
|
||||
raise ValueError("Can only specify one of 'include_with_all_tags', 'include_with_any_tags',"
|
||||
" 'exclude_with_all_tags', and 'exclude_with_any_tags'. If you wish to"
|
||||
" unset one of these options, use --includeWithAllTags='' or similar")
|
||||
|
||||
jstests = []
|
||||
jstests_list = []
|
||||
for root in roots:
|
||||
jstests.extend(globstar.iglob(root))
|
||||
jstests_list.extend(globstar.iglob(root))
|
||||
|
||||
(remaining, included, _) = _filter_by_filename("jstest",
|
||||
jstests,
|
||||
include_files,
|
||||
exclude_files)
|
||||
using_tags = False
|
||||
for tag in tags.values():
|
||||
if tag:
|
||||
using_tags = True
|
||||
|
||||
# Skip parsing comments if not using tags
|
||||
# Skip converting 'jstests_list' to a set when it isn't being filtered in order to retain its
|
||||
# ordering.
|
||||
if not include_files and not exclude_files and not using_tags:
|
||||
return jstests_list
|
||||
|
||||
jstests_set = _filter_by_filename("jstest", jstests_list, include_files, exclude_files)
|
||||
|
||||
# Skip parsing comments if not using tags.
|
||||
if not using_tags:
|
||||
if include_files:
|
||||
return list(included)
|
||||
elif exclude_files:
|
||||
return list(remaining)
|
||||
return jstests
|
||||
return list(jstests_set)
|
||||
|
||||
jstests = set(remaining)
|
||||
excluded = set()
|
||||
|
||||
for filename in jstests:
|
||||
for filename in jstests_set:
|
||||
file_tags = set(jscomment.get_tags(filename))
|
||||
if tags["include_with_all_tags"] and not tags["include_with_all_tags"] - file_tags:
|
||||
included.add(filename)
|
||||
elif tags["include_with_any_tags"] and tags["include_with_any_tags"] & file_tags:
|
||||
included.add(filename)
|
||||
elif tags["exclude_with_all_tags"] and not tags["exclude_with_all_tags"] - file_tags:
|
||||
if tags["include_with_all_tags"] and tags["include_with_all_tags"] - file_tags:
|
||||
excluded.add(filename)
|
||||
elif tags["exclude_with_any_tags"] and tags["exclude_with_any_tags"] & file_tags:
|
||||
if tags["include_with_any_tags"] and not tags["include_with_any_tags"] & file_tags:
|
||||
excluded.add(filename)
|
||||
if tags["exclude_with_all_tags"] and not tags["exclude_with_all_tags"] - file_tags:
|
||||
excluded.add(filename)
|
||||
if tags["exclude_with_any_tags"] and tags["exclude_with_any_tags"] & file_tags:
|
||||
excluded.add(filename)
|
||||
|
||||
if tags["include_with_all_tags"] or tags["include_with_any_tags"]:
|
||||
if exclude_files:
|
||||
return list((included & jstests) - excluded)
|
||||
return list(included)
|
||||
else:
|
||||
if include_files:
|
||||
return list(included | (jstests - excluded))
|
||||
return list(jstests - excluded)
|
||||
# Specifying include_files overrides tags.
|
||||
return list((jstests_set - excluded) | set(include_files))
|
||||
|
||||
|
||||
def _filter_by_filename(kind, universe, include_files, exclude_files):
|
||||
"""
|
||||
Filters out what tests to run solely by filename.
|
||||
|
||||
Returns the triplet (remaining, included, excluded), where
|
||||
'remaining' is 'universe' after 'included' and 'excluded' were
|
||||
removed from it.
|
||||
Returns either the set of files from 'universe' that are present in 'include_files', or the
|
||||
set of files from 'universe' that aren't present in 'exclude_files', depending on which of
|
||||
'include_files' and 'exclude_files' is non-empty.
|
||||
|
||||
An error is raised if both 'include_files' and 'exclude_files' are specified.
|
||||
"""
|
||||
|
||||
if not utils.is_string_list(include_files):
|
||||
@@ -209,38 +193,25 @@ def _filter_by_filename(kind, universe, include_files, exclude_files):
|
||||
raise ValueError("Cannot specify both include_files and exclude_files")
|
||||
|
||||
universe = set(universe)
|
||||
files = include_files if include_files else exclude_files
|
||||
|
||||
(verbatim, globbed) = _partition(files)
|
||||
# Remove all matching files of 'verbatim' from 'universe'.
|
||||
files_verbatim = _pop_all(kind, universe, verbatim)
|
||||
files_globbed = set()
|
||||
|
||||
for file_pattern in globbed:
|
||||
files_globbed.update(globstar.iglob(file_pattern))
|
||||
|
||||
# Remove all matching files of 'files_globbed' from 'universe' without checking whether
|
||||
# the same file is expanded to multiple times. This implicitly takes an intersection
|
||||
# between 'files_globbed' and 'universe'.
|
||||
files_globbed = _pop_all(kind, universe, files_globbed, validate=False)
|
||||
|
||||
if include_files:
|
||||
(verbatim, globbed) = _partition(include_files)
|
||||
# Remove all matching files of 'verbatim' from 'universe'.
|
||||
included_verbatim = _pop_all(kind, universe, verbatim)
|
||||
included_globbed = set()
|
||||
return files_verbatim | files_globbed
|
||||
|
||||
for file_pattern in globbed:
|
||||
included_globbed.update(globstar.iglob(file_pattern))
|
||||
|
||||
# Remove all matching files of 'included_globbed' from 'universe' without checking whether
|
||||
# the same file is expanded to multiple times. This implicitly takes an intersection
|
||||
# between 'included_globbed' and 'universe'.
|
||||
included_globbed = _pop_all(kind, universe, included_globbed, validate=False)
|
||||
return (universe, included_verbatim | included_globbed, set())
|
||||
|
||||
elif exclude_files:
|
||||
(verbatim, globbed) = _partition(exclude_files)
|
||||
|
||||
# Remove all matching files of 'verbatim' from 'universe'.
|
||||
excluded_verbatim = _pop_all(kind, universe, verbatim)
|
||||
excluded_globbed = set()
|
||||
|
||||
for file_pattern in globbed:
|
||||
excluded_globbed.update(globstar.iglob(file_pattern))
|
||||
|
||||
# Remove all matching files of 'excluded_globbed' from 'universe' without checking whether
|
||||
# the same file is expanded to multiple times. This implicitly takes an intersection
|
||||
# between 'excluded_globbed' and 'universe'.
|
||||
excluded_globbed = _pop_all(kind, universe, excluded_globbed, validate=False)
|
||||
return (universe, set(), excluded_verbatim | excluded_globbed)
|
||||
|
||||
return (universe, set(), set())
|
||||
return universe
|
||||
|
||||
|
||||
def _partition(pathnames, normpath=True):
|
||||
|
||||
@@ -60,13 +60,22 @@ class Fixture(object):
|
||||
"""
|
||||
return True
|
||||
|
||||
def get_connection_string(self):
|
||||
def get_internal_connection_string(self):
|
||||
"""
|
||||
Returns the connection string for this fixture. This is NOT a
|
||||
driver connection string, but a connection string of the format
|
||||
expected by the mongo::ConnectionString class.
|
||||
"""
|
||||
raise NotImplementedError("get_connection_string must be implemented by Fixture subclasses")
|
||||
raise NotImplementedError(
|
||||
"get_internal_connection_string must be implemented by Fixture subclasses")
|
||||
|
||||
def get_driver_connection_url(self):
|
||||
"""
|
||||
Return the mongodb connection string as defined here:
|
||||
https://docs.mongodb.com/manual/reference/connection-string/
|
||||
"""
|
||||
raise NotImplementedError(
|
||||
"get_driver_connection_url must be implemented by Fixture subclasses")
|
||||
|
||||
def __str__(self):
|
||||
return "%s (Job #%d)" % (self.__class__.__name__, self.job_num)
|
||||
|
||||
@@ -5,7 +5,6 @@ Master/slave fixture for executing JSTests against.
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os.path
|
||||
import socket
|
||||
|
||||
import pymongo
|
||||
|
||||
@@ -160,6 +159,12 @@ class MasterSlaveFixture(interface.ReplFixture):
|
||||
mongod_options = self.mongod_options.copy()
|
||||
mongod_options.update(self.slave_options)
|
||||
mongod_options["slave"] = ""
|
||||
mongod_options["source"] = "%s:%d" % (socket.gethostname(), self.port)
|
||||
mongod_options["source"] = self.master.get_internal_connection_string()
|
||||
mongod_options["dbpath"] = os.path.join(self._dbpath_prefix, "slave")
|
||||
return self._new_mongod(mongod_logger, mongod_options)
|
||||
|
||||
def get_internal_connection_string(self):
|
||||
return self.master.get_internal_connection_string()
|
||||
|
||||
def get_driver_connection_url(self):
|
||||
return self.master.get_driver_connection_url()
|
||||
|
||||
@@ -30,7 +30,9 @@ class ReplicaSetFixture(interface.ReplFixture):
|
||||
preserve_dbpath=False,
|
||||
num_nodes=2,
|
||||
auth_options=None,
|
||||
replset_config_options=None):
|
||||
replset_config_options=None,
|
||||
voting_secondaries=False,
|
||||
use_replica_set_connection_string=False):
|
||||
|
||||
interface.ReplFixture.__init__(self, logger, job_num)
|
||||
|
||||
@@ -40,6 +42,8 @@ class ReplicaSetFixture(interface.ReplFixture):
|
||||
self.num_nodes = num_nodes
|
||||
self.auth_options = auth_options
|
||||
self.replset_config_options = utils.default_if_none(replset_config_options, {})
|
||||
self.voting_secondaries = voting_secondaries
|
||||
self.use_replica_set_connection_string = use_replica_set_connection_string
|
||||
|
||||
# The dbpath in mongod_options is used as the dbpath prefix for replica set members and
|
||||
# takes precedence over other settings. The ShardedClusterFixture uses this parameter to
|
||||
@@ -78,12 +82,13 @@ class ReplicaSetFixture(interface.ReplFixture):
|
||||
# Initiate the replica set.
|
||||
members = []
|
||||
for (i, node) in enumerate(self.nodes):
|
||||
member_info = {"_id": i, "host": node.get_connection_string()}
|
||||
member_info = {"_id": i, "host": node.get_internal_connection_string()}
|
||||
if i > 0:
|
||||
member_info["priority"] = 0
|
||||
if i >= 7:
|
||||
# Only 7 nodes in a replica set can vote, so the other members must be non-voting.
|
||||
member_info["votes"] = 0
|
||||
if i >= 7 or not self.voting_secondaries:
|
||||
# Only 7 nodes in a replica set can vote, so the other members must still be
|
||||
# non-voting when this fixture is configured to have voting secondaries.
|
||||
member_info["votes"] = 0
|
||||
members.append(member_info)
|
||||
initiate_cmd_obj = {"replSetInitiate": {"_id": self.replset_name, "members": members}}
|
||||
|
||||
@@ -184,9 +189,23 @@ class ReplicaSetFixture(interface.ReplFixture):
|
||||
|
||||
return logging.loggers.new_logger(logger_name, parent=self.logger)
|
||||
|
||||
def get_connection_string(self):
|
||||
def get_internal_connection_string(self):
|
||||
if self.replset_name is None:
|
||||
raise ValueError("Must call setup() before calling get_connection_string()")
|
||||
raise ValueError("Must call setup() before calling get_internal_connection_string()")
|
||||
|
||||
conn_strs = [node.get_connection_string() for node in self.nodes]
|
||||
conn_strs = [node.get_internal_connection_string() for node in self.nodes]
|
||||
return self.replset_name + "/" + ",".join(conn_strs)
|
||||
|
||||
def get_driver_connection_url(self):
|
||||
if self.replset_name is None:
|
||||
raise ValueError("Must call setup() before calling get_driver_connection_url()")
|
||||
|
||||
if self.use_replica_set_connection_string:
|
||||
# The mongo shell requires the database name when specifying a replica set connection
|
||||
# string, so we hardcode "test" because that's the default database anyway.
|
||||
conn_strs = [node.get_internal_connection_string() for node in self.nodes]
|
||||
return "mongodb://" + ",".join(conn_strs) + "/test?replicaSet=" + self.replset_name
|
||||
else:
|
||||
# We return a direct connection to the expected pimary when only the first node is
|
||||
# electable because we want the client to error out if a stepdown occurs.
|
||||
return self.nodes[0].get_driver_connection_url()
|
||||
|
||||
@@ -170,6 +170,15 @@ class ShardedClusterFixture(interface.Fixture):
|
||||
all(shard.is_running() for shard in self.shards) and
|
||||
self.mongos is not None and self.mongos.is_running())
|
||||
|
||||
def get_internal_connection_string(self):
|
||||
if self.mongos is None:
|
||||
raise ValueError("Must call setup() before calling get_internal_connection_string()")
|
||||
|
||||
return self.mongos.get_internal_connection_string()
|
||||
|
||||
def get_driver_connection_url(self):
|
||||
return "mongodb://" + self.get_internal_connection_string()
|
||||
|
||||
def _new_configsvr(self):
|
||||
"""
|
||||
Returns a replicaset.ReplicaSetFixture configured to be used as
|
||||
@@ -222,16 +231,11 @@ class ShardedClusterFixture(interface.Fixture):
|
||||
mongos_logger = logging.loggers.new_logger(logger_name, parent=self.logger)
|
||||
|
||||
mongos_options = copy.deepcopy(self.mongos_options)
|
||||
configdb_hostname = socket.gethostname()
|
||||
|
||||
if self.separate_configsvr:
|
||||
configdb_replset = ShardedClusterFixture._CONFIGSVR_REPLSET_NAME
|
||||
configdb_port = self.configsvr.port
|
||||
mongos_options["configdb"] = "%s/%s:%d" % (configdb_replset,
|
||||
configdb_hostname,
|
||||
configdb_port)
|
||||
mongos_options["configdb"] = self.configsvr.get_internal_connection_string()
|
||||
else:
|
||||
mongos_options["configdb"] = "%s:%d" % (configdb_hostname, self.shards[0].port)
|
||||
mongos_options["configdb"] = "%s:%d" % (socket.gethostname(), self.shards[0].port)
|
||||
|
||||
return _MongoSFixture(mongos_logger,
|
||||
self.job_num,
|
||||
@@ -247,9 +251,9 @@ class ShardedClusterFixture(interface.Fixture):
|
||||
for more details.
|
||||
"""
|
||||
|
||||
hostname = socket.gethostname()
|
||||
self.logger.info("Adding %s:%d as a shard..." % (hostname, shard.port))
|
||||
client.admin.command({"addShard": "%s:%d" % (hostname, shard.port)})
|
||||
connection_string = shard.get_internal_connection_string()
|
||||
self.logger.info("Adding %s as a shard...", connection_string)
|
||||
client.admin.command({"addShard": connection_string})
|
||||
|
||||
|
||||
class _MongoSFixture(interface.Fixture):
|
||||
@@ -351,3 +355,12 @@ class _MongoSFixture(interface.Fixture):
|
||||
|
||||
def is_running(self):
|
||||
return self.mongos is not None and self.mongos.poll() is None
|
||||
|
||||
def get_internal_connection_string(self):
|
||||
if self.mongos is None:
|
||||
raise ValueError("Must call setup() before calling get_internal_connection_string()")
|
||||
|
||||
return "%s:%d" % (socket.gethostname(), self.port)
|
||||
|
||||
def get_driver_connection_url(self):
|
||||
return "mongodb://" + self.get_internal_connection_string()
|
||||
|
||||
@@ -6,7 +6,6 @@ from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import shutil
|
||||
import socket
|
||||
import time
|
||||
|
||||
@@ -93,8 +92,9 @@ class MongoDFixture(interface.Fixture):
|
||||
raise errors.TestFailure("%s did not exit cleanly" % (self))
|
||||
|
||||
def setup(self):
|
||||
if not self.preserve_dbpath:
|
||||
shutil.rmtree(self._dbpath, ignore_errors=True)
|
||||
"""Set up the mongod."""
|
||||
if not self.preserve_dbpath and os.path.lexists(self._dbpath):
|
||||
utils.rmtree(self._dbpath, ignore_errors=False)
|
||||
|
||||
try:
|
||||
os.makedirs(self._dbpath)
|
||||
@@ -178,8 +178,11 @@ class MongoDFixture(interface.Fixture):
|
||||
def is_running(self):
|
||||
return self.mongod is not None and self.mongod.poll() is None
|
||||
|
||||
def get_connection_string(self):
|
||||
def get_internal_connection_string(self):
|
||||
if self.mongod is None:
|
||||
raise ValueError("Must call setup() before calling get_connection_string()")
|
||||
raise ValueError("Must call setup() before calling get_internal_connection_string()")
|
||||
|
||||
return "%s:%d" % (socket.gethostname(), self.port)
|
||||
|
||||
def get_driver_connection_url(self):
|
||||
return "mongodb://" + self.get_internal_connection_string()
|
||||
|
||||
@@ -6,7 +6,6 @@ from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import shutil
|
||||
import unittest
|
||||
|
||||
from .. import config
|
||||
@@ -173,7 +172,7 @@ class CPPIntegrationTestCase(TestCase):
|
||||
def configure(self, fixture):
|
||||
TestCase.configure(self, fixture)
|
||||
|
||||
self.program_options["connectionString"] = self.fixture.get_connection_string()
|
||||
self.program_options["connectionString"] = self.fixture.get_internal_connection_string()
|
||||
|
||||
def run_test(self):
|
||||
try:
|
||||
@@ -222,7 +221,7 @@ class DBTestCase(TestCase):
|
||||
dbpath = os.path.join(dbpath_prefix, "job%d" % (self.fixture.job_num), "unittest")
|
||||
self.dbtest_options["dbpath"] = dbpath
|
||||
|
||||
shutil.rmtree(dbpath, ignore_errors=True)
|
||||
utils.rmtree(dbpath, ignore_errors=True)
|
||||
|
||||
try:
|
||||
os.makedirs(dbpath)
|
||||
@@ -279,6 +278,7 @@ class JSTestCase(TestCase):
|
||||
js_filename,
|
||||
shell_executable=None,
|
||||
shell_options=None,
|
||||
use_connection_string=False,
|
||||
test_kind="JSTest"):
|
||||
"Initializes the JSTestCase with the JS file to run."
|
||||
|
||||
@@ -289,6 +289,7 @@ class JSTestCase(TestCase):
|
||||
|
||||
self.js_filename = js_filename
|
||||
self.shell_options = utils.default_if_none(shell_options, {}).copy()
|
||||
self.use_connection_string = use_connection_string
|
||||
|
||||
def configure(self, fixture):
|
||||
TestCase.configure(self, fixture)
|
||||
@@ -316,7 +317,7 @@ class JSTestCase(TestCase):
|
||||
global_vars["TestData"] = test_data
|
||||
self.shell_options["global_vars"] = global_vars
|
||||
|
||||
shutil.rmtree(data_dir, ignore_errors=True)
|
||||
utils.rmtree(data_dir, ignore_errors=True)
|
||||
|
||||
try:
|
||||
os.makedirs(data_dir)
|
||||
@@ -349,10 +350,16 @@ class JSTestCase(TestCase):
|
||||
raise
|
||||
|
||||
def _make_process(self):
|
||||
return core.programs.mongo_shell_program(self.logger,
|
||||
executable=self.shell_executable,
|
||||
filename=self.js_filename,
|
||||
**self.shell_options)
|
||||
connection_string = None
|
||||
if self.use_connection_string:
|
||||
connection_string = self.fixture.get_driver_connection_url()
|
||||
|
||||
return core.programs.mongo_shell_program(
|
||||
self.logger,
|
||||
executable=self.shell_executable,
|
||||
filename=self.js_filename,
|
||||
connection_string=connection_string,
|
||||
**self.shell_options)
|
||||
|
||||
|
||||
class MongosTestCase(TestCase):
|
||||
|
||||
@@ -5,6 +5,8 @@ Helper functions.
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os.path
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
import pymongo
|
||||
import yaml
|
||||
@@ -14,6 +16,28 @@ def default_if_none(value, default):
|
||||
return value if value is not None else default
|
||||
|
||||
|
||||
def rmtree(path, **kwargs):
|
||||
"""Wrap shutil.rmtreee.
|
||||
|
||||
Use a UTF-8 unicode path if Windows.
|
||||
See https://bugs.python.org/issue24672, where shutil.rmtree can fail with UTF-8.
|
||||
Use a bytes path to rmtree, otherwise.
|
||||
See https://github.com/pypa/setuptools/issues/706.
|
||||
"""
|
||||
if is_windows():
|
||||
if not isinstance(path, unicode):
|
||||
path = unicode(path, "utf-8")
|
||||
else:
|
||||
if isinstance(path, unicode):
|
||||
path = path.encode("utf-8")
|
||||
shutil.rmtree(path, **kwargs)
|
||||
|
||||
|
||||
def is_windows():
|
||||
"""Return True if Windows."""
|
||||
return sys.platform.startswith("win32") or sys.platform.startswith("cygwin")
|
||||
|
||||
|
||||
def is_string_list(lst):
|
||||
"""
|
||||
Returns true if 'lst' is a list of strings, and false otherwise.
|
||||
|
||||
67
buildscripts/tests/resmokelib/logging/test_buildlogger.py
Normal file
67
buildscripts/tests/resmokelib/logging/test_buildlogger.py
Normal file
@@ -0,0 +1,67 @@
|
||||
"""Unit tests for the buildscripts.resmokelib.logging.buildlogger module."""
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import json
|
||||
import unittest
|
||||
|
||||
from buildscripts.resmokelib.logging import buildlogger
|
||||
|
||||
|
||||
class TestLogsSplitter(unittest.TestCase):
|
||||
"""Unit tests for the _LogsSplitter class."""
|
||||
|
||||
def test_split_no_logs(self):
|
||||
logs = []
|
||||
max_size = 10
|
||||
self.assertEqual([[]], buildlogger._LogsSplitter.split_logs(logs, max_size))
|
||||
|
||||
def test_split_no_max_size(self):
|
||||
logs = self.__generate_logs(size=30)
|
||||
max_size = None
|
||||
self.assertEqual([logs], buildlogger._LogsSplitter.split_logs(logs, max_size))
|
||||
|
||||
def test_split_max_size_smaller(self):
|
||||
logs = self.__generate_logs(size=20)
|
||||
max_size = 30
|
||||
self.assertEqual([logs], buildlogger._LogsSplitter.split_logs(logs, max_size))
|
||||
|
||||
def test_split_max_size_equal(self):
|
||||
logs = self.__generate_logs(size=30)
|
||||
max_size = 30
|
||||
self.assertEqual([logs], buildlogger._LogsSplitter.split_logs(logs, max_size))
|
||||
|
||||
def test_split_max_size_larger(self):
|
||||
logs = self.__generate_logs(size=31)
|
||||
max_size = 30
|
||||
self.assertEqual(
|
||||
[logs[0:-1], logs[-1:]],
|
||||
buildlogger._LogsSplitter.split_logs(logs, max_size))
|
||||
|
||||
logs = self.__generate_logs(size=149)
|
||||
max_size = 19
|
||||
self.assertEqual(
|
||||
[logs[0:3], logs[3:6], logs[6:9], logs[9:12], logs[12:15],
|
||||
logs[15:18], logs[18:21], logs[21:24], logs[24:27], logs[27:]],
|
||||
buildlogger._LogsSplitter.split_logs(logs, max_size))
|
||||
|
||||
def check_split_sizes(self, splits, max_size):
|
||||
for split in splits:
|
||||
self.assertTrue(TestLogsSplitter.size(split) <= max_size)
|
||||
|
||||
def __generate_logs(self, size):
|
||||
# The size of [ "x" ] is 5. This is the minimum size we generate.
|
||||
self.assertTrue(size >= 5)
|
||||
# Each new "x" adds 5 to the size.
|
||||
nb_lines = size / 5
|
||||
# Each additional "x" on a line adds 1 to the size.
|
||||
last_line_extra = size % 5
|
||||
logs = ["x"] * nb_lines
|
||||
logs[-1] += "x" * last_line_extra
|
||||
self.assertEqual(size, TestLogsSplitter.size(logs))
|
||||
return logs
|
||||
|
||||
@staticmethod
|
||||
def size(logs):
|
||||
"""Returns the size of the log lines when represented in JSON."""
|
||||
return len(json.dumps(logs, encoding="utf-8"))
|
||||
1
buildscripts/tests/resmokelib/utils/__init__.py
Normal file
1
buildscripts/tests/resmokelib/utils/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
"""Empty."""
|
||||
126
buildscripts/tests/resmokelib/utils/test_rmtree.py
Normal file
126
buildscripts/tests/resmokelib/utils/test_rmtree.py
Normal file
@@ -0,0 +1,126 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
""" Unit tests for utils.rmtree. """
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
from buildscripts.resmokelib import utils
|
||||
|
||||
# pylint: disable=missing-docstring,protected-access
|
||||
|
||||
|
||||
def rmtree(dir_root):
|
||||
"""Invoke utils.rmtree(dir_root) and return True if removed."""
|
||||
utils.rmtree(dir_root)
|
||||
return not os.path.exists(dir_root)
|
||||
|
||||
|
||||
def create_file(path):
|
||||
"""Create file named 'path'."""
|
||||
with open(path, "w") as fh:
|
||||
fh.write("")
|
||||
|
||||
|
||||
def ascii_filesystemencoding():
|
||||
"""Return True if the file system encoding is type ASCII.
|
||||
|
||||
See https://www.iana.org/assignments/character-sets/character-sets.xhtml.
|
||||
"""
|
||||
encoding = sys.getfilesystemencoding()
|
||||
return encoding.startswith("ANSI_X3.4") or encoding == "US-ASCII"
|
||||
|
||||
|
||||
def string_for_ascii_filesystem_encoding(path):
|
||||
"""Return encoded string type for unicode on ASCII file system encoding.
|
||||
|
||||
Some file system encodings are set to ASCII if LANG=C or LC_ALL=C is specified.
|
||||
"""
|
||||
if ascii_filesystemencoding() and isinstance(path, unicode):
|
||||
return path.encode("utf-8")
|
||||
return path
|
||||
|
||||
|
||||
class RmtreeTestCase(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.temp_dir_root = tempfile.mkdtemp()
|
||||
cls.cwd = os.getcwd()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
os.chdir(cls.cwd)
|
||||
shutil.rmtree(cls.temp_dir_root, ignore_errors=True)
|
||||
|
||||
def do_test(self, name):
|
||||
pass
|
||||
|
||||
def test_ascii(self):
|
||||
# ASCII name
|
||||
self.do_test("ascii")
|
||||
|
||||
def test_unicode(self):
|
||||
# Unicode name
|
||||
self.do_test(u"unicode")
|
||||
|
||||
def test_greek(self):
|
||||
# Name with Greek
|
||||
self.do_test(string_for_ascii_filesystem_encoding(u"ελληνικά"))
|
||||
|
||||
def test_japanese(self):
|
||||
# Name with Japanese
|
||||
self.do_test(string_for_ascii_filesystem_encoding(u"会社案"))
|
||||
|
||||
|
||||
class RmtreeFileTests(RmtreeTestCase):
|
||||
def do_test(self, file_name): # pylint: disable=arguments-differ
|
||||
"""Execute file test."""
|
||||
temp_dir = tempfile.mkdtemp(dir=self.temp_dir_root)
|
||||
os.chdir(temp_dir)
|
||||
create_file(file_name)
|
||||
os.chdir(self.temp_dir_root)
|
||||
self.assertTrue(rmtree(temp_dir))
|
||||
|
||||
|
||||
class RmtreeDirectoryTests(RmtreeTestCase):
|
||||
def do_test(self, dir_name): # pylint: disable=arguments-differ
|
||||
"""Execute directory test."""
|
||||
os.chdir(self.temp_dir_root)
|
||||
os.mkdir(dir_name)
|
||||
self.assertTrue(rmtree(dir_name))
|
||||
|
||||
|
||||
class RmtreeDirectoryWithNonAsciiTests(RmtreeTestCase):
|
||||
def do_test(self, name):
|
||||
"""Execute directory with non-ASCII file test."""
|
||||
os.chdir(self.temp_dir_root)
|
||||
os.mkdir(name)
|
||||
os.chdir(name)
|
||||
create_file(name)
|
||||
os.chdir(self.temp_dir_root)
|
||||
self.assertTrue(rmtree(name))
|
||||
|
||||
|
||||
class ShutilWindowsRmtreeFileTests(RmtreeFileTests):
|
||||
def do_test(self, file_name):
|
||||
"""Execute file test that are known to fail in shutil.rmtree."""
|
||||
if not utils.is_windows():
|
||||
print("Skipping ShutilWindowsRmtreeFileTests on non-Windows platforms")
|
||||
return
|
||||
temp_dir = tempfile.mkdtemp(dir=self.temp_dir_root)
|
||||
os.chdir(temp_dir)
|
||||
create_file(file_name)
|
||||
os.chdir(self.temp_dir_root)
|
||||
with self.assertRaises(WindowsError): # pylint: disable=undefined-variable
|
||||
shutil.rmtree(temp_dir)
|
||||
|
||||
def test_ascii(self):
|
||||
pass
|
||||
|
||||
def test_unicode(self):
|
||||
pass
|
||||
1
debian/init.d
vendored
1
debian/init.d
vendored
@@ -133,6 +133,7 @@ start_server() {
|
||||
ulimit -v unlimited
|
||||
ulimit -n 64000
|
||||
ulimit -m unlimited
|
||||
ulimit -l unlimited
|
||||
|
||||
# In dash, ulimit takes -p for maximum user processes
|
||||
# In bash, it's -u
|
||||
|
||||
2
debian/mongod.service
vendored
2
debian/mongod.service
vendored
@@ -17,6 +17,8 @@ LimitAS=infinity
|
||||
LimitNOFILE=64000
|
||||
# processes/threads
|
||||
LimitNPROC=64000
|
||||
# locked memory
|
||||
LimitMEMLOCK=infinity
|
||||
# total threads (user+kernel)
|
||||
TasksMax=infinity
|
||||
TasksAccounting=false
|
||||
|
||||
1
debian/mongod.upstart
vendored
1
debian/mongod.upstart
vendored
@@ -9,6 +9,7 @@ limit as unlimited unlimited
|
||||
limit nofile 64000 64000
|
||||
limit rss unlimited unlimited
|
||||
limit nproc 64000 64000
|
||||
limit memlock unlimited unlimited
|
||||
|
||||
kill timeout 300 # wait 300s between SIGTERM and SIGKILL.
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,19 +9,18 @@ post:
|
||||
params:
|
||||
working_dir: work
|
||||
script: |
|
||||
set -v
|
||||
source ./dsienv.sh
|
||||
$DSI_PATH/bin/make_artifact.sh
|
||||
make_artifact.sh
|
||||
- command: s3.put
|
||||
params:
|
||||
aws_key: ${aws_key}
|
||||
aws_secret: ${aws_secret}
|
||||
local_file: work/reports.tgz
|
||||
remote_file: ${project}/${build_variant}/${revision}/${task_id}/${version_id}/logs/${task_name}-${build_id}.${ext|tgz}
|
||||
local_file: work/dsi-artifacts.tgz
|
||||
remote_file: ${project}/${build_variant}/${revision}/${task_id}/${version_id}/logs/dsi-artifacts-${task_name}-${build_id}-${execution}.${ext|tgz}
|
||||
bucket: mciuploads
|
||||
permissions: public-read
|
||||
content_type: ${content_type|application/x-gzip}
|
||||
display_name: test-log
|
||||
display_name: Dsi Artifacts - Execution ${execution}
|
||||
- command: attach.results
|
||||
params:
|
||||
file_location: work/report.json
|
||||
@@ -58,12 +57,17 @@ functions:
|
||||
working_dir: work
|
||||
script: |
|
||||
cat > bootstrap.yml <<EOF
|
||||
cluster_type: ${cluster}
|
||||
infrastructure_provisioning: ${cluster}
|
||||
platform: ${platform}
|
||||
setup: ${setup}
|
||||
mongodb_setup: ${setup}
|
||||
storageEngine: ${storageEngine}
|
||||
test: ${test}.longevity
|
||||
test_control: ${test}.longevity
|
||||
production: true
|
||||
workloads_dir: ../src/workloads/workloads
|
||||
ycsb_dir: ../src/YCSB/YCSB
|
||||
|
||||
# compositions of expansions
|
||||
mongodb_binary_archive: "https://s3.amazonaws.com/mciuploads/${project}/${version_id}/${revision}/${platform}/mongod-${version_id}.tar.gz"
|
||||
EOF
|
||||
|
||||
cat > runtime.yml <<EOF
|
||||
@@ -85,11 +89,6 @@ functions:
|
||||
ext: ${ext}
|
||||
script_flags : ${script_flags}
|
||||
dsi_rev: ${dsi_rev}
|
||||
compare_task: ${compare_task}
|
||||
workloads_rev: ${workloads_rev}
|
||||
|
||||
# compositions of expansions
|
||||
mongodb_binary_archive: "https://s3.amazonaws.com/mciuploads/${project}/${version_id}/${revision}/${platform}/mongod-${version_id}.tar.gz"
|
||||
EOF
|
||||
- command: shell.exec
|
||||
params:
|
||||
@@ -112,8 +111,6 @@ functions:
|
||||
- command: shell.exec
|
||||
params:
|
||||
working_dir: work
|
||||
# setup execution environment
|
||||
# configure environment
|
||||
script: |
|
||||
set -e
|
||||
virtualenv ./venv
|
||||
@@ -126,12 +123,11 @@ functions:
|
||||
set -v
|
||||
set -e
|
||||
source work/dsienv.sh
|
||||
$DSI_PATH/bin/setup-dsi-env.sh
|
||||
setup-dsi-env.sh
|
||||
ls -a work
|
||||
|
||||
"infrastructure provisioning":
|
||||
"deploy cluster":
|
||||
- command: shell.exec
|
||||
# call infrastructure-provisioning.py. This will either create a cluster, or update tags on existing instances.
|
||||
params:
|
||||
working_dir: work
|
||||
script: |
|
||||
@@ -139,22 +135,13 @@ functions:
|
||||
set -v
|
||||
source ./dsienv.sh
|
||||
source ./venv/bin/activate
|
||||
$DSI_PATH/bin/infrastructure_provisioning.py
|
||||
|
||||
"configure mongodb cluster":
|
||||
- command: shell.exec
|
||||
# bring up the mongod
|
||||
params:
|
||||
working_dir: work
|
||||
script: |
|
||||
set -e
|
||||
set -o verbose
|
||||
source ./dsienv.sh
|
||||
source ./venv/bin/activate
|
||||
$DSI_PATH/bin/mongodb_setup.py && echo "${setup} MongoDB Cluster STARTED."
|
||||
infrastructure_provisioning.py
|
||||
workload_setup.py
|
||||
mongodb_setup.py
|
||||
|
||||
"run test":
|
||||
- command: shell.exec
|
||||
type: test
|
||||
params:
|
||||
working_dir: work
|
||||
script: |
|
||||
@@ -162,9 +149,7 @@ functions:
|
||||
set -v
|
||||
source ./dsienv.sh
|
||||
source ./venv/bin/activate
|
||||
echo "Run test for ${test}-${storageEngine} with setup ${setup}"
|
||||
$DSI_PATH/bin/run_test.py ${storageEngine} ${test} ${cluster}
|
||||
echo "Complete test for ${test} with setup ${setup}!"
|
||||
test_control.py
|
||||
- command: "json.send"
|
||||
params:
|
||||
name: "perf"
|
||||
@@ -178,42 +163,20 @@ functions:
|
||||
script: |
|
||||
set -e
|
||||
set -o verbose
|
||||
source ./dsienv.sh
|
||||
# Longevity runs so rarely, we simply teardown the cluster when done.
|
||||
# Note that nowadays infrastructure_teardown.py is actually copying the terraform.tfstate into /data/infrastructure_provisioning
|
||||
# but as of this writing the rhel70-perf-longevity distro didn't actually use the teardown hook.
|
||||
source ./dsienv.sh
|
||||
source ./venv/bin/activate
|
||||
$DSI_PATH/bin/infrastructure_teardown.py
|
||||
infrastructure_teardown.py
|
||||
echo "Cluster DESTROYED."
|
||||
echo
|
||||
echo "All perf results"
|
||||
cd ..
|
||||
cat perf.json | egrep "name|ops_per_sec"
|
||||
|
||||
"make test log artifact":
|
||||
- command: shell.exec
|
||||
params:
|
||||
working_dir: work
|
||||
script: |
|
||||
set -v
|
||||
source ./dsienv.sh
|
||||
$DSI_PATH/bin/make_artifact.sh
|
||||
|
||||
"analyze":
|
||||
- command: json.get_history
|
||||
params:
|
||||
task: ${task_name}
|
||||
file: "work/history.json"
|
||||
name: "perf"
|
||||
- command: json.get_history
|
||||
params:
|
||||
tags: true
|
||||
task: ${task_name}
|
||||
file: "work/tags.json"
|
||||
name: "perf"
|
||||
- command: shell.exec
|
||||
# post_run_check.py and longevity_override.json for DSI tests are part of dsi repo
|
||||
type : test
|
||||
params:
|
||||
working_dir: work
|
||||
@@ -223,7 +186,7 @@ functions:
|
||||
TAG="3.0.12-Baseline"
|
||||
PROJECT="mongo-longevity"
|
||||
OVERRIDEFILE="../src/dsi/dsi/analysis/${branch_name}/longevity_override.json"
|
||||
python -u ../src/dsi/dsi/analysis/post_run_check.py ${script_flags} --reports-analysis reports --perf-file reports/perf.json --rev ${revision} -f history.json -t tags.json --refTag $TAG --overrideFile $OVERRIDEFILE --project_id $PROJECT --task_name ${task_name} --variant ${build_variant}
|
||||
python -u ../src/dsi/dsi/analysis/post_run_check.py ${script_flags} --reports-analysis reports --perf-file perf.json --rev ${revision} --refTag $TAG --overrideFile $OVERRIDEFILE --project_id $PROJECT --task_name ${task_name} --variant ${build_variant}
|
||||
|
||||
tasks:
|
||||
- name: compile
|
||||
@@ -272,13 +235,8 @@ tasks:
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "ycsb"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
- func: "deploy cluster"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "ycsb"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
vars:
|
||||
script_flags: --ycsb-throughput-analysis reports
|
||||
@@ -293,13 +251,8 @@ tasks:
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "ycsb"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
- func: "deploy cluster"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "ycsb"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
vars:
|
||||
script_flags: --ycsb-throughput-analysis reports
|
||||
@@ -318,6 +271,11 @@ modules:
|
||||
branch: master
|
||||
|
||||
|
||||
|
||||
#######################################
|
||||
# Linux Buildvariants #
|
||||
#######################################
|
||||
|
||||
buildvariants:
|
||||
- name: linux-wt-shard
|
||||
display_name: Linux WT Shard
|
||||
|
||||
10
etc/perf.yml
10
etc/perf.yml
@@ -76,7 +76,7 @@ functions:
|
||||
set -v
|
||||
chmod +x mongod
|
||||
chmod +x mongo
|
||||
git clone https://github.com/mongodb/mongo-perf perf
|
||||
git clone git@github.com:mongodb/mongo-perf.git perf
|
||||
cd perf
|
||||
git describe --tags
|
||||
- command: shell.exec
|
||||
@@ -152,7 +152,7 @@ functions:
|
||||
# appropriate flags if it's `true`.
|
||||
reports_analysis_flags="--reports-analysis . --perf-file perf/perf.json"
|
||||
cmd_flags=$([ "${reports_analysis}" = "true" ] && echo "$reports_analysis_flags" || echo "")
|
||||
REFTAG="3.0.15-Baseline"
|
||||
REFTAG="3.2.19-Baseline"
|
||||
OVERRIDE="../dsi/analysis/${branch_name}/perf_override.json"
|
||||
python ../dsi/analysis/perf_regression_check.py $cmd_flags -f history.json --rev ${revision} -t tags.json --refTag $REFTAG --overrideFile $OVERRIDE --variant ${build_variant} --task ${task_name} --threshold 0.10 --threadThreshold 0.15
|
||||
"run perf tests":
|
||||
@@ -166,6 +166,7 @@ functions:
|
||||
source ./venv/bin/activate
|
||||
pip install argparse
|
||||
- command: shell.exec
|
||||
type : test
|
||||
params:
|
||||
working_dir: src
|
||||
script: |
|
||||
@@ -357,7 +358,10 @@ buildvariants:
|
||||
modules:
|
||||
- enterprise
|
||||
expansions:
|
||||
compile_flags: &compile_flags -j$(grep -c ^processor /proc/cpuinfo) CC=/opt/mongodbtoolchain/bin/gcc CXX=/opt/mongodbtoolchain/bin/g++ --release --ssl
|
||||
# We are explicitly tracking the rhel62 variant compile options from evergreen.yml for
|
||||
# microbenchmarks, since they run on the centos6 boxes. If we can get proper artifacts directly
|
||||
# from that project, we should do that and remove the compile tasks.
|
||||
compile_flags: &compile_flags --ssl MONGO_DISTMOD=rhel62 -j$(grep -c ^processor /proc/cpuinfo) --release --variables-files=etc/scons/mongodbtoolchain_gcc.vars
|
||||
mongod_exec_wrapper: &exec_wrapper "numactl --physcpubind=4,5,6,7 -i 1"
|
||||
perf_exec_wrapper: &perf_wrapper "numactl --physcpubind=1,2,3 -i 0"
|
||||
mongod_flags: "--storageEngine=inMemory --logpath ./mongod.log --fork --syncdelay 0 --setParameter ttlMonitorEnabled=false --setParameter diagnosticDataCollectionEnabled=false --inMemoryEngineConfigString 'eviction=(threads_min=1),' --inMemorySizeGB 60 --auth"
|
||||
|
||||
@@ -10,23 +10,23 @@ post:
|
||||
working_dir: work
|
||||
script: |
|
||||
source ./dsienv.sh
|
||||
$DSI_PATH/bin/make_artifact.sh
|
||||
make_artifact.sh
|
||||
- command: s3.put
|
||||
params:
|
||||
aws_key: ${aws_key}
|
||||
aws_secret: ${aws_secret}
|
||||
local_file: work/reports.tgz
|
||||
remote_file: ${project}/${build_variant}/${revision}/${task_id}/${version_id}/logs/${task_name}-${build_id}-${execution}.${ext|tgz}
|
||||
local_file: work/dsi-artifacts.tgz
|
||||
remote_file: ${project_dir}/${build_variant}/${revision}/${task_id}/${version_id}/logs/dsi-artifacts-${task_name}-${build_id}-${execution}.${ext|tgz}
|
||||
bucket: mciuploads
|
||||
permissions: public-read
|
||||
content_type: ${content_type|application/x-gzip}
|
||||
display_name: test-log - Execution ${execution}
|
||||
display_name: Dsi Artifacts - Execution ${execution}
|
||||
- command: s3.put
|
||||
params:
|
||||
aws_key: ${aws_key}
|
||||
aws_secret: ${aws_secret}
|
||||
local_file: src/workloads/workloads/jsdoc/jsdocs-redirect.html
|
||||
remote_file: ${project}/${build_variant}/${revision}/${task_id}/${version_id}/logs/workloads-${task_name}-${build_id}.html
|
||||
remote_file: ${project_dir}/${build_variant}/${revision}/${task_id}/${version_id}/logs/workloads-${task_name}-${build_id}.html
|
||||
bucket: mciuploads
|
||||
permissions: public-read
|
||||
content_type: text/html
|
||||
@@ -34,13 +34,17 @@ post:
|
||||
- command: attach.results
|
||||
params:
|
||||
file_location: work/report.json
|
||||
- command: "json.send"
|
||||
params:
|
||||
name: "perf"
|
||||
file: "work/perf.json"
|
||||
- command: shell.exec
|
||||
params:
|
||||
working_dir: work
|
||||
script: |
|
||||
source ./dsienv.sh
|
||||
if [ -e /data/infrastructure_provisioning/terraform/provisioned.${cluster} ]; then
|
||||
$DSI_PATH/bin/mark_idle.sh
|
||||
mark_idle.sh
|
||||
fi
|
||||
|
||||
- command: shell.exec
|
||||
@@ -57,6 +61,44 @@ post:
|
||||
- command: shell.cleanup
|
||||
|
||||
functions:
|
||||
"compile mongodb":
|
||||
- command: shell.exec
|
||||
params:
|
||||
working_dir: src
|
||||
script: |
|
||||
set -o errexit
|
||||
set -o verbose
|
||||
${scons|scons} ${compile_flags|} mongo mongod mongos
|
||||
mkdir -p mongodb/bin
|
||||
mv mongo mongodb/bin
|
||||
mv mongod mongodb/bin
|
||||
mv mongos mongodb/bin
|
||||
tar czf mongodb${wtdevelop|}.tar.gz mongodb
|
||||
- command: s3.put
|
||||
params:
|
||||
aws_key: ${aws_key}
|
||||
aws_secret: ${aws_secret}
|
||||
local_file: src/mongodb${wtdevelop|}.tar.gz
|
||||
remote_file: ${project_dir}/${version_id}/${revision}/${platform}/mongodb${wtdevelop|}-${version_id}.tar.gz
|
||||
bucket: mciuploads
|
||||
permissions: public-read
|
||||
content_type: ${content_type|application/x-gzip}
|
||||
display_name: mongodb${wtdevelop|}.tar.gz
|
||||
|
||||
# NOTE: Unlike evergreen.yml, there's no conditional here. If called, this is never a noop!
|
||||
"use WiredTiger develop" :
|
||||
command: shell.exec
|
||||
params:
|
||||
working_dir: src
|
||||
script: |
|
||||
set -o errexit
|
||||
set -o verbose
|
||||
cd src/third_party
|
||||
for wtdir in api dist examples ext lang src test tools ; do
|
||||
rm -rf wiredtiger/$wtdir
|
||||
mv wtdevelop/$wtdir wiredtiger/
|
||||
done
|
||||
|
||||
"prepare environment":
|
||||
- command: shell.exec
|
||||
params:
|
||||
@@ -76,12 +118,15 @@ functions:
|
||||
working_dir: work
|
||||
script: |
|
||||
cat > bootstrap.yml <<EOF
|
||||
cluster_type: ${cluster}
|
||||
infrastructure_provisioning: ${cluster}
|
||||
platform: ${platform}
|
||||
setup: ${setup}
|
||||
mongodb_setup: ${setup}
|
||||
storageEngine: ${storageEngine}
|
||||
test: ${test}
|
||||
test_control: ${test}
|
||||
production: true
|
||||
mongodb_binary_archive: "https://s3.amazonaws.com/mciuploads/${project_dir}/${version_id}/${revision}/${platform}/mongodb${wtdevelop|}-${version_id}.tar.gz"
|
||||
workloads_dir: ../src/workloads/workloads
|
||||
ycsb_dir: ../src/YCSB/YCSB
|
||||
EOF
|
||||
|
||||
cat > runtime.yml <<EOF
|
||||
@@ -96,6 +141,7 @@ functions:
|
||||
workdir: ${workdir}
|
||||
revision: ${revision}
|
||||
project: ${project}
|
||||
project_dir: ${project_dir}
|
||||
branch_name: ${branch_name}
|
||||
|
||||
# sys-perf expansions
|
||||
@@ -104,10 +150,8 @@ functions:
|
||||
script_flags : ${script_flags}
|
||||
dsi_rev: ${dsi_rev}
|
||||
workloads_rev: ${workloads_rev}
|
||||
|
||||
# compositions of expansions
|
||||
mongodb_binary_archive: "https://s3.amazonaws.com/mciuploads/${project}/${version_id}/${revision}/${platform}/mongod-${version_id}.tar.gz"
|
||||
EOF
|
||||
|
||||
- command: shell.exec
|
||||
params:
|
||||
silent: true
|
||||
@@ -124,6 +168,8 @@ functions:
|
||||
aws_secret_key: "${terraform_secret}"
|
||||
perf_jira_user: "${perf_jira_user}"
|
||||
perf_jira_pw: "${perf_jira_pw}"
|
||||
dsi_analysis_atlas_user: "${dsi_analysis_atlas_user}"
|
||||
dsi_analysis_atlas_pw: "${dsi_analysis_atlas_pw}"
|
||||
EOF
|
||||
chmod 400 runtime_secret.yml
|
||||
- command: shell.exec
|
||||
@@ -133,107 +179,59 @@ functions:
|
||||
# configure environment, has private information, no logging
|
||||
script: |
|
||||
set -e
|
||||
virtualenv ./venv
|
||||
source ./venv/bin/activate
|
||||
pip install -r ../src/dsi/dsi/requirements.txt
|
||||
python ../src/dsi/dsi/bin/bootstrap.py --production
|
||||
ls
|
||||
pwd
|
||||
../src/dsi/dsi/run-dsi python ../src/dsi/dsi/bin/bootstrap.py
|
||||
- command: shell.exec
|
||||
params:
|
||||
script: |
|
||||
set -v
|
||||
set -e
|
||||
source work/dsienv.sh
|
||||
$DSI_PATH/bin/setup-dsi-env.sh
|
||||
setup-dsi-env.sh
|
||||
ls -a work
|
||||
|
||||
"infrastructure provisioning":
|
||||
"deploy cluster":
|
||||
- command: shell.exec
|
||||
# call infrastructure-provisioning.py. This will either create a cluster, or update tags on existing instances.
|
||||
params:
|
||||
working_dir: work
|
||||
script: |
|
||||
set -e
|
||||
set -v
|
||||
source ./dsienv.sh
|
||||
source ./venv/bin/activate
|
||||
$DSI_PATH/bin/infrastructure_provisioning.py
|
||||
|
||||
"configure mongodb cluster":
|
||||
- command: shell.exec
|
||||
# bring up the mongod
|
||||
params:
|
||||
working_dir: work
|
||||
script: |
|
||||
set -e
|
||||
set -o verbose
|
||||
source ./dsienv.sh
|
||||
source ./venv/bin/activate
|
||||
$DSI_PATH/bin/mongodb_setup.py && echo "${setup} MongoDB Cluster STARTED."
|
||||
../src/dsi/dsi/run-dsi infrastructure_provisioning.py
|
||||
../src/dsi/dsi/run-dsi workload_setup.py
|
||||
../src/dsi/dsi/run-dsi mongodb_setup.py
|
||||
|
||||
"run test":
|
||||
- command: shell.exec
|
||||
type: test
|
||||
params:
|
||||
working_dir: work
|
||||
script: |
|
||||
set -e
|
||||
set -v
|
||||
source ./dsienv.sh
|
||||
source ./venv/bin/activate
|
||||
echo "Run test for ${test}-${storageEngine} with setup ${setup}"
|
||||
$DSI_PATH/bin/run_test.py ${storageEngine} ${test} ${cluster}
|
||||
../src/dsi/dsi/run-dsi test_control.py
|
||||
- command: "json.send"
|
||||
params:
|
||||
name: "perf"
|
||||
file: "work/perf.json"
|
||||
|
||||
"make test log artifact":
|
||||
- command: shell.exec
|
||||
params:
|
||||
working_dir: work
|
||||
script: |
|
||||
source ./dsienv.sh
|
||||
$DSI_PATH/bin/make_artifact.sh
|
||||
|
||||
"analyze":
|
||||
- command: json.get_history
|
||||
params:
|
||||
task: ${task_name}
|
||||
file: "work/history.json"
|
||||
name: "perf"
|
||||
- command: json.get_history
|
||||
params:
|
||||
tags: true
|
||||
task: ${task_name}
|
||||
file: "work/tags.json"
|
||||
name: "perf"
|
||||
- command: shell.exec
|
||||
# generate dashboard data
|
||||
type : test
|
||||
params:
|
||||
working_dir: work
|
||||
silent: true
|
||||
script: |
|
||||
set -o errexit
|
||||
TAGS="3.2.17-Baseline"
|
||||
OVERRIDEFILE="../src/dsi/dsi/analysis/v3.2/system_perf_override.json"
|
||||
python -u ../src/dsi/dsi/analysis/dashboard_gen.py --rev ${revision} -f history.json -t tags.json --refTag $TAGS --overrideFile $OVERRIDEFILE --project_id sys-perf --variant ${build_variant} --task ${task_name} --jira-user ${perf_jira_user} --jira-password ${perf_jira_pw} || true
|
||||
- command: "json.send"
|
||||
params:
|
||||
name: "dashboard"
|
||||
file: "work/dashboard.json"
|
||||
../src/dsi/dsi/run-dsi detect-changes
|
||||
- command: shell.exec
|
||||
# post_run_check.py and override.json for DSI tests are part of dsi repo
|
||||
type : test
|
||||
params:
|
||||
working_dir: work
|
||||
script: |
|
||||
set -o errexit
|
||||
set -o verbose
|
||||
TAG="3.2.17-Baseline"
|
||||
TAG="3.2.21-Baseline"
|
||||
OVERRIDEFILE="../src/dsi/dsi/analysis/${branch_name}/system_perf_override.json"
|
||||
python -u ../src/dsi/dsi/analysis/post_run_check.py ${script_flags} --reports-analysis reports --perf-file reports/perf.json --rev ${revision} -f history.json -t tags.json --refTag $TAG --overrideFile $OVERRIDEFILE --project_id sys-perf --variant ${build_variant} --task ${task_name}
|
||||
python -u ../src/dsi/dsi/analysis/post_run_check.py ${script_flags} --reports-analysis reports --perf-file perf.json --rev ${revision} --refTag $TAG --overrideFile $OVERRIDEFILE --project_id sys-perf --variant ${build_variant} --task ${task_name}
|
||||
|
||||
#######################################
|
||||
# Tasks #
|
||||
@@ -245,323 +243,132 @@ tasks:
|
||||
- command: git.get_project
|
||||
params:
|
||||
directory: src
|
||||
- command: git.apply_patch
|
||||
params:
|
||||
directory: src
|
||||
- command: shell.exec
|
||||
params:
|
||||
working_dir: src
|
||||
script: |
|
||||
set -o errexit
|
||||
set -o verbose
|
||||
${scons|scons} ${compile_flags|} mongo mongod mongos
|
||||
mkdir -p mongodb/bin
|
||||
mv mongo mongodb/bin
|
||||
mv mongod mongodb/bin
|
||||
mv mongos mongodb/bin
|
||||
tar cvf mongodb.tar mongodb
|
||||
gzip mongodb.tar
|
||||
- command: s3.put
|
||||
params:
|
||||
aws_key: ${aws_key}
|
||||
aws_secret: ${aws_secret}
|
||||
local_file: src/mongodb.tar.gz
|
||||
remote_file: ${project}/${version_id}/${revision}/${platform}/mongod-${version_id}.tar.gz
|
||||
bucket: mciuploads
|
||||
permissions: public-read
|
||||
content_type: ${content_type|application/x-gzip}
|
||||
display_name: mongodb.tar.gz
|
||||
- func: "compile mongodb"
|
||||
|
||||
- name: industry_benchmarks_WT
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: linux-standalone
|
||||
- name: industry_benchmarks
|
||||
priority: 5
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "ycsb"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
- func: "deploy cluster"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "ycsb"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
vars:
|
||||
script_flags: --ycsb-throughput-analysis reports
|
||||
|
||||
- name: industry_benchmarks_MMAPv1
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: linux-standalone
|
||||
- name: industry_benchmarks_wmajority
|
||||
priority: 5
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "ycsb"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "ycsb-wmajority"
|
||||
- func: "deploy cluster"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "ycsb"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
vars:
|
||||
script_flags: --ycsb-throughput-analysis reports
|
||||
|
||||
- name: industry_benchmarks_wmajority_WT
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: linux-standalone
|
||||
- name: crud_workloads
|
||||
priority: 5
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "ycsb-wmajority"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "crud_workloads"
|
||||
- func: "deploy cluster"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "ycsb-wmajority"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
vars:
|
||||
script_flags: --ycsb-throughput-analysis reports
|
||||
|
||||
- name: industry_benchmarks_wmajority_MMAPv1
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: linux-standalone
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "ycsb-wmajority"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "ycsb-wmajority"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
vars:
|
||||
script_flags: --ycsb-throughput-analysis reports
|
||||
|
||||
- name: core_workloads_WT
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: linux-standalone
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "core"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "core"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
|
||||
- name: core_workloads_MMAPv1
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: linux-standalone
|
||||
- name: mixed_workloads
|
||||
priority: 5
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "core"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "mixed_workloads"
|
||||
- func: "deploy cluster"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "core"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
|
||||
- name: non_sharded_workloads_WT
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: linux-standalone
|
||||
- name: misc_workloads
|
||||
priority: 5
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
test: "misc_workloads"
|
||||
- func: "deploy cluster"
|
||||
- func: "run test"
|
||||
- func: "analyze"
|
||||
|
||||
- name: map_reduce_workloads
|
||||
priority: 5
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
test: "map_reduce_workloads"
|
||||
- func: "deploy cluster"
|
||||
- func: "run test"
|
||||
- func: "analyze"
|
||||
|
||||
- name: smoke_test
|
||||
priority: 5
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
test: "short"
|
||||
- func: "deploy cluster"
|
||||
- func: "run test"
|
||||
- func: "analyze"
|
||||
|
||||
- name: non_sharded_workloads
|
||||
priority: 5
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "non_sharded"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
- func: "deploy cluster"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "non_sharded"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
|
||||
- name: non_sharded_workloads_MMAPv1
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: linux-standalone
|
||||
- name: mongos_workloads
|
||||
priority: 5
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "non_sharded"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "non_sharded"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
|
||||
- name: mongos_workloads_WT
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: linux-standalone
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "mongos"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
- func: "deploy cluster"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "mongos"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
|
||||
- name: mongos_workloads_MMAPv1
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: linux-standalone
|
||||
exec_timeout_secs: 32400 # 9 hours
|
||||
- name: move_chunk_workloads
|
||||
priority: 5
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "mongos"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "mongos"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
|
||||
- name: move_chunk_workloads_WT
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: linux-standalone
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "move_chunk"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
- func: "deploy cluster"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "move_chunk"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
|
||||
- name: move_chunk_workloads_MMAPv1
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: linux-standalone
|
||||
- name: move_chunk_waiting_workloads
|
||||
priority: 5
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "move_chunk"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "move_chunk_waiting"
|
||||
- func: "deploy cluster"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "move_chunk"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
|
||||
- name: initialsync_WT
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: linux-standalone
|
||||
- name: initialsync
|
||||
priority: 5
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "initialSync"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "initialsync"
|
||||
- func: "deploy cluster"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "wiredTiger"
|
||||
test: "initialSync"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
|
||||
- name: initialsync_MMAPv1
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant : linux-standalone
|
||||
commands:
|
||||
- func: "prepare environment"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "initialSync"
|
||||
- func: "infrastructure provisioning"
|
||||
- func: "configure mongodb cluster"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
- func: "run test"
|
||||
vars:
|
||||
storageEngine: "mmapv1"
|
||||
test: "initialSync"
|
||||
- func: "make test log artifact"
|
||||
- func: "analyze"
|
||||
|
||||
|
||||
#######################################
|
||||
# Modules #
|
||||
#######################################
|
||||
@@ -579,11 +386,34 @@ modules:
|
||||
branch: master
|
||||
|
||||
|
||||
#######################################
|
||||
# Buildvariants #
|
||||
#######################################
|
||||
buildvariants:
|
||||
|
||||
# We are explicitly tracking the rhel70 variant compile options from evergreen.yml. If we can get
|
||||
# proper artifacts directly from that project, we should do that and remove these tasks.
|
||||
- name: compile-rhel70
|
||||
display_name: Compile on rhel70
|
||||
batchtime: 1440 # 24 hours
|
||||
modules:
|
||||
- wtdevelop
|
||||
expansions:
|
||||
compile_flags: --ssl MONGO_DISTMOD=rhel70 -j$(grep -c ^processor /proc/cpuinfo) --release --variables-files=etc/scons/mongodbtoolchain_gcc.vars
|
||||
gorootvars: GOROOT=/opt/go PATH="/opt/go/bin:$PATH"
|
||||
platform: linux
|
||||
project_dir: &project_dir dsi
|
||||
tooltags: ""
|
||||
use_scons_cache: true
|
||||
run_on:
|
||||
- "rhel70"
|
||||
tasks:
|
||||
- name: compile
|
||||
|
||||
|
||||
#######################################
|
||||
# Linux Buildvariants #
|
||||
#######################################
|
||||
|
||||
buildvariants:
|
||||
- name: linux-1-node-replSet
|
||||
display_name: Linux 1-Node ReplSet
|
||||
batchtime: 10080 # 7 days
|
||||
@@ -591,43 +421,49 @@ buildvariants:
|
||||
- dsi
|
||||
- workloads
|
||||
expansions:
|
||||
compile_flags: -j$(grep -c ^processor /proc/cpuinfo) CC=/opt/mongodbtoolchain/bin/gcc CXX=/opt/mongodbtoolchain/bin/g++ --release
|
||||
compile_flags: --ssl MONGO_DISTMOD=rhel70 -j$(grep -c ^processor /proc/cpuinfo) --release --variables-files=etc/scons/mongodbtoolchain_gcc.vars
|
||||
setup: single-replica
|
||||
cluster: single
|
||||
platform: linux
|
||||
project: &project dsi-v3.2
|
||||
project_dir: *project_dir
|
||||
storageEngine: wiredTiger
|
||||
run_on:
|
||||
- "rhel70-perf-single"
|
||||
tasks:
|
||||
- name: industry_benchmarks_WT
|
||||
- name: core_workloads_WT
|
||||
- name: industry_benchmarks_MMAPv1
|
||||
- name: core_workloads_MMAPv1
|
||||
- name: non_sharded_workloads_WT
|
||||
- name: non_sharded_workloads_MMAPv1
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: compile-rhel70
|
||||
tasks: &1nodetasks
|
||||
- name: industry_benchmarks
|
||||
- name: crud_workloads
|
||||
- name: mixed_workloads
|
||||
- name: misc_workloads
|
||||
- name: map_reduce_workloads
|
||||
- name: smoke_test
|
||||
- name: non_sharded_workloads
|
||||
|
||||
- name: linux-standalone
|
||||
display_name: Linux Standalone
|
||||
batchtime: 10080 # 7 days
|
||||
modules: *modules
|
||||
expansions:
|
||||
compile_flags: -j$(grep -c ^processor /proc/cpuinfo) CC=/opt/mongodbtoolchain/bin/gcc CXX=/opt/mongodbtoolchain/bin/g++ --release
|
||||
setup: standalone
|
||||
cluster: single
|
||||
platform: linux
|
||||
project: *project
|
||||
project_dir: *project_dir
|
||||
storageEngine: wiredTiger
|
||||
run_on:
|
||||
- "rhel70-perf-single"
|
||||
tasks:
|
||||
- name: compile
|
||||
distros:
|
||||
- rhel70
|
||||
- name: industry_benchmarks_WT
|
||||
- name: core_workloads_WT
|
||||
- name: industry_benchmarks_MMAPv1
|
||||
- name: core_workloads_MMAPv1
|
||||
- name: non_sharded_workloads_WT
|
||||
- name: non_sharded_workloads_MMAPv1
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: compile-rhel70
|
||||
tasks: &standalonetasks
|
||||
- name: industry_benchmarks
|
||||
- name: crud_workloads
|
||||
- name: mixed_workloads
|
||||
- name: misc_workloads
|
||||
- name: map_reduce_workloads
|
||||
- name: smoke_test
|
||||
- name: non_sharded_workloads
|
||||
|
||||
- name: linux-3-shard
|
||||
display_name: Linux 3-Shard Cluster
|
||||
@@ -638,20 +474,23 @@ buildvariants:
|
||||
setup: shard
|
||||
cluster: shard
|
||||
platform: linux
|
||||
project: *project
|
||||
project_dir: *project_dir
|
||||
storageEngine: wiredTiger
|
||||
run_on:
|
||||
- "rhel70-perf-shard"
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: compile-rhel70
|
||||
tasks:
|
||||
- name: industry_benchmarks_WT
|
||||
- name: core_workloads_WT
|
||||
- name: industry_benchmarks_MMAPv1
|
||||
- name: industry_benchmarks_wmajority_WT
|
||||
- name: industry_benchmarks_wmajority_MMAPv1
|
||||
- name: core_workloads_MMAPv1
|
||||
- name: mongos_workloads_WT
|
||||
- name: mongos_workloads_MMAPv1
|
||||
- name: move_chunk_workloads_WT
|
||||
- name: move_chunk_workloads_MMAPv1
|
||||
- name: industry_benchmarks
|
||||
- name: crud_workloads
|
||||
- name: mixed_workloads
|
||||
- name: misc_workloads
|
||||
- name: map_reduce_workloads
|
||||
- name: smoke_test
|
||||
- name: industry_benchmarks_wmajority
|
||||
- name: mongos_workloads
|
||||
- name: move_chunk_workloads
|
||||
|
||||
- name: linux-3-node-replSet
|
||||
display_name: Linux 3-Node ReplSet
|
||||
@@ -662,18 +501,22 @@ buildvariants:
|
||||
setup: replica
|
||||
cluster: replica
|
||||
platform: linux
|
||||
project: *project
|
||||
project_dir: *project_dir
|
||||
storageEngine: wiredTiger
|
||||
run_on:
|
||||
- "rhel70-perf-replset"
|
||||
tasks:
|
||||
- name: industry_benchmarks_WT
|
||||
- name: core_workloads_WT
|
||||
- name: industry_benchmarks_MMAPv1
|
||||
- name: industry_benchmarks_wmajority_WT
|
||||
- name: industry_benchmarks_wmajority_MMAPv1
|
||||
- name: core_workloads_MMAPv1
|
||||
- name: non_sharded_workloads_WT
|
||||
- name: non_sharded_workloads_MMAPv1
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: compile-rhel70
|
||||
tasks: &3nodetasks
|
||||
- name: industry_benchmarks
|
||||
- name: crud_workloads
|
||||
- name: mixed_workloads
|
||||
- name: misc_workloads
|
||||
- name: map_reduce_workloads
|
||||
- name: smoke_test
|
||||
- name: industry_benchmarks_wmajority
|
||||
- name: non_sharded_workloads
|
||||
|
||||
- name: linux-3-node-replSet-initialsync
|
||||
display_name: Linux 3-Node ReplSet Initial Sync
|
||||
@@ -684,10 +527,132 @@ buildvariants:
|
||||
setup: replica-2node
|
||||
cluster: replica
|
||||
platform: linux
|
||||
project: *project
|
||||
project_dir: *project_dir
|
||||
storageEngine: wiredTiger
|
||||
run_on:
|
||||
- "rhel70-perf-replset"
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: compile-rhel70
|
||||
tasks:
|
||||
- name: initialsync_WT
|
||||
- name: initialsync_MMAPv1
|
||||
- name: initialsync
|
||||
|
||||
#######################################
|
||||
# MMAP Buildvariants #
|
||||
#######################################
|
||||
- name: mmap-1-node-replSet
|
||||
display_name: MMAP 1-Node ReplSet
|
||||
batchtime: 10080 # 7 days
|
||||
modules: *modules
|
||||
expansions:
|
||||
setup: single-replica
|
||||
cluster: single
|
||||
platform: linux
|
||||
storageEngine: "mmapv1"
|
||||
project_dir: *project_dir
|
||||
run_on:
|
||||
- "rhel70-perf-single"
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: compile-rhel70
|
||||
tasks:
|
||||
- name: smoke_test
|
||||
- name: industry_benchmarks
|
||||
- name: crud_workloads
|
||||
- name: mixed_workloads
|
||||
- name: misc_workloads
|
||||
- name: map_reduce_workloads
|
||||
- name: non_sharded_workloads
|
||||
|
||||
- name: mmap-standalone
|
||||
display_name: MMAP Standalone
|
||||
batchtime: 10080 # 7 days
|
||||
modules: *modules
|
||||
expansions:
|
||||
setup: standalone
|
||||
cluster: single
|
||||
platform: linux
|
||||
storageEngine: "mmapv1"
|
||||
project_dir: *project_dir
|
||||
run_on:
|
||||
- "rhel70-perf-single"
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: compile-rhel70
|
||||
tasks:
|
||||
- name: smoke_test
|
||||
- name: industry_benchmarks
|
||||
- name: crud_workloads
|
||||
- name: mixed_workloads
|
||||
- name: misc_workloads
|
||||
- name: map_reduce_workloads
|
||||
- name: non_sharded_workloads
|
||||
|
||||
- name: mmap-3-shard
|
||||
display_name: MMAP 3-Shard Cluster
|
||||
batchtime: 10080 # 7 days
|
||||
modules: *modules
|
||||
expansions:
|
||||
setup: shard
|
||||
cluster: shard
|
||||
platform: linux
|
||||
storageEngine: "mmapv1"
|
||||
project_dir: *project_dir
|
||||
run_on:
|
||||
- "rhel70-perf-shard"
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: compile-rhel70
|
||||
tasks:
|
||||
- name: smoke_test
|
||||
- name: industry_benchmarks
|
||||
- name: industry_benchmarks_wmajority
|
||||
- name: crud_workloads
|
||||
- name: mixed_workloads
|
||||
- name: misc_workloads
|
||||
- name: map_reduce_workloads
|
||||
- name: mongos_workloads
|
||||
- name: move_chunk_workloads
|
||||
|
||||
- name: mmap-3-node-replSet
|
||||
display_name: MMAP 3-Node ReplSet
|
||||
batchtime: 10080 # 7 days
|
||||
modules: *modules
|
||||
expansions:
|
||||
setup: replica
|
||||
cluster: replica
|
||||
platform: linux
|
||||
storageEngine: "mmapv1"
|
||||
project_dir: *project_dir
|
||||
run_on:
|
||||
- "rhel70-perf-replset"
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: compile-rhel70
|
||||
tasks:
|
||||
- name: smoke_test
|
||||
- name: industry_benchmarks
|
||||
- name: industry_benchmarks_wmajority
|
||||
- name: crud_workloads
|
||||
- name: mixed_workloads
|
||||
- name: misc_workloads
|
||||
- name: map_reduce_workloads
|
||||
- name: non_sharded_workloads
|
||||
|
||||
- name: mmap-3-node-replSet-initialsync
|
||||
display_name: MMAP 3-Node ReplSet Initial Sync
|
||||
batchtime: 10080 # 7 days
|
||||
modules: *modules
|
||||
expansions:
|
||||
setup: replica-2node
|
||||
cluster: replica
|
||||
platform: linux
|
||||
storageEngine: "mmapv1"
|
||||
project_dir: *project_dir
|
||||
run_on:
|
||||
- "rhel70-perf-replset"
|
||||
depends_on:
|
||||
- name: compile
|
||||
variant: compile-rhel70
|
||||
tasks:
|
||||
- name: initialsync
|
||||
|
||||
44
jstests/auth/scram-credentials-invalid.js
Normal file
44
jstests/auth/scram-credentials-invalid.js
Normal file
@@ -0,0 +1,44 @@
|
||||
// Ensure that attempting to use SCRAM-SHA-1 auth on a
|
||||
// user with invalid SCRAM-SHA-1 credentials fails gracefully.
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
function runTest(mongod) {
|
||||
assert(mongod);
|
||||
const admin = mongod.getDB('admin');
|
||||
const test = mongod.getDB('test');
|
||||
|
||||
admin.createUser({user: 'admin', pwd: 'pass', roles: jsTest.adminUserRoles});
|
||||
assert(admin.auth('admin', 'pass'));
|
||||
|
||||
test.createUser({user: 'user', pwd: 'pass', roles: jsTest.basicUserRoles});
|
||||
|
||||
// Give the test user an invalid set of SCRAM-SHA-1 credentials.
|
||||
assert.eq(admin.system.users.update({_id: "test.user"},
|
||||
{
|
||||
$set: {
|
||||
"credentials.SCRAM-SHA-1": {
|
||||
salt: "AAAA",
|
||||
storedKey: "AAAA",
|
||||
serverKey: "AAAA",
|
||||
iterationCount: 10000
|
||||
}
|
||||
}
|
||||
}).nModified,
|
||||
1,
|
||||
"Should have updated one document for user@test");
|
||||
admin.logout();
|
||||
|
||||
assert(!test.auth({user: 'user', pwd: 'pass'}));
|
||||
|
||||
assert.soon(function() {
|
||||
const log = cat(mongod.fullOptions.logFile);
|
||||
return /Unable to perform SCRAM-SHA-1 auth.* invalid SCRAM credentials/.test(log);
|
||||
}, "No warning issued for invalid SCRAM-SHA-1 credendials doc", 30 * 1000, 5 * 1000);
|
||||
}
|
||||
|
||||
const mongod = MongoRunner.runMongod({auth: "", useLogFiles: true});
|
||||
runTest(mongod);
|
||||
MongoRunner.stopMongod(mongod);
|
||||
})();
|
||||
@@ -48,6 +48,7 @@ var blacklist = [
|
||||
'convert_to_capped_collection_index.js', // convertToCapped can't be run on mongos processes
|
||||
'findAndModify_remove_queue.js', // remove cannot be {} for findAndModify
|
||||
'findAndModify_update_collscan.js', // findAndModify requires a shard key
|
||||
'findAndModify_update_grow.js', // can cause OOM kills on test hosts
|
||||
'findAndModify_update_queue.js', // findAndModify requires a shard key
|
||||
'group.js', // the group command cannot be issued against a sharded cluster
|
||||
'group_cond.js', // the group command cannot be issued against a sharded cluster
|
||||
|
||||
@@ -279,6 +279,16 @@
|
||||
db.adminCommand({applyOps: [{"op": "i", "ns": t.getFullName(), "o": {_id: 5, x: 17}}]}),
|
||||
"Applying an insert operation on a non-existent collection should fail");
|
||||
|
||||
assert.commandFailed(
|
||||
db.adminCommand({
|
||||
applyOps: [{
|
||||
"op": "c",
|
||||
"ns": "admin.$cmd",
|
||||
"o": {applyOps: [{"op": "i", "ns": t.getFullName(), "o": {_id: 5, x: 17}}]}
|
||||
}]
|
||||
}),
|
||||
"Applying a nested insert operation on a non-existent collection should fail");
|
||||
|
||||
assert.commandWorked(db.createCollection(t.getName()));
|
||||
var a = assert.commandWorked(
|
||||
db.adminCommand({applyOps: [{"op": "i", "ns": t.getFullName(), "o": {_id: 5, x: 17}}]}));
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// @tags: [assumes_write_concern_unchanged]
|
||||
|
||||
//
|
||||
// Ensures that mongod respects the batch write protocols for delete
|
||||
//
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// @tags: [assumes_write_concern_unchanged]
|
||||
|
||||
//
|
||||
// Ensures that mongod respects the batch write protocol for inserts
|
||||
//
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// @tags: [assumes_write_concern_unchanged]
|
||||
|
||||
//
|
||||
// Ensures that mongod respects the batch write protocols for updates
|
||||
//
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Test the bypassDocumentValidation flag with some database commands. The test uses relevant shell
|
||||
// helpers when they're available for the respective server commands.
|
||||
//
|
||||
// @tags: [requires_collmod_command]
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
// Test NamespaceDetails::cappedTruncateAfter via "captrunc" command
|
||||
//
|
||||
// @tags: [
|
||||
// # This test attempts to perform read operations on a capped collection after truncating
|
||||
// # documents using the captrunc command. The writes from the captrunc command aren't guaranteed
|
||||
// # to become visible until a later w="majority" write occurs.
|
||||
// assumes_write_concern_unchanged,
|
||||
// ]
|
||||
(function() {
|
||||
var coll = db.capped6;
|
||||
|
||||
|
||||
@@ -5,9 +5,9 @@ var coll = db.collection_info_cache_race;
|
||||
coll.drop();
|
||||
assert.commandWorked(db.createCollection(coll.getName(), {autoIndexId: false}));
|
||||
// Fails when SERVER-16502 was not fixed, due to invariant
|
||||
assert.writeOK(coll.save({_id: false}, {writeConcern: {w: 1}}));
|
||||
assert.writeOK(coll.save({_id: false}));
|
||||
|
||||
coll.drop();
|
||||
assert.commandWorked(db.createCollection(coll.getName(), {autoIndexId: false}));
|
||||
assert.eq(null, coll.findOne());
|
||||
assert.writeOK(coll.save({_id: false}, {writeConcern: {w: 1}}));
|
||||
assert.writeOK(coll.save({_id: false}));
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Basic js tests for the collMod command.
|
||||
// Test setting the usePowerOf2Sizes flag, and modifying TTL indexes.
|
||||
//
|
||||
// @tags: [requires_collmod_command]
|
||||
|
||||
function debug(x) {
|
||||
// printjson( x );
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
//
|
||||
// Tests that a collMod with a bad specification does not cause any changes, and does not crash the
|
||||
// server.
|
||||
//
|
||||
// @tags: [requires_collmod_command]
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// SERVER-16676 Make sure compact doesn't leave the collection with bad indexes
|
||||
// SERVER-16967 Make sure compact doesn't crash while collections are being dropped
|
||||
// in a different database.
|
||||
//
|
||||
// @tags: [requires_parallel_shell]
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Tests to see what validity checks are done for 10gen specific object construction
|
||||
//
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
// Takes a list of constructors and returns a new list with an extra entry for each constructor with
|
||||
// "new" prepended
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
// Test that interrupting a count returns an error code.
|
||||
//
|
||||
// @tags: [
|
||||
// # This test attempts to perform a count command and find it using the currentOp command. The
|
||||
// # former operation may be routed to a secondary in the replica set, whereas the latter must be
|
||||
// # routed to the primary.
|
||||
// assumes_read_preference_unchanged,
|
||||
// ]
|
||||
|
||||
t = db.count10;
|
||||
t.drop();
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
// Test that the plan summary string appears in db.currentOp() for
|
||||
// count operations. SERVER-14064.
|
||||
// Test that the plan summary string appears in db.currentOp() for count operations. SERVER-14064.
|
||||
//
|
||||
// @tags: [
|
||||
// # This test attempts to perform a find command and find it using the currentOp command. The
|
||||
// # former operation may be routed to a secondary in the replica set, whereas the latter must be
|
||||
// # routed to the primary.
|
||||
// assumes_read_preference_unchanged,
|
||||
// ]
|
||||
|
||||
var t = db.jstests_count_plan_summary;
|
||||
t.drop();
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// @tags: [assumes_write_concern_unchanged]
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/**
|
||||
* Tests that long-running operations show up in currentOp and report the locks they are holding.
|
||||
*
|
||||
* @tags: [requires_parallel_shell]
|
||||
*/
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @tags: [requires_parallel_shell]
|
||||
t = db.cursora;
|
||||
|
||||
function run(n, atomic) {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Yield and delete test case for query optimizer cursor. SERVER-4401
|
||||
//
|
||||
// @tags: [requires_parallel_shell]
|
||||
|
||||
t = db.jstests_distinct3;
|
||||
t.drop();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Test basic inserts and updates with document validation.
|
||||
//
|
||||
// @tags: [requires_collmod_command]
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Verify invalid validator statements won't work and that we
|
||||
// can't create validated collections on restricted databases.
|
||||
//
|
||||
// @tags: [requires_collmod_command]
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @tags: [requires_collmod_command]
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// test dropping a db with simultaneous commits
|
||||
//
|
||||
// @tags: [assumes_write_concern_unchanged]
|
||||
|
||||
m = db.getMongo();
|
||||
baseName = "jstests_dur_droprace";
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Test that client gets stack trace on failed invoke
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
f = db.jstests_error2;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
|
||||
// @tags: [requires_eval_command]
|
||||
assert.eq(17,
|
||||
db.eval(function() {
|
||||
return 11 + 6;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
t = db.eval1;
|
||||
t.drop();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
t = db.eval3;
|
||||
t.drop();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
t = db.eval4;
|
||||
t.drop();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
t = db.eval5;
|
||||
t.drop();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
t = db.eval6;
|
||||
t.drop();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
assert.eq(6, db.eval("5 + 1"), "A");
|
||||
assert.throws(function(z) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
a = [1, "asd", null, [2, 3], new Date(), {x: 1}];
|
||||
|
||||
@@ -20,4 +21,4 @@ try {
|
||||
db.eval("return db");
|
||||
db.eval("return print");
|
||||
} catch (ex) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Test that the eval command can't be used to invoke the mapReduce command. SERVER-17889.
|
||||
//
|
||||
// @tags: [requires_eval_command]
|
||||
(function() {
|
||||
"use strict";
|
||||
db.eval_mr.drop();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
t = db.eval_nolock;
|
||||
t.drop();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
t = db.evala;
|
||||
t.drop();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Check the return value of a db.eval function running a database query, and ensure the function's
|
||||
// contents are logged in the profile log.
|
||||
//
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
// Use a reserved database name to avoid a conflict in the parallel test suite.
|
||||
var stddb = db;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
t = db.jstests_evalc;
|
||||
t.drop();
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
t = db.jstests_evald;
|
||||
t.drop();
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
t = db.jstests_evale;
|
||||
t.drop();
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// SERVER-17499: Test behavior of getMore on aggregation cursor under eval command.
|
||||
//
|
||||
// @tags: [requires_eval_command]
|
||||
db.evalg.drop();
|
||||
for (var i = 0; i < 102; ++i) {
|
||||
db.evalg.insert({});
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
/**
|
||||
* Test that db.eval does not support auth.
|
||||
*
|
||||
* @tags: [requires_eval_command]
|
||||
*/
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
/** SERVER-2451 Kill cursor while explain is yielding */
|
||||
/**
|
||||
* SERVER-2451 Kill cursor while explain is yielding
|
||||
*
|
||||
* @tags: [requires_parallel_shell]
|
||||
*/
|
||||
|
||||
t = db.jstests_explain3;
|
||||
t.drop();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Ensures that find and modify will not apply an update to a document which, due to a concurrent
|
||||
// modification, no longer matches the query predicate.
|
||||
//
|
||||
// @tags: [requires_parallel_shell]
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
* - Confirm that writes can progress after fsyncUnlock
|
||||
* - Confirm that the command can be run repeatedly without breaking things
|
||||
* - Confirm that the pseudo commands and eval can perform fsyncLock/Unlock
|
||||
*
|
||||
* @tags: [requires_eval_command]
|
||||
*/
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
// Test various cursor behaviors
|
||||
//
|
||||
// @tags: [
|
||||
// # This test attempts to enable profiling on a server and then get profiling data by reading
|
||||
// # from the "system.profile" collection. The former operation must be routed to the primary in
|
||||
// # a replica set, whereas the latter may be routed to a secondary.
|
||||
// assumes_read_preference_unchanged,
|
||||
// ]
|
||||
var t = db.geo_s2getmmm;
|
||||
t.drop();
|
||||
t.ensureIndex({geo: "2dsphere"});
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Tests whether the geospatial search is stable under btree updates
|
||||
//
|
||||
// @tags: [assumes_write_concern_unchanged]
|
||||
|
||||
var coll = db.getCollection("jstests_geo_update_btree");
|
||||
coll.drop();
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
// tests getlog as well as slow querying logging
|
||||
//
|
||||
// @tags: [
|
||||
// # This test attempts to perform a find command and see that it ran using the getLog command.
|
||||
// # The former operation may be routed to a secondary in the replica set, whereas the latter must
|
||||
// # be routed to the primary.
|
||||
// assumes_read_preference_unchanged,
|
||||
// ]
|
||||
|
||||
glcol = db.getLogTest2;
|
||||
glcol.drop();
|
||||
|
||||
@@ -6,20 +6,24 @@
|
||||
* Displays index filters for all query shapes in a collection.
|
||||
*
|
||||
* - planCacheClearFilters
|
||||
* Clears index filter for a single query shape or,
|
||||
* if the query shape is omitted, all filters for the collection.
|
||||
* Clears index filter for a single query shape or, if the query shape is omitted, all filters for
|
||||
* the collection.
|
||||
*
|
||||
* - planCacheSetFilter
|
||||
* Sets index filter for a query shape. Overrides existing filter.
|
||||
*
|
||||
* Not a lot of data access in this test suite. Hint commands
|
||||
* manage a non-persistent mapping in the server of
|
||||
* query shape to list of index specs.
|
||||
* Not a lot of data access in this test suite. Hint commands manage a non-persistent mapping in the
|
||||
* server of query shape to list of index specs.
|
||||
*
|
||||
* Only time we might need to execute a query is to check the plan
|
||||
* cache state. We would do this with the planCacheListPlans command
|
||||
* on the same query shape with the index filters.
|
||||
* Only time we might need to execute a query is to check the plan cache state. We would do this
|
||||
* with the planCacheListPlans command on the same query shape with the index filters.
|
||||
*
|
||||
* @tags: [
|
||||
* # This test attempts to perform queries with plan cache filters set up. The former operation
|
||||
* # may be routed to a secondary in the replica set, whereas the latter must be routed to the
|
||||
* # primary.
|
||||
* assumes_read_preference_unchanged,
|
||||
* ]
|
||||
*/
|
||||
|
||||
var t = db.jstests_index_filter_commands;
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
// @tags: [
|
||||
// # This test attempts to perform write operations and get index usage statistics using the
|
||||
// # $indexStats stage. The former operation must be routed to the primary in a replica set,
|
||||
// # whereas the latter may be routed to a secondary.
|
||||
// assumes_read_preference_unchanged,
|
||||
// ]
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
t = db.jstests_js3;
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
t = db.jstests_js7;
|
||||
t.drop();
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
c = db.jstests_js9;
|
||||
c.drop();
|
||||
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
* terminate until the server determines that they've spent too much time in JS execution, typically
|
||||
* after 30 seconds of wall clock time have passed. For these operations to take a long time, the
|
||||
* counted collection must not be empty; hence an initial write to the collection is required.
|
||||
*
|
||||
* @tags: [requires_parallel_shell]
|
||||
*/
|
||||
|
||||
t = db.jstests_killop;
|
||||
@@ -73,4 +75,4 @@ jsTestLog("Waiting for ops to terminate");
|
||||
// don't want to pass if timeout killed the js function.
|
||||
var end = new Date();
|
||||
var diff = end - start;
|
||||
assert.lt(diff, 30000, "Start: " + start + "; end: " + end + "; diff: " + diff);
|
||||
assert.lt(diff, 30000, "Start: " + start + "; end: " + end + "; diff: " + diff);
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* to complete. Interrupting a collection drop could leave the database in an inconsistent state.
|
||||
* This test confirms that killOp won't interrupt a collection drop, and that the drop occurs
|
||||
* successfully.
|
||||
*
|
||||
* @tags: [requires_parallel_shell]
|
||||
*/
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// SERVER-27996/SERVER-28022 Missing invalidation for system.namespaces writes
|
||||
//
|
||||
// @tags: [requires_collmod_command]
|
||||
(function() {
|
||||
'use strict';
|
||||
var dbInvalidName = 'system_namespaces_invalidations';
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
|
||||
// Test db.loadServerScripts()
|
||||
//
|
||||
// @tags: [requires_parallel_shell]
|
||||
|
||||
var testdb = db.getSisterDB("loadserverscripts");
|
||||
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
// Tests query/command option $maxTimeMS.
|
||||
//
|
||||
// @tags: [
|
||||
// # This test attempts to perform read operations after having enabled the maxTimeAlwaysTimeOut
|
||||
// # failpoint. The former operations may be routed to a secondary in the replica set, whereas the
|
||||
// # latter must be routed to the primary.
|
||||
// assumes_read_preference_unchanged,
|
||||
// requires_collmod_command,
|
||||
// ]
|
||||
|
||||
var t = db.max_time_ms;
|
||||
var exceededTimeLimit = 50; // ErrorCodes::ExceededTimeLimit
|
||||
|
||||
@@ -1,97 +1,142 @@
|
||||
// test min / max query parameters
|
||||
// Test min / max query parameters.
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
addData = function() {
|
||||
t.save({a: 1, b: 1});
|
||||
t.save({a: 1, b: 2});
|
||||
t.save({a: 2, b: 1});
|
||||
t.save({a: 2, b: 2});
|
||||
};
|
||||
load("jstests/aggregation/extras/utils.js"); // For resultsEq.
|
||||
|
||||
t = db.jstests_minmax;
|
||||
t.drop();
|
||||
t.ensureIndex({a: 1, b: 1});
|
||||
addData();
|
||||
const coll = db.jstests_minmax;
|
||||
coll.drop();
|
||||
|
||||
printjson(t.find().min({a: 1, b: 2}).max({a: 2, b: 1}).toArray());
|
||||
assert.eq(1, t.find().min({a: 1, b: 2}).max({a: 2, b: 1}).toArray().length);
|
||||
assert.eq(2, t.find().min({a: 1, b: 2}).max({a: 2, b: 1.5}).toArray().length);
|
||||
assert.eq(2, t.find().min({a: 1, b: 2}).max({a: 2, b: 2}).toArray().length);
|
||||
function addData() {
|
||||
assert.writeOK(coll.save({a: 1, b: 1}));
|
||||
assert.writeOK(coll.save({a: 1, b: 2}));
|
||||
assert.writeOK(coll.save({a: 2, b: 1}));
|
||||
assert.writeOK(coll.save({a: 2, b: 2}));
|
||||
}
|
||||
|
||||
// just one bound
|
||||
assert.eq(3, t.find().min({a: 1, b: 2}).toArray().length);
|
||||
assert.eq(3, t.find().max({a: 2, b: 1.5}).toArray().length);
|
||||
assert.eq(3, t.find().min({a: 1, b: 2}).hint({a: 1, b: 1}).toArray().length);
|
||||
assert.eq(3, t.find().max({a: 2, b: 1.5}).hint({a: 1, b: 1}).toArray().length);
|
||||
assert.commandWorked(coll.ensureIndex({a: 1, b: 1}));
|
||||
addData();
|
||||
|
||||
t.drop();
|
||||
t.ensureIndex({a: 1, b: -1});
|
||||
addData();
|
||||
assert.eq(4, t.find().min({a: 1, b: 2}).toArray().length);
|
||||
assert.eq(4, t.find().max({a: 2, b: 0.5}).toArray().length);
|
||||
assert.eq(1, t.find().min({a: 2, b: 1}).toArray().length);
|
||||
assert.eq(1, t.find().max({a: 1, b: 1.5}).toArray().length);
|
||||
assert.eq(4, t.find().min({a: 1, b: 2}).hint({a: 1, b: -1}).toArray().length);
|
||||
assert.eq(4, t.find().max({a: 2, b: 0.5}).hint({a: 1, b: -1}).toArray().length);
|
||||
assert.eq(1, t.find().min({a: 2, b: 1}).hint({a: 1, b: -1}).toArray().length);
|
||||
assert.eq(1, t.find().max({a: 1, b: 1.5}).hint({a: 1, b: -1}).toArray().length);
|
||||
assert.eq(1, coll.find().min({a: 1, b: 2}).max({a: 2, b: 1}).toArray().length);
|
||||
assert.eq(2, coll.find().min({a: 1, b: 2}).max({a: 2, b: 1.5}).toArray().length);
|
||||
assert.eq(2, coll.find().min({a: 1, b: 2}).max({a: 2, b: 2}).toArray().length);
|
||||
|
||||
// hint doesn't match
|
||||
assert.throws(function() {
|
||||
t.find().min({a: 1}).hint({a: 1, b: -1}).toArray();
|
||||
});
|
||||
assert.throws(function() {
|
||||
t.find().min({a: 1, b: 1}).max({a: 1}).hint({a: 1, b: -1}).toArray();
|
||||
});
|
||||
assert.throws(function() {
|
||||
t.find().min({b: 1}).max({a: 1, b: 2}).hint({a: 1, b: -1}).toArray();
|
||||
});
|
||||
assert.throws(function() {
|
||||
t.find().min({a: 1}).hint({$natural: 1}).toArray();
|
||||
});
|
||||
assert.throws(function() {
|
||||
t.find().max({a: 1}).hint({$natural: 1}).toArray();
|
||||
});
|
||||
// Single bound.
|
||||
assert.eq(3, coll.find().min({a: 1, b: 2}).toArray().length);
|
||||
assert.eq(3, coll.find().max({a: 2, b: 1.5}).toArray().length);
|
||||
assert.eq(3, coll.find().min({a: 1, b: 2}).hint({a: 1, b: 1}).toArray().length);
|
||||
assert.eq(3, coll.find().max({a: 2, b: 1.5}).hint({a: 1, b: 1}).toArray().length);
|
||||
|
||||
// Reverse direction scan of the a:1 index between a:6 (inclusive) and a:3 (exclusive).
|
||||
t.drop();
|
||||
t.ensureIndex({a: 1});
|
||||
for (i = 0; i < 10; ++i) {
|
||||
t.save({_id: i, a: i});
|
||||
}
|
||||
if (0) { // SERVER-3766
|
||||
reverseResult = t.find().min({a: 6}).max({a: 3}).sort({a: -1}).hint({a: 1}).toArray();
|
||||
assert.eq([{_id: 6, a: 6}, {_id: 5, a: 5}, {_id: 4, a: 4}], reverseResult);
|
||||
}
|
||||
coll.drop();
|
||||
assert.commandWorked(coll.ensureIndex({a: 1, b: -1}));
|
||||
addData();
|
||||
assert.eq(4, coll.find().min({a: 1, b: 2}).toArray().length);
|
||||
assert.eq(4, coll.find().max({a: 2, b: 0.5}).toArray().length);
|
||||
assert.eq(1, coll.find().min({a: 2, b: 1}).toArray().length);
|
||||
assert.eq(1, coll.find().max({a: 1, b: 1.5}).toArray().length);
|
||||
assert.eq(4, coll.find().min({a: 1, b: 2}).hint({a: 1, b: -1}).toArray().length);
|
||||
assert.eq(4, coll.find().max({a: 2, b: 0.5}).hint({a: 1, b: -1}).toArray().length);
|
||||
assert.eq(1, coll.find().min({a: 2, b: 1}).hint({a: 1, b: -1}).toArray().length);
|
||||
assert.eq(1, coll.find().max({a: 1, b: 1.5}).hint({a: 1, b: -1}).toArray().length);
|
||||
|
||||
//
|
||||
// SERVER-15015.
|
||||
//
|
||||
// Hint doesn't match.
|
||||
assert.throws(function() {
|
||||
coll.find().min({a: 1}).hint({a: 1, b: -1}).toArray();
|
||||
});
|
||||
assert.throws(function() {
|
||||
coll.find().min({a: 1, b: 1}).max({a: 1}).hint({a: 1, b: -1}).toArray();
|
||||
});
|
||||
assert.throws(function() {
|
||||
coll.find().min({b: 1}).max({a: 1, b: 2}).hint({a: 1, b: -1}).toArray();
|
||||
});
|
||||
assert.throws(function() {
|
||||
coll.find().min({a: 1}).hint({$natural: 1}).toArray();
|
||||
});
|
||||
assert.throws(function() {
|
||||
coll.find().max({a: 1}).hint({$natural: 1}).toArray();
|
||||
});
|
||||
|
||||
// Test ascending index.
|
||||
t.drop();
|
||||
t.ensureIndex({a: 1});
|
||||
t.insert({a: 3});
|
||||
t.insert({a: 4});
|
||||
t.insert({a: 5});
|
||||
coll.drop();
|
||||
assert.commandWorked(coll.ensureIndex({a: 1}));
|
||||
for (var i = 0; i < 10; ++i) {
|
||||
assert.writeOK(coll.save({_id: i, a: i}));
|
||||
}
|
||||
|
||||
var cursor = t.find().min({a: 4});
|
||||
assert.eq(4, cursor.next()["a"]);
|
||||
assert.eq(5, cursor.next()["a"]);
|
||||
assert(!cursor.hasNext());
|
||||
// Reverse direction scan of the a:1 index between a:6 (inclusive) and a:3 (exclusive) is
|
||||
// expected to fail, as max must be > min.
|
||||
var error = assert.throws(function() {
|
||||
coll.find().min({a: 6}).max({a: 3}).sort({a: -1}).toArray();
|
||||
});
|
||||
assert.eq(error.code, ErrorCodes.BadValue);
|
||||
|
||||
cursor = t.find().max({a: 4});
|
||||
assert.eq(3, cursor.next()["a"]);
|
||||
assert(!cursor.hasNext());
|
||||
error = assert.throws(function() {
|
||||
coll.find().min({a: 6}).max({a: 3}).sort({a: -1}).hint({a: 1}).toArray();
|
||||
});
|
||||
assert.eq(error.code, ErrorCodes.BadValue);
|
||||
|
||||
// Test descending index.
|
||||
t.dropIndexes();
|
||||
t.ensureIndex({a: -1});
|
||||
// A find with identical min and max values is expected to fail, as max is exclusive.
|
||||
error = assert.throws(function() {
|
||||
coll.find().min({a: 2}).max({a: 2}).toArray();
|
||||
});
|
||||
assert.eq(error.code, ErrorCodes.BadValue);
|
||||
|
||||
cursor = t.find().min({a: 4});
|
||||
assert.eq(4, cursor.next()["a"]);
|
||||
assert.eq(3, cursor.next()["a"]);
|
||||
assert(!cursor.hasNext());
|
||||
error = assert.throws(function() {
|
||||
coll.find().min({a: 2}).max({a: 2}).hint({a: 1}).toArray();
|
||||
});
|
||||
assert.eq(error.code, ErrorCodes.BadValue);
|
||||
|
||||
cursor = t.find().max({a: 4});
|
||||
assert.eq(5, cursor.next()["a"]);
|
||||
assert(!cursor.hasNext());
|
||||
error = assert.throws(function() {
|
||||
coll.find().min({a: 2}).max({a: 2}).sort({a: -1}).toArray();
|
||||
});
|
||||
assert.eq(error.code, ErrorCodes.BadValue);
|
||||
|
||||
error = assert.throws(function() {
|
||||
coll.find().min({a: 2}).max({a: 2}).sort({a: -1}).hint({a: 1}).toArray();
|
||||
});
|
||||
assert.eq(error.code, ErrorCodes.BadValue);
|
||||
|
||||
coll.drop();
|
||||
addData();
|
||||
assert.commandWorked(coll.ensureIndex({a: 1, b: 1}));
|
||||
|
||||
error = assert.throws(function() {
|
||||
coll.find().min({a: 1, b: 2}).max({a: 1, b: 2}).toArray();
|
||||
});
|
||||
assert.eq(error.code, ErrorCodes.BadValue);
|
||||
|
||||
error = assert.throws(function() {
|
||||
coll.find().min({a: 1, b: 2}).max({a: 1, b: 2}).hint({a: 1, b: 1}).toArray();
|
||||
});
|
||||
assert.eq(error.code, ErrorCodes.BadValue);
|
||||
|
||||
// Test ascending index.
|
||||
coll.drop();
|
||||
assert.commandWorked(coll.ensureIndex({a: 1}));
|
||||
assert.writeOK(coll.insert({a: 3}));
|
||||
assert.writeOK(coll.insert({a: 4}));
|
||||
assert.writeOK(coll.insert({a: 5}));
|
||||
|
||||
var cursor = coll.find().min({a: 4});
|
||||
assert.eq(4, cursor.next().a);
|
||||
assert.eq(5, cursor.next().a);
|
||||
|
||||
assert(!cursor.hasNext());
|
||||
|
||||
cursor = coll.find().max({a: 4});
|
||||
assert.eq(3, cursor.next()["a"]);
|
||||
assert(!cursor.hasNext());
|
||||
|
||||
// Test descending index.
|
||||
assert.commandWorked(coll.dropIndexes());
|
||||
assert.commandWorked(coll.ensureIndex({a: -1}));
|
||||
|
||||
cursor = coll.find().min({a: 4});
|
||||
assert.eq(4, cursor.next().a);
|
||||
assert.eq(3, cursor.next().a);
|
||||
|
||||
assert(!cursor.hasNext());
|
||||
|
||||
cursor = coll.find().max({a: 4});
|
||||
assert.eq(5, cursor.next()["a"]);
|
||||
assert(!cursor.hasNext());
|
||||
}());
|
||||
|
||||
@@ -79,8 +79,6 @@ verifyMax({a: {a: 1}}, [0, 1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
verifyMin({a: 'a'}, []);
|
||||
verifyMax({a: 'a'}, [0, 1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
|
||||
verifyResultIds(t.find().min({a: 4}).max({a: 4}).toArray(), []);
|
||||
|
||||
// Now with a compound index.
|
||||
reset(t);
|
||||
assert.commandWorked(t.ensureIndex({a: 1, b: -1}));
|
||||
@@ -101,8 +99,6 @@ verifyMax({a: {a: 1}, b: 1}, [0, 1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
verifyMin({a: 'a', b: 1}, []);
|
||||
verifyMax({a: 'a', b: 1}, [0, 1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
|
||||
verifyResultIds(t.find().min({a: 4, b: 1}).max({a: 4, b: 1}).toArray(), []);
|
||||
|
||||
// Edge cases on b values
|
||||
verifyMin({a: 1, b: Infinity}, [0, 1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
verifyMin({a: 2, b: Infinity}, [3, 4, 5, 6, 7, 8]);
|
||||
@@ -146,8 +142,6 @@ verifyMax({a: {a: 1}}, []);
|
||||
verifyMin({a: 'a'}, [0, 1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
verifyMax({a: 'a'}, []);
|
||||
|
||||
verifyResultIds(t.find().min({a: 4}).max({a: 4}).toArray(), []);
|
||||
|
||||
// Now with a compound index.
|
||||
reset(t);
|
||||
t.ensureIndex({a: -1, b: -1});
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Test killop applied to m/r operations and child ops of m/r operations.
|
||||
//
|
||||
// @tags: [requires_parallel_shell]
|
||||
|
||||
t = db.jstests_mr_killop;
|
||||
t.drop();
|
||||
|
||||
@@ -3,8 +3,17 @@
|
||||
t = db.mr_optim;
|
||||
t.drop();
|
||||
|
||||
// We drop the output collection to ensure the test can be run multiple times successfully. We
|
||||
// explicitly avoid using the DBCollection#drop() shell helper to avoid implicitly sharding the
|
||||
// collection during the sharded_collections_jscore_passthrough.yml test suite when reading the
|
||||
// results from the output collection in the reformat() function.
|
||||
var res = db.runCommand({drop: "mr_optim_out"});
|
||||
if (res.ok !== 1) {
|
||||
assert.commandFailedWithCode(res, ErrorCodes.NamespaceNotFound);
|
||||
}
|
||||
|
||||
for (var i = 0; i < 1000; ++i) {
|
||||
t.save({a: Math.random(1000), b: Math.random(10000)});
|
||||
assert.writeOK(t.save({a: Math.random(1000), b: Math.random(10000)}));
|
||||
}
|
||||
|
||||
function m() {
|
||||
@@ -21,7 +30,7 @@ function reformat(r) {
|
||||
if (r.results)
|
||||
cursor = r.results;
|
||||
else
|
||||
cursor = r.find();
|
||||
cursor = r.find().sort({_id: 1});
|
||||
cursor.forEach(function(z) {
|
||||
x[z._id] = z.value;
|
||||
});
|
||||
@@ -43,4 +52,4 @@ res.drop();
|
||||
|
||||
assert.eq(x, x2, "object from inline and collection are not equal");
|
||||
|
||||
t.drop();
|
||||
t.drop();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// checks that operations do not create a database
|
||||
//
|
||||
// @tags: [requires_collmod_command]
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
@@ -32,4 +34,4 @@
|
||||
noDB(mydb);
|
||||
assert.writeOK(coll.insert({}));
|
||||
mydb.dropDatabase();
|
||||
}());
|
||||
}());
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
// check notablescan mode
|
||||
//
|
||||
// @tags: [
|
||||
// # This test attempts to perform read operations after having enabled the notablescan server
|
||||
// # parameter. The former operations may be routed to a secondary in the replica set, whereas the
|
||||
// # latter must be routed to the primary.
|
||||
// assumes_read_preference_unchanged,
|
||||
// ]
|
||||
|
||||
t = db.test_notablescan;
|
||||
t.drop();
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
// Test clearing of the plan cache, either manually through the planCacheClear command,
|
||||
// or due to system events such as an index build.
|
||||
//
|
||||
// @tags: [
|
||||
// # This test attempts to perform queries and introspect/manipulate the server's plan cache
|
||||
// # entries. The former operation may be routed to a secondary in the replica set, whereas the
|
||||
// # latter must be routed to the primary.
|
||||
// assumes_read_preference_unchanged,
|
||||
// ]
|
||||
|
||||
var t = db.jstests_plan_cache_clear;
|
||||
t.drop();
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
// Test the planCacheListPlans command.
|
||||
//
|
||||
// @tags: [
|
||||
// # This test attempts to perform queries and introspect the server's plan cache entries. The
|
||||
// # former operation may be routed to a secondary in the replica set, whereas the latter must be
|
||||
// # routed to the primary.
|
||||
// assumes_read_preference_unchanged,
|
||||
// ]
|
||||
|
||||
var t = db.jstests_plan_cache_list_plans;
|
||||
t.drop();
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
// Test the planCacheListQueryShapes command, which returns a list of query shapes
|
||||
// for the queries currently cached in the collection.
|
||||
//
|
||||
// @tags: [
|
||||
// # This test attempts to perform queries with plan cache filters set up. The former operation
|
||||
// # may be routed to a secondary in the replica set, whereas the latter must be routed to the
|
||||
// # primary.
|
||||
// assumes_read_preference_unchanged,
|
||||
// ]
|
||||
|
||||
var t = db.jstests_plan_cache_list_shapes;
|
||||
t.drop();
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
// Test the shell helpers which wrap the plan cache commands.
|
||||
//
|
||||
// @tags: [
|
||||
// # This test attempts to perform queries and introspect the server's plan cache entries. The
|
||||
// # former operation may be routed to a secondary in the replica set, whereas the latter must be
|
||||
// # routed to the primary.
|
||||
// assumes_read_preference_unchanged,
|
||||
// ]
|
||||
|
||||
var t = db.jstests_plan_cache_shell_helpers;
|
||||
t.drop();
|
||||
|
||||
@@ -24,7 +24,7 @@ assert(result.hasOwnProperty('millis'));
|
||||
assert(result.hasOwnProperty('query'));
|
||||
assert.eq('string', typeof(result.query));
|
||||
// String value is truncated.
|
||||
assert(result.query.match(/filter: { a: "a+\.\.\." } }$/));
|
||||
assert(result.query.match(/filter: { a: "a+\.\.\." }/));
|
||||
|
||||
assert.commandWorked(coll.getDB().runCommand({profile: 0}));
|
||||
coll.getDB().system.profile.drop();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
// Check cases where index scans are aborted due to the collection being dropped. SERVER-4400
|
||||
//
|
||||
// @tags: [requires_parallel_shell]
|
||||
|
||||
t = db.jstests_queryoptimizer3;
|
||||
t.drop();
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// Basic tests for a form of stack recursion that's been shown to cause C++
|
||||
// side stack overflows in the past. See SERVER-19614.
|
||||
// Basic tests for a form of stack recursion that's been shown to cause C++ side stack overflows in
|
||||
// the past. See SERVER-19614.
|
||||
//
|
||||
// @tags: [requires_eval_command]
|
||||
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user