diff options
author | Garren Smith <garren.smith@gmail.com> | 2018-12-04 15:39:22 +0200 |
---|---|---|
committer | Paul J. Davis <paul.joseph.davis@gmail.com> | 2019-01-09 11:33:29 -0600 |
commit | 74e246de0d3d948f97cee94088f2c11e7264b397 (patch) | |
tree | a5c9e856f91af00fed456e6f73c52fa59257f670 | |
parent | 092194de5e84a85ee0bcd39ecf7e0da098307ad4 (diff) | |
download | couchdb-74e246de0d3d948f97cee94088f2c11e7264b397.tar.gz |
Add partition search tests
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | src/dreyfus_httpd.erl | 1 | ||||
-rw-r--r-- | test/elixir/mix.exs | 30 | ||||
-rw-r--r-- | test/elixir/mix.lock | 5 | ||||
-rwxr-xr-x | test/elixir/run | 4 | ||||
-rw-r--r-- | test/elixir/test/partition_search_test.exs | 187 | ||||
-rw-r--r-- | test/elixir/test/test_helper.exs | 4 |
7 files changed, 233 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore index 4598aa522..16fd00698 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ ebin/ .*.sw? +test/elixir/_build +test/elixir/deps diff --git a/src/dreyfus_httpd.erl b/src/dreyfus_httpd.erl index e3ef5a96c..37270b7af 100644 --- a/src/dreyfus_httpd.erl +++ b/src/dreyfus_httpd.erl @@ -17,6 +17,7 @@ -export([handle_search_req/3, handle_info_req/3, handle_disk_size_req/3, handle_cleanup_req/2, handle_analyze_req/1]). + -include("dreyfus.hrl"). -include_lib("couch/include/couch_db.hrl"). -import(chttpd, [send_method_not_allowed/2, send_json/2, send_json/3, diff --git a/test/elixir/mix.exs b/test/elixir/mix.exs new file mode 100644 index 000000000..9b0f642dd --- /dev/null +++ b/test/elixir/mix.exs @@ -0,0 +1,30 @@ +defmodule Foo.Mixfile do + use Mix.Project + + def project do + [ + app: :foo, + version: "0.1.0", + elixir: "~> 1.5", + start_permanent: Mix.env == :prod, + deps: deps() + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + extra_applications: [:logger] + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + # {:dep_from_hexpm, "~> 0.3.0"}, + {:httpotion, "~> 3.0"}, + {:jiffy, "~> 0.14.11"} + # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}, + ] + end +end diff --git a/test/elixir/mix.lock b/test/elixir/mix.lock new file mode 100644 index 000000000..ed51e5312 --- /dev/null +++ b/test/elixir/mix.lock @@ -0,0 +1,5 @@ +%{ + "httpotion": {:hex, :httpotion, "3.1.0", "14d20d9b0ce4e86e253eb91e4af79e469ad949f57a5d23c0a51b2f86559f6589", [:mix], [{:ibrowse, "~> 4.4", [hex: :ibrowse, repo: "hexpm", optional: false]}], "hexpm"}, + "ibrowse": {:hex, :ibrowse, "4.4.1", "2b7d0637b0f8b9b4182de4bd0f2e826a4da2c9b04898b6e15659ba921a8d6ec2", [:rebar3], [], "hexpm"}, + "jiffy": {:hex, :jiffy, "0.14.13", "225a9a35e26417832c611526567194b4d3adc4f0dfa5f2f7008f4684076f2a01", [:rebar3], [], "hexpm"}, +} diff --git a/test/elixir/run b/test/elixir/run new file mode 100755 index 000000000..66a5947b7 --- /dev/null +++ b/test/elixir/run @@ -0,0 +1,4 @@ +#!/bin/bash -e +cd "$(dirname "$0")" +mix deps.get +mix test --trace diff --git a/test/elixir/test/partition_search_test.exs b/test/elixir/test/partition_search_test.exs new file mode 100644 index 000000000..98b23b508 --- /dev/null +++ b/test/elixir/test/partition_search_test.exs @@ -0,0 +1,187 @@ +defmodule PartitionSearchTest do + use CouchTestCase + + @moduletag :search + + @moduledoc """ + Test Partition functionality with search + """ + + def create_search_docs(db_name, pk1 \\ "foo", pk2 \\ "bar") do + docs = for i <- 1..10 do + id = if rem(i, 2) == 0 do + "#{pk1}:#{i}" + else + "#{pk2}:#{i}" + end + %{ + :_id => id, + :value => i, + :some => "field" + } + end + + resp = Couch.post("/#{db_name}/_bulk_docs", body: %{:docs => docs} ) + assert resp.status_code == 201 + end + + def create_ddoc(db_name, opts \\ %{}) do + indexFn = "function(doc) {\n if (doc.some) {\n index('some', doc.some);\n }\n}" + default_ddoc = %{ + indexes: %{ + books: %{ + analyzer: %{name: "standard"}, + index: indexFn + } + } + } + + ddoc = Enum.into(opts, default_ddoc) + + resp = Couch.put("/#{db_name}/_design/library", body: ddoc) + assert resp.status_code == 201 + assert Map.has_key?(resp.body, "ok") == true + end + + def get_ids (resp) do + %{:body => %{"rows" => rows}} = resp + Enum.map(rows, fn row -> row["id"] end) + end + + @tag :with_partitioned_db + test "Simple query returns partitioned search results", context do + db_name = context[:db_name] + create_search_docs(db_name) + create_ddoc(db_name) + + url = "/#{db_name}/_partition/foo/_design/library/_search/books" + resp = Couch.get(url, query: %{q: "some:field"}) + assert resp.status_code == 200 + ids = get_ids(resp) + assert ids == ["foo:10", "foo:2", "foo:4", "foo:6", "foo:8"] + + url = "/#{db_name}/_partition/bar/_design/library/_search/books" + resp = Couch.get(url, query: %{q: "some:field"}) + assert resp.status_code == 200 + ids = get_ids(resp) + assert ids == ["bar:1", "bar:3", "bar:5", "bar:7", "bar:9"] + end + + @tag :with_partitioned_db + test "Only returns docs in partition not those in shard", context do + db_name = context[:db_name] + create_search_docs(db_name, "foo", "bar42") + create_ddoc(db_name) + + url = "/#{db_name}/_partition/foo/_design/library/_search/books" + resp = Couch.get(url, query: %{q: "some:field"}) + assert resp.status_code == 200 + ids = get_ids(resp) + assert ids == ["foo:10", "foo:2", "foo:4", "foo:6", "foo:8"] + end + + @tag :with_partitioned_db + test "Works with bookmarks and limit", context do + db_name = context[:db_name] + create_search_docs(db_name) + create_ddoc(db_name) + + url = "/#{db_name}/_partition/foo/_design/library/_search/books" + resp = Couch.get(url, query: %{q: "some:field", limit: 3}) + assert resp.status_code == 200 + ids = get_ids(resp) + assert ids == ["foo:10", "foo:2", "foo:4"] + + %{:body => %{"bookmark" => bookmark}} = resp + + resp = Couch.get(url, query: %{q: "some:field", limit: 3, bookmark: bookmark}) + assert resp.status_code == 200 + ids = get_ids(resp) + assert ids == ["foo:6", "foo:8"] + + resp = Couch.get(url, query: %{q: "some:field", limit: 2000, bookmark: bookmark}) + assert resp.status_code == 200 + ids = get_ids(resp) + assert ids == ["foo:6", "foo:8"] + + resp = Couch.get(url, query: %{q: "some:field", limit: 2001, bookmark: bookmark}) + assert resp.status_code == 400 + end + + @tag :with_partitioned_db + test "Cannot do global query with partition view", context do + db_name = context[:db_name] + create_search_docs(db_name) + create_ddoc(db_name) + + url = "/#{db_name}/_design/library/_search/books" + resp = Couch.get(url, query: %{q: "some:field"}) + assert resp.status_code == 400 + %{:body => %{"reason" => reason}} = resp + assert Regex.match?(~r/mandatory for queries to this index./, reason) + end + + @tag :with_partitioned_db + test "Cannot do partition query with global search ddoc", context do + db_name = context[:db_name] + create_search_docs(db_name) + create_ddoc(db_name, options: %{partitioned: false}) + + url = "/#{db_name}/_partition/foo/_design/library/_search/books" + resp = Couch.get(url, query: %{q: "some:field"}) + assert resp.status_code == 400 + %{:body => %{"reason" => reason}} = resp + assert reason == "`partition` not supported on this index" + end + + @tag :with_db + test "normal search on non-partitioned dbs still work", context do + db_name = context[:db_name] + create_search_docs(db_name) + create_ddoc(db_name) + + url = "/#{db_name}/_design/library/_search/books" + resp = Couch.get(url, query: %{q: "some:field"}) + assert resp.status_code == 200 + ids = get_ids(resp) + assert ids == ["bar:1", "bar:5", "bar:9", "foo:2", "bar:3", "foo:4", "foo:6", "bar:7", "foo:8", "foo:10"] + end + + @tag :with_db + test "normal search on non-partitioned dbs without limit", context do + db_name = context[:db_name] + create_search_docs(db_name) + create_ddoc(db_name) + + url = "/#{db_name}/_design/library/_search/books" + resp = Couch.get(url, query: %{q: "some:field"}) + assert resp.status_code == 200 + ids = get_ids(resp) + assert ids == ["bar:1", "bar:5", "bar:9", "foo:2", "bar:3", "foo:4", "foo:6", "bar:7", "foo:8", "foo:10"] + end + + @tag :with_db + test "normal search on non-partitioned dbs with limit", context do + db_name = context[:db_name] + create_search_docs(db_name) + create_ddoc(db_name) + + url = "/#{db_name}/_design/library/_search/books" + resp = Couch.get(url, query: %{q: "some:field", limit: 3}) + assert resp.status_code == 200 + ids = get_ids(resp) + assert ids == ["bar:1", "bar:5", "bar:9"] + end + + @tag :with_db + test "normal search on non-partitioned dbs with over limit", context do + db_name = context[:db_name] + create_search_docs(db_name) + create_ddoc(db_name) + + url = "/#{db_name}/_design/library/_search/books" + resp = Couch.get(url, query: %{q: "some:field", limit: 201}) + assert resp.status_code == 400 + end + +end diff --git a/test/elixir/test/test_helper.exs b/test/elixir/test/test_helper.exs new file mode 100644 index 000000000..6eb20e242 --- /dev/null +++ b/test/elixir/test/test_helper.exs @@ -0,0 +1,4 @@ +Code.require_file "../../../../couchdb/test/elixir/lib/couch.ex", __DIR__ +Code.require_file "../../../../couchdb/test/elixir/test/test_helper.exs", __DIR__ +Code.require_file "../../../../couchdb/test/elixir/test/support/couch_test_case.ex", __DIR__ +Code.require_file "../../../../couchdb/test/elixir/lib/couch/db_test.ex", __DIR__ |