summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Newson <rnewson@apache.org>2021-03-09 15:49:15 +0000
committerRobert Newson <rnewson@apache.org>2021-03-10 17:33:39 +0000
commitc1c8295f7cf8139b9dc87c64cea19dbd8e6c2ea3 (patch)
tree6add2b1f5afa9c880fc14d3cd65f6e134f67134a
parentfdd53774bd802fe9e6b6eb473ae5b40c7436137c (diff)
downloadcouchdb-c1c8295f7cf8139b9dc87c64cea19dbd8e6c2ea3.tar.gz
Verify correctness with concurrent updates
-rw-r--r--test/elixir/lib/couch.ex13
-rw-r--r--test/elixir/test/concurrent_writes_test.exs51
-rw-r--r--test/elixir/test/config/suite.elixir4
3 files changed, 68 insertions, 0 deletions
diff --git a/test/elixir/lib/couch.ex b/test/elixir/lib/couch.ex
index 5928d5dd6..fd76ad1dd 100644
--- a/test/elixir/lib/couch.ex
+++ b/test/elixir/lib/couch.ex
@@ -79,6 +79,7 @@ defmodule Couch do
# request_timeout largely just so we know which timeout fired.
@request_timeout 60_000
@inactivity_timeout 55_000
+ @max_sessions 1_000
def process_url("http://" <> _ = url) do
url
@@ -117,6 +118,7 @@ defmodule Couch do
|> set_auth_options()
|> set_inactivity_timeout()
|> set_request_timeout()
+ |> set_max_sessions()
end
def process_request_body(body) do
@@ -176,6 +178,17 @@ defmodule Couch do
Keyword.put_new(options, :timeout, timeout)
end
+ def set_max_sessions(options) do
+ Keyword.update(
+ options,
+ :ibrowse,
+ [{:max_sessions, @max_sessions}],
+ fn ibrowse ->
+ Keyword.put_new(ibrowse, :max_sessions, @max_sessions)
+ end
+ )
+ end
+
def login(userinfo) do
[user, pass] = String.split(userinfo, ":", parts: 2)
login(user, pass)
diff --git a/test/elixir/test/concurrent_writes_test.exs b/test/elixir/test/concurrent_writes_test.exs
new file mode 100644
index 000000000..bf3c0a652
--- /dev/null
+++ b/test/elixir/test/concurrent_writes_test.exs
@@ -0,0 +1,51 @@
+defmodule ConcurrentWritesTest do
+ use CouchTestCase
+
+ @moduletag :concurrent_writes
+ @moduletag kind: :single_node
+
+ @moduledoc """
+ Test CouchDB under concurrent write load
+ """
+
+ @tag :with_db
+ test "Primary data tests", context do
+ n = 120
+ db_name = context[:db_name]
+ 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
+ send parent, :done
+ end end)
+ Enum.each(1..n, fn _x -> receive do :done -> :done end end)
+ Enum.each(1..n, fn x ->
+ assert Couch.get("/#{db_name}/doc#{x}").body["a"] == x
+ end)
+ assert Couch.get("/#{db_name}").body["doc_count"] == n
+ end
+
+ @tag :with_db
+ test "Secondary data tests", context do
+ n = 120
+ 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
+ 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(1..n)
+ end
+
+end
diff --git a/test/elixir/test/config/suite.elixir b/test/elixir/test/config/suite.elixir
index a87918246..65f972c2f 100644
--- a/test/elixir/test/config/suite.elixir
+++ b/test/elixir/test/config/suite.elixir
@@ -131,6 +131,10 @@
"CompactTest": [
"compaction reduces size of deleted docs"
],
+ "ConcurrentWritesTest": [
+ "Primary data tests",
+ "Secondary data tests"
+ ],
"ConfigTest": [
"Atoms, binaries, and strings suffice as whitelist sections and keys.",
"Blacklist is functional",