| defmodule PartitionViewUpdateTest do |
| use CouchTestCase |
| import PartitionHelpers |
| |
| @moduledoc """ |
| Test Partition view update functionality |
| """ |
| @tag :with_partitioned_db |
| test "view updates properly remove old keys", context do |
| db_name = context[:db_name] |
| create_partition_docs(db_name, "foo", "bar") |
| create_partition_ddoc(db_name) |
| |
| check_key = fn key, num_rows -> |
| url = "/#{db_name}/_partition/foo/_design/mrtest/_view/some" |
| resp = Couch.get(url, query: [key: key]) |
| assert resp.status_code == 200 |
| assert length(resp.body["rows"]) == num_rows |
| end |
| |
| check_key.(2, 1) |
| |
| resp = Couch.get("/#{db_name}/foo:2") |
| doc = Map.put(resp.body, "value", 4) |
| resp = Couch.put("/#{db_name}/foo:2", query: [w: 3], body: doc) |
| assert resp.status_code >= 201 and resp.status_code <= 202 |
| |
| check_key.(4, 2) |
| check_key.(2, 0) |
| end |
| |
| @tag :skip_on_jenkins |
| @tag :with_partitioned_db |
| test "query with update=false works", context do |
| db_name = context[:db_name] |
| create_partition_docs(db_name) |
| create_partition_ddoc(db_name) |
| |
| url = "/#{db_name}/_partition/foo/_design/mrtest/_view/some" |
| |
| resp = |
| Couch.get( |
| url, |
| query: %{ |
| update: "true", |
| limit: 3 |
| } |
| ) |
| |
| assert resp.status_code == 200 |
| ids = get_ids(resp) |
| assert ids == ["foo:2", "foo:4", "foo:6"] |
| |
| # Avoid race conditions by attempting to get a full response |
| # from every shard before we do our update:false test |
| for _ <- 1..12 do |
| resp = Couch.get(url) |
| assert resp.status_code == 200 |
| end |
| |
| Couch.put("/#{db_name}/foo:1", body: %{some: "field"}) |
| |
| retry_until(fn -> |
| resp = |
| Couch.get( |
| url, |
| query: %{ |
| update: "false", |
| limit: 3 |
| } |
| ) |
| |
| assert resp.status_code == 200 |
| ids = get_ids(resp) |
| assert ids == ["foo:2", "foo:4", "foo:6"] |
| end) |
| end |
| |
| @tag :with_partitioned_db |
| test "purge removes view rows", context do |
| db_name = context[:db_name] |
| create_partition_docs(db_name) |
| create_partition_ddoc(db_name) |
| |
| url = "/#{db_name}/_partition/foo/_design/mrtest/_view/some" |
| |
| resp = Couch.get(url) |
| assert resp.status_code == 200 |
| %{body: body} = resp |
| assert length(body["rows"]) == 50 |
| |
| resp = Couch.get("/#{db_name}/foo:2") |
| assert resp.status_code == 200 |
| %{body: body} = resp |
| rev = body["_rev"] |
| |
| body = %{"foo:2" => [rev]} |
| resp = Couch.post("/#{db_name}/_purge", query: [w: 3], body: body) |
| assert resp.status_code in [201, 202] |
| |
| resp = Couch.get(url) |
| assert resp.status_code == 200 |
| %{body: body} = resp |
| assert length(body["rows"]) == 49 |
| end |
| |
| @tag :with_partitioned_db |
| test "purged conflict changes view rows", context do |
| db_name = context[:db_name] |
| create_partition_docs(db_name) |
| create_partition_ddoc(db_name) |
| |
| url = "/#{db_name}/_partition/foo/_design/mrtest/_view/some" |
| |
| resp = Couch.get(url) |
| assert resp.status_code == 200 |
| %{body: body} = resp |
| assert length(body["rows"]) == 50 |
| |
| # Create a conflict on foo:2. Since the 4096 |
| # value is deeper than the conflict we can assert |
| # that's in the view before the purge and assert |
| # that 8192 is in the view after the purge. |
| resp = Couch.get("/#{db_name}/foo:2") |
| assert resp.status_code == 200 |
| %{body: body} = resp |
| rev1 = body["_rev"] |
| |
| doc = %{_id: "foo:2", _rev: rev1, value: 4096, some: "field"} |
| resp = Couch.post("/#{db_name}", query: [w: 3], body: doc) |
| assert resp.status_code in [201, 202] |
| %{body: body} = resp |
| rev2 = body["rev"] |
| |
| query = [w: 3, new_edits: false] |
| conflict_rev = "1-4a75b4efa0804859b3dfd327cbc1c2f9" |
| doc = %{_id: "foo:2", _rev: conflict_rev, value: 8192, some: "field"} |
| resp = Couch.put("/#{db_name}/foo:2", query: query, body: doc) |
| assert resp.status_code in [201, 202] |
| |
| # Check that our expected row exists |
| resp = Couch.get(url, query: [key: 4096]) |
| assert resp.status_code == 200 |
| %{body: body} = resp |
| [row] = body["rows"] |
| assert row["id"] == "foo:2" |
| |
| # Remove the current row to be replaced with |
| # a row from the conflict |
| body = %{"foo:2" => [rev2]} |
| resp = Couch.post("/#{db_name}/_purge", query: [w: 3], body: body) |
| assert resp.status_code in [201, 202] |
| |
| resp = Couch.get(url, query: [key: 8192]) |
| assert resp.status_code == 200 |
| %{body: body} = resp |
| [row] = body["rows"] |
| assert row["id"] == "foo:2" |
| end |
| end |