You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@couchdb.apache.org by GitBox <gi...@apache.org> on 2018/01/31 13:10:54 UTC

[GitHub] janl closed pull request #1127: Fix for issue #603 - Error 500 when creating a db below quorum

janl closed pull request #1127: Fix for issue #603 - Error 500 when creating a db below quorum
URL: https://github.com/apache/couchdb/pull/1127
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/Makefile b/Makefile
index c8c0b093fb..8ccbf820c9 100644
--- a/Makefile
+++ b/Makefile
@@ -91,6 +91,8 @@ fauxton: share/www
 .PHONY: check
 # target: check - Test everything
 check: all
+	@$(MAKE) test-cluster-with-quorum
+	@$(MAKE) test-cluster-without-quorum
 	@$(MAKE) eunit
 	@$(MAKE) javascript
 	@$(MAKE) mango-test
@@ -129,6 +131,42 @@ endif
             'test/javascript/run --suites "$(suites)" \
             --ignore "$(ignore_js_suites)"'
 
+# TODO: port to Makefile.win
+.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'
+
+# TODO: port to Makefile.win
+.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
diff --git a/dev/run b/dev/run
index 4924de1f60..a5d8fde8cc 100755
--- a/dev/run
+++ b/dev/run
@@ -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 d793f4f13a..db914f90e7 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 c611be51ee..8ae4244675 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 0000000000..f8efd6e68c
--- /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 0000000000..0d8ff8367b
--- /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 + "/");
+};


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services