summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Vatamaniuc <vatamane@apache.org>2021-03-18 16:33:44 -0400
committerNick Vatamaniuc <vatamane@apache.org>2021-03-18 16:39:12 -0400
commitb0670b33b7b57e7b33cc6700de8d5488893ef6c4 (patch)
tree053a71dcb39e27b266ef83b00285828b7eeebdb4
parent36eae8f7f6fb1ea67a51bed77499d50921d6738f (diff)
downloadcouchdb-add-concurrent-test-with-intermettent-view-queries.tar.gz
* `Secondary data tests with updates and queries`: Like the `Secondary data tests with updates` but adds intermittent queries while updates are taking place. * `Secondary data tests with deletes and queries`: Deletes and queries intermettently. This one was specifically crafted to trigger the `ebtree:lookup_multi/3` error and hopefully other similar ones. The retry_until section at the end was added to differentiate between the case were we return a partial view and when the view is actually broken and it will never "catch up". Once we start returning only completed views, we remove that section.
-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