summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarren Smith <garren.smith@gmail.com>2018-12-04 15:39:22 +0200
committerPaul J. Davis <paul.joseph.davis@gmail.com>2019-01-09 11:33:29 -0600
commit74e246de0d3d948f97cee94088f2c11e7264b397 (patch)
treea5c9e856f91af00fed456e6f73c52fa59257f670
parent092194de5e84a85ee0bcd39ecf7e0da098307ad4 (diff)
downloadcouchdb-74e246de0d3d948f97cee94088f2c11e7264b397.tar.gz
Add partition search tests
-rw-r--r--.gitignore2
-rw-r--r--src/dreyfus_httpd.erl1
-rw-r--r--test/elixir/mix.exs30
-rw-r--r--test/elixir/mix.lock5
-rwxr-xr-xtest/elixir/run4
-rw-r--r--test/elixir/test/partition_search_test.exs187
-rw-r--r--test/elixir/test/test_helper.exs4
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__