Skip to content

Commit 8ba77c3

Browse files
davispgarrensmithrnewson
committed
Add Elixir tests for database partitions
Co-authored-by: Garren Smith <garren.smith@gmail.com> Co-authored-by: Robert Newson <rnewson@apache.org>
1 parent c0737c5 commit 8ba77c3

File tree

7 files changed

+1580
-3
lines changed

7 files changed

+1580
-3
lines changed
Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
defmodule PartitionCrudTest do
2+
use CouchTestCase
3+
4+
@tag :with_partitioned_db
5+
test "Sets partition in db info", context do
6+
db_name = context[:db_name]
7+
resp = Couch.get("/#{db_name}")
8+
%{body: body} = resp
9+
assert body["props"] == %{"partitioned" => true}
10+
end
11+
12+
@tag :with_partitioned_db
13+
test "PUT and GET document", context do
14+
db_name = context[:db_name]
15+
id = "my-partition:doc"
16+
url = "/#{db_name}/#{id}"
17+
18+
resp = Couch.put(url, body: %{partitioned_doc: true})
19+
%{body: doc} = resp
20+
assert resp.status_code == 201
21+
assert doc["id"] == id
22+
23+
resp = Couch.get(url)
24+
assert resp.status_code == 200
25+
26+
%{body: doc} = resp
27+
assert doc["_id"] == id
28+
end
29+
30+
@tag :with_partitioned_db
31+
test "PUT fails if a partition key is not supplied", context do
32+
db_name = context[:db_name]
33+
id = "not-partitioned"
34+
url = "/#{db_name}/#{id}"
35+
36+
resp = Couch.put(url, body: %{partitioned_doc: false})
37+
assert resp.status_code == 400
38+
39+
error = %{
40+
"error" => "illegal_docid",
41+
"reason" => "Document id must contain a partition"
42+
}
43+
44+
assert Map.get(resp, :body) == error
45+
end
46+
47+
@tag :with_partitioned_db
48+
test "PUT fails for partitions with _", context do
49+
db_name = context[:db_name]
50+
id = "_bad:partitioned"
51+
url = "/#{db_name}/#{id}"
52+
53+
resp = Couch.put(url, body: %{partitioned_doc: false})
54+
55+
error = %{
56+
"error" => "illegal_docid",
57+
"reason" => "Only reserved document ids may start with underscore."
58+
}
59+
60+
assert resp.status_code == 400
61+
assert Map.get(resp, :body) == error
62+
end
63+
64+
@tag :with_partitioned_db
65+
test "PUT fails for bad partitions", context do
66+
db_name = context[:db_name]
67+
id = "bad:"
68+
url = "/#{db_name}/#{id}"
69+
70+
resp = Couch.put(url, body: %{partitioned_doc: false})
71+
72+
error = %{
73+
"error" => "illegal_docid",
74+
"reason" => "Document id must not be empty"
75+
}
76+
77+
assert resp.status_code == 400
78+
assert Map.get(resp, :body) == error
79+
end
80+
81+
@tag :with_partitioned_db
82+
test "POST and GET document", context do
83+
db_name = context[:db_name]
84+
id = "my-partition-post:doc"
85+
url = "/#{db_name}"
86+
87+
resp = Couch.post(url, body: %{_id: id, partitioned_doc: true})
88+
assert resp.status_code == 201
89+
90+
resp = Couch.get("#{url}/#{id}")
91+
assert resp.status_code == 200
92+
93+
%{body: doc} = resp
94+
assert doc["_id"] == id
95+
end
96+
97+
@tag :with_partitioned_db
98+
test "POST and _bulk_get document", context do
99+
db_name = context[:db_name]
100+
id = "my-partition-post:doc"
101+
url = "/#{db_name}"
102+
103+
resp = Couch.post(url, body: %{_id: id, partitioned_doc: true})
104+
assert resp.status_code == 201
105+
106+
resp = Couch.post("#{url}/_bulk_get", body: %{docs: [%{id: id}]})
107+
assert resp.status_code == 200
108+
109+
%{body: body} = resp
110+
111+
assert %{
112+
"results" => [
113+
%{
114+
"docs" => [
115+
%{
116+
"ok" => %{
117+
"_id" => "my-partition-post:doc",
118+
"_rev" => "1-43d86359741cb629c0953a2beb6e9d7a",
119+
"partitioned_doc" => true
120+
}
121+
}
122+
],
123+
"id" => "my-partition-post:doc"
124+
}
125+
]
126+
} == body
127+
end
128+
129+
@tag :with_partitioned_db
130+
test "_bulk_get bad partitioned document", context do
131+
db_name = context[:db_name]
132+
id = "my-partition-post"
133+
url = "/#{db_name}"
134+
135+
resp = Couch.post("#{url}/_bulk_get", body: %{docs: [%{id: id}]})
136+
assert resp.status_code == 200
137+
%{:body => body} = resp
138+
139+
assert %{
140+
"results" => [
141+
%{
142+
"docs" => [
143+
%{
144+
"error" => %{
145+
"error" => "illegal_docid",
146+
"id" => "my-partition-post",
147+
"reason" => "Document id must contain a partition",
148+
"rev" => :null
149+
}
150+
}
151+
],
152+
"id" => "my-partition-post"
153+
}
154+
]
155+
} == body
156+
end
157+
158+
@tag :with_partitioned_db
159+
test "POST fails if a partition key is not supplied", context do
160+
db_name = context[:db_name]
161+
id = "not-partitioned-post"
162+
url = "/#{db_name}"
163+
164+
resp = Couch.post(url, body: %{_id: id, partitited_doc: false})
165+
assert resp.status_code == 400
166+
end
167+
168+
@tag :with_partitioned_db
169+
test "_bulk_docs saves docs with partition key", context do
170+
db_name = context[:db_name]
171+
172+
docs = [
173+
%{_id: "foo:1"},
174+
%{_id: "bar:1"}
175+
]
176+
177+
url = "/#{db_name}"
178+
resp = Couch.post("#{url}/_bulk_docs", body: %{:docs => docs})
179+
assert resp.status_code == 201
180+
181+
resp = Couch.get("#{url}/foo:1")
182+
assert resp.status_code == 200
183+
184+
resp = Couch.get("#{url}/bar:1")
185+
assert resp.status_code == 200
186+
end
187+
188+
@tag :with_partitioned_db
189+
test "_bulk_docs errors with missing partition key", context do
190+
db_name = context[:db_name]
191+
192+
docs = [
193+
%{_id: "foo1"}
194+
]
195+
196+
error = %{
197+
"error" => "illegal_docid",
198+
"reason" => "Document id must contain a partition"
199+
}
200+
201+
url = "/#{db_name}"
202+
resp = Couch.post("#{url}/_bulk_docs", body: %{:docs => docs})
203+
assert resp.status_code == 400
204+
assert Map.get(resp, :body) == error
205+
end
206+
207+
@tag :with_partitioned_db
208+
test "_bulk_docs errors with bad partition key", context do
209+
db_name = context[:db_name]
210+
211+
docs = [
212+
%{_id: "_foo:1"}
213+
]
214+
215+
error = %{
216+
"error" => "illegal_docid",
217+
"reason" => "Only reserved document ids may start with underscore."
218+
}
219+
220+
url = "/#{db_name}"
221+
resp = Couch.post("#{url}/_bulk_docs", body: %{:docs => docs})
222+
assert resp.status_code == 400
223+
assert Map.get(resp, :body) == error
224+
end
225+
226+
@tag :with_partitioned_db
227+
test "_bulk_docs errors with bad doc key", context do
228+
db_name = context[:db_name]
229+
230+
docs = [
231+
%{_id: "foo:"}
232+
]
233+
234+
error = %{
235+
"error" => "illegal_docid",
236+
"reason" => "Document id must not be empty"
237+
}
238+
239+
url = "/#{db_name}"
240+
resp = Couch.post("#{url}/_bulk_docs", body: %{:docs => docs})
241+
assert resp.status_code == 400
242+
assert Map.get(resp, :body) == error
243+
end
244+
245+
@tag :with_partitioned_db
246+
test "saves attachment with partitioned doc", context do
247+
db_name = context[:db_name]
248+
id = "foo:doc-with-attachment"
249+
250+
doc = %{
251+
_id: id,
252+
_attachments: %{
253+
"foo.txt": %{
254+
content_type: "text/plain",
255+
data: Base.encode64("This is a text document to save")
256+
}
257+
}
258+
}
259+
260+
resp = Couch.put("/#{db_name}/#{id}", body: doc)
261+
262+
assert resp.status_code == 201
263+
264+
resp = Couch.get("/#{db_name}/#{id}")
265+
assert resp.status_code == 200
266+
body = Map.get(resp, :body)
267+
rev = Map.get(body, "_rev")
268+
269+
assert body["_attachments"] == %{
270+
"foo.txt" => %{
271+
"content_type" => "text/plain",
272+
"digest" => "md5-OW2BoZAtMqs1E+fAnLpNBw==",
273+
"length" => 31,
274+
"revpos" => 1,
275+
"stub" => true
276+
}
277+
}
278+
279+
resp = Couch.get("/#{db_name}/#{id}/foo.txt")
280+
assert Map.get(resp, :body) == "This is a text document to save"
281+
282+
resp =
283+
Couch.put("/#{db_name}/#{id}/bar.txt?rev=#{rev}",
284+
headers: ["Content-Type": "text/plain"],
285+
body: "This is another document"
286+
)
287+
288+
assert resp.status_code == 201
289+
%{:body => body} = resp
290+
assert body["ok"] == true
291+
assert body["id"] == id
292+
end
293+
294+
test "create database with bad `partitioned` value", _context do
295+
resp = Couch.put("/bad-db?partitioned=tru")
296+
assert resp.status_code == 400
297+
298+
assert Map.get(resp, :body) == %{
299+
"error" => "bad_request",
300+
"reason" => "Invalid `partitioned` parameter"
301+
}
302+
end
303+
304+
test "can create unpartitioned system db", _context do
305+
Couch.delete("/_replicator")
306+
resp = Couch.put("/_replicator")
307+
assert resp.status_code == 201
308+
assert resp.body == %{"ok" => true}
309+
end
310+
311+
test "cannot create partitioned system db", _context do
312+
Couch.delete("/_replicator")
313+
314+
resp = Couch.put("/_replicator?partitioned=true")
315+
assert resp.status_code == 400
316+
317+
%{:body => %{"reason" => reason}} = resp
318+
assert Regex.match?(~r/Cannot partition a system database/, reason)
319+
end
320+
end
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
defmodule PartitionDesignDocsTest do
2+
use CouchTestCase
3+
4+
@moduledoc """
5+
Test Partition functionality for partition design docs
6+
"""
7+
8+
@tag :with_partitioned_db
9+
test "/_partition/:pk/_design/doc 404", context do
10+
db_name = context[:db_name]
11+
12+
url = "/#{db_name}/_partition/fake-key/_design/mrtest/"
13+
resp = Couch.get(url)
14+
assert resp.status_code == 404
15+
end
16+
end

0 commit comments

Comments
 (0)