This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch 
add-concurrent-test-with-intermettent-view-queries
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit d1d258ffe7b78ba553992095d3f1e0e81caa1e5f
Author: Nick Vatamaniuc <[email protected]>
AuthorDate: Thu Mar 18 16:33:44 2021 -0400

    Add more concurrent write tests
    
     * `Secondary data tests with updates and queries`: This one is just like 
the
        `Secondary data tests with updates` but adds intermettent queries while
        updates are taking place.
    
     * `Secondary data tests with deletes and queries`: This one deletes and
       queries intermetently. 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 returna 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.
---
 test/elixir/test/concurrent_writes_test.exs | 76 +++++++++++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/test/elixir/test/concurrent_writes_test.exs 
b/test/elixir/test/concurrent_writes_test.exs
index 397c5e8..8bc33df 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

Reply via email to