~ubuntu-branches/ubuntu/maverick/couchdb/maverick

« back to all changes in this revision

Viewing changes to test/etap/112-replication-missing-revs.t

  • Committer: Bazaar Package Importer
  • Author(s): Elliot Murphy
  • Date: 2009-10-13 16:50:35 UTC
  • mfrom: (1.2.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20091013165035-gelrjx6yvpkuyzpf
Tags: 0.10.0-0ubuntu1
* Final 0.10.0 upstream release. (LP: #450442)
  - CouchDB 0.10.0 is now a beta version, not alpha.
  - Fixes replication with 0.9 servers.
  - Fix UUID's tests.
  - Includes ETap into the test suite.
  - Fix UUID's ETags.
  - Fix cookie and oauth+replication.
  - OAuth support for https URL scheme.
  - Reject invalid UTF-8.
* debian/patches
  - dropped oauth-replication-crash-fix-backport.patch
* debian/copyright
  - added src/etap/* to copyright file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env escript
 
2
%% -*- erlang -*-
 
3
 
 
4
% Licensed under the Apache License, Version 2.0 (the "License"); you may not
 
5
% use this file except in compliance with the License.  You may obtain a copy of
 
6
% the License at
 
7
%
 
8
%   http://www.apache.org/licenses/LICENSE-2.0
 
9
%
 
10
% Unless required by applicable law or agreed to in writing, software
 
11
% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 
12
% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
 
13
% License for the specific language governing permissions and limitations under
 
14
% the License.
 
15
 
 
16
%% XXX: Figure out how to -include("couch_db.hrl")
 
17
 
 
18
-record(doc, {id= <<"">>, revs={0, []}, body={[]},
 
19
            attachments=[], deleted=false, meta=[]}).
 
20
 
 
21
-record(http_db, {
 
22
    url,
 
23
    auth = [],
 
24
    resource = "",
 
25
    headers = [
 
26
        {"User-Agent", "CouchDb/"++couch_server:get_version()},
 
27
        {"Accept", "application/json"},
 
28
        {"Accept-Encoding", "gzip"}
 
29
    ],
 
30
    qs = [],
 
31
    method = get,
 
32
    body = nil,
 
33
    options = [
 
34
        {response_format,binary},
 
35
        {inactivity_timeout, 30000}
 
36
    ],
 
37
    retries = 10,
 
38
    pause = 1,
 
39
    conn = nil
 
40
}).
 
41
 
 
42
main(_) ->
 
43
    code:add_patha("src/etap"),
 
44
    code:add_pathz("src/couchdb"),
 
45
    code:add_pathz("src/ibrowse"),
 
46
    code:add_pathz("src/mochiweb"),
 
47
    code:add_pathz("src/erlang-oauth"),
 
48
    
 
49
    etap:plan(12),
 
50
    case (catch test()) of
 
51
        ok ->
 
52
            etap:end_tests();
 
53
        Other ->
 
54
            etap:diag(io_lib:format("Test died abnormally: ~p", [Other])),
 
55
            etap:bail(Other)
 
56
    end,
 
57
    ok.
 
58
 
 
59
test() ->
 
60
    couch_server:start(
 
61
        ["etc/couchdb/default_dev.ini", "etc/couchdb/local_dev.ini"]
 
62
    ),
 
63
    ibrowse:start(),
 
64
    crypto:start(),
 
65
 
 
66
    couch_server:delete(<<"etap-test-source">>, []),
 
67
    couch_server:delete(<<"etap-test-target">>, []),
 
68
 
 
69
    Dbs1 = setup(),
 
70
    test_all(local, local),
 
71
    ok = teardown(Dbs1),
 
72
 
 
73
    Dbs2 = setup(),
 
74
    test_all(local, remote),
 
75
    ok = teardown(Dbs2),
 
76
 
 
77
    Dbs3 = setup(),
 
78
    test_all(remote, local),
 
79
    ok = teardown(Dbs3),
 
80
 
 
81
    Dbs4 = setup(),
 
82
    test_all(remote, remote),
 
83
    ok = teardown(Dbs4),
 
84
 
 
85
    ok.
 
86
 
 
87
test_all(SrcType, TgtType) ->
 
88
    test_unchanged_db(SrcType, TgtType),
 
89
    test_multiple_changes(SrcType, TgtType),
 
90
    test_changes_not_missing(SrcType, TgtType).
 
91
 
 
92
test_unchanged_db(SrcType, TgtType) ->
 
93
    {ok, Pid1} = start_changes_feed(SrcType, 0, false),
 
94
    {ok, Pid2} = start_missing_revs(TgtType, Pid1),
 
95
    etap:is(
 
96
        couch_rep_missing_revs:next(Pid2),
 
97
        complete,
 
98
        io_lib:format(
 
99
            "(~p, ~p) no missing revs if source is unchanged",
 
100
            [SrcType, TgtType])
 
101
    ).
 
102
 
 
103
test_multiple_changes(SrcType, TgtType) ->
 
104
    Expect = {2, [generate_change(), generate_change()]},
 
105
    {ok, Pid1} = start_changes_feed(SrcType, 0, false),
 
106
    {ok, Pid2} = start_missing_revs(TgtType, Pid1),
 
107
    etap:is(
 
108
        get_all_missing_revs(Pid2, {0, []}),
 
109
        Expect,
 
110
        io_lib:format("(~p, ~p) add src docs, get missing tgt revs + high seq",
 
111
            [SrcType, TgtType])
 
112
    ).
 
113
 
 
114
test_changes_not_missing(SrcType, TgtType) ->
 
115
    %% put identical changes on source and target
 
116
    Id = couch_util:new_uuid(),
 
117
    {Id, _Seq, [Rev]} = Expect = generate_change(Id, {[]}, get_db(source)),
 
118
    {Id, _, [Rev]} = generate_change(Id, {[]}, get_db(target)),
 
119
 
 
120
    %% confirm that this change is not in missing revs feed
 
121
    {ok, Pid1} = start_changes_feed(SrcType, 0, false),
 
122
    {ok, Pid2} = start_missing_revs(TgtType, Pid1),
 
123
    {HighSeq, AllRevs} = get_all_missing_revs(Pid2, {0, []}),
 
124
 
 
125
    %% etap:none/3 has a bug, so just define it correctly here
 
126
    etap:is(
 
127
        lists:member(Expect, AllRevs),
 
128
        false,
 
129
        io_lib:format(
 
130
            "(~p, ~p) skip revs that already exist on target",
 
131
            [SrcType, TgtType])
 
132
    ).
 
133
 
 
134
generate_change() ->
 
135
    generate_change(couch_util:new_uuid()).
 
136
 
 
137
generate_change(Id) ->
 
138
    generate_change(Id, {[]}).
 
139
 
 
140
generate_change(Id, EJson) ->
 
141
    generate_change(Id, EJson, get_db(source)).
 
142
 
 
143
generate_change(Id, EJson, Db) ->
 
144
    Doc = couch_doc:from_json_obj(EJson),
 
145
    Seq = get_update_seq(),
 
146
    {ok, Rev} = couch_db:update_doc(Db, Doc#doc{id = Id}, [full_commit]),
 
147
    couch_db:close(Db),
 
148
    {Id, Seq+1, [Rev]}.
 
149
 
 
150
get_all_missing_revs(Pid, {HighSeq, Revs}) ->
 
151
    case couch_rep_missing_revs:next(Pid) of
 
152
    complete ->
 
153
        {HighSeq, lists:flatten(lists:reverse(Revs))};
 
154
    {Seq, More} ->
 
155
        get_all_missing_revs(Pid, {Seq, [More|Revs]})
 
156
    end.
 
157
 
 
158
get_db(source) ->
 
159
    {ok, Db} = couch_db:open(<<"etap-test-source">>, []),
 
160
    Db;
 
161
get_db(target) ->
 
162
    {ok, Db} = couch_db:open(<<"etap-test-target">>, []),
 
163
    Db.
 
164
 
 
165
get_update_seq() ->
 
166
    Db = get_db(source),
 
167
    Seq = couch_db:get_update_seq(Db),
 
168
    couch_db:close(Db),
 
169
    Seq.
 
170
 
 
171
setup() ->
 
172
    {ok, DbA} = couch_db:create(<<"etap-test-source">>, []),
 
173
    {ok, DbB} = couch_db:create(<<"etap-test-target">>, []),
 
174
    [DbA, DbB].
 
175
 
 
176
teardown([DbA, DbB]) ->
 
177
    couch_db:close(DbA),
 
178
    couch_db:close(DbB),
 
179
    couch_server:delete(<<"etap-test-source">>, []),
 
180
    couch_server:delete(<<"etap-test-target">>, []),
 
181
    ok.
 
182
 
 
183
start_changes_feed(local, Since, Continuous) ->
 
184
    Props = [{<<"continuous">>, Continuous}],
 
185
    couch_rep_changes_feed:start_link(self(), get_db(source), Since, Props);
 
186
start_changes_feed(remote, Since, Continuous) ->
 
187
    Props = [{<<"continuous">>, Continuous}],
 
188
    Db = #http_db{url = "http://127.0.0.1:5984/etap-test-source/"},
 
189
    couch_rep_changes_feed:start_link(self(), Db, Since, Props).
 
190
 
 
191
start_missing_revs(local, Changes) ->
 
192
    couch_rep_missing_revs:start_link(self(), get_db(target), Changes, []);
 
193
start_missing_revs(remote, Changes) ->
 
194
    Db = #http_db{url = "http://127.0.0.1:5984/etap-test-target/"},
 
195
    couch_rep_missing_revs:start_link(self(), Db, Changes, []).