Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 1ED24114C2 for ; Mon, 11 Aug 2014 20:22:43 +0000 (UTC) Received: (qmail 92182 invoked by uid 500); 11 Aug 2014 20:22:39 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 91841 invoked by uid 500); 11 Aug 2014 20:22:39 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 89850 invoked by uid 99); 11 Aug 2014 20:22:38 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 11 Aug 2014 20:22:38 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 98A3E81412D; Mon, 11 Aug 2014 20:22:38 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: chewbranca@apache.org To: commits@couchdb.apache.org Date: Mon, 11 Aug 2014 20:23:15 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [39/50] [abbrv] Move files out of test/couchdb into top level test/ folder http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/couchdb_update_conflicts_tests.erl ---------------------------------------------------------------------- diff --git a/test/couchdb/couchdb_update_conflicts_tests.erl b/test/couchdb/couchdb_update_conflicts_tests.erl deleted file mode 100644 index 7226860..0000000 --- a/test/couchdb/couchdb_update_conflicts_tests.erl +++ /dev/null @@ -1,243 +0,0 @@ -% Licensed under the Apache License, Version 2.0 (the "License"); you may not -% use this file except in compliance with the License. You may obtain a copy of -% the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -% License for the specific language governing permissions and limitations under -% the License. - --module(couchdb_update_conflicts_tests). - --include("couch_eunit.hrl"). --include_lib("couchdb/couch_db.hrl"). - --define(i2l(I), integer_to_list(I)). --define(ADMIN_USER, {userctx, #user_ctx{roles=[<<"_admin">>]}}). --define(DOC_ID, <<"foobar">>). --define(NUM_CLIENTS, [100, 500, 1000, 2000, 5000, 10000]). --define(TIMEOUT, 10000). - - -start() -> - {ok, Pid} = couch_server_sup:start_link(?CONFIG_CHAIN), - couch_config:set("couchdb", "delayed_commits", "true", false), - Pid. - -stop(Pid) -> - erlang:monitor(process, Pid), - couch_server_sup:stop(), - receive - {'DOWN', _, _, Pid, _} -> - ok - after ?TIMEOUT -> - throw({timeout, server_stop}) - end. - -setup() -> - DbName = ?tempdb(), - {ok, Db} = couch_db:create(DbName, [?ADMIN_USER, overwrite]), - Doc = couch_doc:from_json_obj({[{<<"_id">>, ?DOC_ID}, - {<<"value">>, 0}]}), - {ok, Rev} = couch_db:update_doc(Db, Doc, []), - ok = couch_db:close(Db), - RevStr = couch_doc:rev_to_str(Rev), - {DbName, RevStr}. -setup(_) -> - setup(). - -teardown({DbName, _}) -> - ok = couch_server:delete(DbName, []), - ok. -teardown(_, {DbName, _RevStr}) -> - teardown({DbName, _RevStr}). - - -view_indexes_cleanup_test_() -> - { - "Update conflicts", - { - setup, - fun start/0, fun stop/1, - [ - concurrent_updates(), - couchdb_188() - ] - } - }. - -concurrent_updates()-> - { - "Concurrent updates", - { - foreachx, - fun setup/1, fun teardown/2, - [{NumClients, fun should_concurrently_update_doc/2} - || NumClients <- ?NUM_CLIENTS] - } - }. - -couchdb_188()-> - { - "COUCHDB-188", - { - foreach, - fun setup/0, fun teardown/1, - [fun should_bulk_create_delete_doc/1] - } - }. - - -should_concurrently_update_doc(NumClients, {DbName, InitRev})-> - {?i2l(NumClients) ++ " clients", - {inorder, - [{"update doc", - {timeout, ?TIMEOUT div 1000, - ?_test(concurrent_doc_update(NumClients, DbName, InitRev))}}, - {"ensure in single leaf", - ?_test(ensure_in_single_revision_leaf(DbName))}]}}. - -should_bulk_create_delete_doc({DbName, InitRev})-> - ?_test(bulk_delete_create(DbName, InitRev)). - - -concurrent_doc_update(NumClients, DbName, InitRev) -> - Clients = lists:map( - fun(Value) -> - ClientDoc = couch_doc:from_json_obj({[ - {<<"_id">>, ?DOC_ID}, - {<<"_rev">>, InitRev}, - {<<"value">>, Value} - ]}), - Pid = spawn_client(DbName, ClientDoc), - {Value, Pid, erlang:monitor(process, Pid)} - end, - lists:seq(1, NumClients)), - - lists:foreach(fun({_, Pid, _}) -> Pid ! go end, Clients), - - {NumConflicts, SavedValue} = lists:foldl( - fun({Value, Pid, MonRef}, {AccConflicts, AccValue}) -> - receive - {'DOWN', MonRef, process, Pid, {ok, _NewRev}} -> - {AccConflicts, Value}; - {'DOWN', MonRef, process, Pid, conflict} -> - {AccConflicts + 1, AccValue}; - {'DOWN', MonRef, process, Pid, Error} -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, "Client " ++ ?i2l(Value) - ++ " got update error: " - ++ couch_util:to_list(Error)}]}) - after ?TIMEOUT div 2 -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, "Timeout waiting for client " - ++ ?i2l(Value) ++ " to die"}]}) - end - end, {0, nil}, Clients), - ?assertEqual(NumClients - 1, NumConflicts), - - {ok, Db} = couch_db:open_int(DbName, []), - {ok, Leaves} = couch_db:open_doc_revs(Db, ?DOC_ID, all, []), - ok = couch_db:close(Db), - ?assertEqual(1, length(Leaves)), - - [{ok, Doc2}] = Leaves, - {JsonDoc} = couch_doc:to_json_obj(Doc2, []), - ?assertEqual(SavedValue, couch_util:get_value(<<"value">>, JsonDoc)). - -ensure_in_single_revision_leaf(DbName) -> - {ok, Db} = couch_db:open_int(DbName, []), - {ok, Leaves} = couch_db:open_doc_revs(Db, ?DOC_ID, all, []), - ok = couch_db:close(Db), - [{ok, Doc}] = Leaves, - - %% FIXME: server restart won't work from test side - %% stop(ok), - %% start(), - - {ok, Db2} = couch_db:open_int(DbName, []), - {ok, Leaves2} = couch_db:open_doc_revs(Db2, ?DOC_ID, all, []), - ok = couch_db:close(Db2), - ?assertEqual(1, length(Leaves2)), - - [{ok, Doc2}] = Leaves, - ?assertEqual(Doc, Doc2). - -bulk_delete_create(DbName, InitRev) -> - {ok, Db} = couch_db:open_int(DbName, []), - - DeletedDoc = couch_doc:from_json_obj({[ - {<<"_id">>, ?DOC_ID}, - {<<"_rev">>, InitRev}, - {<<"_deleted">>, true} - ]}), - NewDoc = couch_doc:from_json_obj({[ - {<<"_id">>, ?DOC_ID}, - {<<"value">>, 666} - ]}), - - {ok, Results} = couch_db:update_docs(Db, [DeletedDoc, NewDoc], []), - ok = couch_db:close(Db), - - ?assertEqual(2, length([ok || {ok, _} <- Results])), - [{ok, Rev1}, {ok, Rev2}] = Results, - - {ok, Db2} = couch_db:open_int(DbName, []), - {ok, [{ok, Doc1}]} = couch_db:open_doc_revs( - Db2, ?DOC_ID, [Rev1], [conflicts, deleted_conflicts]), - {ok, [{ok, Doc2}]} = couch_db:open_doc_revs( - Db2, ?DOC_ID, [Rev2], [conflicts, deleted_conflicts]), - ok = couch_db:close(Db2), - - {Doc1Props} = couch_doc:to_json_obj(Doc1, []), - {Doc2Props} = couch_doc:to_json_obj(Doc2, []), - - %% Document was deleted - ?assert(couch_util:get_value(<<"_deleted">>, Doc1Props)), - %% New document not flagged as deleted - ?assertEqual(undefined, couch_util:get_value(<<"_deleted">>, - Doc2Props)), - %% New leaf revision has the right value - ?assertEqual(666, couch_util:get_value(<<"value">>, - Doc2Props)), - %% Deleted document has no conflicts - ?assertEqual(undefined, couch_util:get_value(<<"_conflicts">>, - Doc1Props)), - %% Deleted document has no deleted conflicts - ?assertEqual(undefined, couch_util:get_value(<<"_deleted_conflicts">>, - Doc1Props)), - %% New leaf revision doesn't have conflicts - ?assertEqual(undefined, couch_util:get_value(<<"_conflicts">>, - Doc1Props)), - %% New leaf revision doesn't have deleted conflicts - ?assertEqual(undefined, couch_util:get_value(<<"_deleted_conflicts">>, - Doc1Props)), - - %% Deleted revision has position 2 - ?assertEqual(2, element(1, Rev1)), - %% New leaf revision has position 1 - ?assertEqual(1, element(1, Rev2)). - - -spawn_client(DbName, Doc) -> - spawn(fun() -> - {ok, Db} = couch_db:open_int(DbName, []), - receive - go -> ok - end, - erlang:yield(), - Result = try - couch_db:update_doc(Db, Doc, []) - catch _:Error -> - Error - end, - ok = couch_db:close(Db), - exit(Result) - end). http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/couchdb_vhosts_tests.erl ---------------------------------------------------------------------- diff --git a/test/couchdb/couchdb_vhosts_tests.erl b/test/couchdb/couchdb_vhosts_tests.erl deleted file mode 100644 index 94b1957..0000000 --- a/test/couchdb/couchdb_vhosts_tests.erl +++ /dev/null @@ -1,441 +0,0 @@ -% Licensed under the Apache License, Version 2.0 (the "License"); you may not -% use this file except in compliance with the License. You may obtain a copy of -% the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -% License for the specific language governing permissions and limitations under -% the License. - --module(couchdb_vhosts_tests). - --include("couch_eunit.hrl"). --include_lib("couchdb/couch_db.hrl"). - --define(ADMIN_USER, {user_ctx, #user_ctx{roles=[<<"_admin">>]}}). --define(TIMEOUT, 1000). --define(iofmt(S, A), lists:flatten(io_lib:format(S, A))). - - -start() -> - {ok, Pid} = couch_server_sup:start_link(?CONFIG_CHAIN), - Pid. - -stop(Pid) -> - erlang:monitor(process, Pid), - couch_server_sup:stop(), - receive - {'DOWN', _, _, Pid, _} -> - ok - after ?TIMEOUT -> - throw({timeout, server_stop}) - end. - -setup() -> - DbName = ?tempdb(), - {ok, Db} = couch_db:create(DbName, [?ADMIN_USER]), - Doc = couch_doc:from_json_obj({[ - {<<"_id">>, <<"doc1">>}, - {<<"value">>, 666} - ]}), - - Doc1 = couch_doc:from_json_obj({[ - {<<"_id">>, <<"_design/doc1">>}, - {<<"shows">>, {[ - {<<"test">>, <<"function(doc, req) { - return { json: { - requested_path: '/' + req.requested_path.join('/'), - path: '/' + req.path.join('/')}};}">>} - ]}}, - {<<"rewrites">>, [ - {[ - {<<"from">>, <<"/">>}, - {<<"to">>, <<"_show/test">>} - ]} - ]} - ]}), - {ok, _} = couch_db:update_docs(Db, [Doc, Doc1]), - couch_db:ensure_full_commit(Db), - couch_db:close(Db), - - Addr = couch_config:get("httpd", "bind_address", "127.0.0.1"), - Port = integer_to_list(mochiweb_socket_server:get(couch_httpd, port)), - Url = "http://" ++ Addr ++ ":" ++ Port, - {Url, ?b2l(DbName)}. - -setup_oauth() -> - DbName = ?tempdb(), - {ok, Db} = couch_db:create(DbName, [?ADMIN_USER]), - - couch_config:set("couch_httpd_auth", "authentication_db", - ?b2l(?tempdb()), false), - couch_config:set("oauth_token_users", "otoksec1", "joe", false), - couch_config:set("oauth_consumer_secrets", "consec1", "foo", false), - couch_config:set("oauth_token_secrets", "otoksec1", "foobar", false), - couch_config:set("couch_httpd_auth", "require_valid_user", "true", false), - - ok = couch_config:set( - "vhosts", "oauth-example.com", - "/" ++ ?b2l(DbName) ++ "/_design/test/_rewrite/foobar", false), - - DDoc = couch_doc:from_json_obj({[ - {<<"_id">>, <<"_design/test">>}, - {<<"language">>, <<"javascript">>}, - {<<"rewrites">>, [ - {[ - {<<"from">>, <<"foobar">>}, - {<<"to">>, <<"_info">>} - ]} - ]} - ]}), - {ok, _} = couch_db:update_doc(Db, DDoc, []), - - couch_db:ensure_full_commit(Db), - couch_db:close(Db), - - Addr = couch_config:get("httpd", "bind_address", "127.0.0.1"), - Port = integer_to_list(mochiweb_socket_server:get(couch_httpd, port)), - Url = "http://" ++ Addr ++ ":" ++ Port, - {Url, ?b2l(DbName)}. - -teardown({_, DbName}) -> - ok = couch_server:delete(?l2b(DbName), []), - ok. - - -vhosts_test_() -> - { - "Virtual Hosts rewrite tests", - { - setup, - fun start/0, fun stop/1, - { - foreach, - fun setup/0, fun teardown/1, - [ - fun should_return_database_info/1, - fun should_return_revs_info/1, - fun should_serve_utils_for_vhost/1, - fun should_return_virtual_request_path_field_in_request/1, - fun should_return_real_request_path_field_in_request/1, - fun should_match_wildcard_vhost/1, - fun should_return_db_info_for_wildcard_vhost_for_custom_db/1, - fun should_replace_rewrite_variables_for_db_and_doc/1, - fun should_return_db_info_for_vhost_with_resource/1, - fun should_return_revs_info_for_vhost_with_resource/1, - fun should_return_db_info_for_vhost_with_wildcard_resource/1, - fun should_return_path_for_vhost_with_wildcard_host/1 - ] - } - } - }. - -oauth_test_() -> - { - "Virtual Hosts OAuth tests", - { - setup, - fun start/0, fun stop/1, - { - foreach, - fun setup_oauth/0, fun teardown/1, - [ - fun should_require_auth/1, - fun should_succeed_oauth/1, - fun should_fail_oauth_with_wrong_credentials/1 - ] - } - } - }. - - -should_return_database_info({Url, DbName}) -> - ?_test(begin - ok = couch_config:set("vhosts", "example.com", "/" ++ DbName, false), - case test_request:get(Url, [], [{host_header, "example.com"}]) of - {ok, _, _, Body} -> - {JsonBody} = ejson:decode(Body), - ?assert(proplists:is_defined(<<"db_name">>, JsonBody)); - Else -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, ?iofmt("Request failed: ~p", [Else])}]}) - end - end). - -should_return_revs_info({Url, DbName}) -> - ?_test(begin - ok = couch_config:set("vhosts", "example.com", "/" ++ DbName, false), - case test_request:get(Url ++ "/doc1?revs_info=true", [], - [{host_header, "example.com"}]) of - {ok, _, _, Body} -> - {JsonBody} = ejson:decode(Body), - ?assert(proplists:is_defined(<<"_revs_info">>, JsonBody)); - Else -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, ?iofmt("Request failed: ~p", [Else])}]}) - end - end). - -should_serve_utils_for_vhost({Url, DbName}) -> - ?_test(begin - ok = couch_config:set("vhosts", "example.com", "/" ++ DbName, false), - case test_request:get(Url ++ "/_utils/index.html", [], - [{host_header, "example.com"}]) of - {ok, _, _, Body} -> - ?assertMatch(<<"", _/binary>>, Body); - Else -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, ?iofmt("Request failed: ~p", [Else])}]}) - end - end). - -should_return_virtual_request_path_field_in_request({Url, DbName}) -> - ?_test(begin - ok = couch_config:set("vhosts", "example1.com", - "/" ++ DbName ++ "/_design/doc1/_rewrite/", - false), - case test_request:get(Url, [], [{host_header, "example1.com"}]) of - {ok, _, _, Body} -> - {Json} = ejson:decode(Body), - ?assertEqual(<<"/">>, - proplists:get_value(<<"requested_path">>, Json)); - Else -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, ?iofmt("Request failed: ~p", [Else])}]}) - end - end). - -should_return_real_request_path_field_in_request({Url, DbName}) -> - ?_test(begin - ok = couch_config:set("vhosts", "example1.com", - "/" ++ DbName ++ "/_design/doc1/_rewrite/", - false), - case test_request:get(Url, [], [{host_header, "example1.com"}]) of - {ok, _, _, Body} -> - {Json} = ejson:decode(Body), - Path = ?l2b("/" ++ DbName ++ "/_design/doc1/_show/test"), - ?assertEqual(Path, proplists:get_value(<<"path">>, Json)); - Else -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, ?iofmt("Request failed: ~p", [Else])}]}) - end - end). - -should_match_wildcard_vhost({Url, DbName}) -> - ?_test(begin - ok = couch_config:set("vhosts", "*.example.com", - "/" ++ DbName ++ "/_design/doc1/_rewrite", false), - case test_request:get(Url, [], [{host_header, "test.example.com"}]) of - {ok, _, _, Body} -> - {Json} = ejson:decode(Body), - Path = ?l2b("/" ++ DbName ++ "/_design/doc1/_show/test"), - ?assertEqual(Path, proplists:get_value(<<"path">>, Json)); - Else -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, ?iofmt("Request failed: ~p", [Else])}]}) - end - end). - -should_return_db_info_for_wildcard_vhost_for_custom_db({Url, DbName}) -> - ?_test(begin - ok = couch_config:set("vhosts", ":dbname.example1.com", - "/:dbname", false), - Host = DbName ++ ".example1.com", - case test_request:get(Url, [], [{host_header, Host}]) of - {ok, _, _, Body} -> - {JsonBody} = ejson:decode(Body), - ?assert(proplists:is_defined(<<"db_name">>, JsonBody)); - Else -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, ?iofmt("Request failed: ~p", [Else])}]}) - end - end). - -should_replace_rewrite_variables_for_db_and_doc({Url, DbName}) -> - ?_test(begin - ok = couch_config:set("vhosts",":appname.:dbname.example1.com", - "/:dbname/_design/:appname/_rewrite/", false), - Host = "doc1." ++ DbName ++ ".example1.com", - case test_request:get(Url, [], [{host_header, Host}]) of - {ok, _, _, Body} -> - {Json} = ejson:decode(Body), - Path = ?l2b("/" ++ DbName ++ "/_design/doc1/_show/test"), - ?assertEqual(Path, proplists:get_value(<<"path">>, Json)); - Else -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, ?iofmt("Request failed: ~p", [Else])}]}) - end - end). - -should_return_db_info_for_vhost_with_resource({Url, DbName}) -> - ?_test(begin - ok = couch_config:set("vhosts", - "example.com/test", "/" ++ DbName, false), - ReqUrl = Url ++ "/test", - case test_request:get(ReqUrl, [], [{host_header, "example.com"}]) of - {ok, _, _, Body} -> - {JsonBody} = ejson:decode(Body), - ?assert(proplists:is_defined(<<"db_name">>, JsonBody)); - Else -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, ?iofmt("Request failed: ~p", [Else])}]}) - end - end). - - -should_return_revs_info_for_vhost_with_resource({Url, DbName}) -> - ?_test(begin - ok = couch_config:set("vhosts", - "example.com/test", "/" ++ DbName, false), - ReqUrl = Url ++ "/test/doc1?revs_info=true", - case test_request:get(ReqUrl, [], [{host_header, "example.com"}]) of - {ok, _, _, Body} -> - {JsonBody} = ejson:decode(Body), - ?assert(proplists:is_defined(<<"_revs_info">>, JsonBody)); - Else -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, ?iofmt("Request failed: ~p", [Else])}]}) - end - end). - -should_return_db_info_for_vhost_with_wildcard_resource({Url, DbName}) -> - ?_test(begin - ok = couch_config:set("vhosts", "*.example2.com/test", "/*", false), - ReqUrl = Url ++ "/test", - Host = DbName ++ ".example2.com", - case test_request:get(ReqUrl, [], [{host_header, Host}]) of - {ok, _, _, Body} -> - {JsonBody} = ejson:decode(Body), - ?assert(proplists:is_defined(<<"db_name">>, JsonBody)); - Else -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, ?iofmt("Request failed: ~p", [Else])}]}) - end - end). - -should_return_path_for_vhost_with_wildcard_host({Url, DbName}) -> - ?_test(begin - ok = couch_config:set("vhosts", "*/test1", - "/" ++ DbName ++ "/_design/doc1/_show/test", - false), - case test_request:get(Url ++ "/test1") of - {ok, _, _, Body} -> - {Json} = ejson:decode(Body), - Path = ?l2b("/" ++ DbName ++ "/_design/doc1/_show/test"), - ?assertEqual(Path, proplists:get_value(<<"path">>, Json)); - Else -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, ?iofmt("Request failed: ~p", [Else])}]}) - end - end). - -should_require_auth({Url, _}) -> - ?_test(begin - case test_request:get(Url, [], [{host_header, "oauth-example.com"}]) of - {ok, Code, _, Body} -> - ?assertEqual(401, Code), - {JsonBody} = ejson:decode(Body), - ?assertEqual(<<"unauthorized">>, - couch_util:get_value(<<"error">>, JsonBody)); - Else -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, ?iofmt("Request failed: ~p", [Else])}]}) - end - end). - -should_succeed_oauth({Url, _}) -> - ?_test(begin - AuthDbName = couch_config:get("couch_httpd_auth", "authentication_db"), - JoeDoc = couch_doc:from_json_obj({[ - {<<"_id">>, <<"org.couchdb.user:joe">>}, - {<<"type">>, <<"user">>}, - {<<"name">>, <<"joe">>}, - {<<"roles">>, []}, - {<<"password_sha">>, <<"fe95df1ca59a9b567bdca5cbaf8412abd6e06121">>}, - {<<"salt">>, <<"4e170ffeb6f34daecfd814dfb4001a73">>} - ]}), - {ok, AuthDb} = couch_db:open_int(?l2b(AuthDbName), [?ADMIN_USER]), - {ok, _} = couch_db:update_doc(AuthDb, JoeDoc, [?ADMIN_USER]), - - Host = "oauth-example.com", - Consumer = {"consec1", "foo", hmac_sha1}, - SignedParams = oauth:sign( - "GET", "http://" ++ Host ++ "/", [], Consumer, "otoksec1", "foobar"), - OAuthUrl = oauth:uri(Url, SignedParams), - - case test_request:get(OAuthUrl, [], [{host_header, Host}]) of - {ok, Code, _, Body} -> - ?assertEqual(200, Code), - {JsonBody} = ejson:decode(Body), - ?assertEqual(<<"test">>, - couch_util:get_value(<<"name">>, JsonBody)); - Else -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, ?iofmt("Request failed: ~p", [Else])}]}) - end - end). - -should_fail_oauth_with_wrong_credentials({Url, _}) -> - ?_test(begin - AuthDbName = couch_config:get("couch_httpd_auth", "authentication_db"), - JoeDoc = couch_doc:from_json_obj({[ - {<<"_id">>, <<"org.couchdb.user:joe">>}, - {<<"type">>, <<"user">>}, - {<<"name">>, <<"joe">>}, - {<<"roles">>, []}, - {<<"password_sha">>, <<"fe95df1ca59a9b567bdca5cbaf8412abd6e06121">>}, - {<<"salt">>, <<"4e170ffeb6f34daecfd814dfb4001a73">>} - ]}), - {ok, AuthDb} = couch_db:open_int(?l2b(AuthDbName), [?ADMIN_USER]), - {ok, _} = couch_db:update_doc(AuthDb, JoeDoc, [?ADMIN_USER]), - - Host = "oauth-example.com", - Consumer = {"consec1", "bad_secret", hmac_sha1}, - SignedParams = oauth:sign( - "GET", "http://" ++ Host ++ "/", [], Consumer, "otoksec1", "foobar"), - OAuthUrl = oauth:uri(Url, SignedParams), - - case test_request:get(OAuthUrl, [], [{host_header, Host}]) of - {ok, Code, _, Body} -> - ?assertEqual(401, Code), - {JsonBody} = ejson:decode(Body), - ?assertEqual(<<"unauthorized">>, - couch_util:get_value(<<"error">>, JsonBody)); - Else -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, ?iofmt("Request failed: ~p", [Else])}]}) - end - end). http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/couchdb_views_tests.erl ---------------------------------------------------------------------- diff --git a/test/couchdb/couchdb_views_tests.erl b/test/couchdb/couchdb_views_tests.erl deleted file mode 100644 index 6d81f32..0000000 --- a/test/couchdb/couchdb_views_tests.erl +++ /dev/null @@ -1,669 +0,0 @@ -% Licensed under the Apache License, Version 2.0 (the "License"); you may not -% use this file except in compliance with the License. You may obtain a copy of -% the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -% License for the specific language governing permissions and limitations under -% the License. - --module(couchdb_views_tests). - --include("couch_eunit.hrl"). --include_lib("couchdb/couch_db.hrl"). --include_lib("couch_mrview/include/couch_mrview.hrl"). - --define(ADMIN_USER, {user_ctx, #user_ctx{roles=[<<"_admin">>]}}). --define(DELAY, 100). --define(TIMEOUT, 1000). - - -start() -> - {ok, Pid} = couch_server_sup:start_link(?CONFIG_CHAIN), - Pid. - -stop(Pid) -> - erlang:monitor(process, Pid), - couch_server_sup:stop(), - receive - {'DOWN', _, _, Pid, _} -> - ok - after ?TIMEOUT -> - throw({timeout, server_stop}) - end. - -setup() -> - DbName = ?tempdb(), - {ok, Db} = couch_db:create(DbName, [?ADMIN_USER]), - ok = couch_db:close(Db), - FooRev = create_design_doc(DbName, <<"_design/foo">>, <<"bar">>), - query_view(DbName, "foo", "bar"), - BooRev = create_design_doc(DbName, <<"_design/boo">>, <<"baz">>), - query_view(DbName, "boo", "baz"), - {DbName, {FooRev, BooRev}}. - -setup_with_docs() -> - DbName = ?tempdb(), - {ok, Db} = couch_db:create(DbName, [?ADMIN_USER]), - ok = couch_db:close(Db), - create_docs(DbName), - create_design_doc(DbName, <<"_design/foo">>, <<"bar">>), - DbName. - -teardown({DbName, _}) -> - teardown(DbName); -teardown(DbName) when is_binary(DbName) -> - couch_server:delete(DbName, [?ADMIN_USER]), - ok. - - -view_indexes_cleanup_test_() -> - { - "View indexes cleanup", - { - setup, - fun start/0, fun stop/1, - { - foreach, - fun setup/0, fun teardown/1, - [ - fun should_have_two_indexes_alive_before_deletion/1, - fun should_cleanup_index_file_after_ddoc_deletion/1, - fun should_cleanup_all_index_files/1 - ] - } - } - }. - -view_group_db_leaks_test_() -> - { - "View group db leaks", - { - setup, - fun start/0, fun stop/1, - { - foreach, - fun setup_with_docs/0, fun teardown/1, - [ - fun couchdb_1138/1, - fun couchdb_1309/1 - ] - } - } - }. - -view_group_shutdown_test_() -> - { - "View group shutdown", - { - setup, - fun start/0, fun stop/1, - [couchdb_1283()] - } - }. - - -should_not_remember_docs_in_index_after_backup_restore_test() -> - %% COUCHDB-640 - start(), - DbName = setup_with_docs(), - - ok = backup_db_file(DbName), - create_doc(DbName, "doc666"), - - Rows0 = query_view(DbName, "foo", "bar"), - ?assert(has_doc("doc1", Rows0)), - ?assert(has_doc("doc2", Rows0)), - ?assert(has_doc("doc3", Rows0)), - ?assert(has_doc("doc666", Rows0)), - - restore_backup_db_file(DbName), - - Rows1 = query_view(DbName, "foo", "bar"), - ?assert(has_doc("doc1", Rows1)), - ?assert(has_doc("doc2", Rows1)), - ?assert(has_doc("doc3", Rows1)), - ?assertNot(has_doc("doc666", Rows1)), - - teardown(DbName), - stop(whereis(couch_server_sup)). - - -should_upgrade_legacy_view_files_test() -> - start(), - - ok = couch_config:set("query_server_config", "commit_freq", "0", false), - - DbName = <<"test">>, - DbFileName = "test.couch", - DbFilePath = filename:join([?FIXTURESDIR, DbFileName]), - OldViewName = "3b835456c235b1827e012e25666152f3.view", - FixtureViewFilePath = filename:join([?FIXTURESDIR, OldViewName]), - NewViewName = "a1c5929f912aca32f13446122cc6ce50.view", - - DbDir = couch_config:get("couchdb", "database_dir"), - ViewDir = couch_config:get("couchdb", "view_index_dir"), - OldViewFilePath = filename:join([ViewDir, ".test_design", OldViewName]), - NewViewFilePath = filename:join([ViewDir, ".test_design", "mrview", - NewViewName]), - - % cleanup - Files = [ - filename:join([DbDir, DbFileName]), - OldViewFilePath, - NewViewFilePath - ], - lists:foreach(fun(File) -> file:delete(File) end, Files), - - % copy old db file into db dir - {ok, _} = file:copy(DbFilePath, filename:join([DbDir, DbFileName])), - - % copy old view file into view dir - ok = filelib:ensure_dir(filename:join([ViewDir, ".test_design"])), - {ok, _} = file:copy(FixtureViewFilePath, OldViewFilePath), - - % ensure old header - OldHeader = read_header(OldViewFilePath), - ?assertMatch(#index_header{}, OldHeader), - - % query view for expected results - Rows0 = query_view(DbName, "test", "test"), - ?assertEqual(2, length(Rows0)), - - % ensure old file gone - ?assertNot(filelib:is_regular(OldViewFilePath)), - - % add doc to trigger update - DocUrl = db_url(DbName) ++ "/boo", - {ok, _, _, _} = test_request:put( - DocUrl, [{"Content-Type", "application/json"}], <<"{\"a\":3}">>), - - % query view for expected results - Rows1 = query_view(DbName, "test", "test"), - ?assertEqual(3, length(Rows1)), - - % ensure new header - timer:sleep(2000), % have to wait for awhile to upgrade the index - NewHeader = read_header(NewViewFilePath), - ?assertMatch(#mrheader{}, NewHeader), - - teardown(DbName), - stop(whereis(couch_server_sup)). - - -should_have_two_indexes_alive_before_deletion({DbName, _}) -> - view_cleanup(DbName), - ?_assertEqual(2, count_index_files(DbName)). - -should_cleanup_index_file_after_ddoc_deletion({DbName, {FooRev, _}}) -> - delete_design_doc(DbName, <<"_design/foo">>, FooRev), - view_cleanup(DbName), - ?_assertEqual(1, count_index_files(DbName)). - -should_cleanup_all_index_files({DbName, {FooRev, BooRev}})-> - delete_design_doc(DbName, <<"_design/foo">>, FooRev), - delete_design_doc(DbName, <<"_design/boo">>, BooRev), - view_cleanup(DbName), - ?_assertEqual(0, count_index_files(DbName)). - -couchdb_1138(DbName) -> - ?_test(begin - {ok, IndexerPid} = couch_index_server:get_index( - couch_mrview_index, DbName, <<"_design/foo">>), - ?assert(is_pid(IndexerPid)), - ?assert(is_process_alive(IndexerPid)), - ?assertEqual(2, count_db_refs(DbName)), - - Rows0 = query_view(DbName, "foo", "bar"), - ?assertEqual(3, length(Rows0)), - ?assertEqual(2, count_db_refs(DbName)), - ?assert(is_process_alive(IndexerPid)), - - create_doc(DbName, "doc1000"), - Rows1 = query_view(DbName, "foo", "bar"), - ?assertEqual(4, length(Rows1)), - ?assertEqual(2, count_db_refs(DbName)), - ?assert(is_process_alive(IndexerPid)), - - Ref1 = get_db_ref_counter(DbName), - compact_db(DbName), - Ref2 = get_db_ref_counter(DbName), - ?assertEqual(2, couch_ref_counter:count(Ref2)), - ?assertNotEqual(Ref2, Ref1), - ?assertNot(is_process_alive(Ref1)), - ?assert(is_process_alive(IndexerPid)), - - compact_view_group(DbName, "foo"), - ?assertEqual(2, count_db_refs(DbName)), - Ref3 = get_db_ref_counter(DbName), - ?assertEqual(Ref3, Ref2), - ?assert(is_process_alive(IndexerPid)), - - create_doc(DbName, "doc1001"), - Rows2 = query_view(DbName, "foo", "bar"), - ?assertEqual(5, length(Rows2)), - ?assertEqual(2, count_db_refs(DbName)), - ?assert(is_process_alive(IndexerPid)) - end). - -couchdb_1309(DbName) -> - ?_test(begin - {ok, IndexerPid} = couch_index_server:get_index( - couch_mrview_index, DbName, <<"_design/foo">>), - ?assert(is_pid(IndexerPid)), - ?assert(is_process_alive(IndexerPid)), - ?assertEqual(2, count_db_refs(DbName)), - - create_doc(DbName, "doc1001"), - Rows0 = query_view(DbName, "foo", "bar"), - check_rows_value(Rows0, null), - ?assertEqual(4, length(Rows0)), - ?assertEqual(2, count_db_refs(DbName)), - ?assert(is_process_alive(IndexerPid)), - - update_design_doc(DbName, <<"_design/foo">>, <<"bar">>), - {ok, NewIndexerPid} = couch_index_server:get_index( - couch_mrview_index, DbName, <<"_design/foo">>), - ?assert(is_pid(NewIndexerPid)), - ?assert(is_process_alive(NewIndexerPid)), - ?assertNotEqual(IndexerPid, NewIndexerPid), - ?assertEqual(2, count_db_refs(DbName)), - - Rows1 = query_view(DbName, "foo", "bar", ok), - ?assertEqual(0, length(Rows1)), - Rows2 = query_view(DbName, "foo", "bar"), - check_rows_value(Rows2, 1), - ?assertEqual(4, length(Rows2)), - - MonRef0 = erlang:monitor(process, IndexerPid), - receive - {'DOWN', MonRef0, _, _, _} -> - ok - after ?TIMEOUT -> - erlang:error( - {assertion_failed, - [{module, ?MODULE}, {line, ?LINE}, - {reason, "old view group is not dead after ddoc update"}]}) - end, - - MonRef1 = erlang:monitor(process, NewIndexerPid), - ok = couch_server:delete(DbName, [?ADMIN_USER]), - receive - {'DOWN', MonRef1, _, _, _} -> - ok - after ?TIMEOUT -> - erlang:error( - {assertion_failed, - [{module, ?MODULE}, {line, ?LINE}, - {reason, "new view group did not die after DB deletion"}]}) - end - end). - -couchdb_1283() -> - ?_test(begin - ok = couch_config:set("couchdb", "max_dbs_open", "3", false), - ok = couch_config:set("couchdb", "delayed_commits", "false", false), - - {ok, MDb1} = couch_db:create(?tempdb(), [?ADMIN_USER]), - DDoc = couch_doc:from_json_obj({[ - {<<"_id">>, <<"_design/foo">>}, - {<<"language">>, <<"javascript">>}, - {<<"views">>, {[ - {<<"foo">>, {[ - {<<"map">>, <<"function(doc) { emit(doc._id, null); }">>} - ]}}, - {<<"foo2">>, {[ - {<<"map">>, <<"function(doc) { emit(doc._id, null); }">>} - ]}}, - {<<"foo3">>, {[ - {<<"map">>, <<"function(doc) { emit(doc._id, null); }">>} - ]}}, - {<<"foo4">>, {[ - {<<"map">>, <<"function(doc) { emit(doc._id, null); }">>} - ]}}, - {<<"foo5">>, {[ - {<<"map">>, <<"function(doc) { emit(doc._id, null); }">>} - ]}} - ]}} - ]}), - {ok, _} = couch_db:update_doc(MDb1, DDoc, []), - ok = populate_db(MDb1, 100, 100), - query_view(MDb1#db.name, "foo", "foo"), - ok = couch_db:close(MDb1), - - {ok, Db1} = couch_db:create(?tempdb(), [?ADMIN_USER]), - ok = couch_db:close(Db1), - {ok, Db2} = couch_db:create(?tempdb(), [?ADMIN_USER]), - ok = couch_db:close(Db2), - {ok, Db3} = couch_db:create(?tempdb(), [?ADMIN_USER]), - ok = couch_db:close(Db3), - - Writer1 = spawn_writer(Db1#db.name), - Writer2 = spawn_writer(Db2#db.name), - - ?assert(is_process_alive(Writer1)), - ?assert(is_process_alive(Writer2)), - - ?assertEqual(ok, get_writer_status(Writer1)), - ?assertEqual(ok, get_writer_status(Writer2)), - - {ok, MonRef} = couch_mrview:compact(MDb1#db.name, <<"_design/foo">>, - [monitor]), - - Writer3 = spawn_writer(Db3#db.name), - ?assert(is_process_alive(Writer3)), - ?assertEqual({error, all_dbs_active}, get_writer_status(Writer3)), - - ?assert(is_process_alive(Writer1)), - ?assert(is_process_alive(Writer2)), - ?assert(is_process_alive(Writer3)), - - receive - {'DOWN', MonRef, process, _, Reason} -> - ?assertEqual(normal, Reason) - after ?TIMEOUT -> - erlang:error( - {assertion_failed, - [{module, ?MODULE}, {line, ?LINE}, - {reason, "Failure compacting view group"}]}) - end, - - ?assertEqual(ok, writer_try_again(Writer3)), - ?assertEqual(ok, get_writer_status(Writer3)), - - ?assert(is_process_alive(Writer1)), - ?assert(is_process_alive(Writer2)), - ?assert(is_process_alive(Writer3)), - - ?assertEqual(ok, stop_writer(Writer1)), - ?assertEqual(ok, stop_writer(Writer2)), - ?assertEqual(ok, stop_writer(Writer3)) - end). - -create_doc(DbName, DocId) when is_list(DocId) -> - create_doc(DbName, ?l2b(DocId)); -create_doc(DbName, DocId) when is_binary(DocId) -> - {ok, Db} = couch_db:open(DbName, [?ADMIN_USER]), - Doc666 = couch_doc:from_json_obj({[ - {<<"_id">>, DocId}, - {<<"value">>, 999} - ]}), - {ok, _} = couch_db:update_docs(Db, [Doc666]), - couch_db:ensure_full_commit(Db), - couch_db:close(Db). - -create_docs(DbName) -> - {ok, Db} = couch_db:open(DbName, [?ADMIN_USER]), - Doc1 = couch_doc:from_json_obj({[ - {<<"_id">>, <<"doc1">>}, - {<<"value">>, 1} - - ]}), - Doc2 = couch_doc:from_json_obj({[ - {<<"_id">>, <<"doc2">>}, - {<<"value">>, 2} - - ]}), - Doc3 = couch_doc:from_json_obj({[ - {<<"_id">>, <<"doc3">>}, - {<<"value">>, 3} - - ]}), - {ok, _} = couch_db:update_docs(Db, [Doc1, Doc2, Doc3]), - couch_db:ensure_full_commit(Db), - couch_db:close(Db). - -populate_db(Db, BatchSize, N) when N > 0 -> - Docs = lists:map( - fun(_) -> - couch_doc:from_json_obj({[ - {<<"_id">>, couch_uuids:new()}, - {<<"value">>, base64:encode(crypto:rand_bytes(1000))} - ]}) - end, - lists:seq(1, BatchSize)), - {ok, _} = couch_db:update_docs(Db, Docs, []), - populate_db(Db, BatchSize, N - length(Docs)); -populate_db(_Db, _, _) -> - ok. - -create_design_doc(DbName, DDName, ViewName) -> - {ok, Db} = couch_db:open(DbName, [?ADMIN_USER]), - DDoc = couch_doc:from_json_obj({[ - {<<"_id">>, DDName}, - {<<"language">>, <<"javascript">>}, - {<<"views">>, {[ - {ViewName, {[ - {<<"map">>, <<"function(doc) { emit(doc.value, null); }">>} - ]}} - ]}} - ]}), - {ok, Rev} = couch_db:update_doc(Db, DDoc, []), - couch_db:ensure_full_commit(Db), - couch_db:close(Db), - Rev. - -update_design_doc(DbName, DDName, ViewName) -> - {ok, Db} = couch_db:open(DbName, [?ADMIN_USER]), - {ok, Doc} = couch_db:open_doc(Db, DDName, [?ADMIN_USER]), - {Props} = couch_doc:to_json_obj(Doc, []), - Rev = couch_util:get_value(<<"_rev">>, Props), - DDoc = couch_doc:from_json_obj({[ - {<<"_id">>, DDName}, - {<<"_rev">>, Rev}, - {<<"language">>, <<"javascript">>}, - {<<"views">>, {[ - {ViewName, {[ - {<<"map">>, <<"function(doc) { emit(doc.value, 1); }">>} - ]}} - ]}} - ]}), - {ok, NewRev} = couch_db:update_doc(Db, DDoc, [?ADMIN_USER]), - couch_db:ensure_full_commit(Db), - couch_db:close(Db), - NewRev. - -delete_design_doc(DbName, DDName, Rev) -> - {ok, Db} = couch_db:open(DbName, [?ADMIN_USER]), - DDoc = couch_doc:from_json_obj({[ - {<<"_id">>, DDName}, - {<<"_rev">>, couch_doc:rev_to_str(Rev)}, - {<<"_deleted">>, true} - ]}), - {ok, _} = couch_db:update_doc(Db, DDoc, [Rev]), - couch_db:close(Db). - -db_url(DbName) -> - Addr = couch_config:get("httpd", "bind_address", "127.0.0.1"), - Port = integer_to_list(mochiweb_socket_server:get(couch_httpd, port)), - "http://" ++ Addr ++ ":" ++ Port ++ "/" ++ ?b2l(DbName). - -query_view(DbName, DDoc, View) -> - query_view(DbName, DDoc, View, false). - -query_view(DbName, DDoc, View, Stale) -> - {ok, Code, _Headers, Body} = test_request:get( - db_url(DbName) ++ "/_design/" ++ DDoc ++ "/_view/" ++ View - ++ case Stale of - false -> []; - _ -> "?stale=" ++ atom_to_list(Stale) - end), - ?assertEqual(200, Code), - {Props} = ejson:decode(Body), - couch_util:get_value(<<"rows">>, Props, []). - -check_rows_value(Rows, Value) -> - lists:foreach( - fun({Row}) -> - ?assertEqual(Value, couch_util:get_value(<<"value">>, Row)) - end, Rows). - -view_cleanup(DbName) -> - {ok, Db} = couch_db:open(DbName, [?ADMIN_USER]), - couch_mrview:cleanup(Db), - couch_db:close(Db). - -get_db_ref_counter(DbName) -> - {ok, #db{fd_ref_counter = Ref} = Db} = couch_db:open_int(DbName, []), - ok = couch_db:close(Db), - Ref. - -count_db_refs(DbName) -> - Ref = get_db_ref_counter(DbName), - % have to sleep a bit to let couchdb cleanup all refs and leave only - % active ones. otherwise the related tests will randomly fail due to - % count number mismatch - timer:sleep(200), - couch_ref_counter:count(Ref). - -count_index_files(DbName) -> - % call server to fetch the index files - RootDir = couch_config:get("couchdb", "view_index_dir"), - length(filelib:wildcard(RootDir ++ "/." ++ - binary_to_list(DbName) ++ "_design"++"/mrview/*")). - -has_doc(DocId1, Rows) -> - DocId = iolist_to_binary(DocId1), - lists:any(fun({R}) -> lists:member({<<"id">>, DocId}, R) end, Rows). - -backup_db_file(DbName) -> - DbDir = couch_config:get("couchdb", "database_dir"), - DbFile = filename:join([DbDir, ?b2l(DbName) ++ ".couch"]), - {ok, _} = file:copy(DbFile, DbFile ++ ".backup"), - ok. - -restore_backup_db_file(DbName) -> - DbDir = couch_config:get("couchdb", "database_dir"), - stop(whereis(couch_server_sup)), - DbFile = filename:join([DbDir, ?b2l(DbName) ++ ".couch"]), - ok = file:delete(DbFile), - ok = file:rename(DbFile ++ ".backup", DbFile), - start(), - ok. - -compact_db(DbName) -> - {ok, Db} = couch_db:open_int(DbName, []), - {ok, _} = couch_db:start_compact(Db), - ok = couch_db:close(Db), - wait_db_compact_done(DbName, 10). - -wait_db_compact_done(_DbName, 0) -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, "DB compaction failed to finish"}]}); -wait_db_compact_done(DbName, N) -> - {ok, Db} = couch_db:open_int(DbName, []), - ok = couch_db:close(Db), - case is_pid(Db#db.compactor_pid) of - false -> - ok; - true -> - ok = timer:sleep(?DELAY), - wait_db_compact_done(DbName, N - 1) - end. - -compact_view_group(DbName, DDocId) when is_list(DDocId) -> - compact_view_group(DbName, ?l2b("_design/" ++ DDocId)); -compact_view_group(DbName, DDocId) when is_binary(DDocId) -> - ok = couch_mrview:compact(DbName, DDocId), - wait_view_compact_done(DbName, DDocId, 10). - -wait_view_compact_done(_DbName, _DDocId, 0) -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, "DB compaction failed to finish"}]}); -wait_view_compact_done(DbName, DDocId, N) -> - {ok, Code, _Headers, Body} = test_request:get( - db_url(DbName) ++ "/" ++ ?b2l(DDocId) ++ "/_info"), - ?assertEqual(200, Code), - {Info} = ejson:decode(Body), - {IndexInfo} = couch_util:get_value(<<"view_index">>, Info), - CompactRunning = couch_util:get_value(<<"compact_running">>, IndexInfo), - case CompactRunning of - false -> - ok; - true -> - ok = timer:sleep(?DELAY), - wait_view_compact_done(DbName, DDocId, N - 1) - end. - -spawn_writer(DbName) -> - Parent = self(), - spawn(fun() -> - process_flag(priority, high), - writer_loop(DbName, Parent) - end). - -get_writer_status(Writer) -> - Ref = make_ref(), - Writer ! {get_status, Ref}, - receive - {db_open, Ref} -> - ok; - {db_open_error, Error, Ref} -> - Error - after ?TIMEOUT -> - timeout - end. - -writer_try_again(Writer) -> - Ref = make_ref(), - Writer ! {try_again, Ref}, - receive - {ok, Ref} -> - ok - after ?TIMEOUT -> - timeout - end. - -stop_writer(Writer) -> - Ref = make_ref(), - Writer ! {stop, Ref}, - receive - {ok, Ref} -> - ok - after ?TIMEOUT -> - erlang:error({assertion_failed, - [{module, ?MODULE}, - {line, ?LINE}, - {reason, "Timeout on stopping process"}]}) - end. - -writer_loop(DbName, Parent) -> - case couch_db:open_int(DbName, []) of - {ok, Db} -> - writer_loop_1(Db, Parent); - Error -> - writer_loop_2(DbName, Parent, Error) - end. - -writer_loop_1(Db, Parent) -> - receive - {get_status, Ref} -> - Parent ! {db_open, Ref}, - writer_loop_1(Db, Parent); - {stop, Ref} -> - ok = couch_db:close(Db), - Parent ! {ok, Ref} - end. - -writer_loop_2(DbName, Parent, Error) -> - receive - {get_status, Ref} -> - Parent ! {db_open_error, Error, Ref}, - writer_loop_2(DbName, Parent, Error); - {try_again, Ref} -> - Parent ! {ok, Ref}, - writer_loop(DbName, Parent) - end. - -read_header(File) -> - {ok, Fd} = couch_file:open(File), - {ok, {_Sig, Header}} = couch_file:read_header(Fd), - couch_file:close(Fd), - Header. http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/fixtures/3b835456c235b1827e012e25666152f3.view ---------------------------------------------------------------------- diff --git a/test/couchdb/fixtures/3b835456c235b1827e012e25666152f3.view b/test/couchdb/fixtures/3b835456c235b1827e012e25666152f3.view deleted file mode 100644 index 9c67648..0000000 Binary files a/test/couchdb/fixtures/3b835456c235b1827e012e25666152f3.view and /dev/null differ http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/fixtures/couch_config_tests_1.ini ---------------------------------------------------------------------- diff --git a/test/couchdb/fixtures/couch_config_tests_1.ini b/test/couchdb/fixtures/couch_config_tests_1.ini deleted file mode 100644 index 55451da..0000000 --- a/test/couchdb/fixtures/couch_config_tests_1.ini +++ /dev/null @@ -1,22 +0,0 @@ -; Licensed to the Apache Software Foundation (ASF) under one -; or more contributor license agreements. See the NOTICE file -; distributed with this work for additional information -; regarding copyright ownership. The ASF licenses this file -; to you under the Apache License, Version 2.0 (the -; "License"); you may not use this file except in compliance -; with the License. You may obtain a copy of the License at -; -; http://www.apache.org/licenses/LICENSE-2.0 -; -; Unless required by applicable law or agreed to in writing, -; software distributed under the License is distributed on an -; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -; KIND, either express or implied. See the License for the -; specific language governing permissions and limitations -; under the License. - -[couchdb] -max_dbs_open=10 - -[httpd] -port=4895 http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/fixtures/couch_config_tests_2.ini ---------------------------------------------------------------------- diff --git a/test/couchdb/fixtures/couch_config_tests_2.ini b/test/couchdb/fixtures/couch_config_tests_2.ini deleted file mode 100644 index 5f46357..0000000 --- a/test/couchdb/fixtures/couch_config_tests_2.ini +++ /dev/null @@ -1,22 +0,0 @@ -; Licensed to the Apache Software Foundation (ASF) under one -; or more contributor license agreements. See the NOTICE file -; distributed with this work for additional information -; regarding copyright ownership. The ASF licenses this file -; to you under the Apache License, Version 2.0 (the -; "License"); you may not use this file except in compliance -; with the License. You may obtain a copy of the License at -; -; http://www.apache.org/licenses/LICENSE-2.0 -; -; Unless required by applicable law or agreed to in writing, -; software distributed under the License is distributed on an -; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -; KIND, either express or implied. See the License for the -; specific language governing permissions and limitations -; under the License. - -[httpd] -port = 80 - -[fizbang] -unicode = normalized http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/fixtures/couch_stats_aggregates.cfg ---------------------------------------------------------------------- diff --git a/test/couchdb/fixtures/couch_stats_aggregates.cfg b/test/couchdb/fixtures/couch_stats_aggregates.cfg deleted file mode 100644 index 30e475d..0000000 --- a/test/couchdb/fixtures/couch_stats_aggregates.cfg +++ /dev/null @@ -1,19 +0,0 @@ -% Licensed to the Apache Software Foundation (ASF) under one -% or more contributor license agreements. See the NOTICE file -% distributed with this work for additional information -% regarding copyright ownership. The ASF licenses this file -% to you under the Apache License, Version 2.0 (the -% "License"); you may not use this file except in compliance -% with the License. You may obtain a copy of the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, -% software distributed under the License is distributed on an -% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -% KIND, either express or implied. See the License for the -% specific language governing permissions and limitations -% under the License. - -{testing, stuff, "yay description"}. -{number, '11', "randomosity"}. http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/fixtures/couch_stats_aggregates.ini ---------------------------------------------------------------------- diff --git a/test/couchdb/fixtures/couch_stats_aggregates.ini b/test/couchdb/fixtures/couch_stats_aggregates.ini deleted file mode 100644 index cc5cd21..0000000 --- a/test/couchdb/fixtures/couch_stats_aggregates.ini +++ /dev/null @@ -1,20 +0,0 @@ -; Licensed to the Apache Software Foundation (ASF) under one -; or more contributor license agreements. See the NOTICE file -; distributed with this work for additional information -; regarding copyright ownership. The ASF licenses this file -; to you under the Apache License, Version 2.0 (the -; "License"); you may not use this file except in compliance -; with the License. You may obtain a copy of the License at -; -; http://www.apache.org/licenses/LICENSE-2.0 -; -; Unless required by applicable law or agreed to in writing, -; software distributed under the License is distributed on an -; "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -; KIND, either express or implied. See the License for the -; specific language governing permissions and limitations -; under the License. - -[stats] -rate = 10000000 ; We call collect_sample in testing -samples = [0, 1] http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/fixtures/logo.png ---------------------------------------------------------------------- diff --git a/test/couchdb/fixtures/logo.png b/test/couchdb/fixtures/logo.png deleted file mode 100644 index d21ac02..0000000 Binary files a/test/couchdb/fixtures/logo.png and /dev/null differ http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/fixtures/os_daemon_bad_perm.sh ---------------------------------------------------------------------- diff --git a/test/couchdb/fixtures/os_daemon_bad_perm.sh b/test/couchdb/fixtures/os_daemon_bad_perm.sh deleted file mode 100644 index 345c8b4..0000000 --- a/test/couchdb/fixtures/os_daemon_bad_perm.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh -e -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may not -# use this file except in compliance with the License. You may obtain a copy of -# the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations under -# the License. -# -# Please do not make this file executable as that's the error being tested. - -sleep 5 http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/fixtures/os_daemon_can_reboot.sh ---------------------------------------------------------------------- diff --git a/test/couchdb/fixtures/os_daemon_can_reboot.sh b/test/couchdb/fixtures/os_daemon_can_reboot.sh deleted file mode 100755 index 5bc10e8..0000000 --- a/test/couchdb/fixtures/os_daemon_can_reboot.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -e -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may not -# use this file except in compliance with the License. You may obtain a copy of -# the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations under -# the License. - -sleep 2 http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/fixtures/os_daemon_configer.escript ---------------------------------------------------------------------- diff --git a/test/couchdb/fixtures/os_daemon_configer.escript b/test/couchdb/fixtures/os_daemon_configer.escript deleted file mode 100755 index d437423..0000000 --- a/test/couchdb/fixtures/os_daemon_configer.escript +++ /dev/null @@ -1,101 +0,0 @@ -#! /usr/bin/env escript - -% Licensed under the Apache License, Version 2.0 (the "License"); you may not -% use this file except in compliance with the License. You may obtain a copy of -% the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -% License for the specific language governing permissions and limitations under -% the License. - --include("../couch_eunit.hrl"). - - -read() -> - case io:get_line('') of - eof -> - stop; - Data -> - ejson:decode(Data) - end. - -write(Mesg) -> - Data = iolist_to_binary(ejson:encode(Mesg)), - io:format(binary_to_list(Data) ++ "\n", []). - -get_cfg(Section) -> - write([<<"get">>, Section]), - read(). - -get_cfg(Section, Name) -> - write([<<"get">>, Section, Name]), - read(). - -log(Mesg) -> - write([<<"log">>, Mesg]). - -log(Mesg, Level) -> - write([<<"log">>, Mesg, {[{<<"level">>, Level}]}]). - -test_get_cfg1() -> - Path = list_to_binary(?FILE), - FileName = list_to_binary(filename:basename(?FILE)), - {[{FileName, Path}]} = get_cfg(<<"os_daemons">>). - -test_get_cfg2() -> - Path = list_to_binary(?FILE), - FileName = list_to_binary(filename:basename(?FILE)), - Path = get_cfg(<<"os_daemons">>, FileName), - <<"sequential">> = get_cfg(<<"uuids">>, <<"algorithm">>). - - -test_get_unknown_cfg() -> - {[]} = get_cfg(<<"aal;3p4">>), - null = get_cfg(<<"aal;3p4">>, <<"313234kjhsdfl">>). - -test_log() -> - log(<<"foobar!">>), - log(<<"some stuff!">>, <<"debug">>), - log(2), - log(true), - write([<<"log">>, <<"stuff">>, 2]), - write([<<"log">>, 3, null]), - write([<<"log">>, [1, 2], {[{<<"level">>, <<"debug">>}]}]), - write([<<"log">>, <<"true">>, {[]}]). - -do_tests() -> - test_get_cfg1(), - test_get_cfg2(), - test_get_unknown_cfg(), - test_log(), - loop(io:read("")). - -loop({ok, _}) -> - loop(io:read("")); -loop(eof) -> - init:stop(); -loop({error, _Reason}) -> - init:stop(). - -main([]) -> - init_code_path(), - couch_config:start_link(?CONFIG_CHAIN), - couch_drv:start_link(), - do_tests(). - -init_code_path() -> - Paths = [ - "couchdb", - "ejson", - "erlang-oauth", - "ibrowse", - "mochiweb", - "snappy" - ], - lists:foreach(fun(Name) -> - code:add_patha(filename:join([?BUILDDIR, "src", Name])) - end, Paths). http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/fixtures/os_daemon_die_on_boot.sh ---------------------------------------------------------------------- diff --git a/test/couchdb/fixtures/os_daemon_die_on_boot.sh b/test/couchdb/fixtures/os_daemon_die_on_boot.sh deleted file mode 100755 index 256ee79..0000000 --- a/test/couchdb/fixtures/os_daemon_die_on_boot.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -e -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may not -# use this file except in compliance with the License. You may obtain a copy of -# the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations under -# the License. - -exit 1 http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/fixtures/os_daemon_die_quickly.sh ---------------------------------------------------------------------- diff --git a/test/couchdb/fixtures/os_daemon_die_quickly.sh b/test/couchdb/fixtures/os_daemon_die_quickly.sh deleted file mode 100755 index f5a1368..0000000 --- a/test/couchdb/fixtures/os_daemon_die_quickly.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -e -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may not -# use this file except in compliance with the License. You may obtain a copy of -# the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations under -# the License. - -sleep 1 http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/fixtures/os_daemon_looper.escript ---------------------------------------------------------------------- diff --git a/test/couchdb/fixtures/os_daemon_looper.escript b/test/couchdb/fixtures/os_daemon_looper.escript deleted file mode 100755 index 73974e9..0000000 --- a/test/couchdb/fixtures/os_daemon_looper.escript +++ /dev/null @@ -1,26 +0,0 @@ -#! /usr/bin/env escript - -% Licensed under the Apache License, Version 2.0 (the "License"); you may not -% use this file except in compliance with the License. You may obtain a copy of -% the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -% License for the specific language governing permissions and limitations under -% the License. - -loop() -> - loop(io:read("")). - -loop({ok, _}) -> - loop(io:read("")); -loop(eof) -> - stop; -loop({error, Reason}) -> - throw({error, Reason}). - -main([]) -> - loop(). http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/fixtures/test.couch ---------------------------------------------------------------------- diff --git a/test/couchdb/fixtures/test.couch b/test/couchdb/fixtures/test.couch deleted file mode 100644 index 32c79af..0000000 Binary files a/test/couchdb/fixtures/test.couch and /dev/null differ http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/json_stream_parse_tests.erl ---------------------------------------------------------------------- diff --git a/test/couchdb/json_stream_parse_tests.erl b/test/couchdb/json_stream_parse_tests.erl deleted file mode 100644 index 92303b6..0000000 --- a/test/couchdb/json_stream_parse_tests.erl +++ /dev/null @@ -1,151 +0,0 @@ -% Licensed under the Apache License, Version 2.0 (the "License"); you may not -% use this file except in compliance with the License. You may obtain a copy of -% the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -% License for the specific language governing permissions and limitations under -% the License. - --module(json_stream_parse_tests). - --include("couch_eunit.hrl"). - --define(CASES, - [ - {1, "1", "integer numeric literial"}, - {3.1416, "3.14160", "float numeric literal"}, % text representation may truncate, trail zeroes - {-1, "-1", "negative integer numeric literal"}, - {-3.1416, "-3.14160", "negative float numeric literal"}, - {12.0e10, "1.20000e+11", "float literal in scientific notation"}, - {1.234E+10, "1.23400e+10", "another float literal in scientific notation"}, - {-1.234E-10, "-1.23400e-10", "negative float literal in scientific notation"}, - {10.0, "1.0e+01", "yet another float literal in scientific notation"}, - {123.456, "1.23456E+2", "yet another float literal in scientific notation"}, - {10.0, "1e1", "yet another float literal in scientific notation"}, - {<<"foo">>, "\"foo\"", "string literal"}, - {<<"foo", 5, "bar">>, "\"foo\\u0005bar\"", "string literal with \\u0005"}, - {<<"">>, "\"\"", "empty string literal"}, - {<<"\n\n\n">>, "\"\\n\\n\\n\"", "only new lines literal"}, - {<<"\" \b\f\r\n\t\"">>, "\"\\\" \\b\\f\\r\\n\\t\\\"\"", - "only white spaces string literal"}, - {null, "null", "null literal"}, - {true, "true", "true literal"}, - {false, "false", "false literal"}, - {<<"null">>, "\"null\"", "null string literal"}, - {<<"true">>, "\"true\"", "true string literal"}, - {<<"false">>, "\"false\"", "false string literal"}, - {{[]}, "{}", "empty object literal"}, - {{[{<<"foo">>, <<"bar">>}]}, "{\"foo\":\"bar\"}", - "simple object literal"}, - {{[{<<"foo">>, <<"bar">>}, {<<"baz">>, 123}]}, - "{\"foo\":\"bar\",\"baz\":123}", "another simple object literal"}, - {[], "[]", "empty array literal"}, - {[[]], "[[]]", "empty array literal inside a single element array literal"}, - {[1, <<"foo">>], "[1,\"foo\"]", "simple non-empty array literal"}, - {[1199344435545.0, 1], "[1199344435545.0,1]", - "another simple non-empty array literal"}, - {[false, true, 321, null], "[false, true, 321, null]", "array of literals"}, - {{[{<<"foo">>, [123]}]}, "{\"foo\":[123]}", - "object literal with an array valued property"}, - {{[{<<"foo">>, {[{<<"bar">>, true}]}}]}, - "{\"foo\":{\"bar\":true}}", "nested object literal"}, - {{[{<<"foo">>, []}, {<<"bar">>, {[{<<"baz">>, true}]}}, - {<<"alice">>, <<"bob">>}]}, - "{\"foo\":[],\"bar\":{\"baz\":true},\"alice\":\"bob\"}", - "complex object literal"}, - {[-123, <<"foo">>, {[{<<"bar">>, []}]}, null], - "[-123,\"foo\",{\"bar\":[]},null]", - "complex array literal"} - ] -). - - -raw_json_input_test_() -> - Tests = lists:map( - fun({EJson, JsonString, Desc}) -> - {Desc, - ?_assert(equiv(EJson, json_stream_parse:to_ejson(JsonString)))} - end, ?CASES), - {"Tests with raw JSON string as the input", Tests}. - -one_byte_data_fun_test_() -> - Tests = lists:map( - fun({EJson, JsonString, Desc}) -> - DataFun = fun() -> single_byte_data_fun(JsonString) end, - {Desc, - ?_assert(equiv(EJson, json_stream_parse:to_ejson(DataFun)))} - end, ?CASES), - {"Tests with a 1 byte output data function as the input", Tests}. - -test_multiple_bytes_data_fun_test_() -> - Tests = lists:map( - fun({EJson, JsonString, Desc}) -> - DataFun = fun() -> multiple_bytes_data_fun(JsonString) end, - {Desc, - ?_assert(equiv(EJson, json_stream_parse:to_ejson(DataFun)))} - end, ?CASES), - {"Tests with a multiple bytes output data function as the input", Tests}. - - -%% Test for equivalence of Erlang terms. -%% Due to arbitrary order of construction, equivalent objects might -%% compare unequal as erlang terms, so we need to carefully recurse -%% through aggregates (tuples and objects). -equiv({Props1}, {Props2}) -> - equiv_object(Props1, Props2); -equiv(L1, L2) when is_list(L1), is_list(L2) -> - equiv_list(L1, L2); -equiv(N1, N2) when is_number(N1), is_number(N2) -> - N1 == N2; -equiv(B1, B2) when is_binary(B1), is_binary(B2) -> - B1 == B2; -equiv(true, true) -> - true; -equiv(false, false) -> - true; -equiv(null, null) -> - true. - -%% Object representation and traversal order is unknown. -%% Use the sledgehammer and sort property lists. -equiv_object(Props1, Props2) -> - L1 = lists:keysort(1, Props1), - L2 = lists:keysort(1, Props2), - Pairs = lists:zip(L1, L2), - true = lists:all( - fun({{K1, V1}, {K2, V2}}) -> - equiv(K1, K2) andalso equiv(V1, V2) - end, - Pairs). - -%% Recursively compare tuple elements for equivalence. -equiv_list([], []) -> - true; -equiv_list([V1 | L1], [V2 | L2]) -> - equiv(V1, V2) andalso equiv_list(L1, L2). - -single_byte_data_fun([]) -> - done; -single_byte_data_fun([H | T]) -> - {<>, fun() -> single_byte_data_fun(T) end}. - -multiple_bytes_data_fun([]) -> - done; -multiple_bytes_data_fun(L) -> - N = crypto:rand_uniform(0, 7), - {Part, Rest} = split(L, N), - {list_to_binary(Part), fun() -> multiple_bytes_data_fun(Rest) end}. - -split(L, N) when length(L) =< N -> - {L, []}; -split(L, N) -> - take(N, L, []). - -take(0, L, Acc) -> - {lists:reverse(Acc), L}; -take(N, [H|L], Acc) -> - take(N - 1, L, [H | Acc]). http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/test_request.erl ---------------------------------------------------------------------- diff --git a/test/couchdb/test_request.erl b/test/couchdb/test_request.erl deleted file mode 100644 index 68e4956..0000000 --- a/test/couchdb/test_request.erl +++ /dev/null @@ -1,75 +0,0 @@ -% Licensed under the Apache License, Version 2.0 (the "License"); you may not -% use this file except in compliance with the License. You may obtain a copy of -% the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -% License for the specific language governing permissions and limitations under -% the License. - --module(test_request). - --export([get/1, get/2, get/3]). --export([put/2, put/3]). --export([options/1, options/2, options/3]). --export([request/3, request/4]). - -get(Url) -> - request(get, Url, []). - -get(Url, Headers) -> - request(get, Url, Headers). -get(Url, Headers, Opts) -> - request(get, Url, Headers, [], Opts). - - -put(Url, Body) -> - request(put, Url, [], Body). - -put(Url, Headers, Body) -> - request(put, Url, Headers, Body). - - -options(Url) -> - request(options, Url, []). - -options(Url, Headers) -> - request(options, Url, Headers). - -options(Url, Headers, Opts) -> - request(options, Url, Headers, [], Opts). - - -request(Method, Url, Headers) -> - request(Method, Url, Headers, []). - -request(Method, Url, Headers, Body) -> - request(Method, Url, Headers, Body, [], 3). - -request(Method, Url, Headers, Body, Opts) -> - request(Method, Url, Headers, Body, Opts, 3). - -request(_Method, _Url, _Headers, _Body, _Opts, 0) -> - {error, request_failed}; -request(Method, Url, Headers, Body, Opts, N) -> - case code:is_loaded(ibrowse) of - false -> - {ok, _} = ibrowse:start(); - _ -> - ok - end, - case ibrowse:send_req(Url, Headers, Method, Body, Opts) of - {ok, Code0, RespHeaders, RespBody0} -> - Code = list_to_integer(Code0), - RespBody = iolist_to_binary(RespBody0), - {ok, Code, RespHeaders, RespBody}; - {error, {'EXIT', {normal, _}}} -> - % Connection closed right after a successful request that - % used the same connection. - request(Method, Url, Headers, Body, N - 1); - Error -> - Error - end. http://git-wip-us.apache.org/repos/asf/couchdb-couch/blob/661443fb/test/couchdb/test_web.erl ---------------------------------------------------------------------- diff --git a/test/couchdb/test_web.erl b/test/couchdb/test_web.erl deleted file mode 100644 index 1de2cd1..0000000 --- a/test/couchdb/test_web.erl +++ /dev/null @@ -1,112 +0,0 @@ -% Licensed under the Apache License, Version 2.0 (the "License"); you may not -% use this file except in compliance with the License. You may obtain a copy of -% the License at -% -% http://www.apache.org/licenses/LICENSE-2.0 -% -% Unless required by applicable law or agreed to in writing, software -% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -% License for the specific language governing permissions and limitations under -% the License. - --module(test_web). --behaviour(gen_server). - --include("couch_eunit.hrl"). - --export([start_link/0, stop/0, loop/1, get_port/0, set_assert/1, check_last/0]). --export([init/1, terminate/2, code_change/3]). --export([handle_call/3, handle_cast/2, handle_info/2]). - --define(SERVER, test_web_server). --define(HANDLER, test_web_handler). --define(DELAY, 500). - -start_link() -> - gen_server:start({local, ?HANDLER}, ?MODULE, [], []), - mochiweb_http:start([ - {name, ?SERVER}, - {loop, {?MODULE, loop}}, - {port, 0} - ]). - -loop(Req) -> - %?debugFmt("Handling request: ~p", [Req]), - case gen_server:call(?HANDLER, {check_request, Req}) of - {ok, RespInfo} -> - {ok, Req:respond(RespInfo)}; - {raw, {Status, Headers, BodyChunks}} -> - Resp = Req:start_response({Status, Headers}), - lists:foreach(fun(C) -> Resp:send(C) end, BodyChunks), - erlang:put(mochiweb_request_force_close, true), - {ok, Resp}; - {chunked, {Status, Headers, BodyChunks}} -> - Resp = Req:respond({Status, Headers, chunked}), - timer:sleep(?DELAY), - lists:foreach(fun(C) -> Resp:write_chunk(C) end, BodyChunks), - Resp:write_chunk([]), - {ok, Resp}; - {error, Reason} -> - ?debugFmt("Error: ~p", [Reason]), - Body = lists:flatten(io_lib:format("Error: ~p", [Reason])), - {ok, Req:respond({200, [], Body})} - end. - -get_port() -> - mochiweb_socket_server:get(?SERVER, port). - -set_assert(Fun) -> - ?assertEqual(ok, gen_server:call(?HANDLER, {set_assert, Fun})). - -check_last() -> - gen_server:call(?HANDLER, last_status). - -init(_) -> - {ok, nil}. - -terminate(_Reason, _State) -> - ok. - -stop() -> - gen_server:cast(?SERVER, stop). - - -handle_call({check_request, Req}, _From, State) when is_function(State, 1) -> - Resp2 = case (catch State(Req)) of - {ok, Resp} -> - {reply, {ok, Resp}, was_ok}; - {raw, Resp} -> - {reply, {raw, Resp}, was_ok}; - {chunked, Resp} -> - {reply, {chunked, Resp}, was_ok}; - Error -> - {reply, {error, Error}, not_ok} - end, - Req:cleanup(), - Resp2; -handle_call({check_request, _Req}, _From, _State) -> - {reply, {error, no_assert_function}, not_ok}; -handle_call(last_status, _From, State) when is_atom(State) -> - {reply, State, nil}; -handle_call(last_status, _From, State) -> - {reply, {error, not_checked}, State}; -handle_call({set_assert, Fun}, _From, nil) -> - {reply, ok, Fun}; -handle_call({set_assert, _}, _From, State) -> - {reply, {error, assert_function_set}, State}; -handle_call(Msg, _From, State) -> - {reply, {ignored, Msg}, State}. - -handle_cast(stop, State) -> - {stop, normal, State}; -handle_cast(Msg, State) -> - ?debugFmt("Ignoring cast message: ~p", [Msg]), - {noreply, State}. - -handle_info(Msg, State) -> - ?debugFmt("Ignoring info message: ~p", [Msg]), - {noreply, State}. - -code_change(_OldVsn, State, _Extra) -> - {ok, State}.