From 80e431f11a401f78651dd4f8f34326b2e5109557 Mon Sep 17 00:00:00 2001 From: jjrodrig Date: Thu, 1 Feb 2018 19:31:29 +0100 Subject: Fix for issue #1136 - Error 500 deleting DB without quorum Complete deletion tests with not found --- src/fabric/src/fabric_db_delete.erl | 6 ++--- test/javascript/run | 8 +++--- .../tests-cluster/with-quorum/db-deletion.js | 30 ++++++++++++++++++++++ .../tests-cluster/without-quorum/db-deletion.js | 30 ++++++++++++++++++++++ .../tests-cluster/without-quorum/db_creation.js | 3 +-- 5 files changed, 68 insertions(+), 9 deletions(-) create mode 100644 test/javascript/tests-cluster/with-quorum/db-deletion.js create mode 100644 test/javascript/tests-cluster/without-quorum/db-deletion.js diff --git a/src/fabric/src/fabric_db_delete.erl b/src/fabric/src/fabric_db_delete.erl index 9ba55fbb8..a1b51088b 100644 --- a/src/fabric/src/fabric_db_delete.erl +++ b/src/fabric/src/fabric_db_delete.erl @@ -81,10 +81,10 @@ maybe_stop(W, Counters) -> {#shard{dbname=Name}, _} = hd(Counters), couch_log:warning("~p not_found ~s", [?MODULE, Name]), {stop, not_found}; - {W, _, _} -> - {stop, ok}; {N, M, _} when N >= (W div 2 + 1), M > 0 -> - {stop, accepted}; + {stop, ok}; + {_, M, _} when M > 0 -> + {stop,accepted}; _ -> {error, internal_server_error} end diff --git a/test/javascript/run b/test/javascript/run index 8ae424467..ca69e1ff2 100755 --- a/test/javascript/run +++ b/test/javascript/run @@ -134,10 +134,11 @@ def main(): tmp.append(name) tests = tmp - fmt = mkformatter(tests) passed = 0 failed = 0 - for test in tests: + if len(tests) > 0 : + fmt = mkformatter(tests) + for test in tests: result = run_couchjs(test, fmt) if result == 0: passed += 1 @@ -169,8 +170,7 @@ def build_test_case_paths(path,args=None): elif os.path.isfile(pname + ".js"): tests.append(pname + ".js") else: - sys.stderr.write("Unknown test: " + name + os.linesep) - exit(1) + sys.stderr.write("Waring - Unknown test: " + name + os.linesep) return tests diff --git a/test/javascript/tests-cluster/with-quorum/db-deletion.js b/test/javascript/tests-cluster/with-quorum/db-deletion.js new file mode 100644 index 000000000..f561e3a0c --- /dev/null +++ b/test/javascript/tests-cluster/with-quorum/db-deletion.js @@ -0,0 +1,30 @@ +// 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 deletion under cluster with quorum conditions. +couchTests.db_deletion = function(debug) { + + if (debug) debugger; + + var db_name = get_random_db_name() + var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}); + + db.createDb(); + + // DB Deletion should return 200 - Ok + xhr = CouchDB.request("DELETE", "/" + db_name + "/"); + T(xhr.status == 200); + +// DB Deletion should return 404 - Not found + xhr = CouchDB.request("DELETE", "/not-existing-db/"); + T(xhr.status == 404); +}; diff --git a/test/javascript/tests-cluster/without-quorum/db-deletion.js b/test/javascript/tests-cluster/without-quorum/db-deletion.js new file mode 100644 index 000000000..006345e30 --- /dev/null +++ b/test/javascript/tests-cluster/without-quorum/db-deletion.js @@ -0,0 +1,30 @@ +// 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_deletion = function(debug) { + + if (debug) debugger; + + var db_name = get_random_db_name() + var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}); + + db.createDb(); + + // DB Deletion should return 202 - Acepted + xhr = CouchDB.request("DELETE", "/" + db_name + "/"); + T(xhr.status == 202); + + // DB Deletion should return 404 - Not found + xhr = CouchDB.request("DELETE", "/not-existing-db/"); + T(xhr.status == 404); +}; diff --git a/test/javascript/tests-cluster/without-quorum/db_creation.js b/test/javascript/tests-cluster/without-quorum/db_creation.js index 0d8ff8367..a21d37746 100644 --- a/test/javascript/tests-cluster/without-quorum/db_creation.js +++ b/test/javascript/tests-cluster/without-quorum/db_creation.js @@ -23,6 +23,5 @@ couchTests.db_creation = function(debug) { T(xhr.status == 202); // cleanup - // TODO DB deletions fails if the quorum is not met. - xhr = CouchDB.request("DELETE", "/" + db_name + "/"); + db.deleteDb(); }; -- cgit v1.2.1 From 177c22d0f541fdeb6e0f6457ab6ea9afa7bdea9a Mon Sep 17 00:00:00 2001 From: jjrodrig Date: Thu, 29 Mar 2018 23:34:42 +0200 Subject: Deletion responds 200 after a response from every node, and 202 in other case --- src/fabric/src/fabric_db_delete.erl | 4 ++-- test/javascript/tests-cluster/with-quorum/db-deletion.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/fabric/src/fabric_db_delete.erl b/src/fabric/src/fabric_db_delete.erl index a1b51088b..c146cb6cd 100644 --- a/src/fabric/src/fabric_db_delete.erl +++ b/src/fabric/src/fabric_db_delete.erl @@ -79,9 +79,9 @@ maybe_stop(W, Counters) -> case {Ok + NotFound, Ok, NotFound} of {W, 0, W} -> {#shard{dbname=Name}, _} = hd(Counters), - couch_log:warning("~p not_found ~s", [?MODULE, Name]), + couch_log:warning("~p not_found ~d", [?MODULE, Name]), {stop, not_found}; - {N, M, _} when N >= (W div 2 + 1), M > 0 -> + {W, _, _} -> {stop, ok}; {_, M, _} when M > 0 -> {stop,accepted}; diff --git a/test/javascript/tests-cluster/with-quorum/db-deletion.js b/test/javascript/tests-cluster/with-quorum/db-deletion.js index f561e3a0c..079fb493d 100644 --- a/test/javascript/tests-cluster/with-quorum/db-deletion.js +++ b/test/javascript/tests-cluster/with-quorum/db-deletion.js @@ -19,10 +19,10 @@ couchTests.db_deletion = function(debug) { var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}); db.createDb(); - - // DB Deletion should return 200 - Ok + + // DB Deletion should return 202 - Acceted as the custer is not complete xhr = CouchDB.request("DELETE", "/" + db_name + "/"); - T(xhr.status == 200); + T(xhr.status == 202); // DB Deletion should return 404 - Not found xhr = CouchDB.request("DELETE", "/not-existing-db/"); -- cgit v1.2.1 From 71cf9f4b53728bd5df5f5b5cc349187ca9da67bb Mon Sep 17 00:00:00 2001 From: jjrodrig Date: Mon, 9 Jul 2018 23:10:42 +0200 Subject: Adjust deletion tests in different cluster quorum conditions --- .../tests-cluster/with-quorum/db-deletion.js | 30 ---------------------- .../tests-cluster/with-quorum/db_deletion.js | 12 ++++++--- .../tests-cluster/without-quorum/db-deletion.js | 30 ---------------------- .../tests-cluster/without-quorum/db_deletion.js | 16 +++++++----- .../db_deletion_overridden_quorum.js | 8 ++---- 5 files changed, 20 insertions(+), 76 deletions(-) delete mode 100644 test/javascript/tests-cluster/with-quorum/db-deletion.js delete mode 100644 test/javascript/tests-cluster/without-quorum/db-deletion.js diff --git a/test/javascript/tests-cluster/with-quorum/db-deletion.js b/test/javascript/tests-cluster/with-quorum/db-deletion.js deleted file mode 100644 index 079fb493d..000000000 --- a/test/javascript/tests-cluster/with-quorum/db-deletion.js +++ /dev/null @@ -1,30 +0,0 @@ -// 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 deletion under cluster with quorum conditions. -couchTests.db_deletion = function(debug) { - - if (debug) debugger; - - var db_name = get_random_db_name() - var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}); - - db.createDb(); - - // DB Deletion should return 202 - Acceted as the custer is not complete - xhr = CouchDB.request("DELETE", "/" + db_name + "/"); - T(xhr.status == 202); - -// DB Deletion should return 404 - Not found - xhr = CouchDB.request("DELETE", "/not-existing-db/"); - T(xhr.status == 404); -}; diff --git a/test/javascript/tests-cluster/with-quorum/db_deletion.js b/test/javascript/tests-cluster/with-quorum/db_deletion.js index bef4cae43..079fb493d 100644 --- a/test/javascript/tests-cluster/with-quorum/db_deletion.js +++ b/test/javascript/tests-cluster/with-quorum/db_deletion.js @@ -10,15 +10,21 @@ // License for the specific language governing permissions and limitations under // the License. -// Do DB deletion in a cluster with quorum conditions. +// Do DB deletion under cluster with quorum conditions. couchTests.db_deletion = function(debug) { if (debug) debugger; var db_name = get_random_db_name() var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}); + db.createDb(); - db.deleteDb(); - T(db.last_req.status="200","Should return 200"); + // DB Deletion should return 202 - Acceted as the custer is not complete + xhr = CouchDB.request("DELETE", "/" + db_name + "/"); + T(xhr.status == 202); + +// DB Deletion should return 404 - Not found + xhr = CouchDB.request("DELETE", "/not-existing-db/"); + T(xhr.status == 404); }; diff --git a/test/javascript/tests-cluster/without-quorum/db-deletion.js b/test/javascript/tests-cluster/without-quorum/db-deletion.js deleted file mode 100644 index 006345e30..000000000 --- a/test/javascript/tests-cluster/without-quorum/db-deletion.js +++ /dev/null @@ -1,30 +0,0 @@ -// 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_deletion = function(debug) { - - if (debug) debugger; - - var db_name = get_random_db_name() - var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}); - - db.createDb(); - - // DB Deletion should return 202 - Acepted - xhr = CouchDB.request("DELETE", "/" + db_name + "/"); - T(xhr.status == 202); - - // DB Deletion should return 404 - Not found - xhr = CouchDB.request("DELETE", "/not-existing-db/"); - T(xhr.status == 404); -}; diff --git a/test/javascript/tests-cluster/without-quorum/db_deletion.js b/test/javascript/tests-cluster/without-quorum/db_deletion.js index 04b15c058..006345e30 100644 --- a/test/javascript/tests-cluster/without-quorum/db_deletion.js +++ b/test/javascript/tests-cluster/without-quorum/db_deletion.js @@ -10,19 +10,21 @@ // License for the specific language governing permissions and limitations under // the License. -// Do DB deletion in a cluster with quorum conditions. +// Do DB creation under cluster with quorum conditions. couchTests.db_deletion = function(debug) { if (debug) debugger; var db_name = get_random_db_name() var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}); - db.createDb(); - //db.deleteDb(); - // TODO DB deletions fails if the quorum is not met. + db.createDb(); + + // DB Deletion should return 202 - Acepted xhr = CouchDB.request("DELETE", "/" + db_name + "/"); - //T(db.last_req.status="202","Should return 202"); - console.log("Skipped-TODO: Fix issue 500 Error on delete. 202->"+xhr.status) - + T(xhr.status == 202); + + // DB Deletion should return 404 - Not found + xhr = CouchDB.request("DELETE", "/not-existing-db/"); + T(xhr.status == 404); }; diff --git a/test/javascript/tests-cluster/without-quorum/db_deletion_overridden_quorum.js b/test/javascript/tests-cluster/without-quorum/db_deletion_overridden_quorum.js index 4a1efce23..11b344cfb 100644 --- a/test/javascript/tests-cluster/without-quorum/db_deletion_overridden_quorum.js +++ b/test/javascript/tests-cluster/without-quorum/db_deletion_overridden_quorum.js @@ -19,11 +19,7 @@ couchTests.db_deletion_overridden_quorum = function(debug) { var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"},{"w":1}); db.createDb(); - - //db.deleteDb(); - // TODO DB deletions fails if the quorum is not met. + // DB deletions does not consider overriden quorum param. xhr = CouchDB.request("DELETE", "/" + db_name + "/"); - //T(db.last_req.status="200","Should return 200"); - console.log("Skipped-TODO: Fix issue 500 Error on delete - Not considering overriden quorum. 200->"+xhr.status); - + T(db.last_req.status="202","Should return 202"); }; -- cgit v1.2.1 From 45a0ad9e78bbd5596b58f369ddda44254555755b Mon Sep 17 00:00:00 2001 From: Jan Lehnardt Date: Sun, 8 Jul 2018 15:48:39 +0200 Subject: Add `conflicts: true` option to mango selectors This allows for using Mango queries for finding docs with conflicts. Closes #1101 --- src/mango/src/mango_cursor_view.erl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mango/src/mango_cursor_view.erl b/src/mango/src/mango_cursor_view.erl index 1e2108b7d..dbea36e77 100644 --- a/src/mango/src/mango_cursor_view.erl +++ b/src/mango/src/mango_cursor_view.erl @@ -70,7 +70,8 @@ explain(Cursor) -> {end_key, maybe_replace_max_json(Args#mrargs.end_key)}, {direction, Args#mrargs.direction}, {stable, Args#mrargs.stable}, - {update, Args#mrargs.update} + {update, Args#mrargs.update}, + {conflicts, Args#mrargs.conflicts} ]}}]. @@ -283,9 +284,8 @@ apply_opts([{r, RStr} | Rest], Args) -> NewArgs = Args#mrargs{include_docs = IncludeDocs}, apply_opts(Rest, NewArgs); apply_opts([{conflicts, true} | Rest], Args) -> - % I need to patch things so that views can specify - % parameters when loading the docs from disk - apply_opts(Rest, Args); + NewArgs = Args#mrargs{conflicts = true}, + apply_opts(Rest, NewArgs); apply_opts([{conflicts, false} | Rest], Args) -> % Ignored cause default apply_opts(Rest, Args); -- cgit v1.2.1 From 572234fb5026ae64ec7f6ed84728f2b1ef63d955 Mon Sep 17 00:00:00 2001 From: Jan Lehnardt Date: Fri, 13 Jul 2018 15:08:46 +0200 Subject: Add tests for mango conflict finding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I couldn’t find a cleaner way to add _bulk_docs with `new_edits: false`. --- src/mango/test/19-find-conflicts.py | 41 +++++++++++++++++++++++++++++++++++++ src/mango/test/mango.py | 5 +++++ 2 files changed, 46 insertions(+) create mode 100644 src/mango/test/19-find-conflicts.py diff --git a/src/mango/test/19-find-conflicts.py b/src/mango/test/19-find-conflicts.py new file mode 100644 index 000000000..c6d59f00d --- /dev/null +++ b/src/mango/test/19-find-conflicts.py @@ -0,0 +1,41 @@ +# 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. + +import mango +import copy + +DOC = [ + { + "_id": "doc", + "a": 2 + } +] + +CONFLICT = [ + { + "_id": "doc", + "_rev": "1-23202479633c2b380f79507a776743d5", + "a": 1 + } +] + +class ChooseCorrectIndexForDocs(mango.DbPerClass): + def setUp(self): + self.db.recreate() + self.db.save_docs(copy.deepcopy(DOC)) + self.db.save_docs_with_conflicts(copy.deepcopy(CONFLICT)) + + def test_retrieve_conflicts(self): + self.db.create_index(["_conflicts"]) + result = self.db.find({"_conflicts": { "$exists": True}}, conflicts=True) + self.assertEqual(result[0]['_conflicts'][0], '1-23202479633c2b380f79507a776743d5') + self.assertEqual(result[0]['_rev'], '1-3975759ccff3842adf690a5c10caee42') diff --git a/src/mango/test/mango.py b/src/mango/test/mango.py index 9b6b998cd..bc12bbc68 100644 --- a/src/mango/test/mango.py +++ b/src/mango/test/mango.py @@ -95,6 +95,11 @@ class Database(object): def save_doc(self, doc): self.save_docs([doc]) + def save_docs_with_conflicts(self, docs, **kwargs): + body = json.dumps({"docs": docs, "new_edits": False}) + r = self.sess.post(self.path("_bulk_docs"), data=body, params=kwargs) + r.raise_for_status() + def save_docs(self, docs, **kwargs): body = json.dumps({"docs": docs}) r = self.sess.post(self.path("_bulk_docs"), data=body, params=kwargs) -- cgit v1.2.1