summaryrefslogtreecommitdiff
path: root/test/elixir/test/compact_test.exs
blob: d99a7a78ee33a2c61fecfdd3957aa2b85a14da90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
defmodule CompactTest do
  use CouchTestCase

  @moduletag :compact

  @moduledoc """
  Test CouchDB compaction
  This is a port of compact.js
  """

  @att_doc_id "att_doc"
  @att_name "foo.txt"
  @att_plaintext "This is plain text"

  # Need to investigate why compaction is not compacting (or compactor cannot complete)
  # Refer:- https://github.com/apache/couchdb/pull/2127
  @tag :pending
  @tag :skip_on_jenkins
  @tag :with_db
  test "compaction reduces size of deleted docs", context do
    db = context[:db_name]
    docs = populate(db)
    info = get_info(db)
    orig_data_size = info["sizes"]["active"]
    orig_disk_size = info["sizes"]["file"]
    start_time = info["instance_start_time"]
    assert is_integer(orig_data_size) and is_integer(orig_disk_size)
    assert orig_data_size < orig_disk_size

    delete(db, docs)

    retry_until(fn ->
      deleted_data_size = get_info(db)["data_size"]
      assert deleted_data_size > orig_data_size
    end)

    deleted_data_size = get_info(db)["data_size"]

    compact(db)

    retry_until(fn ->
      assert get_info(db)["instance_start_time"] == start_time
      assert_attachment_available(db)
      info = get_info(db)
      final_data_size = info["sizes"]["active"]
      final_disk_size = info["sizes"]["file"]
      assert final_data_size < final_disk_size
      assert is_integer(final_data_size) and is_integer(final_disk_size)
      assert final_data_size < deleted_data_size
    end)
  end

  defp assert_attachment_available(db) do
    resp = Couch.get("/#{db}/#{@att_doc_id}/#{@att_name}")
    assert resp.body == @att_plaintext
    assert resp.headers["content-type"] == "text/plain"
    assert Couch.get("/#{db}").body["doc_count"] == 1
  end

  defp populate(db) do
    docs = create_docs(0..19)
    resp = Couch.post("/#{db}/_bulk_docs", body: %{docs: docs})
    assert resp.status_code in [201, 202]
    docs = rev(docs, resp.body)

    doc = %{
      _id: "#{@att_doc_id}",
      _attachments: %{
        "#{@att_name}": %{content_type: "text/plain", data: Base.encode64(@att_plaintext)}
      }
    }

    resp = Couch.put("/#{db}/#{doc._id}", body: doc)
    assert resp.status_code in [201, 202]
    docs
  end

  defp delete(db, docs) do
    docs = Enum.map(docs, &Map.put(&1, :_deleted, true))
    resp = Couch.post("/#{db}/_bulk_docs", body: %{docs: docs})
    assert resp.status_code in [201, 202]
    assert Couch.post("/#{db}/_ensure_full_commit").body["ok"] == true
  end

  defp compact(db) do
    assert Couch.post("/#{db}/_compact").status_code == 202

    retry_until(
      fn ->
        Couch.get("/#{db}").body["compact_running"] == false
      end,
      200,
      20_000
    )
  end

  defp get_info(db) do
    Couch.get("/#{db}").body
  end
end