Skip to content

Commit

Permalink
Attempt to fix flaky users db security test
Browse files Browse the repository at this point in the history
 * Reset _users db before and after use to avoid polluting other tests.

 * Use a common reset db and "wait for auth cache" helper function

 * Since we're testing chttpd auth don't bother also setting httpd
   authentication_db, that just stops and resets the local port httpd listener,
   but we're not testing backend auth.

 * Use a retry in login for security db to avoid flakiness
  • Loading branch information
nickva committed Nov 20, 2023
1 parent 0fa2967 commit eb1a588
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 66 deletions.
21 changes: 21 additions & 0 deletions test/elixir/lib/couch/dbtest.ex
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,27 @@ defmodule Couch.DBTest do
{:ok, resp}
end

def reset_db(db_name, opts \\ []) do
delete_db(db_name)
create_db(db_name, opts)
end

# Use this function when testing authentication after resetting (re-creating)
# _users db. The auth cache can take up to 5 seconds or so to notice the old
# db is gone and spawn another changes feed for the new users db.
#
def wait_for_design_auth(users_db) do
retry_until(fn ->
resp =
Couch.get(
"/#{users_db}/_changes",
query: [feed: "longpoll", timeout: 5000, filter: "_design"]
)
results = resp.body["results"]
is_list(results) && length(results) > 0
end, 500, 60_000)
end

def create_doc(db_name, body) do
resp = Couch.post("/#{db_name}", body: body)
assert resp.status_code in [201, 202]
Expand Down
25 changes: 3 additions & 22 deletions test/elixir/test/cookie_auth_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -31,32 +31,13 @@ defmodule CookieAuthTest do
@password "3.141592653589"

setup do
# Create db if not exists
Couch.put("/#{@users_db}")

retry_until(fn ->
resp =
Couch.get(
"/#{@users_db}/_changes",
query: [feed: "longpoll", timeout: 5000, filter: "_design"]
)
length(resp.body["results"]) > 0
end)

reset_db(@users_db)
wait_for_design_auth(@users_db)
on_exit(&tear_down/0)

:ok
end

defp tear_down do
# delete users
user = URI.encode("org.couchdb.user:jchris")
user_doc = Couch.get("/#{@users_db}/#{URI.encode(user)}").body
Couch.delete("/#{@users_db}/#{user}", query: [rev: user_doc["_rev"]])

user = URI.encode("org.couchdb.user:Jason Davies")
user_doc = Couch.get("/#{@users_db}/#{user}").body
Couch.delete("/#{@users_db}/#{user}", query: [rev: user_doc["_rev"]])
reset_db(@users_db)
end

defp login(user, password) do
Expand Down
3 changes: 1 addition & 2 deletions test/elixir/test/reader_acl_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ defmodule ReaderACLTest do
}
]
setup do
# Create db if not exists
Couch.put("/#{@users_db_name}")
reset_db(@users_db_name)

# create a user with top-secret-clearance
user_doc =
Expand Down
14 changes: 11 additions & 3 deletions test/elixir/test/security_validation_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,14 @@ defmodule SecurityValidationTest do
setup_all do
auth_db_name = random_db_name()
{:ok, _} = create_db(auth_db_name)
on_exit(fn -> delete_db(auth_db_name) end)
on_exit(fn ->
delete_db(auth_db_name)
reset_db("_users")
end)

configs = [
{"httpd", "authentication_handlers",
{"chttpd", "authentication_handlers",
"{couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}"},
{"couch_httpd_auth", "authentication_db", auth_db_name},
{"chttpd_auth", "authentication_db", auth_db_name}
]

Expand All @@ -84,6 +86,12 @@ defmodule SecurityValidationTest do
assert Couch.post("/#{auth_db_name}", body: doc).body["ok"]
end)

# Reset users db to force the auth cache to restart and use
# the new auth db
reset_db("_users")

wait_for_design_auth(auth_db_name)

{:ok, [auth_db_name: auth_db_name]}
end

Expand Down
35 changes: 11 additions & 24 deletions test/elixir/test/users_db_security_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,13 @@ defmodule UsersDbSecurityTest do
}

setup_all do
# Create db if not exists
Couch.put("/#{@users_db}")

retry_until(fn ->
resp =
Couch.get(
"/#{@users_db}/_changes",
query: [feed: "longpoll", timeout: 5000, filter: "_design"]
)

length(resp.body["results"]) > 0
end)

reset_db(@users_db)
wait_for_design_auth(@users_db)
on_exit(&tear_down/0)

:ok
end

defp tear_down do
users = Map.keys(@login_user)
Enum.each(users, fn name ->
resp = Couch.get("/#{@users_db}/org.couchdb.user:#{name}")
if resp.status_code == 200 do
rev = resp.body["_rev"]
Couch.delete("/#{@users_db}/org.couchdb.user:#{name}?rev=#{rev}")
end
end)
reset_db(@users_db)
end

defp login_as(user, password \\ nil) do
Expand All @@ -51,7 +31,14 @@ defmodule UsersDbSecurityTest do
_ -> password
end

sess = Couch.login(user, pwd)
sess = retry_until(fn ->
try do
Couch.login(user, pwd)
catch
_, _ ->
false
end
end, 500, 60_000)
assert sess.cookie, "Login correct is expected"
sess
end
Expand Down
18 changes: 3 additions & 15 deletions test/elixir/test/users_db_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -29,25 +29,13 @@ defmodule UsersDbTest do
]

setup do
# Create db if not exists
Couch.put("/#{@users_db_name}")

resp =
Couch.get(
"/#{@users_db_name}/_changes",
query: [feed: "longpoll", timeout: 5000, filter: "_design"]
)

assert resp.body

reset_db(@users_db_name)
wait_for_design_auth(@users_db_name)
on_exit(&tear_down/0)

:ok
end

defp tear_down do
delete_db(@users_db_name)
create_db(@users_db_name)
reset_db(@users_db_name)
end

defp save_as(db_name, doc, options) do
Expand Down

0 comments on commit eb1a588

Please sign in to comment.