diff options
author | Juanjo <juanjo@localhost.localdomain> | 2018-01-24 15:01:40 +0100 |
---|---|---|
committer | Jan Lehnardt <jan@apache.org> | 2018-01-31 14:10:49 +0100 |
commit | 960a6f9dcca7ece74838e377b091050284a3233a (patch) | |
tree | 1d3781a86a224d55722c273f254a1484bb18a91d | |
parent | 884db891de6f7004f31a9a1a9d50b0162b1dca8e (diff) | |
download | couchdb-960a6f9dcca7ece74838e377b091050284a3233a.tar.gz |
Fix for issue #603 - Error 500 when creating a db below quorum
Add degrade-cluster option for cluster testing
Add tests for different cluster conditions with/without quorum
Add test-cluster-with-quorum and test-cluster-without-quorum tasks
-rw-r--r-- | Makefile | 34 | ||||
-rwxr-xr-x | dev/run | 24 | ||||
-rw-r--r-- | src/fabric/src/fabric_db_create.erl | 4 | ||||
-rwxr-xr-x | test/javascript/run | 16 | ||||
-rw-r--r-- | test/javascript/tests-cluster/with-quorum/db-creation.js | 27 | ||||
-rw-r--r-- | test/javascript/tests-cluster/without-quorum/db-creation.js | 28 |
6 files changed, 122 insertions, 11 deletions
@@ -129,6 +129,40 @@ endif 'test/javascript/run --suites "$(suites)" \ --ignore "$(ignore_js_suites)"' +.PHONY: test-cluster-with-quorum +test-cluster-with-quorum: + @mkdir -p share/www/script/test +ifeq ($(IN_RELEASE), true) + @cp test/javascript/tests/lorem*.txt share/www/script/test/ +else + @mkdir -p src/fauxton/dist/release/test + @cp test/javascript/tests/lorem*.txt src/fauxton/dist/release/test/ +endif + @rm -rf dev/lib + @dev/run -n 3 -q --with-admin-party-please \ + --enable-erlang-views --degrade-cluster 1 \ + -c 'startup_jitter=0' \ + 'test/javascript/run --suites "$(suites)" \ + --ignore "$(ignore_js_suites)" \ + --path test/javascript/tests-cluster/with-quorum' + +.PHONY: test-cluster-without-quorum +test-cluster-without-quorum: + @mkdir -p share/www/script/test +ifeq ($(IN_RELEASE), true) + @cp test/javascript/tests/lorem*.txt share/www/script/test/ +else + @mkdir -p src/fauxton/dist/release/test + @cp test/javascript/tests/lorem*.txt src/fauxton/dist/release/test/ +endif + @rm -rf dev/lib + @dev/run -n 3 -q --with-admin-party-please \ + --enable-erlang-views --degrade-cluster 2 \ + -c 'startup_jitter=0' \ + 'test/javascript/run --suites "$(suites)" \ + --ignore "$(ignore_js_suites)" \ + --path test/javascript/tests-cluster/without-quorum' + .PHONY: soak-javascript soak-javascript: @mkdir -p share/www/script/test @@ -130,6 +130,8 @@ def setup_argparse(): help='The node number to seed them when creating the node(s)') parser.add_option('-c', '--config-overrides', action="append", default=[], help='Optional key=val config overrides. Can be repeated') + parser.add_option('--degrade-cluster', dest="degrade_cluster",type=int, default=0, + help='The number of nodes that should be stopped after cluster config') return parser.parse_args() @@ -142,6 +144,7 @@ def setup_context(opts, args): 'admin': opts.admin.split(':', 1) if opts.admin else None, 'nodes': ['node%d' % (i + opts.node_number) for i in range(opts.nodes)], 'node_number': opts.node_number, + 'degrade_cluster': opts.degrade_cluster, 'devdir': os.path.dirname(fpath), 'rootdir': os.path.dirname(os.path.dirname(fpath)), 'cmd': ' '.join(args), @@ -337,18 +340,35 @@ def startup(ctx): cluster_setup_with_admin_party(ctx) else: cluster_setup(ctx) - + if ctx['degrade_cluster'] > 0: + degrade_cluster(ctx) def kill_processes(ctx): for proc in ctx['procs']: if proc and proc.returncode is None: proc.kill() +def degrade_cluster(ctx): + if ctx['with_haproxy']: + haproxy_proc = ctx['procs'].pop() + for i in range(0,ctx['degrade_cluster']): + proc = ctx['procs'].pop() + if proc is not None: + kill_process(proc) + if ctx['with_haproxy']: + ctx['procs'].append(haproxy_proc) + +@log('Stoping proc {proc.pid}') +def kill_process(proc): + if proc and proc.returncode is None: + proc.kill() def boot_nodes(ctx): for node in ctx['nodes']: ctx['procs'].append(boot_node(ctx, node)) - ctx['procs'].append(boot_haproxy(ctx)) + haproxy_proc = boot_haproxy(ctx) + if haproxy_proc is not None: + ctx['procs'].append(haproxy_proc) def ensure_all_nodes_alive(ctx): diff --git a/src/fabric/src/fabric_db_create.erl b/src/fabric/src/fabric_db_create.erl index d793f4f13..db914f90e 100644 --- a/src/fabric/src/fabric_db_create.erl +++ b/src/fabric/src/fabric_db_create.erl @@ -146,9 +146,9 @@ maybe_stop(W, Counters) -> {ok, {W, Counters}}; false -> case lists:sum([1 || {_, ok} <- Counters]) of - W -> + NumOk when NumOk >= (W div 2 +1) -> {stop, ok}; - NumOk when NumOk >= (W div 2 + 1) -> + NumOk when NumOk > 0 -> {stop, accepted}; _ -> {error, internal_server_error} diff --git a/test/javascript/run b/test/javascript/run index c611be51e..8ae424467 100755 --- a/test/javascript/run +++ b/test/javascript/run @@ -107,7 +107,10 @@ def options(): dest="ignore", help="Ignore test suites"), op.make_option("-u", "--suites", type="string", action="callback", default=None, callback=get_delimited_list, - dest="suites", help="Run specific suites") + dest="suites", help="Run specific suites"), + op.make_option("-p", "--path", type="string", + default="test/javascript/tests", + dest="test_path", help="Path where the tests are located") ] @@ -118,10 +121,9 @@ def main(): run_list = [] ignore_list = [] tests = [] - - run_list = ["test/javascript/tests"] if not opts.suites else opts.suites - run_list = build_test_case_paths(run_list) - ignore_list = build_test_case_paths(opts.ignore) + run_list = [opts.test_path] if not opts.suites else opts.suites + run_list = build_test_case_paths(opts.test_path,run_list) + ignore_list = build_test_case_paths(opts.test_path,opts.ignore) # sort is needed because certain tests fail if executed out of order tests = sorted(list(set(run_list)-set(ignore_list))) @@ -151,7 +153,7 @@ def main(): failed, passed) + os.linesep) exit(failed > 0) -def build_test_case_paths(args=None): +def build_test_case_paths(path,args=None): tests = [] if args is None: args = [] @@ -161,7 +163,7 @@ def build_test_case_paths(args=None): elif os.path.isfile(name): check = tests.append(name) else: - pname = os.path.join("test/javascript/tests", name) + pname = os.path.join(path, name) if os.path.isfile(pname): tests.append(pname) elif os.path.isfile(pname + ".js"): diff --git a/test/javascript/tests-cluster/with-quorum/db-creation.js b/test/javascript/tests-cluster/with-quorum/db-creation.js new file mode 100644 index 000000000..f8efd6e68 --- /dev/null +++ b/test/javascript/tests-cluster/with-quorum/db-creation.js @@ -0,0 +1,27 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +// Do DB creation under cluster with quorum conditions. +couchTests.db_creation = function(debug) { + + if (debug) debugger; + + var db_name = get_random_db_name() + var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}); + + // DB Creation should return 201 - Created + xhr = CouchDB.request("PUT", "/" + db_name + "/"); + T(xhr.status == 201); + + // cleanup + db.deleteDb(); +}; diff --git a/test/javascript/tests-cluster/without-quorum/db-creation.js b/test/javascript/tests-cluster/without-quorum/db-creation.js new file mode 100644 index 000000000..0d8ff8367 --- /dev/null +++ b/test/javascript/tests-cluster/without-quorum/db-creation.js @@ -0,0 +1,28 @@ +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +// Do DB creation under cluster without quorum conditions. +couchTests.db_creation = function(debug) { + + if (debug) debugger; + + var db_name = get_random_db_name() + var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}); + + // DB Creation should return 202- Accepted + xhr = CouchDB.request("PUT", "/" + db_name + "/"); + T(xhr.status == 202); + + // cleanup + // TODO DB deletions fails if the quorum is not met. + xhr = CouchDB.request("DELETE", "/" + db_name + "/"); +}; |