diff --git a/src/mango/test/08-text-limit-test.py b/src/mango/test/08-text-limit-test.py deleted file mode 100644 index ae827813d7..0000000000 --- a/src/mango/test/08-text-limit-test.py +++ /dev/null @@ -1,135 +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. - -import mango -import limit_docs -import unittest - - -@unittest.skipUnless(mango.has_text_service(), "requires text service") -class LimitTests(mango.LimitDocsTextTests): - def test_limit_field(self): - q = {"$or": [{"user_id": {"$lt": 10}}, {"filtered_array.[]": 1}]} - docs = self.db.find(q, limit=10) - assert len(docs) == 8 - for d in docs: - assert d["user_id"] < 10 - - def test_limit_field2(self): - q = {"$or": [{"user_id": {"$lt": 20}}, {"filtered_array.[]": 1}]} - docs = self.db.find(q, limit=10) - assert len(docs) == 10 - for d in docs: - assert d["user_id"] < 20 - - def test_limit_field3(self): - q = {"$or": [{"user_id": {"$lt": 100}}, {"filtered_array.[]": 1}]} - docs = self.db.find(q, limit=1) - assert len(docs) == 1 - for d in docs: - assert d["user_id"] < 100 - - def test_limit_field4(self): - q = {"$or": [{"user_id": {"$lt": 0}}, {"filtered_array.[]": 1}]} - docs = self.db.find(q, limit=35) - assert len(docs) == 0 - - # We reach our cap here of 50 - def test_limit_field5(self): - q = {"age": {"$exists": True}} - docs = self.db.find(q, limit=250) - assert len(docs) == 75 - for d in docs: - assert d["age"] < 100 - - def test_limit_skip_field1(self): - q = {"$or": [{"user_id": {"$lt": 100}}, {"filtered_array.[]": 1}]} - docs = self.db.find(q, limit=10, skip=20) - assert len(docs) == 10 - for d in docs: - assert d["user_id"] > 20 - - def test_limit_skip_field2(self): - q = {"$or": [{"user_id": {"$lt": 100}}, {"filtered_array.[]": 1}]} - docs = self.db.find(q, limit=100, skip=100) - assert len(docs) == 0 - - def test_limit_skip_field3(self): - q = {"$or": [{"user_id": {"$lt": 20}}, {"filtered_array.[]": 1}]} - docs = self.db.find(q, limit=1, skip=30) - assert len(docs) == 0 - - def test_limit_skip_field4(self): - q = {"$or": [{"user_id": {"$lt": 100}}, {"filtered_array.[]": 1}]} - docs = self.db.find(q, limit=0, skip=0) - assert len(docs) == 0 - - def test_limit_skip_field5(self): - q = {"$or": [{"user_id": {"$lt": 100}}, {"filtered_array.[]": 1}]} - try: - self.db.find(q, limit=-1) - except Exception as e: - assert e.response.status_code == 400 - else: - raise AssertionError("Should have thrown error for negative limit") - - def test_limit_skip_field6(self): - q = {"$or": [{"user_id": {"$lt": 100}}, {"filtered_array.[]": 1}]} - try: - self.db.find(q, skip=-1) - except Exception as e: - assert e.response.status_code == 400 - else: - raise AssertionError("Should have thrown error for negative skip") - - # Basic test to ensure we can iterate through documents with a bookmark - def test_limit_bookmark(self): - for i in range(1, len(limit_docs.DOCS), 5): - self.run_bookmark_check(i) - - for i in range(1, len(limit_docs.DOCS), 5): - self.run_bookmark_sort_check(i) - - def run_bookmark_check(self, size): - q = {"age": {"$gt": 0}} - seen_docs = set() - bm = None - while True: - json = self.db.find(q, limit=size, bookmark=bm, return_raw=True) - for doc in json["docs"]: - assert doc["_id"] not in seen_docs - seen_docs.add(doc["_id"]) - if not len(json["docs"]): - break - assert json["bookmark"] != bm - bm = json["bookmark"] - assert len(seen_docs) == len(limit_docs.DOCS) - - def run_bookmark_sort_check(self, size): - q = {"age": {"$gt": 0}} - seen_docs = set() - bm = None - age = 0 - while True: - json = self.db.find( - q, limit=size, bookmark=bm, sort=["age"], return_raw=True - ) - for doc in json["docs"]: - assert doc["_id"] not in seen_docs - assert doc["age"] >= age - age = doc["age"] - seen_docs.add(doc["_id"]) - if not len(json["docs"]): - break - assert json["bookmark"] != bm - bm = json["bookmark"] - assert len(seen_docs) == len(limit_docs.DOCS) diff --git a/test/elixir/test/config/search.elixir b/test/elixir/test/config/search.elixir index 87715d4caf..d525e9259f 100644 --- a/test/elixir/test/config/search.elixir +++ b/test/elixir/test/config/search.elixir @@ -37,6 +37,18 @@ "elem match non object" ], "LimitTests": [ - "limit field" + "limit field", + "limit field 2", + "limit field 3", + "limit field 4", + "limit field 5", + "limit skip field 1", + "limit skip field 2", + "limit skip field 3", + "limit skip field 4", + "limit skip field 5", + "limit skip field 6", + "limit bookmark", + "limit bookmark with sort", ] } diff --git a/test/elixir/test/mango/08_text_limit_test.exs b/test/elixir/test/mango/08_text_limit_test.exs index 07c6b01f98..e3dfba8f3a 100644 --- a/test/elixir/test/mango/08_text_limit_test.exs +++ b/test/elixir/test/mango/08_text_limit_test.exs @@ -21,9 +21,164 @@ defmodule LimitTests do test "limit field" do q = %{"$or" => [%{"user_id" => %{"$lt" => 10}}, %{"filtered_array.[]" => 1}]} - {:ok, docs} = MangoDatabase.find(@db_name, q, limit: 10) + {:ok, docs} = MangoDatabase.find(@db_name, q, limit: 10, sort: ["user_id"]) assert length(docs) == 8 Enum.each(docs, fn d -> assert d["user_id"] < 10 end) end + + test "limit field 2" do + q = %{"$or" => [%{"user_id" => %{"$lt" => 20}}, %{"filtered_array.[]" => 1}]} + {:ok, docs} = MangoDatabase.find(@db_name, q, limit: 10, sort: ["user_id"]) + assert length(docs) == 10 + Enum.each(docs, fn d -> assert d["user_id"] < 20 end) + end + + test "limit field 3" do + q = %{"$or" => [%{"user_id" => %{"$lt" => 100}}, %{"filtered_array.[]" => 1}]} + {:ok, docs} = MangoDatabase.find(@db_name, q, limit: 1, sort: ["user_id"]) + assert length(docs) == 1 + Enum.each(docs, fn d -> assert d["user_id"] < 100 end) + end + + test "limit field 4" do + q = %{"$or" => [%{"user_id" => %{"$lt" => 0}}, %{"filtered_array.[]" => 1}]} + {:ok, docs} = MangoDatabase.find(@db_name, q, limit: 35) + assert Enum.empty?(docs) + end + + # We reach our cap here of 50 + test "limit field 5" do + q = %{"age" => %{"$exists" => true}} + {:ok, docs} = MangoDatabase.find(@db_name, q, limit: 250) + assert length(docs) == LimitDocs.get_docs_length() + Enum.each(docs, fn d -> assert d["age"] < 100 end) + end + + test "limit skip field 1" do + q = %{"$or" => [%{"user_id" => %{"$lt" => 100}}, %{"filtered_array.[]" => 1}]} + {:ok, docs} = MangoDatabase.find(@db_name, q, limit: 10, skip: 20, sort: ["user_id"]) + assert length(docs) == 10 + Enum.each(docs, fn d -> assert d["user_id"] > 20 end) + end + + test "limit skip field 2" do + q = %{"$or" => [%{"user_id" => %{"$lt" => 100}}, %{"filtered_array.[]" => 1}]} + {:ok, docs} = MangoDatabase.find(@db_name, q, limit: 100, skip: 100) + assert Enum.empty?(docs) + end + + test "limit skip field 3" do + q = %{"$or" => [%{"user_id" => %{"$lt" => 20}}, %{"filtered_array.[]" => 1}]} + {:ok, docs} = MangoDatabase.find(@db_name, q, limit: 1, skip: 30) + assert Enum.empty?(docs) + end + + test "limit skip field 4" do + q = %{"$or" => [%{"user_id" => %{"$lt" => 100}}, %{"filtered_array.[]" => 1}]} + {:ok, docs} = MangoDatabase.find(@db_name, q, limit: 0, skip: 0) + assert Enum.empty?(docs) + end + + test "limit skip field 5" do + q = %{"$or" => [%{"user_id" => %{"$lt" => 100}}, %{"filtered_array.[]" => 1}]} + {:error, resp} = MangoDatabase.find(@db_name, q, limit: -1) + assert resp.status_code == 400 + end + + test "limit skip field 6" do + q = %{"$or" => [%{"user_id" => %{"$lt" => 100}}, %{"filtered_array.[]" => 1}]} + {:error, resp} = MangoDatabase.find(@db_name, q, skip: -1) + assert resp.status_code == 400 + end + + # Basic test to ensure we can iterate through documents with a bookmark + test "limit bookmark" do + Enum.each( + Enum.to_list(1..LimitDocs.get_docs_length()//5), #[1] + fn size -> + seen_docs = run_bookmark_check(size, "") + + assert MapSet.size(seen_docs) == LimitDocs.get_docs_length() + end + ) + end + + defp run_bookmark_check(size, bookmark) do + q = %{"age" => %{"$gt" => 0}} + seen_docs = MapSet.new([]) + + seen_docs = get_docs(q, size, bookmark, seen_docs) + + assert MapSet.size(seen_docs) == LimitDocs.get_docs_length() + + seen_docs + end + + defp get_docs(q, size, bookmark, seen_docs) do + {:ok, json} = MangoDatabase.find(@db_name, q, limit: size, bookmark: bookmark, return_raw: true) + + seen_docs = Enum.reduce(json["docs"], seen_docs, + fn doc, seen_docs -> + assert not Enum.member?(seen_docs, doc["_id"]) + MapSet.put(seen_docs, doc["_id"]) + end + ) + + if length(json["docs"]) != 0 do + assert bookmark != json["bookmark"] + get_docs(q, size, json["bookmark"], seen_docs) + else + seen_docs + end + end + + test "limit bookmark with sort" do + Enum.each( + Enum.to_list(1..LimitDocs.get_docs_length()//5), #[1] + fn size -> + seen_docs = run_bookmark_check_with_sort(size, "", 0) + + assert MapSet.size(seen_docs) == LimitDocs.get_docs_length() + end + ) + end + + defp run_bookmark_check_with_sort(size, bookmark, age) do + q = %{"age" => %{"$gt" => 0}} + seen_docs = MapSet.new([]) + + seen_docs = get_docs_with_sort(q, size, bookmark, age, seen_docs) + + assert MapSet.size(seen_docs) == LimitDocs.get_docs_length() + + seen_docs + end + + defp get_docs_with_sort(q, size, bookmark, age, seen_docs) do + {:ok, json} = MangoDatabase.find( + @db_name, + q, + limit: size, + bookmark: bookmark, + sort: ["age"], + return_raw: true + ) + + {seen_docs, age} = Enum.reduce(json["docs"], {seen_docs, age}, + fn doc, {seen_docs, age} -> + assert not Enum.member?(seen_docs, doc["_id"]) + assert doc["age"] >= age + + {MapSet.put(seen_docs, doc["_id"]), doc["age"]} + end + ) + + if length(json["docs"]) != 0 do + assert bookmark != json["bookmark"] + get_docs_with_sort(q, size, json["bookmark"], age, seen_docs) + else + seen_docs + end + end end diff --git a/test/elixir/test/support/limit_docs.ex b/test/elixir/test/support/limit_docs.ex index 5a474f2dd3..0551856088 100644 --- a/test/elixir/test/support/limit_docs.ex +++ b/test/elixir/test/support/limit_docs.ex @@ -109,4 +109,8 @@ defmodule LimitDocs do defp add_text_indexes(db) do MangoDatabase.create_text_index(db) end + + def get_docs_length() do + length(@docs) + end end diff --git a/test/elixir/test/support/mango_database.ex b/test/elixir/test/support/mango_database.ex index 1b5b4ab63a..52806825e5 100644 --- a/test/elixir/test/support/mango_database.ex +++ b/test/elixir/test/support/mango_database.ex @@ -165,7 +165,8 @@ defmodule MangoDatabase do r: 1, conflicts: false, explain: false, - return_raw: false + return_raw: false, + bookmark: nil, ] options = Keyword.merge(defaults, opts) @@ -187,6 +188,7 @@ defmodule MangoDatabase do |> put_if_set("fields", options, :fields) |> put_if_set("execution_stats", options, :executionStats) |> put_if_set("allow_fallback", options, :allow_fallback) + |> put_if_set("bookmark", options, :bookmark) ) case {(options[:explain] or options[:return_raw]), resp.status_code} do