You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by be...@apache.org on 2014/01/09 01:38:47 UTC
[02/12] move test -> src/test
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/etap/210-os-proc-pool.t
----------------------------------------------------------------------
diff --git a/test/etap/210-os-proc-pool.t b/test/etap/210-os-proc-pool.t
deleted file mode 100755
index d80707e..0000000
--- a/test/etap/210-os-proc-pool.t
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-% 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.
-
-main(_) ->
- test_util:init_code_path(),
-
- etap:plan(21),
- case (catch test()) of
- ok ->
- etap:end_tests();
- Other ->
- etap:diag(io_lib:format("Test died abnormally: ~p", [Other])),
- etap:bail(Other)
- end,
- ok.
-
-
-test() ->
- couch_server_sup:start_link(test_util:config_files()),
- couch_config:set("query_server_config", "os_process_limit", "3", false),
-
- test_pool_full(),
- test_client_unexpected_exit(),
-
- couch_server_sup:stop(),
- ok.
-
-
-test_pool_full() ->
- Client1 = spawn_client(),
- Client2 = spawn_client(),
- Client3 = spawn_client(),
-
- etap:diag("Check that we can spawn the max number of processes."),
- etap:is(ping_client(Client1), ok, "Client 1 started ok."),
- etap:is(ping_client(Client2), ok, "Client 2 started ok."),
- etap:is(ping_client(Client3), ok, "Client 3 started ok."),
-
- Proc1 = get_client_proc(Client1, "1"),
- Proc2 = get_client_proc(Client2, "2"),
- Proc3 = get_client_proc(Client3, "3"),
- etap:isnt(Proc1, Proc2, "Clients 1 and 2 got different procs."),
- etap:isnt(Proc2, Proc3, "Clients 2 and 3 got different procs."),
- etap:isnt(Proc1, Proc3, "Clients 1 and 3 got different procs."),
-
- etap:diag("Check that client 4 blocks waiting for a process."),
- Client4 = spawn_client(),
- etap:is(ping_client(Client4), timeout, "Client 4 blocked while waiting."),
-
- etap:diag("Check that stopping a client gives up its process."),
- etap:is(stop_client(Client1), ok, "First client stopped."),
-
- etap:diag("And check that our blocked process has been unblocked."),
- etap:is(ping_client(Client4), ok, "Client was unblocked."),
-
- Proc4 = get_client_proc(Client4, "4"),
- etap:is(Proc4, Proc1, "Client 4 got proc that client 1 got before."),
-
- lists:map(fun(C) -> ok = stop_client(C) end, [Client2, Client3, Client4]).
-
-
-test_client_unexpected_exit() ->
- Client1 = spawn_client(),
- Client2 = spawn_client(),
- Client3 = spawn_client(),
-
- etap:diag("Check that up to os_process_limit clients started."),
- etap:is(ping_client(Client1), ok, "Client 1 started ok."),
- etap:is(ping_client(Client2), ok, "Client 2 started ok."),
- etap:is(ping_client(Client3), ok, "Client 3 started ok."),
-
- Proc1 = get_client_proc(Client1, "1"),
- Proc2 = get_client_proc(Client2, "2"),
- Proc3 = get_client_proc(Client3, "3"),
- etap:isnt(Proc1, Proc2, "Clients 1 and 2 got different procs."),
- etap:isnt(Proc2, Proc3, "Clients 2 and 3 got different procs."),
- etap:isnt(Proc1, Proc3, "Clients 1 and 3 got different procs."),
-
- etap:diag("Check that killing a client frees an os_process."),
- etap:is(kill_client(Client1), ok, "Client 1 died all right."),
-
- etap:diag("Check that a new client is not blocked on boot."),
- Client4 = spawn_client(),
- etap:is(ping_client(Client4), ok, "New client booted without blocking."),
-
- Proc4 = get_client_proc(Client4, "4"),
- etap:isnt(Proc4, Proc1,
- "Client 4 got a proc different from the one client 1 got before."),
- etap:isnt(Proc4, Proc2, "Client 4's proc different from client 2's proc."),
- etap:isnt(Proc4, Proc3, "Client 4's proc different from client 3's proc."),
-
- lists:map(fun(C) -> ok = stop_client(C) end, [Client2, Client3, Client4]).
-
-
-spawn_client() ->
- Parent = self(),
- Ref = make_ref(),
- Pid = spawn(fun() ->
- Proc = couch_query_servers:get_os_process(<<"javascript">>),
- loop(Parent, Ref, Proc)
- end),
- {Pid, Ref}.
-
-
-ping_client({Pid, Ref}) ->
- Pid ! ping,
- receive
- {pong, Ref} -> ok
- after 3000 -> timeout
- end.
-
-
-get_client_proc({Pid, Ref}, ClientName) ->
- Pid ! get_proc,
- receive
- {proc, Ref, Proc} -> Proc
- after 3000 ->
- etap:bail("Timeout getting client " ++ ClientName ++ " proc.")
- end.
-
-
-stop_client({Pid, Ref}) ->
- Pid ! stop,
- receive
- {stop, Ref} -> ok
- after 3000 -> timeout
- end.
-
-
-kill_client({Pid, Ref}) ->
- Pid ! die,
- receive
- {die, Ref} -> ok
- after 3000 -> timeout
- end.
-
-
-loop(Parent, Ref, Proc) ->
- receive
- ping ->
- Parent ! {pong, Ref},
- loop(Parent, Ref, Proc);
- get_proc ->
- Parent ! {proc, Ref, Proc},
- loop(Parent, Ref, Proc);
- stop ->
- couch_query_servers:ret_os_process(Proc),
- Parent ! {stop, Ref};
- die ->
- Parent ! {die, Ref},
- exit(some_error)
- end.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/etap/220-compaction-daemon.t
----------------------------------------------------------------------
diff --git a/test/etap/220-compaction-daemon.t b/test/etap/220-compaction-daemon.t
deleted file mode 100755
index 4c63b66..0000000
--- a/test/etap/220-compaction-daemon.t
+++ /dev/null
@@ -1,225 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-
-% 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.
-
--record(user_ctx, {
- name = null,
- roles = [],
- handler
-}).
-
-test_db_name() ->
- <<"couch_test_compaction_daemon">>.
-
-main(_) ->
- test_util:init_code_path(),
-
- etap:plan(10),
- case (catch test()) of
- ok ->
- etap:end_tests();
- Other ->
- etap:diag(io_lib:format("Test died abnormally: ~p", [Other])),
- etap:bail(Other)
- end,
- ok.
-
-test() ->
- couch_server_sup:start_link(test_util:config_files()),
- timer:sleep(1000),
- put(addr, couch_config:get("httpd", "bind_address", "127.0.0.1")),
- put(port, integer_to_list(mochiweb_socket_server:get(couch_httpd, port))),
-
- disable_compact_daemon(),
-
- delete_db(),
- {ok, Db} = create_db(),
-
- add_design_doc(Db),
- couch_db:close(Db),
- populate(70, 70, 200 * 1024),
-
- {_, DbFileSize} = get_db_frag(),
- {_, ViewFileSize} = get_view_frag(),
-
- % enable automatic compaction
- ok = couch_config:set("compaction_daemon", "check_interval", "3", false),
- ok = couch_config:set("compaction_daemon", "min_file_size", "100000", false),
- ok = couch_config:set(
- "compactions",
- binary_to_list(test_db_name()),
- "[{db_fragmentation, \"70%\"}, {view_fragmentation, \"70%\"}]",
- false),
-
- ok = timer:sleep(4000), % something >= check_interval
- wait_compaction_finished(),
-
- {DbFrag2, DbFileSize2} = get_db_frag(),
- {ViewFrag2, ViewFileSize2} = get_view_frag(),
-
- etap:is(true, (DbFrag2 < 70), "Database fragmentation is < 70% after compaction"),
- etap:is(true, (ViewFrag2 < 70), "View fragmentation is < 70% after compaction"),
- etap:is(true, (DbFileSize2 < DbFileSize), "Database file size decreased"),
- etap:is(true, (ViewFileSize2 < ViewFileSize), "View file size decreased"),
-
- disable_compact_daemon(),
- ok = timer:sleep(6000), % 2 times check_interval
- etap:is(couch_db:is_idle(Db), true, "Database is idle"),
- populate(70, 70, 200 * 1024),
- {_, DbFileSize3} = get_db_frag(),
- {_, ViewFileSize3} = get_view_frag(),
-
- % enable automatic compaction
- ok = couch_config:set(
- "compactions",
- "_default",
- "[{db_fragmentation, \"70%\"}, {view_fragmentation, \"70%\"}]",
- false),
-
- ok = timer:sleep(4000), % something >= check_interval
- wait_compaction_finished(),
-
- {DbFrag4, DbFileSize4} = get_db_frag(),
- {ViewFrag4, ViewFileSize4} = get_view_frag(),
-
- etap:is(true, (DbFrag4 < 70), "Database fragmentation is < 70% after compaction"),
- etap:is(true, (ViewFrag4 < 70), "View fragmentation is < 70% after compaction"),
- etap:is(true, (DbFileSize4 < DbFileSize3), "Database file size decreased again"),
- etap:is(true, (ViewFileSize4 < ViewFileSize3), "View file size decreased again"),
-
- ok = timer:sleep(6000), % 2 times check_interval
- etap:is(couch_db:is_idle(Db), true, "Database is idle"),
-
- delete_db(),
- couch_server_sup:stop(),
- ok.
-
-disable_compact_daemon() ->
- Configs = couch_config:get("compactions"),
- lists:foreach(
- fun({DbName, _}) ->
- ok = couch_config:delete("compactions", DbName, false)
- end,
- Configs).
-
-admin_user_ctx() ->
- {user_ctx, #user_ctx{roles = [<<"_admin">>]}}.
-
-create_db() ->
- {ok, _} = couch_db:create(test_db_name(), [admin_user_ctx()]).
-
-delete_db() ->
- couch_server:delete(test_db_name(), [admin_user_ctx()]).
-
-add_design_doc(Db) ->
- DDoc = couch_doc:from_json_obj({[
- {<<"_id">>, <<"_design/foo">>},
- {<<"language">>, <<"javascript">>},
- {<<"views">>, {[
- {<<"foo">>, {[
- {<<"map">>, <<"function(doc) { emit(doc._id, doc); }">>}
- ]}},
- {<<"foo2">>, {[
- {<<"map">>, <<"function(doc) { emit(doc._id, doc); }">>}
- ]}},
- {<<"foo3">>, {[
- {<<"map">>, <<"function(doc) { emit(doc._id, doc); }">>}
- ]}}
- ]}}
- ]}),
- {ok, _} = couch_db:update_docs(Db, [DDoc]),
- {ok, _} = couch_db:ensure_full_commit(Db),
- ok.
-
-populate(DbFrag, ViewFrag, MinFileSize) ->
- {CurDbFrag, DbFileSize} = get_db_frag(),
- {CurViewFrag, ViewFileSize} = get_view_frag(),
- populate(
- DbFrag, ViewFrag, MinFileSize, CurDbFrag, CurViewFrag,
- lists:min([DbFileSize, ViewFileSize])).
-
-populate(DbFrag, ViewFrag, MinFileSize, CurDbFrag, CurViewFrag, FileSize)
- when CurDbFrag >= DbFrag, CurViewFrag >= ViewFrag, FileSize >= MinFileSize ->
- ok;
-populate(DbFrag, ViewFrag, MinFileSize, _, _, _) ->
- update(),
- {CurDbFrag, DbFileSize} = get_db_frag(),
- {CurViewFrag, ViewFileSize} = get_view_frag(),
- populate(
- DbFrag, ViewFrag, MinFileSize, CurDbFrag, CurViewFrag,
- lists:min([DbFileSize, ViewFileSize])).
-
-update() ->
- {ok, Db} = couch_db:open_int(test_db_name(), []),
- lists:foreach(fun(_) ->
- Doc = couch_doc:from_json_obj({[{<<"_id">>, couch_uuids:new()}]}),
- {ok, _} = couch_db:update_docs(Db, [Doc]),
- query_view()
- end, lists:seq(1, 100)),
- couch_db:close(Db).
-
-db_url() ->
- "http://" ++ get(addr) ++ ":" ++ get(port) ++ "/" ++
- binary_to_list(test_db_name()).
-
-query_view() ->
- {ok, Code, _Headers, _Body} = test_util:request(
- db_url() ++ "/_design/foo/_view/foo", [], get),
- case Code of
- 200 ->
- ok;
- _ ->
- etap:bail("error querying view")
- end.
-
-get_db_frag() ->
- {ok, Db} = couch_db:open_int(test_db_name(), []),
- {ok, Info} = couch_db:get_db_info(Db),
- couch_db:close(Db),
- FileSize = couch_util:get_value(disk_size, Info),
- DataSize = couch_util:get_value(data_size, Info),
- {round((FileSize - DataSize) / FileSize * 100), FileSize}.
-
-get_view_frag() ->
- {ok, Db} = couch_db:open_int(test_db_name(), []),
- {ok, Info} = couch_mrview:get_info(Db, <<"_design/foo">>),
- couch_db:close(Db),
- FileSize = couch_util:get_value(disk_size, Info),
- DataSize = couch_util:get_value(data_size, Info),
- {round((FileSize - DataSize) / FileSize * 100), FileSize}.
-
-
-wait_compaction_finished() ->
- Parent = self(),
- Loop = spawn_link(fun() -> wait_loop(Parent) end),
- receive
- {done, Loop} ->
- etap:diag("Database and view compaction have finished")
- after 60000 ->
- etap:bail("Compaction not triggered")
- end.
-
-wait_loop(Parent) ->
- {ok, Db} = couch_db:open_int(test_db_name(), []),
- {ok, DbInfo} = couch_db:get_db_info(Db),
- {ok, ViewInfo} = couch_mrview:get_info(Db, <<"_design/foo">>),
- couch_db:close(Db),
- case (couch_util:get_value(compact_running, ViewInfo) =:= true) orelse
- (couch_util:get_value(compact_running, DbInfo) =:= true) of
- false ->
- Parent ! {done, self()};
- true ->
- ok = timer:sleep(500),
- wait_loop(Parent)
- end.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/etap/230-pbkfd2.t
----------------------------------------------------------------------
diff --git a/test/etap/230-pbkfd2.t b/test/etap/230-pbkfd2.t
deleted file mode 100644
index d980ef6..0000000
--- a/test/etap/230-pbkfd2.t
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-
-% 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.
-
-main(_) ->
- test_util:init_code_path(),
- etap:plan(6),
- etap:is(couch_passwords:pbkdf2(<<"password">>, <<"salt">>, 1, 20),
- {ok, <<"0c60c80f961f0e71f3a9b524af6012062fe037a6">>},
- "test vector #1"),
- etap:is(couch_passwords:pbkdf2(<<"password">>, <<"salt">>, 2, 20),
- {ok, <<"ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957">>},
- "test vector #2"),
- etap:is(couch_passwords:pbkdf2(<<"password">>, <<"salt">>, 4096, 20),
- {ok, <<"4b007901b765489abead49d926f721d065a429c1">>},
- "test vector #3"),
- etap:is(couch_passwords:pbkdf2(<<"passwordPASSWORDpassword">>,
- <<"saltSALTsaltSALTsaltSALTsaltSALTsalt">>, 4096, 25),
- {ok, <<"3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038">>},
- "test vector #4"),
- etap:is(couch_passwords:pbkdf2(<<"pass\0word">>, <<"sa\0lt">>, 4096, 16),
- {ok, <<"56fa6aa75548099dcc37d7f03425e0c3">>},
- "test vector #5"),
- etap:is(couch_passwords:pbkdf2(<<"password">>, <<"salt">>, 16777216, 20),
- {ok, <<"eefe3d61cd4da4e4e9945b3d6ba2158c2634e984">>},
- "test vector #6"),
- etap:end_tests().
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/etap/231-cors.t
----------------------------------------------------------------------
diff --git a/test/etap/231-cors.t b/test/etap/231-cors.t
deleted file mode 100644
index dd08ca8..0000000
--- a/test/etap/231-cors.t
+++ /dev/null
@@ -1,433 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-
-% 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.
-
--record(user_ctx, {
- name = null,
- roles = [],
- handler
-}).
-
-
--define(SUPPORTED_METHODS, "GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT, COPY, OPTIONS").
-server() ->
- lists:concat([
- "http://127.0.0.1:",
- mochiweb_socket_server:get(couch_httpd, port),
- "/"
- ]).
-
-
-main(_) ->
- test_util:init_code_path(),
-
- etap:plan(28),
- case (catch test()) of
- ok ->
- etap:end_tests();
- Other ->
- etap:diag(io_lib:format("Test died abnormally: ~p", [Other])),
- etap:bail(Other)
- end,
- ok.
-
-dbname() -> "etap-test-db".
-dbname1() -> "etap-test-db1".
-dbname2() -> "etap-test-db2".
-
-admin_user_ctx() -> {user_ctx, #user_ctx{roles=[<<"_admin">>]}}.
-
-set_admin_password(UserName, Password) ->
- Hashed = couch_passwords:hash_admin_password(Password),
- couch_config:set("admins", UserName, Hashed, false).
-
-cycle_db(DbName) ->
- couch_server:delete(list_to_binary(DbName), [admin_user_ctx()]),
- {ok, Db} = couch_db:create(list_to_binary(DbName), [admin_user_ctx()]),
- Db.
-
-test() ->
-
- ibrowse:start(),
- crypto:start(),
-
- %% launch couchdb
- couch_server_sup:start_link(test_util:config_files()),
-
- %% initialize db
- timer:sleep(1000),
- Db = cycle_db(dbname()),
- Db1 = cycle_db(dbname1()),
- Db2 = cycle_db(dbname2()),
-
- % CORS is disabled by default
- test_no_headers_server(),
- test_no_headers_db(),
-
- % Now enable CORS
- ok = couch_config:set("httpd", "enable_cors", "true", false),
- ok = couch_config:set("cors", "origins", "http://example.com", false),
-
- %% do tests
- test_incorrect_origin_simple_request(),
- test_incorrect_origin_preflight_request(),
-
- test_preflight_request(),
- test_db_request(),
- test_doc_with_attachment_request(),
- test_doc_with_attachment_range_request(),
- test_db_preflight_request(),
- test_db1_origin_request(),
- test_preflight_with_port1(),
- test_preflight_with_scheme1(),
-
- ok = couch_config:set("cors", "origins", "http://example.com:5984", false),
- test_preflight_with_port2(),
-
- ok = couch_config:set("cors", "origins", "https://example.com:5984", false),
- test_preflight_with_scheme2(),
-
- ok = couch_config:set("cors", "origins", "*", false),
- test_preflight_with_wildcard(),
-
- ok = couch_config:set("cors", "origins", "http://example.com", false),
- test_case_sensitive_mismatch_of_allowed_origins(),
-
- % http://www.w3.org/TR/cors/#supports-credentials
- % 6.1.3
- % If the resource supports credentials add a single
- % Access-Control-Allow-Origin header, with the value
- % of the Origin header as value, and add a single
- % Access-Control-Allow-Credentials header with the
- % case-sensitive string "true" as value.
- % Otherwise, add a single Access-Control-Allow-Origin
- % header, with either the value of the Origin header
- % or the string "*" as value.
- % Note: The string "*" cannot be used for a resource
- % that supports credentials.
- test_db_request_credentials_header_off(),
- ok = couch_config:set("cors", "credentials", "true", false),
- test_db_request_credentials_header_on(),
- % We don’t test wildcards & credentials as that would
- % fall into the realm of validating config values
- % which we don’t do at all yet
-
- % test with vhosts
- ok = couch_config:set("vhosts", "example.com", "/", false),
- test_preflight_request(true),
- test_db_request(true),
- test_db_preflight_request(true),
- test_db1_origin_request(true),
- test_preflight_with_port1(true),
- test_preflight_with_scheme1(true),
-
- % TBD
- % test multiple per-host configuration
-
- %% do tests with auth
- ok = set_admin_password("test", "test"),
-
- test_db_preflight_auth_request(),
- test_db_origin_auth_request(),
-
-
- %% restart boilerplate
- catch couch_db:close(Db),
- catch couch_db:close(Db1),
- catch couch_db:close(Db2),
-
- couch_server:delete(list_to_binary(dbname()), [admin_user_ctx()]),
- couch_server:delete(list_to_binary(dbname1()), [admin_user_ctx()]),
- couch_server:delete(list_to_binary(dbname2()), [admin_user_ctx()]),
-
- timer:sleep(3000),
- couch_server_sup:stop(),
- ok.
-
-test_preflight_request() -> test_preflight_request(false).
-test_db_request() -> test_db_request(false).
-test_db_preflight_request() -> test_db_preflight_request(false).
-test_db1_origin_request() -> test_db1_origin_request(false).
-test_preflight_with_port1() -> test_preflight_with_port1(false).
-test_preflight_with_scheme1() -> test_preflight_with_scheme1(false).
-
-%% Cors is disabled, should not return Access-Control-Allow-Origin
-test_no_headers_server() ->
- Headers = [{"Origin", "http://127.0.0.1"}],
- {ok, _, Resp, _} = ibrowse:send_req(server(), Headers, get, []),
- etap:is(proplists:get_value("Access-Control-Allow-Origin", Resp),
- undefined, "No CORS Headers when disabled").
-
-%% Cors is disabled, should not return Access-Control-Allow-Origin
-test_no_headers_db() ->
- Headers = [{"Origin", "http://127.0.0.1"}],
- Url = server() ++ "etap-test-db",
- {ok, _, Resp, _} = ibrowse:send_req(Url, Headers, get, []),
- etap:is(proplists:get_value("Access-Control-Allow-Origin", Resp),
- undefined, "No CORS Headers when disabled").
-
-test_incorrect_origin_simple_request() ->
- Headers = [{"Origin", "http://127.0.0.1"}],
- {ok, _, RespHeaders, _} = ibrowse:send_req(server(), Headers, get, []),
- etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders),
- undefined,
- "Specified invalid origin, no Access").
-
-test_incorrect_origin_preflight_request() ->
- Headers = [{"Origin", "http://127.0.0.1"},
- {"Access-Control-Request-Method", "GET"}],
- {ok, _, RespHeaders, _} = ibrowse:send_req(server(), Headers, options, []),
- etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders),
- undefined,
- "invalid origin").
-
-test_preflight_request(VHost) ->
- Headers = [{"Origin", "http://example.com"},
- {"Access-Control-Request-Method", "GET"}]
- ++ maybe_append_vhost(VHost),
-
- case ibrowse:send_req(server(), Headers, options, []) of
- {ok, _, RespHeaders, _} ->
- etap:is(proplists:get_value("Access-Control-Allow-Methods", RespHeaders),
- ?SUPPORTED_METHODS,
- "test_preflight_request Access-Control-Allow-Methods ok");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-test_db_request(VHost) ->
- Headers = [{"Origin", "http://example.com"}]
- ++ maybe_append_vhost(VHost),
- Url = server() ++ "etap-test-db",
- case ibrowse:send_req(Url, Headers, get, []) of
- {ok, _, RespHeaders, _Body} ->
- etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders),
- "http://example.com",
- "db Access-Control-Allow-Origin ok"),
- etap:is(proplists:get_value("Access-Control-Expose-Headers", RespHeaders),
- "Cache-Control, Content-Type, Server",
- "db Access-Control-Expose-Headers ok");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-% COUCHDB-1689
-test_doc_with_attachment_request() ->
- DocUrl = server() ++ "etap-test-db/doc1",
- ibrowse:send_req(DocUrl ++ "/attachment.txt",
- [{"Content-Type", "text/plain"}], put, "this is a text attachment"),
-
- Headers = [{"Origin", "http://example.com"}],
- Url = DocUrl ++ "?attachments=true",
- case ibrowse:send_req(Url, Headers, get, []) of
- {ok, Code, _RespHeaders, _Body} ->
- etap:is(Code, "200", "Response without errors");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-% COUCHDB-1689
-test_doc_with_attachment_range_request() ->
- AttachmentUrl = server() ++ "etap-test-db/doc2/attachment.bin",
- % Use a Content-Type that doesn't get compressed
- ibrowse:send_req(AttachmentUrl,
- [{"Content-Type", "application/octet-stream"}], put,
- "this is an attachment"),
-
- Headers = [{"Origin", "http://example.com"}, {"Range", "bytes=0-6"}],
- case ibrowse:send_req(AttachmentUrl, Headers, get, []) of
- {ok, Code, _RespHeaders, _Body} ->
- etap:is(Code, "206", "Response without errors");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-% COUCHDB-1697
-test_if_none_match_header() ->
- Url = server() ++ "etap-test-db/doc2",
- Headers = [{"Origin", "http://example.com"}],
- {ok, _, _RespHeaders, _} = ibrowse:send_req(Url, Headers, get, []),
- ETag = proplists:get_value("ETag", _RespHeaders),
- Headers2 = [{"Origin", "http://example.com"}, {"If-None-Match", ETag}],
- case ibrowse:send_req(Url, Headers2, get, []) of
- {ok, Code, _RespHeaders2, _} ->
- etap:is(Code, "304", "Responded with Not Modified");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-test_db_request_credentials_header_off() ->
- Headers = [{"Origin", "http://example.com"}],
- Url = server() ++ "etap-test-db",
- case ibrowse:send_req(Url, Headers, get, []) of
- {ok, _, RespHeaders, _Body} ->
- etap:is(proplists:get_value("Access-Control-Allow-Credentials", RespHeaders),
- undefined,
- "db Access-Control-Allow-Credentials off");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-test_db_request_credentials_header_on() ->
- Headers = [{"Origin", "http://example.com"}],
- Url = server() ++ "etap-test-db",
- case ibrowse:send_req(Url, Headers, get, []) of
- {ok, _, RespHeaders, _Body} ->
- etap:is(proplists:get_value("Access-Control-Allow-Credentials", RespHeaders),
- "true",
- "db Access-Control-Allow-Credentials ok");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-test_db_preflight_request(VHost) ->
- Url = server() ++ "etap-test-db",
- Headers = [{"Origin", "http://example.com"},
- {"Access-Control-Request-Method", "GET"}]
- ++ maybe_append_vhost(VHost),
- case ibrowse:send_req(Url, Headers, options, []) of
- {ok, _, RespHeaders, _} ->
- etap:is(proplists:get_value("Access-Control-Allow-Methods", RespHeaders),
- ?SUPPORTED_METHODS,
- "db Access-Control-Allow-Methods ok");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-
-test_db1_origin_request(VHost) ->
- Headers = [{"Origin", "http://example.com"}]
- ++ maybe_append_vhost(VHost),
- Url = server() ++ "etap-test-db1",
- case ibrowse:send_req(Url, Headers, get, [], [{host_header, "example.com"}]) of
- {ok, _, RespHeaders, _Body} ->
- etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders),
- "http://example.com",
- "db origin ok");
- _Else ->
- io:format("else ~p~n", [_Else]),
- etap:is(false, true, "ibrowse failed")
- end.
-
-test_db_preflight_auth_request() ->
- Url = server() ++ "etap-test-db2",
- Headers = [{"Origin", "http://example.com"},
- {"Access-Control-Request-Method", "GET"}],
- case ibrowse:send_req(Url, Headers, options, []) of
- {ok, _Status, RespHeaders, _} ->
- etap:is(proplists:get_value("Access-Control-Allow-Methods", RespHeaders),
- ?SUPPORTED_METHODS,
- "db Access-Control-Allow-Methods ok");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-
-test_db_origin_auth_request() ->
- Headers = [{"Origin", "http://example.com"}],
- Url = server() ++ "etap-test-db2",
-
- case ibrowse:send_req(Url, Headers, get, [],
- [{basic_auth, {"test", "test"}}]) of
- {ok, _, RespHeaders, _Body} ->
- etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders),
- "http://example.com",
- "db origin ok");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-test_preflight_with_wildcard() ->
- Headers = [{"Origin", "http://example.com"},
- {"Access-Control-Request-Method", "GET"}],
- case ibrowse:send_req(server(), Headers, options, []) of
- {ok, _, RespHeaders, _} ->
- % I would either expect the current origin or a wildcard to be returned
- etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders),
- "http://example.com",
- "db origin ok");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-test_preflight_with_port1(VHost) ->
- Headers = [{"Origin", "http://example.com:5984"},
- {"Access-Control-Request-Method", "GET"}]
- ++ maybe_append_vhost(VHost),
- case ibrowse:send_req(server(), Headers, options, []) of
- {ok, _, RespHeaders, _} ->
- % I would either expect the current origin or a wildcard to be returned
- etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders),
- undefined,
- "check non defined host:port in origin ok");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-test_preflight_with_port2() ->
- Headers = [{"Origin", "http://example.com:5984"},
- {"Access-Control-Request-Method", "GET"}],
- case ibrowse:send_req(server(), Headers, options, []) of
- {ok, _, RespHeaders, _} ->
- % I would either expect the current origin or a wildcard to be returned
- etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders),
- "http://example.com:5984",
- "check host:port in origin ok");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-test_preflight_with_scheme1(VHost) ->
- Headers = [{"Origin", "https://example.com:5984"},
- {"Access-Control-Request-Method", "GET"}]
- ++ maybe_append_vhost(VHost),
- case ibrowse:send_req(server(), Headers, options, []) of
- {ok, _, RespHeaders, _} ->
- % I would either expect the current origin or a wildcard to be returned
- etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders),
- undefined,
- "check non defined scheme in origin ok");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-test_preflight_with_scheme2() ->
- Headers = [{"Origin", "https://example.com:5984"},
- {"Access-Control-Request-Method", "GET"}],
- case ibrowse:send_req(server(), Headers, options, []) of
- {ok, _, RespHeaders, _} ->
- % I would either expect the current origin or a wildcard to be returned
- etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders),
- "https://example.com:5984",
- "check scheme in origin ok");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-test_case_sensitive_mismatch_of_allowed_origins() ->
- Headers = [{"Origin", "http://EXAMPLE.COM"}],
- Url = server() ++ "etap-test-db",
- case ibrowse:send_req(Url, Headers, get, []) of
- {ok, _, RespHeaders, _Body} ->
- etap:is(proplists:get_value("Access-Control-Allow-Origin", RespHeaders),
- undefined,
- "db access config case mismatch");
- _ ->
- etap:is(false, true, "ibrowse failed")
- end.
-
-maybe_append_vhost(true) ->
- [{"Host", "http://example.com"}];
-maybe_append_vhost(Else) ->
- [].
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/etap/250-upgrade-legacy-view-files.t
----------------------------------------------------------------------
diff --git a/test/etap/250-upgrade-legacy-view-files.t b/test/etap/250-upgrade-legacy-view-files.t
deleted file mode 100644
index e720b1c..0000000
--- a/test/etap/250-upgrade-legacy-view-files.t
+++ /dev/null
@@ -1,168 +0,0 @@
-#!/usr/bin/env escript
-%% -*- erlang -*-
-% 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.
-
-main(_) ->
- test_util:init_code_path(),
-
- etap:plan(8),
- case (catch test()) of
- ok ->
- etap:end_tests();
- Other ->
- etap:diag(io_lib:format("Test died abnormally: ~p", [Other])),
- etap:bail(Other)
- end,
- ok.
-
-
-test() ->
- couch_server_sup:start_link(test_util:config_files()),
-
- % commit sofort
- ok = couch_config:set("query_server_config", "commit_freq", "0"),
-
- test_upgrade(),
-
- couch_server_sup:stop(),
- ok.
-
-fixture_path() ->
- test_util:source_file("test/etap/fixtures").
-
-old_db() ->
- fixture_path() ++ "/" ++ old_db_name().
-
-old_db_name() ->
- "test.couch".
-
-old_view() ->
- fixture_path() ++ "/" ++ old_view_name().
-
-old_view_name() ->
- "3b835456c235b1827e012e25666152f3.view".
-
-new_view_name() ->
- "a1c5929f912aca32f13446122cc6ce50.view".
-
-couch_url() ->
- "http://" ++ addr() ++ ":" ++ port().
-
-addr() ->
- couch_config:get("httpd", "bind_address", "127.0.0.1").
-
-port() ->
- integer_to_list(mochiweb_socket_server:get(couch_httpd, port)).
-
-
-% <= 1.2.x
--record(index_header,
- {seq=0,
- purge_seq=0,
- id_btree_state=nil,
- view_states=nil
- }).
-
-% >= 1.3.x
--record(mrheader, {
- seq=0,
- purge_seq=0,
- id_btree_state=nil,
- view_states=nil
-}).
-
-ensure_header(File, MatchFun, Msg) ->
- {ok, Fd} = couch_file:open(File),
- {ok, {_Sig, Header}} = couch_file:read_header(Fd),
- couch_file:close(Fd),
- etap:fun_is(MatchFun, Header, "ensure " ++ Msg ++ " header for file: " ++ File).
-
-file_exists(File) ->
- % open without creating
- case file:open(File, [read, raw]) of
- {ok, Fd_Read} ->
- file:close(Fd_Read),
- true;
- _Error ->
- false
- end.
-
-cleanup() ->
- DbDir = couch_config:get("couchdb", "database_dir"),
- Files = [
- DbDir ++ "/test.couch",
- DbDir ++ "/.test_design/" ++ old_view_name(),
- DbDir ++ "/.test_design/mrview/" ++ new_view_name()
- ],
- lists:foreach(fun(File) -> file:delete(File) end, Files),
- etap:ok(true, "cleanup").
-
-test_upgrade() ->
-
- cleanup(),
-
- % copy old db file into db dir
- DbDir = couch_config:get("couchdb", "database_dir"),
- DbTarget = DbDir ++ "/" ++ old_db_name(),
- filelib:ensure_dir(DbDir),
- OldDbName = old_db(),
- {ok, _} = file:copy(OldDbName, DbTarget),
-
- % copy old view file into view dir
- ViewDir = couch_config:get("couchdb", "view_index_dir"),
- ViewTarget = ViewDir ++ "/.test_design/" ++ old_view_name(),
- filelib:ensure_dir(ViewTarget),
- OldViewName = old_view(),
- {ok, _} = file:copy(OldViewName, ViewTarget),
-
- % ensure old header
- ensure_header(ViewTarget, fun(#index_header{}) -> true; (_) -> false end, "old"),
-
- % query view
- ViewUrl = couch_url() ++ "/test/_design/test/_view/test",
- {ok, Code, _Headers, Body} = test_util:request(ViewUrl, [], get),
-
- % expect results
- etap:is(Code, 200, "valid view result http status code"),
- ExpectBody = <<"{\"total_rows\":2,\"offset\":0,\"rows\":[\r\n{\"id\":\"193f2f9c596ddc7ad326f7da470009ec\",\"key\":1,\"value\":null},\r\n{\"id\":\"193f2f9c596ddc7ad326f7da470012b6\",\"key\":2,\"value\":null}\r\n]}\n">>,
- etap:is(Body, ExpectBody, "valid view result"),
-
- % ensure old file gone.
- etap:is(file_exists(ViewTarget), false, "ensure old file is gone"),
-
- % ensure new header
- NewViewFile = ViewDir ++ "/.test_design/mrview/" ++ new_view_name(),
-
- % add doc(s)
- test_util:request(
- couch_url() ++ "/test/boo",
- [{"Content-Type", "application/json"}],
- put,
- <<"{\"a\":3}">>),
-
- % query again
- {ok, Code2, _Headers2, Body2} = test_util:request(ViewUrl, [], get),
-
- % expect results
- etap:is(Code2, 200, "valid view result http status code"),
- ExpectBody2 = <<"{\"total_rows\":3,\"offset\":0,\"rows\":[\r\n{\"id\":\"193f2f9c596ddc7ad326f7da470009ec\",\"key\":1,\"value\":null},\r\n{\"id\":\"193f2f9c596ddc7ad326f7da470012b6\",\"key\":2,\"value\":null},\r\n{\"id\":\"boo\",\"key\":3,\"value\":null}\r\n]}\n">>,
- etap:is(Body2, ExpectBody2, "valid view result after doc add"),
-
- % ensure no rebuild
- % TBD no idea how to actually test this.
-
- % ensure new header.
- timer:sleep(2000),
- ensure_header(NewViewFile, fun(#mrheader{}) -> true; (_) -> false end, "new"),
-
- ok.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/etap/Makefile.am
----------------------------------------------------------------------
diff --git a/test/etap/Makefile.am b/test/etap/Makefile.am
deleted file mode 100644
index 66048a9..0000000
--- a/test/etap/Makefile.am
+++ /dev/null
@@ -1,108 +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.
-
-noinst_SCRIPTS = run
-noinst_DATA = test_util.beam test_web.beam
-
-noinst_PROGRAMS = test_cfg_register
-test_cfg_register_SOURCES = test_cfg_register.c
-test_cfg_register_CFLAGS = -D_BSD_SOURCE
-
-%.beam: %.erl
- $(ERLC) $<
-
-run: run.tpl
- sed -e "s|%abs_top_srcdir%|@abs_top_srcdir@|g" \
- -e "s|%abs_top_builddir%|@abs_top_builddir@|g" > \
- $@ < $<
- chmod +x $@
-
-# @@ wildcards are NOT portable, please replace with clean-local rules
-CLEANFILES = run *.beam
-
-DISTCLEANFILES = temp.*
-
-fixture_files = \
- fixtures/3b835456c235b1827e012e25666152f3.view \
- fixtures/test.couch
-
-tap_files = \
- 001-load.t \
- 002-icu-driver.t \
- 010-file-basics.t \
- 011-file-headers.t \
- 020-btree-basics.t \
- 021-btree-reductions.t \
- 030-doc-from-json.t \
- 031-doc-to-json.t \
- 040-util.t \
- 041-uuid-gen-id.ini \
- 041-uuid-gen-seq.ini \
- 041-uuid-gen-utc.ini \
- 041-uuid-gen.t \
- 042-work-queue.t \
- 050-stream.t \
- 060-kt-merging.t \
- 061-kt-missing-leaves.t \
- 062-kt-remove-leaves.t \
- 063-kt-get-leaves.t \
- 064-kt-counting.t \
- 065-kt-stemming.t \
- 070-couch-db.t \
- 072-cleanup.t \
- 073-changes.t \
- 074-doc-update-conflicts.t \
- 075-auth-cache.t \
- 076-file-compression.t \
- 077-couch-db-fast-db-delete-create.t \
- 080-config-get-set.t \
- 081-config-override.1.ini \
- 081-config-override.2.ini \
- 081-config-override.t \
- 082-config-register.t \
- 083-config-no-files.t \
- 090-task-status.t \
- 100-ref-counter.t \
- 120-stats-collect.t \
- 121-stats-aggregates.cfg \
- 121-stats-aggregates.ini \
- 121-stats-aggregates.t \
- 130-attachments-md5.t \
- 140-attachment-comp.t \
- 150-invalid-view-seq.t \
- 160-vhosts.t \
- 170-os-daemons.es \
- 170-os-daemons.t \
- 171-os-daemons-config.es \
- 171-os-daemons-config.t \
- 172-os-daemon-errors.1.sh \
- 172-os-daemon-errors.2.sh \
- 172-os-daemon-errors.3.sh \
- 172-os-daemon-errors.4.sh \
- 172-os-daemon-errors.t \
- 173-os-daemon-cfg-register.t \
- 180-http-proxy.ini \
- 180-http-proxy.t \
- 190-json-stream-parse.t \
- 200-view-group-no-db-leaks.t \
- 201-view-group-shutdown.t \
- 210-os-proc-pool.t \
- 220-compaction-daemon.t \
- 230-pbkfd2.t \
- 231-cors.t \
- 250-upgrade-legacy-view-files.t
-
-EXTRA_DIST = \
- run.tpl \
- test_web.erl \
- $(fixture_files) \
- $(tap_files)
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/etap/fixtures/3b835456c235b1827e012e25666152f3.view
----------------------------------------------------------------------
diff --git a/test/etap/fixtures/3b835456c235b1827e012e25666152f3.view b/test/etap/fixtures/3b835456c235b1827e012e25666152f3.view
deleted file mode 100644
index 9c67648..0000000
Binary files a/test/etap/fixtures/3b835456c235b1827e012e25666152f3.view and /dev/null differ
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/etap/fixtures/test.couch
----------------------------------------------------------------------
diff --git a/test/etap/fixtures/test.couch b/test/etap/fixtures/test.couch
deleted file mode 100644
index 32c79af..0000000
Binary files a/test/etap/fixtures/test.couch and /dev/null differ
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/etap/run.tpl
----------------------------------------------------------------------
diff --git a/test/etap/run.tpl b/test/etap/run.tpl
deleted file mode 100644
index d6d6dbe..0000000
--- a/test/etap/run.tpl
+++ /dev/null
@@ -1,32 +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.
-
-SRCDIR="%abs_top_srcdir%"
-BUILDDIR="%abs_top_builddir%"
-export ERL_LIBS="$BUILDDIR/src/:$ERL_LIBS"
-export ERL_FLAGS="$ERL_FLAGS -pa $BUILDDIR/test/etap/"
-
-if test $# -eq 1; then
- OPTS=""
- TGT=$1
-else
- OPTS=$1
- TGT=$2
-fi
-
-if test -f $TGT; then
- prove $OPTS $TGT
-else
- prove $OPTS $TGT/*.t
-fi
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/etap/test_cfg_register.c
----------------------------------------------------------------------
diff --git a/test/etap/test_cfg_register.c b/test/etap/test_cfg_register.c
deleted file mode 100644
index c910bac..0000000
--- a/test/etap/test_cfg_register.c
+++ /dev/null
@@ -1,31 +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.
-
-#include <stdio.h>
-#include <stdlib.h>
-
-int
-main(int argc, const char * argv[])
-{
- char c = '\0';
- size_t num = 1;
-
- fprintf(stdout, "[\"register\", \"s1\"]\n");
- fprintf(stdout, "[\"register\", \"s2\", \"k\"]\n");
- fflush(stdout);
-
- while(c != '\n' && num > 0) {
- num = fread(&c, 1, 1, stdin);
- }
-
- exit(0);
-}
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/etap/test_util.erl.in
----------------------------------------------------------------------
diff --git a/test/etap/test_util.erl.in b/test/etap/test_util.erl.in
deleted file mode 100644
index 352714e..0000000
--- a/test/etap/test_util.erl.in
+++ /dev/null
@@ -1,94 +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_util).
-
--export([init_code_path/0]).
--export([source_file/1, build_file/1, config_files/0]).
--export([run/2]).
--export([request/3, request/4]).
-
-srcdir() ->
- "@abs_top_srcdir@".
-
-builddir() ->
- "@abs_top_builddir@".
-
-init_code_path() ->
- Paths = [
- "etap",
- "couchdb",
- "ejson",
- "erlang-oauth",
- "ibrowse",
- "mochiweb",
- "snappy"
- ],
- lists:foreach(fun(Name) ->
- code:add_patha(filename:join([builddir(), "src", Name]))
- end, Paths).
-
-source_file(Name) ->
- filename:join([srcdir(), Name]).
-
-build_file(Name) ->
- filename:join([builddir(), Name]).
-
-config_files() ->
- [
- build_file("etc/couchdb/default_dev.ini"),
- source_file("test/random_port.ini"),
- build_file("etc/couchdb/local_dev.ini")
- ].
-
-
-run(Plan, Fun) ->
- test_util:init_code_path(),
- etap:plan(Plan),
- case (catch Fun()) of
- ok ->
- etap:end_tests();
- Other ->
- etap:diag(io_lib:format("Test died abnormally:~n~p", [Other])),
- timer:sleep(500),
- etap:bail(Other)
- end,
- ok.
-
-
-request(Url, Headers, Method) ->
- request(Url, Headers, Method, []).
-
-request(Url, Headers, Method, Body) ->
- request(Url, Headers, Method, Body, 3).
-
-request(_Url, _Headers, _Method, _Body, 0) ->
- {error, request_failed};
-request(Url, Headers, Method, Body, N) ->
- case code:is_loaded(ibrowse) of
- false ->
- {ok, _} = ibrowse:start();
- _ ->
- ok
- end,
- case ibrowse:send_req(Url, Headers, Method, Body) 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(Url, Headers, Method, Body, N - 1);
- Error ->
- Error
- end.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/etap/test_web.erl
----------------------------------------------------------------------
diff --git a/test/etap/test_web.erl b/test/etap/test_web.erl
deleted file mode 100644
index ed78651..0000000
--- a/test/etap/test_web.erl
+++ /dev/null
@@ -1,99 +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).
-
--export([start_link/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).
-
-start_link() ->
- gen_server:start({local, ?HANDLER}, ?MODULE, [], []),
- mochiweb_http:start([
- {name, ?SERVER},
- {loop, {?MODULE, loop}},
- {port, 0}
- ]).
-
-loop(Req) ->
- %etap:diag("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(500),
- lists:foreach(fun(C) -> Resp:write_chunk(C) end, BodyChunks),
- Resp:write_chunk([]),
- {ok, Resp};
- {error, Reason} ->
- etap:diag("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) ->
- ok = gen_server:call(?HANDLER, {set_assert, Fun}).
-
-check_last() ->
- gen_server:call(?HANDLER, last_status).
-
-init(_) ->
- {ok, nil}.
-
-terminate(_Reason, _State) ->
- ok.
-
-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(Msg, State) ->
- etap:diag("Ignoring cast message: ~p", [Msg]),
- {noreply, State}.
-
-handle_info(Msg, State) ->
- etap:diag("Ignoring info message: ~p", [Msg]),
- {noreply, State}.
-
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/javascript/Makefile.am
----------------------------------------------------------------------
diff --git a/test/javascript/Makefile.am b/test/javascript/Makefile.am
deleted file mode 100644
index e7036ca..0000000
--- a/test/javascript/Makefile.am
+++ /dev/null
@@ -1,27 +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.
-
-EXTRA_DIST = \
- cli_runner.js \
- couch_http.js \
- test_setup.js \
- run.tpl
-
-noinst_SCRIPTS = run
-CLEANFILES = run
-
-run: run.tpl
- sed -e "s|%abs_top_srcdir%|$(abs_top_srcdir)|" \
- -e "s|%abs_top_builddir%|$(abs_top_builddir)|" \
- -e "s|%localstaterundir%|$(abs_top_builddir)/tmp/run|g" \
- < $< > $@
- chmod +x $@
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/javascript/cli_runner.js
----------------------------------------------------------------------
diff --git a/test/javascript/cli_runner.js b/test/javascript/cli_runner.js
deleted file mode 100644
index e8ebd2e..0000000
--- a/test/javascript/cli_runner.js
+++ /dev/null
@@ -1,47 +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.
-//
-
-/*
- * Futon test suite was designed to be able to run all tests populated into
- * couchTests. Here we should only be loading one test, so we'll pop the first
- * test off the list and run the test. If more than one item is loaded in the
- * test object, return an error.
- */
-function runTest() {
- var count = 0;
- var start = new Date().getTime();
-
- for(var name in couchTests) {
- count++;
- }
-
- if (count !== 1) {
- console.log('Only one test per file is allowed.');
- quit(1);
- }
-
- try {
- // Add artificial wait for each test of 1 sec
- while (new Date().getTime() < start + 1200);
- couchTests[name]();
- print('OK');
- } catch(e) {
- console.log("FAIL\nReason: " + e.message);
- fmtStack(e.stack);
- quit(1);
- }
-}
-
-waitForSuccess(CouchDB.isRunning, 'isRunning');
-
-runTest();
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/javascript/couch_http.js
----------------------------------------------------------------------
diff --git a/test/javascript/couch_http.js b/test/javascript/couch_http.js
deleted file mode 100644
index c44ce28..0000000
--- a/test/javascript/couch_http.js
+++ /dev/null
@@ -1,73 +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.
-
-(function() {
- if(typeof(CouchHTTP) != "undefined") {
- CouchHTTP.prototype.open = function(method, url, async) {
- if(!/^\s*http:\/\//.test(url)) {
- if(/^\//.test(url)) {
- // The couch.uri file (base_url) has a trailing slash
- url = this.base_url + url.slice(1);
- } else {
- url = this.base_url + url;
- }
- }
-
- return this._open(method, url, async);
- };
-
- CouchHTTP.prototype.setRequestHeader = function(name, value) {
- // Drop content-length headers because cURL will set it for us
- // based on body length
- if(name.toLowerCase().replace(/^\s+|\s+$/g, '') != "content-length") {
- this._setRequestHeader(name, value);
- }
- }
-
- CouchHTTP.prototype.send = function(body) {
- this._send(body || "");
- var headers = {};
- this._headers.forEach(function(hdr) {
- var pair = hdr.split(":");
- var name = pair.shift();
- headers[name] = pair.join(":").replace(/^\s+|\s+$/g, "");
- });
- this.headers = headers;
- };
-
- CouchHTTP.prototype.getResponseHeader = function(name) {
- for(var hdr in this.headers) {
- if(hdr.toLowerCase() == name.toLowerCase()) {
- return this.headers[hdr];
- }
- }
- return null;
- };
- }
-})();
-
-CouchDB.urlPrefix = "";
-CouchDB.newXhr = function() {
- return new CouchHTTP();
-};
-
-CouchDB.xhrheader = function(xhr, header) {
- if(typeof(xhr) == "CouchHTTP") {
- return xhr.getResponseHeader(header);
- } else {
- return xhr.headers[header];
- }
-}
-
-CouchDB.xhrbody = function(xhr) {
- return xhr.responseText || xhr.body;
-}
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/javascript/run.tpl
----------------------------------------------------------------------
diff --git a/test/javascript/run.tpl b/test/javascript/run.tpl
deleted file mode 100644
index 75192da..0000000
--- a/test/javascript/run.tpl
+++ /dev/null
@@ -1,138 +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.
-
-SRC_DIR=%abs_top_srcdir%
-BUILD_DIR=%abs_top_builddir%
-SCRIPT_DIR=$SRC_DIR/share/www/script
-JS_TEST_DIR=$SRC_DIR/test/javascript
-
-COUCHJS=%abs_top_builddir%/src/couchdb/priv/couchjs
-COUCH_URI_FILE=%localstaterundir%/couch.uri
-
-# make check-js calls us with MAKE=$(MAKE) so BSDish `gmake` invocations
-# will get passed on correctly. If $0 gets run manually, default to
-# `make`
-if [ -z "$MAKE" ]; then
- MAKE=make
-fi
-
-trap 'abort' EXIT INT
-
-start() {
- ./utils/run -b -r 0 -n \
- -a $BUILD_DIR/etc/couchdb/default_dev.ini \
- -a $SRC_DIR/test/random_port.ini \
- -a $BUILD_DIR/etc/couchdb/local_dev.ini 1>/dev/null
-}
-
-stop() {
- ./utils/run -d 1>/dev/null
-}
-
-restart() {
- stop
- start
-}
-
-abort() {
- trap - 0
- stop
- exit 2
-}
-
-process_response() {
- while read data
- do
- if [ $data = 'restart' ];
- then
- if [ -z $COUCHDB_NO_START ]; then
- restart
- fi
- else
- echo "$data"
- fi
- done
-}
-
-run() {
- # start the tests
- /bin/echo -n "$1 ... "
- $COUCHJS -H -u $COUCH_URI_FILE \
- $SCRIPT_DIR/json2.js \
- $SCRIPT_DIR/sha1.js \
- $SCRIPT_DIR/oauth.js \
- $SCRIPT_DIR/couch.js \
- $SCRIPT_DIR/replicator_db_inc.js \
- $SCRIPT_DIR/couch_test_runner.js \
- $JS_TEST_DIR/couch_http.js \
- $JS_TEST_DIR/test_setup.js \
- $1 \
- $JS_TEST_DIR/cli_runner.js | process_response
-
- if [ -z $RESULT ]; then
- RESULT=$?
- elif [ "$?" -eq 1 ]; then
- RESULT=$?
- fi
-
-}
-
-run_files() {
- COUNTER=1
- FILE_COUNT=$(ls -l $1 | wc -l)
- FILE_COUNT=$(expr $FILE_COUNT + 0)
- for TEST_SRC in $1
- do
- /bin/echo -n "$COUNTER/$FILE_COUNT "
- COUNTER=$(expr $COUNTER + 1)
- run $TEST_SRC
- done
-}
-
-# start CouchDB
-if [ -z $COUCHDB_NO_START ]; then
- $MAKE dev
- start
-fi
-
-echo "Running javascript tests ..."
-
-if [ "$#" -eq 0 ];
-then
- run_files "$SCRIPT_DIR/test/*.js"
-else
- if [ -d $1 ]; then
- run_files "$1/*.js"
- else
- TEST_SRC="$1"
- if [ ! -f $TEST_SRC ]; then
- TEST_SRC="$SCRIPT_DIR/test/$1"
- if [ ! -f $TEST_SRC ]; then
- TEST_SRC="$SCRIPT_DIR/test/$1.js"
- if [ ! -f $TEST_SRC ]; then
- echo "file $1 does not exist"
- exit 1
- fi
- fi
- fi
- fi
- run $TEST_SRC
-fi
-
-if [ -z $COUCHDB_NO_START ]; then
- stop
-fi
-
-trap - 0
-exit $RESULT
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/javascript/test_setup.js
----------------------------------------------------------------------
diff --git a/test/javascript/test_setup.js b/test/javascript/test_setup.js
deleted file mode 100644
index 9347455..0000000
--- a/test/javascript/test_setup.js
+++ /dev/null
@@ -1,89 +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.
-
-/*
- * Add global couchTests object required for existing tests.
- */
-var couchTests = {};
-
-var console = {
- log: function(arg) {
- var msg = (arg.toString()).replace(/\n/g, "\n ");
- print(msg, true);
- }
-};
-
-var fmtStack = function(stack) {
- if(!stack) {
- console.log("No stack information");
- return;
- }
- console.log("Trace back (most recent call first):\n");
- var re = new RegExp("(.*?)@([^:]*):(.*)$");
- var lines = stack.split("\n");
- for(var i = 0; i < lines.length; i++) {
- var line = lines[i];
- if(!line.length) continue;
- var match = re.exec(line);
- if(!match) continue
- var match = re.exec(line);
- if(!match) continue
- var source = match[1].substr(0, 70);
- var file = match[2];
- var lnum = match[3];
- while(lnum.length < 3) lnum = " " + lnum;
- console.log(" " + lnum + ": " + file);
- console.log(" " + source);
- }
-}
-
-function T(arg1, arg2) {
- if(!arg1) {
- var result = (arg2 ? arg2 : arg1);
- throw((result instanceof Error ? result : Error(result)));
- }
-}
-
-function waitForSuccess(fun, tag) {
- var start = new Date().getTime();
- var complete = false;
-
- while (!complete) {
- var now = new Date().getTime();
- if (now > start + 5000) {
- complete = true;
- print('FAIL');
- print(tag);
- quit(1);
- }
- try {
- while (new Date().getTime() < now + 500);
- complete = fun();
- } catch (e) {}
- }
-}
-
-function restartServer() {
- print('restart');
- var start = new Date().getTime();
- while (new Date().getTime() < start + 1000);
- waitForSuccess(CouchDB.isRunning, 'restart');
-}
-
-/*
- * If last_req is an object, we got something back. This might be an error, but
- * CouchDB is up and running!
- */
-CouchDB.isRunning = function() {
- CouchDB.last_req = CouchDB.request("GET", "/");
- return typeof CouchDB.last_req == 'object';
-};
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/random_port.ini
----------------------------------------------------------------------
diff --git a/test/random_port.ini b/test/random_port.ini
deleted file mode 100644
index 2b2d130..0000000
--- a/test/random_port.ini
+++ /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.
-
-[httpd]
-port = 0
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/view_server/Makefile.am
----------------------------------------------------------------------
diff --git a/test/view_server/Makefile.am b/test/view_server/Makefile.am
deleted file mode 100644
index 11e7feb..0000000
--- a/test/view_server/Makefile.am
+++ /dev/null
@@ -1,15 +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.
-
-EXTRA_DIST = \
- query_server_spec.rb \
- run_native_process.es
http://git-wip-us.apache.org/repos/asf/couchdb/blob/ec7ee43f/test/view_server/query_server_spec.rb
----------------------------------------------------------------------
diff --git a/test/view_server/query_server_spec.rb b/test/view_server/query_server_spec.rb
deleted file mode 100644
index c53daff..0000000
--- a/test/view_server/query_server_spec.rb
+++ /dev/null
@@ -1,824 +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.
-
-# to run (requires ruby and rspec):
-# spec test/view_server/query_server_spec.rb -f specdoc --color
-#
-# environment options:
-# QS_TRACE=true
-# shows full output from the query server
-# QS_LANG=lang
-# run tests on the query server (for now, one of: js, erlang)
-#
-
-COUCH_ROOT = "#{File.dirname(__FILE__)}/../.." unless defined?(COUCH_ROOT)
-LANGUAGE = ENV["QS_LANG"] || "js"
-
-puts "Running query server specs for #{LANGUAGE} query server"
-
-require 'rspec'
-require 'json'
-
-class OSProcessRunner
- def self.run
- trace = ENV["QS_TRACE"] || false
- puts "launching #{run_command}" if trace
- if block_given?
- IO.popen(run_command, "r+") do |io|
- qs = QueryServerRunner.new(io, trace)
- yield qs
- end
- else
- io = IO.popen(run_command, "r+")
- QueryServerRunner.new(io, trace)
- end
- end
- def initialize io, trace = false
- @qsio = io
- @trace = trace
- end
- def close
- @qsio.close
- end
- def reset!
- run(["reset"])
- end
- def add_fun(fun)
- run(["add_fun", fun])
- end
- def teach_ddoc(ddoc)
- run(["ddoc", "new", ddoc_id(ddoc), ddoc])
- end
- def ddoc_run(ddoc, fun_path, args)
- run(["ddoc", ddoc_id(ddoc), fun_path, args])
- end
- def ddoc_id(ddoc)
- d_id = ddoc["_id"]
- raise 'ddoc must have _id' unless d_id
- d_id
- end
- def get_chunks
- resp = jsgets
- raise "not a chunk" unless resp.first == "chunks"
- return resp[1]
- end
- def run json
- rrun json
- jsgets
- end
- def rrun json
- line = json.to_json
- puts "run: #{line}" if @trace
- @qsio.puts line
- end
- def rgets
- resp = @qsio.gets
- puts "got: #{resp}" if @trace
- resp
- end
- def jsgets
- resp = rgets
- # err = @qserr.gets
- # puts "err: #{err}" if err
- if resp
- begin
- rj = JSON.parse("[#{resp.chomp}]")[0]
- rescue JSON::ParserError
- puts "JSON ERROR (dump under trace mode)"
- # puts resp.chomp
- while resp = rgets
- # puts resp.chomp
- end
- end
- if rj.respond_to?(:[]) && rj.is_a?(Array)
- if rj[0] == "log"
- log = rj[1]
- puts "log: #{log}" if @trace
- rj = jsgets
- end
- end
- rj
- else
- raise "no response"
- end
- end
-end
-
-class QueryServerRunner < OSProcessRunner
-
- COMMANDS = {
- "js" => "#{COUCH_ROOT}/bin/couchjs_dev #{COUCH_ROOT}/share/server/main.js",
- "erlang" => "#{COUCH_ROOT}/test/view_server/run_native_process.es"
- }
-
- def self.run_command
- COMMANDS[LANGUAGE]
- end
-end
-
-class ExternalRunner < OSProcessRunner
- def self.run_command
- "#{COUCH_ROOT}/src/couchdb/couchjs #{COUCH_ROOT}/share/server/echo.js"
- end
-end
-
-# we could organize this into a design document per language.
-# that would make testing future languages really easy.
-
-functions = {
- "emit-twice" => {
- "js" => %{function(doc){emit("foo",doc.a); emit("bar",doc.a)}},
- "erlang" => <<-ERLANG
- fun({Doc}) ->
- A = couch_util:get_value(<<"a">>, Doc, null),
- Emit(<<"foo">>, A),
- Emit(<<"bar">>, A)
- end.
- ERLANG
- },
- "emit-once" => {
- "js" => <<-JS,
- function(doc){
- emit("baz",doc.a)
- }
- JS
- "erlang" => <<-ERLANG
- fun({Doc}) ->
- A = couch_util:get_value(<<"a">>, Doc, null),
- Emit(<<"baz">>, A)
- end.
- ERLANG
- },
- "reduce-values-length" => {
- "js" => %{function(keys, values, rereduce) { return values.length; }},
- "erlang" => %{fun(Keys, Values, ReReduce) -> length(Values) end.}
- },
- "reduce-values-sum" => {
- "js" => %{function(keys, values, rereduce) { return sum(values); }},
- "erlang" => %{fun(Keys, Values, ReReduce) -> lists:sum(Values) end.}
- },
- "validate-forbidden" => {
- "js" => <<-JS,
- function(newDoc, oldDoc, userCtx) {
- if(newDoc.bad)
- throw({forbidden:"bad doc"}); "foo bar";
- }
- JS
- "erlang" => <<-ERLANG
- fun({NewDoc}, _OldDoc, _UserCtx) ->
- case couch_util:get_value(<<"bad">>, NewDoc) of
- undefined -> 1;
- _ -> {[{forbidden, <<"bad doc">>}]}
- end
- end.
- ERLANG
- },
- "show-simple" => {
- "js" => <<-JS,
- function(doc, req) {
- log("ok");
- return [doc.title, doc.body].join(' - ');
- }
- JS
- "erlang" => <<-ERLANG
- fun({Doc}, Req) ->
- Title = couch_util:get_value(<<"title">>, Doc),
- Body = couch_util:get_value(<<"body">>, Doc),
- Resp = <<Title/binary, " - ", Body/binary>>,
- {[{<<"body">>, Resp}]}
- end.
- ERLANG
- },
- "show-headers" => {
- "js" => <<-JS,
- function(doc, req) {
- var resp = {"code":200, "headers":{"X-Plankton":"Rusty"}};
- resp.body = [doc.title, doc.body].join(' - ');
- return resp;
- }
- JS
- "erlang" => <<-ERLANG
- fun({Doc}, Req) ->
- Title = couch_util:get_value(<<"title">>, Doc),
- Body = couch_util:get_value(<<"body">>, Doc),
- Resp = <<Title/binary, " - ", Body/binary>>,
- {[
- {<<"code">>, 200},
- {<<"headers">>, {[{<<"X-Plankton">>, <<"Rusty">>}]}},
- {<<"body">>, Resp}
- ]}
- end.
- ERLANG
- },
- "show-sends" => {
- "js" => <<-JS,
- function(head, req) {
- start({headers:{"Content-Type" : "text/plain"}});
- send("first chunk");
- send('second "chunk"');
- return "tail";
- };
- JS
- "erlang" => <<-ERLANG
- fun(Head, Req) ->
- Resp = {[
- {<<"headers">>, {[{<<"Content-Type">>, <<"text/plain">>}]}}
- ]},
- Start(Resp),
- Send(<<"first chunk">>),
- Send(<<"second \\\"chunk\\\"">>),
- <<"tail">>
- end.
- ERLANG
- },
- "show-while-get-rows" => {
- "js" => <<-JS,
- function(head, req) {
- send("first chunk");
- send(req.q);
- var row;
- log("about to getRow " + typeof(getRow));
- while(row = getRow()) {
- send(row.key);
- };
- return "tail";
- };
- JS
- "erlang" => <<-ERLANG,
- fun(Head, {Req}) ->
- Send(<<"first chunk">>),
- Send(couch_util:get_value(<<"q">>, Req)),
- Fun = fun({Row}, _) ->
- Send(couch_util:get_value(<<"key">>, Row)),
- {ok, nil}
- end,
- {ok, _} = FoldRows(Fun, nil),
- <<"tail">>
- end.
- ERLANG
- },
- "show-while-get-rows-multi-send" => {
- "js" => <<-JS,
- function(head, req) {
- send("bacon");
- var row;
- log("about to getRow " + typeof(getRow));
- while(row = getRow()) {
- send(row.key);
- send("eggs");
- };
- return "tail";
- };
- JS
- "erlang" => <<-ERLANG,
- fun(Head, Req) ->
- Send(<<"bacon">>),
- Fun = fun({Row}, _) ->
- Send(couch_util:get_value(<<"key">>, Row)),
- Send(<<"eggs">>),
- {ok, nil}
- end,
- FoldRows(Fun, nil),
- <<"tail">>
- end.
- ERLANG
- },
- "list-simple" => {
- "js" => <<-JS,
- function(head, req) {
- send("first chunk");
- send(req.q);
- var row;
- while(row = getRow()) {
- send(row.key);
- };
- return "early";
- };
- JS
- "erlang" => <<-ERLANG,
- fun(Head, {Req}) ->
- Send(<<"first chunk">>),
- Send(couch_util:get_value(<<"q">>, Req)),
- Fun = fun({Row}, _) ->
- Send(couch_util:get_value(<<"key">>, Row)),
- {ok, nil}
- end,
- FoldRows(Fun, nil),
- <<"early">>
- end.
- ERLANG
- },
- "list-chunky" => {
- "js" => <<-JS,
- function(head, req) {
- send("first chunk");
- send(req.q);
- var row, i=0;
- while(row = getRow()) {
- send(row.key);
- i += 1;
- if (i > 2) {
- return('early tail');
- }
- };
- };
- JS
- "erlang" => <<-ERLANG,
- fun(Head, {Req}) ->
- Send(<<"first chunk">>),
- Send(couch_util:get_value(<<"q">>, Req)),
- Fun = fun
- ({Row}, Count) when Count < 2 ->
- Send(couch_util:get_value(<<"key">>, Row)),
- {ok, Count+1};
- ({Row}, Count) when Count == 2 ->
- Send(couch_util:get_value(<<"key">>, Row)),
- {stop, <<"early tail">>}
- end,
- {ok, Tail} = FoldRows(Fun, 0),
- Tail
- end.
- ERLANG
- },
- "list-old-style" => {
- "js" => <<-JS,
- function(head, req, foo, bar) {
- return "stuff";
- }
- JS
- "erlang" => <<-ERLANG,
- fun(Head, Req, Foo, Bar) ->
- <<"stuff">>
- end.
- ERLANG
- },
- "list-capped" => {
- "js" => <<-JS,
- function(head, req) {
- send("bacon")
- var row, i = 0;
- while(row = getRow()) {
- send(row.key);
- i += 1;
- if (i > 2) {
- return('early');
- }
- };
- }
- JS
- "erlang" => <<-ERLANG,
- fun(Head, Req) ->
- Send(<<"bacon">>),
- Fun = fun
- ({Row}, Count) when Count < 2 ->
- Send(couch_util:get_value(<<"key">>, Row)),
- {ok, Count+1};
- ({Row}, Count) when Count == 2 ->
- Send(couch_util:get_value(<<"key">>, Row)),
- {stop, <<"early">>}
- end,
- {ok, Tail} = FoldRows(Fun, 0),
- Tail
- end.
- ERLANG
- },
- "list-raw" => {
- "js" => <<-JS,
- function(head, req) {
- // log(this.toSource());
- // log(typeof send);
- send("first chunk");
- send(req.q);
- var row;
- while(row = getRow()) {
- send(row.key);
- };
- return "tail";
- };
- JS
- "erlang" => <<-ERLANG,
- fun(Head, {Req}) ->
- Send(<<"first chunk">>),
- Send(couch_util:get_value(<<"q">>, Req)),
- Fun = fun({Row}, _) ->
- Send(couch_util:get_value(<<"key">>, Row)),
- {ok, nil}
- end,
- FoldRows(Fun, nil),
- <<"tail">>
- end.
- ERLANG
- },
- "filter-basic" => {
- "js" => <<-JS,
- function(doc, req) {
- if (doc.good) {
- return true;
- }
- }
- JS
- "erlang" => <<-ERLANG,
- fun({Doc}, Req) ->
- couch_util:get_value(<<"good">>, Doc)
- end.
- ERLANG
- },
- "update-basic" => {
- "js" => <<-JS,
- function(doc, req) {
- doc.world = "hello";
- var resp = [doc, "hello doc"];
- return resp;
- }
- JS
- "erlang" => <<-ERLANG,
- fun({Doc}, Req) ->
- Doc2 = [{<<"world">>, <<"hello">>}|Doc],
- [{Doc2}, {[{<<"body">>, <<"hello doc">>}]}]
- end.
- ERLANG
- },
- "error" => {
- "js" => <<-JS,
- function() {
- throw(["error","error_key","testing"]);
- }
- JS
- "erlang" => <<-ERLANG
- fun(A, B) ->
- throw([<<"error">>,<<"error_key">>,<<"testing">>])
- end.
- ERLANG
- },
- "fatal" => {
- "js" => <<-JS,
- function() {
- throw(["fatal","error_key","testing"]);
- }
- JS
- "erlang" => <<-ERLANG
- fun(A, B) ->
- throw([<<"fatal">>,<<"error_key">>,<<"testing">>])
- end.
- ERLANG
- }
-}
-
-def make_ddoc(fun_path, fun_str)
- doc = {"_id"=>"foo"}
- d = doc
- while p = fun_path.shift
- l = p
- if !fun_path.empty?
- d[p] = {}
- d = d[p]
- end
- end
- d[l] = fun_str
- doc
-end
-
-describe "query server normal case" do
- before(:all) do
- `cd #{COUCH_ROOT} && make`
- @qs = QueryServerRunner.run
- end
- after(:all) do
- @qs.close
- end
- it "should reset" do
- @qs.run(["reset"]).should == true
- end
- it "should not erase ddocs on reset" do
- @fun = functions["show-simple"][LANGUAGE]
- @ddoc = make_ddoc(["shows","simple"], @fun)
- @qs.teach_ddoc(@ddoc)
- @qs.run(["reset"]).should == true
- @qs.ddoc_run(@ddoc,
- ["shows","simple"],
- [{:title => "Best ever", :body => "Doc body"}, {}]).should ==
- ["resp", {"body" => "Best ever - Doc body"}]
- end
-
- it "should run map funs" do
- @qs.reset!
- @qs.run(["add_fun", functions["emit-twice"][LANGUAGE]]).should == true
- @qs.run(["add_fun", functions["emit-once"][LANGUAGE]]).should == true
- rows = @qs.run(["map_doc", {:a => "b"}])
- rows[0][0].should == ["foo", "b"]
- rows[0][1].should == ["bar", "b"]
- rows[1][0].should == ["baz", "b"]
- end
- describe "reduce" do
- before(:all) do
- @fun = functions["reduce-values-length"][LANGUAGE]
- @qs.reset!
- end
- it "should reduce" do
- kvs = (0...10).collect{|i|[i,i*2]}
- @qs.run(["reduce", [@fun], kvs]).should == [true, [10]]
- end
- end
- describe "rereduce" do
- before(:all) do
- @fun = functions["reduce-values-sum"][LANGUAGE]
- @qs.reset!
- end
- it "should rereduce" do
- vs = (0...10).collect{|i|i}
- @qs.run(["rereduce", [@fun], vs]).should == [true, [45]]
- end
- end
-
- describe "design docs" do
- before(:all) do
- @ddoc = {
- "_id" => "foo"
- }
- @qs.reset!
- end
- it "should learn design docs" do
- @qs.teach_ddoc(@ddoc).should == true
- end
- end
-
- # it "should validate"
- describe "validation" do
- before(:all) do
- @fun = functions["validate-forbidden"][LANGUAGE]
- @ddoc = make_ddoc(["validate_doc_update"], @fun)
- @qs.teach_ddoc(@ddoc)
- end
- it "should allow good updates" do
- @qs.ddoc_run(@ddoc,
- ["validate_doc_update"],
- [{"good" => true}, {}, {}]).should == 1
- end
- it "should reject invalid updates" do
- @qs.ddoc_run(@ddoc,
- ["validate_doc_update"],
- [{"bad" => true}, {}, {}]).should == {"forbidden"=>"bad doc"}
- end
- end
-
- describe "show" do
- before(:all) do
- @fun = functions["show-simple"][LANGUAGE]
- @ddoc = make_ddoc(["shows","simple"], @fun)
- @qs.teach_ddoc(@ddoc)
- end
- it "should show" do
- @qs.ddoc_run(@ddoc,
- ["shows","simple"],
- [{:title => "Best ever", :body => "Doc body"}, {}]).should ==
- ["resp", {"body" => "Best ever - Doc body"}]
- end
- end
-
- describe "show with headers" do
- before(:all) do
- # TODO we can make real ddocs up there.
- @fun = functions["show-headers"][LANGUAGE]
- @ddoc = make_ddoc(["shows","headers"], @fun)
- @qs.teach_ddoc(@ddoc)
- end
- it "should show headers" do
- @qs.ddoc_run(
- @ddoc,
- ["shows","headers"],
- [{:title => "Best ever", :body => "Doc body"}, {}]
- ).
- should == ["resp", {"code"=>200,"headers" => {"X-Plankton"=>"Rusty"}, "body" => "Best ever - Doc body"}]
- end
- end
-
- describe "recoverable error" do
- before(:all) do
- @fun = functions["error"][LANGUAGE]
- @ddoc = make_ddoc(["shows","error"], @fun)
- @qs.teach_ddoc(@ddoc)
- end
- it "should not exit" do
- @qs.ddoc_run(@ddoc, ["shows","error"],
- [{"foo"=>"bar"}, {"q" => "ok"}]).
- should == ["error", "error_key", "testing"]
- # still running
- @qs.run(["reset"]).should == true
- end
- end
-
- describe "changes filter" do
- before(:all) do
- @fun = functions["filter-basic"][LANGUAGE]
- @ddoc = make_ddoc(["filters","basic"], @fun)
- @qs.teach_ddoc(@ddoc)
- end
- it "should only return true for good docs" do
- @qs.ddoc_run(@ddoc,
- ["filters","basic"],
- [[{"key"=>"bam", "good" => true}, {"foo" => "bar"}, {"good" => true}], {"req" => "foo"}]
- ).
- should == [true, [true, false, true]]
- end
- end
-
- describe "update" do
- before(:all) do
- # in another patch we can remove this duplication
- # by setting up the design doc for each language ahead of time.
- @fun = functions["update-basic"][LANGUAGE]
- @ddoc = make_ddoc(["updates","basic"], @fun)
- @qs.teach_ddoc(@ddoc)
- end
- it "should return a doc and a resp body" do
- up, doc, resp = @qs.ddoc_run(@ddoc,
- ["updates","basic"],
- [{"foo" => "gnarly"}, {"method" => "POST"}]
- )
- up.should == "up"
- doc.should == {"foo" => "gnarly", "world" => "hello"}
- resp["body"].should == "hello doc"
- end
- end
-
-# end
-# LIST TESTS
-# __END__
-
- describe "ddoc list" do
- before(:all) do
- @ddoc = {
- "_id" => "foo",
- "lists" => {
- "simple" => functions["list-simple"][LANGUAGE],
- "headers" => functions["show-sends"][LANGUAGE],
- "rows" => functions["show-while-get-rows"][LANGUAGE],
- "buffer-chunks" => functions["show-while-get-rows-multi-send"][LANGUAGE],
- "chunky" => functions["list-chunky"][LANGUAGE]
- }
- }
- @qs.teach_ddoc(@ddoc)
- end
-
- describe "example list" do
- it "should run normal" do
- @qs.ddoc_run(@ddoc,
- ["lists","simple"],
- [{"foo"=>"bar"}, {"q" => "ok"}]
- ).should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
- @qs.run(["list_row", {"key"=>"baz"}]).should == ["chunks", ["baz"]]
- @qs.run(["list_row", {"key"=>"bam"}]).should == ["chunks", ["bam"]]
- @qs.run(["list_row", {"key"=>"foom"}]).should == ["chunks", ["foom"]]
- @qs.run(["list_row", {"key"=>"fooz"}]).should == ["chunks", ["fooz"]]
- @qs.run(["list_row", {"key"=>"foox"}]).should == ["chunks", ["foox"]]
- @qs.run(["list_end"]).should == ["end" , ["early"]]
- end
- end
-
- describe "headers" do
- it "should do headers proper" do
- @qs.ddoc_run(@ddoc, ["lists","headers"],
- [{"total_rows"=>1000}, {"q" => "ok"}]
- ).should == ["start", ["first chunk", 'second "chunk"'],
- {"headers"=>{"Content-Type"=>"text/plain"}}]
- @qs.rrun(["list_end"])
- @qs.jsgets.should == ["end", ["tail"]]
- end
- end
-
- describe "with rows" do
- it "should list em" do
- @qs.ddoc_run(@ddoc, ["lists","rows"],
- [{"foo"=>"bar"}, {"q" => "ok"}]).
- should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
- @qs.rrun(["list_row", {"key"=>"baz"}])
- @qs.get_chunks.should == ["baz"]
- @qs.rrun(["list_row", {"key"=>"bam"}])
- @qs.get_chunks.should == ["bam"]
- @qs.rrun(["list_end"])
- @qs.jsgets.should == ["end", ["tail"]]
- end
- it "should work with zero rows" do
- @qs.ddoc_run(@ddoc, ["lists","rows"],
- [{"foo"=>"bar"}, {"q" => "ok"}]).
- should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
- @qs.rrun(["list_end"])
- @qs.jsgets.should == ["end", ["tail"]]
- end
- end
-
- describe "should buffer multiple chunks sent for a single row." do
- it "should should buffer em" do
- @qs.ddoc_run(@ddoc, ["lists","buffer-chunks"],
- [{"foo"=>"bar"}, {"q" => "ok"}]).
- should == ["start", ["bacon"], {"headers"=>{}}]
- @qs.rrun(["list_row", {"key"=>"baz"}])
- @qs.get_chunks.should == ["baz", "eggs"]
- @qs.rrun(["list_row", {"key"=>"bam"}])
- @qs.get_chunks.should == ["bam", "eggs"]
- @qs.rrun(["list_end"])
- @qs.jsgets.should == ["end", ["tail"]]
- end
- end
- it "should end after 2" do
- @qs.ddoc_run(@ddoc, ["lists","chunky"],
- [{"foo"=>"bar"}, {"q" => "ok"}]).
- should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
-
- @qs.run(["list_row", {"key"=>"baz"}]).
- should == ["chunks", ["baz"]]
-
- @qs.run(["list_row", {"key"=>"bam"}]).
- should == ["chunks", ["bam"]]
-
- @qs.run(["list_row", {"key"=>"foom"}]).
- should == ["end", ["foom", "early tail"]]
- # here's where js has to discard quit properly
- @qs.run(["reset"]).
- should == true
- end
- end
- end
-
-
-
-def should_have_exited qs
- begin
- qs.run(["reset"])
- "raise before this (except Erlang)".should == true
- rescue RuntimeError => e
- e.message.should == "no response"
- rescue Errno::EPIPE
- true.should == true
- end
-end
-
-describe "query server that exits" do
- before(:each) do
- @qs = QueryServerRunner.run
- @ddoc = {
- "_id" => "foo",
- "lists" => {
- "capped" => functions["list-capped"][LANGUAGE],
- "raw" => functions["list-raw"][LANGUAGE]
- },
- "shows" => {
- "fatal" => functions["fatal"][LANGUAGE]
- }
- }
- @qs.teach_ddoc(@ddoc)
- end
- after(:each) do
- @qs.close
- end
-
- describe "only goes to 2 list" do
- it "should exit if erlang sends too many rows" do
- @qs.ddoc_run(@ddoc, ["lists","capped"],
- [{"foo"=>"bar"}, {"q" => "ok"}]).
- should == ["start", ["bacon"], {"headers"=>{}}]
- @qs.run(["list_row", {"key"=>"baz"}]).should == ["chunks", ["baz"]]
- @qs.run(["list_row", {"key"=>"foom"}]).should == ["chunks", ["foom"]]
- @qs.run(["list_row", {"key"=>"fooz"}]).should == ["end", ["fooz", "early"]]
- e = @qs.run(["list_row", {"key"=>"foox"}])
- e[0].should == "error"
- e[1].should == "unknown_command"
- should_have_exited @qs
- end
- end
-
- describe "raw list" do
- it "should exit if it gets a non-row in the middle" do
- @qs.ddoc_run(@ddoc, ["lists","raw"],
- [{"foo"=>"bar"}, {"q" => "ok"}]).
- should == ["start", ["first chunk", "ok"], {"headers"=>{}}]
- e = @qs.run(["reset"])
- e[0].should == "error"
- e[1].should == "list_error"
- should_have_exited @qs
- end
- end
-
- describe "fatal error" do
- it "should exit" do
- @qs.ddoc_run(@ddoc, ["shows","fatal"],
- [{"foo"=>"bar"}, {"q" => "ok"}]).
- should == ["error", "error_key", "testing"]
- should_have_exited @qs
- end
- end
-end
-
-describe "thank you for using the tests" do
- it "for more info run with QS_TRACE=true or see query_server_spec.rb file header" do
- end
-end