summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/elixir/test/concurrent_writes_test.exs76
1 files changed, 76 insertions, 0 deletions
diff --git a/test/elixir/test/concurrent_writes_test.exs b/test/elixir/test/concurrent_writes_test.exs
index 397c5e880..8bc33df6f 100644
--- a/test/elixir/test/concurrent_writes_test.exs
+++ b/test/elixir/test/concurrent_writes_test.exs
@@ -72,4 +72,80 @@ defmodule ConcurrentWritesTest do
assert result == Enum.sum(2..n + 1)
end
+ @tag :with_db
+ test "Secondary data tests with updates and queries", context do
+ n = 120
+ query_every_n = 40
+ db_name = context[:db_name]
+ map_fun = "function(doc) { emit(null, doc.a); }"
+ red_fun = "_sum"
+ ddoc_id = "_design/foo"
+ ddoc = %{:views => %{:foo => %{:map => map_fun, :reduce => red_fun}}}
+ Couch.put("/#{db_name}/#{ddoc_id}", body: ddoc)
+ parent = self()
+ Enum.each(1..n,
+ fn x -> spawn fn ->
+ r = Couch.put("/#{db_name}/doc#{x}", body: %{:a => x})
+ assert r.status_code == 201
+ rev = r.body["rev"]
+ if rem(x, query_every_n) == 0 do
+ r = Couch.get("/#{db_name}/#{ddoc_id}/_view/foo")
+ assert r.status_code == 200
+ end
+ r = Couch.put("/#{db_name}/doc#{x}", body: %{:_rev => rev, :a => x + 1})
+ assert r.status_code == 201
+ send parent, :done
+ end end)
+ Enum.each(1..n, fn _x -> receive do :done -> :done end end)
+ rows = Couch.get("/#{db_name}/#{ddoc_id}/_view/foo").body["rows"]
+ result = hd(rows)["value"]
+ assert result == Enum.sum(2..n + 1)
+ end
+
+ # The following test was specifically crafted to trigger the issue fixed in:
+ # https://github.com/apache/couchdb/commit/ec4b2132918338d893a800a823cf5f12d5b2efd5
+ #
+ @tag :with_db
+ test "Secondary data tests with deletes and queries", context do
+ n = 120
+ query_every_n = 40
+ db_name = context[:db_name]
+ map_fun = "function(doc) { emit(null, doc.a); }"
+ red_fun = "_sum"
+ ddoc_id = "_design/foo"
+ ddoc = %{:views => %{:foo => %{:map => map_fun, :reduce => red_fun}}}
+ Couch.put("/#{db_name}/#{ddoc_id}", body: ddoc)
+ parent = self()
+ Enum.each(1..n,
+ fn x -> spawn fn ->
+ r = Couch.put("/#{db_name}/doc#{x}", body: %{:a => x})
+ assert r.status_code == 201
+ rev = r.body["rev"]
+ :timer.sleep(:rand.uniform(1000))
+ r = Couch.delete("/#{db_name}/doc#{x}?rev=#{rev}")
+ assert r.status_code == 200
+ if rem(x, query_every_n) == 0 do
+ r = Couch.get("/#{db_name}/#{ddoc_id}/_view/foo")
+ assert r.status_code == 200
+ end
+ send parent, :done
+ end end)
+ Enum.each(1..n, fn _x -> receive do :done -> :done end end)
+
+ # Keep trying to query the view for a bit to account for the case when
+ # partial view results can be returned. After the following commits merges
+ # `retry_until` can be removed:
+ # https://github.com/apache/couchdb/pull/3391/commits/5a82664d1b0b58dd6c9fe6a79faa51e89211969e
+ #
+ try do
+ retry_until(fn ->
+ [] == Couch.get("/#{db_name}/#{ddoc_id}/_view/foo").body["rows"]
+ end, 1000, 5000)
+ rescue
+ RuntimeError -> :ok
+ end
+
+ assert [] == Couch.get("/#{db_name}/#{ddoc_id}/_view/foo").body["rows"]
+ end
+
end