summaryrefslogtreecommitdiff
path: root/test/elixir/test/view_compaction_test.exs
blob: ed7461aa1942c90e51e218983c73600d267664fd (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
101
102
103
104
105
106
107
108
109
defmodule ViewCompactionTest do
  use CouchTestCase

  @moduledoc """
  Test CouchDB View Compaction Behavior
  This is a port of the view_compaction.js suite
  """
  
  @moduletag :view_compaction
  @moduletag kind: :single_node
  
  @num_docs 1000

  @ddoc %{
    _id: "_design/foo",
    language: "javascript",
    views: %{
      view1: %{
        map: "function(doc) { emit(doc._id, doc.value) }"
      },
      view2: %{
        map:
          "function(doc) { if (typeof(doc.integer) === 'number') {emit(doc._id, doc.integer);} }",
        reduce: "function(keys, values, rereduce) { return sum(values); }"
      }
    }
  }

  defp bulk_save_for_update(db_name, docs) do
    resp = bulk_save(db_name, docs)
    revs = resp.body

    Enum.map(docs, fn m ->
      rev = Enum.at(revs, String.to_integer(m["_id"]))["rev"]

      m
      |> Map.put("_rev", rev)
      |> Map.update!("integer", &(&1 + 1))
    end)
  end

  @tag :with_db
  test "view compaction", context do
    db_name = context[:db_name]
    create_doc(db_name, @ddoc)

    docs = make_docs(0..(@num_docs - 1))
    docs = bulk_save_for_update(db_name, docs)

    resp = view(db_name, "foo/view1")
    assert length(resp.body["rows"]) == @num_docs

    resp = view(db_name, "foo/view2")
    assert length(resp.body["rows"]) == 1

    resp = Couch.get("/#{db_name}/_design/foo/_info")
    assert resp.body["view_index"]["update_seq"] == @num_docs + 1

    docs = bulk_save_for_update(db_name, docs)

    resp = view(db_name, "foo/view1")
    assert length(resp.body["rows"]) == @num_docs

    resp = view(db_name, "foo/view2")
    assert length(resp.body["rows"]) == 1

    resp = Couch.get("/#{db_name}/_design/foo/_info")
    assert resp.body["view_index"]["update_seq"] == 2 * @num_docs + 1

    bulk_save(db_name, docs)
    resp = view(db_name, "foo/view1")
    assert length(resp.body["rows"]) == @num_docs

    resp = view(db_name, "foo/view2")
    assert length(resp.body["rows"]) == 1

    resp = Couch.get("/#{db_name}/_design/foo/_info")
    assert resp.body["view_index"]["update_seq"] == 3 * @num_docs + 1

    disk_size_before_compact = resp.body["view_index"]["sizes"]["file"]
    data_size_before_compact = resp.body["view_index"]["sizes"]["active"]

    assert is_integer(disk_size_before_compact)
    assert data_size_before_compact < disk_size_before_compact

    resp = Couch.post("/#{db_name}/_compact/foo")
    assert resp.body["ok"] == true

    retry_until(fn ->
      resp = Couch.get("/#{db_name}/_design/foo/_info")
      resp.body["view_index"]["compact_running"] == false
    end)

    resp = view(db_name, "foo/view1")
    assert length(resp.body["rows"]) == @num_docs

    resp = view(db_name, "foo/view2")
    assert length(resp.body["rows"]) == 1

    resp = Couch.get("/#{db_name}/_design/foo/_info")
    assert resp.body["view_index"]["update_seq"] == 3 * @num_docs + 1

    disk_size_after_compact = resp.body["view_index"]["sizes"]["file"]
    data_size_after_compact = resp.body["view_index"]["sizes"]["active"]
    assert disk_size_after_compact < disk_size_before_compact
    assert is_integer(data_size_after_compact)
    assert data_size_after_compact < disk_size_after_compact
  end
end