http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/083-config-no-files.t ---------------------------------------------------------------------- diff --git a/test/etap/083-config-no-files.t b/test/etap/083-config-no-files.t deleted file mode 100755 index 3ad0905..0000000 --- a/test/etap/083-config-no-files.t +++ /dev/null @@ -1,53 +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(3), - 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() -> - application:start(config), - - etap:fun_is( - fun(KVPairs) -> length(KVPairs) == 0 end, - config:all(), - "No INI files specified returns 0 key/value pairs." - ), - - ok = config:set("httpd", "port", "80", false), - - etap:is( - config:get("httpd", "port"), - "80", - "Created a new non-persisted k/v pair." - ), - - ok = config:set("httpd", "bind_address", "127.0.0.1"), - etap:is( - config:get("httpd", "bind_address"), - "127.0.0.1", - "Asking for a persistent key/value pair doesn't choke." - ), - - ok.
http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/090-task-status.t ---------------------------------------------------------------------- diff --git a/test/etap/090-task-status.t b/test/etap/090-task-status.t deleted file mode 100755 index 23115bd..0000000 --- a/test/etap/090-task-status.t +++ /dev/null @@ -1,279 +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(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. - -get_task_prop(Pid, Prop) -> - From = list_to_binary(pid_to_list(Pid)), - Element = lists:foldl( - fun(PropList,Acc) -> - case couch_util:get_value(pid,PropList) of - From -> - [PropList | Acc]; - _ -> - [] - end - end, - [], couch_task_status:all() - ), - case couch_util:get_value(Prop, hd(Element), nil) of - nil -> - etap:bail("Could not get property '" ++ couch_util:to_list(Prop) ++ - "' for task " ++ pid_to_list(Pid)); - Value -> - Value - end. - - -loop() -> - receive - {add, Props, From} -> - Resp = couch_task_status:add_task(Props), - From ! {ok, self(), Resp}, - loop(); - {update, Props, From} -> - Resp = couch_task_status:update(Props), - From ! {ok, self(), Resp}, - loop(); - {update_frequency, Msecs, From} -> - Resp = couch_task_status:set_update_frequency(Msecs), - From ! {ok, self(), Resp}, - loop(); - {done, From} -> - From ! {ok, self(), ok} - end. - -call(Pid, Command) -> - Pid ! {Command, self()}, - wait(Pid). - -call(Pid, Command, Arg) -> - Pid ! {Command, Arg, self()}, - wait(Pid). - -wait(Pid) -> - receive - {ok, Pid, Msg} -> Msg - after 1000 -> - throw(timeout_error) - end. - -test() -> - {ok, TaskStatusPid} = couch_task_status:start_link(), - - TaskUpdater = fun() -> loop() end, - % create three updaters - Pid1 = spawn(TaskUpdater), - Pid2 = spawn(TaskUpdater), - Pid3 = spawn(TaskUpdater), - - ok = call(Pid1, add, [{type, replication}, {progress, 0}]), - etap:is( - length(couch_task_status:all()), - 1, - "Started a task" - ), - Task1StartTime = get_task_prop(Pid1, started_on), - etap:is( - is_integer(Task1StartTime), - true, - "Task start time is defined." - ), - etap:is( - get_task_prop(Pid1, updated_on), - Task1StartTime, - "Task's start time is the same as the update time before an update." - ), - - etap:is( - call(Pid1, add, [{type, compaction}, {progress, 0}]), - {add_task_error, already_registered}, - "Unable to register multiple tasks for a single Pid." - ), - - etap:is( - get_task_prop(Pid1, type), - replication, - "Task type is 'replication'." - ), - etap:is( - get_task_prop(Pid1, progress), - 0, - "Task progress is 0." - ), - - ok = timer:sleep(1000), - call(Pid1, update, [{progress, 25}]), - etap:is( - get_task_prop(Pid1, progress), - 25, - "Task progress is 25." - ), - etap:is( - get_task_prop(Pid1, updated_on) > Task1StartTime, - true, - "Task's last update time has increased after an update." - ), - - call(Pid2, add, [{type, compaction}, {progress, 0}]), - etap:is( - length(couch_task_status:all()), - 2, - "Started a second task." - ), - Task2StartTime = get_task_prop(Pid2, started_on), - etap:is( - is_integer(Task2StartTime), - true, - "Second task's start time is defined." - ), - etap:is( - get_task_prop(Pid2, updated_on), - Task2StartTime, - "Second task's start time is the same as the update time before an update." - ), - - etap:is( - get_task_prop(Pid2, type), - compaction, - "Second task's type is 'compaction'." - ), - etap:is( - get_task_prop(Pid2, progress), - 0, - "Second task's progress is 0." - ), - - ok = timer:sleep(1000), - call(Pid2, update, [{progress, 33}]), - etap:is( - get_task_prop(Pid2, progress), - 33, - "Second task's progress updated to 33." - ), - etap:is( - get_task_prop(Pid2, updated_on) > Task2StartTime, - true, - "Second task's last update time has increased after an update." - ), - - call(Pid3, add, [{type, indexer}, {progress, 0}]), - etap:is( - length(couch_task_status:all()), - 3, - "Registered a third task." - ), - Task3StartTime = get_task_prop(Pid3, started_on), - etap:is( - is_integer(Task3StartTime), - true, - "Third task's start time is defined." - ), - etap:is( - get_task_prop(Pid3, updated_on), - Task3StartTime, - "Third task's start time is the same as the update time before an update." - ), - - etap:is( - get_task_prop(Pid3, type), - indexer, - "Third task's type is 'indexer'." - ), - etap:is( - get_task_prop(Pid3, progress), - 0, - "Third task's progress is 0." - ), - - ok = timer:sleep(1000), - call(Pid3, update, [{progress, 50}]), - etap:is( - get_task_prop(Pid3, progress), - 50, - "Third task's progress updated to 50." - ), - etap:is( - get_task_prop(Pid3, updated_on) > Task3StartTime, - true, - "Third task's last update time has increased after an update." - ), - - call(Pid3, update_frequency, 500), - call(Pid3, update, [{progress, 66}]), - etap:is( - get_task_prop(Pid3, progress), - 66, - "Third task's progress updated to 66." - ), - - call(Pid3, update, [{progress, 67}]), - etap:is( - get_task_prop(Pid3, progress), - 66, - "Task update dropped because of frequency limit." - ), - - call(Pid3, update_frequency, 0), - call(Pid3, update, [{progress, 77}]), - etap:is( - get_task_prop(Pid3, progress), - 77, - "Task updated after reseting frequency limit." - ), - - - call(Pid1, done), - etap:is( - length(couch_task_status:all()), - 2, - "First task finished." - ), - - call(Pid2, done), - etap:is( - length(couch_task_status:all()), - 1, - "Second task finished." - ), - - call(Pid3, done), - etap:is( - length(couch_task_status:all()), - 0, - "Third task finished." - ), - - erlang:monitor(process, TaskStatusPid), - couch_task_status:stop(), - receive - {'DOWN', _, _, TaskStatusPid, _} -> - ok - after - 1000 -> - throw(timeout_error) - end, - - ok. http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/120-stats-collect.t ---------------------------------------------------------------------- diff --git a/test/etap/120-stats-collect.t b/test/etap/120-stats-collect.t deleted file mode 100755 index a30f9ac..0000000 --- a/test/etap/120-stats-collect.t +++ /dev/null @@ -1,150 +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(11), - case (catch test()) of - ok -> - etap:end_tests(); - Other -> - etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), - etap:bail() - end, - ok. - -test() -> - couch_stats_collector:start(), - ok = test_counters(), - ok = test_abs_values(), - ok = test_proc_counting(), - ok = test_all(), - ok. - -test_counters() -> - AddCount = fun() -> couch_stats_collector:increment(foo) end, - RemCount = fun() -> couch_stats_collector:decrement(foo) end, - repeat(AddCount, 100), - repeat(RemCount, 25), - repeat(AddCount, 10), - repeat(RemCount, 5), - etap:is( - couch_stats_collector:get(foo), - 80, - "Incrememnt tracks correctly." - ), - - repeat(RemCount, 80), - etap:is( - couch_stats_collector:get(foo), - 0, - "Decremented to zaro." - ), - ok. - -test_abs_values() -> - lists:map(fun(Val) -> - couch_stats_collector:record(bar, Val) - end, lists:seq(1, 15)), - etap:is( - couch_stats_collector:get(bar), - lists:seq(1, 15), - "Absolute values are recorded correctly." - ), - - couch_stats_collector:clear(bar), - etap:is( - couch_stats_collector:get(bar), - nil, - "Absolute values are cleared correctly." - ), - ok. - -test_proc_counting() -> - Self = self(), - OnePid = spawn(fun() -> - couch_stats_collector:track_process_count(hoopla), - Self ! reporting, - receive sepuku -> ok end - end), - R1 = erlang:monitor(process, OnePid), - receive reporting -> ok end, - etap:is( - couch_stats_collector:get(hoopla), - 1, - "track_process_count increments the counter." - ), - - TwicePid = spawn(fun() -> - couch_stats_collector:track_process_count(hoopla), - couch_stats_collector:track_process_count(hoopla), - Self ! reporting, - receive sepuku -> ok end - end), - R2 = erlang:monitor(process, TwicePid), - receive reporting -> ok end, - etap:is( - couch_stats_collector:get(hoopla), - 3, - "track_process_count allows more than one incrememnt per Pid" - ), - - OnePid ! sepuku, - receive {'DOWN', R1, _, _, _} -> ok end, - timer:sleep(250), - etap:is( - couch_stats_collector:get(hoopla), - 2, - "Process count is decremented when process exits." - ), - - TwicePid ! sepuku, - receive {'DOWN', R2, _, _, _} -> ok end, - timer:sleep(250), - etap:is( - couch_stats_collector:get(hoopla), - 0, - "Process count is decremented for each call to track_process_count." - ), - ok. - -test_all() -> - couch_stats_collector:record(bar, 0.0), - couch_stats_collector:record(bar, 1.0), - etap:is( - lists:sort(couch_stats_collector:all()), - [ {bar,[1.0,0.0]}, {foo,0}, { hoopla,0} ], - "all/0 returns all counters and absolute values." - ), - - etap:is( - lists:sort(couch_stats_collector:all(incremental)), - [ {foo, 0}, {hoopla, 0} ], - "all/1 returns only the specified type." - ), - - couch_stats_collector:record(zing, 90), - etap:is( - lists:sort(couch_stats_collector:all(absolute)), - [ {bar,[1.0,0.0]}, {zing,"Z"} ], - "all/1 returns only the specified type." - ), - ok. - -repeat(_, 0) -> - ok; -repeat(Fun, Count) -> - Fun(), - repeat(Fun, Count-1). http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/121-stats-aggregates.cfg ---------------------------------------------------------------------- diff --git a/test/etap/121-stats-aggregates.cfg b/test/etap/121-stats-aggregates.cfg deleted file mode 100644 index 30e475d..0000000 --- a/test/etap/121-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/blob/0b7b43c9/test/etap/121-stats-aggregates.ini ---------------------------------------------------------------------- diff --git a/test/etap/121-stats-aggregates.ini b/test/etap/121-stats-aggregates.ini deleted file mode 100644 index cc5cd21..0000000 --- a/test/etap/121-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/blob/0b7b43c9/test/etap/121-stats-aggregates.t ---------------------------------------------------------------------- diff --git a/test/etap/121-stats-aggregates.t b/test/etap/121-stats-aggregates.t deleted file mode 100755 index 4436beb..0000000 --- a/test/etap/121-stats-aggregates.t +++ /dev/null @@ -1,162 +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. - -ini_file() -> - test_util:source_file("test/etap/121-stats-aggregates.ini"). - -cfg_file() -> - test_util:source_file("test/etap/121-stats-aggregates.cfg"). - -main(_) -> - test_util:run(17, fun() -> test() end). - -test() -> - config_sup:start_link([ini_file()]), - couch_stats_collector:start(), - couch_stats_aggregator:start(cfg_file()), - ok = test_all_empty(), - ok = test_get_empty(), - ok = test_count_stats(), - ok = test_abs_stats(), - ok. - -test_all_empty() -> - {Aggs} = couch_stats_aggregator:all(), - - etap:is(length(Aggs), 2, "There are only two aggregate types in testing."), - etap:is( - couch_util:get_value(testing, Aggs), - {[{stuff, make_agg(<<"yay description">>, - null, null, null, null, null)}]}, - "{testing, stuff} is empty at start." - ), - etap:is( - couch_util:get_value(number, Aggs), - {[{'11', make_agg(<<"randomosity">>, - null, null, null, null, null)}]}, - "{number, '11'} is empty at start." - ), - ok. - -test_get_empty() -> - etap:is( - couch_stats_aggregator:get_json({testing, stuff}), - make_agg(<<"yay description">>, null, null, null, null, null), - "Getting {testing, stuff} returns an empty aggregate." - ), - etap:is( - couch_stats_aggregator:get_json({number, '11'}), - make_agg(<<"randomosity">>, null, null, null, null, null), - "Getting {number, '11'} returns an empty aggregate." - ), - ok. - -test_count_stats() -> - lists:foreach(fun(_) -> - couch_stats_collector:increment({testing, stuff}) - end, lists:seq(1, 100)), - couch_stats_aggregator:collect_sample(), - etap:is( - couch_stats_aggregator:get_json({testing, stuff}), - make_agg(<<"yay description">>, 100, 100, null, 100, 100), - "COUNT: Adding values changes the stats." - ), - etap:is( - couch_stats_aggregator:get_json({testing, stuff}, 1), - make_agg(<<"yay description">>, 100, 100, null, 100, 100), - "COUNT: Adding values changes stats for all times." - ), - - timer:sleep(500), - couch_stats_aggregator:collect_sample(), - etap:is( - couch_stats_aggregator:get_json({testing, stuff}), - make_agg(<<"yay description">>, 100, 50, 70.711, 0, 100), - "COUNT: Removing values changes stats." - ), - etap:is( - couch_stats_aggregator:get_json({testing, stuff}, 1), - make_agg(<<"yay description">>, 100, 50, 70.711, 0, 100), - "COUNT: Removing values changes stats for all times." - ), - - timer:sleep(600), - couch_stats_aggregator:collect_sample(), - etap:is( - couch_stats_aggregator:get_json({testing, stuff}), - make_agg(<<"yay description">>, 100, 33.333, 57.735, 0, 100), - "COUNT: Letting time passes doesn't remove data from time 0 aggregates" - ), - etap:is( - couch_stats_aggregator:get_json({testing, stuff}, 1), - make_agg(<<"yay description">>, 0, 0, 0, 0, 0), - "COUNT: Letting time pass removes data from other time aggregates." - ), - ok. - -test_abs_stats() -> - lists:foreach(fun(X) -> - couch_stats_collector:record({number, 11}, X) - end, lists:seq(0, 10)), - couch_stats_aggregator:collect_sample(), - etap:is( - couch_stats_aggregator:get_json({number, 11}), - make_agg(<<"randomosity">>, 5, 5, null, 5, 5), - "ABS: Adding values changes the stats." - ), - etap:is( - couch_stats_aggregator:get_json({number, 11}, 1), - make_agg(<<"randomosity">>, 5, 5, null, 5, 5), - "ABS: Adding values changes stats for all times." - ), - - timer:sleep(500), - couch_stats_collector:record({number, 11}, 15), - couch_stats_aggregator:collect_sample(), - etap:is( - couch_stats_aggregator:get_json({number, 11}), - make_agg(<<"randomosity">>, 20, 10, 7.071, 5, 15), - "ABS: New values changes stats" - ), - etap:is( - couch_stats_aggregator:get_json({number, 11}, 1), - make_agg(<<"randomosity">>, 20, 10, 7.071, 5, 15), - "ABS: Removing values changes stats for all times." - ), - - timer:sleep(600), - couch_stats_aggregator:collect_sample(), - etap:is( - couch_stats_aggregator:get_json({number, 11}), - make_agg(<<"randomosity">>, 20, 10, 7.071, 5, 15), - "ABS: Letting time passes doesn't remove data from time 0 aggregates" - ), - etap:is( - couch_stats_aggregator:get_json({number, 11}, 1), - make_agg(<<"randomosity">>, 15, 15, null, 15, 15), - "ABS: Letting time pass removes data from other time aggregates." - ), - ok. - -make_agg(Desc, Sum, Mean, StdDev, Min, Max) -> - {[ - {description, Desc}, - {current, Sum}, - {sum, Sum}, - {mean, Mean}, - {stddev, StdDev}, - {min, Min}, - {max, Max} - ]}. http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/130-attachments-md5.t ---------------------------------------------------------------------- diff --git a/test/etap/130-attachments-md5.t b/test/etap/130-attachments-md5.t deleted file mode 100755 index fad057e..0000000 --- a/test/etap/130-attachments-md5.t +++ /dev/null @@ -1,248 +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. - -test_db_name() -> - <<"etap-test-db">>. - -docid() -> - case get(docid) of - undefined -> - put(docid, 1), - "1"; - Count -> - put(docid, Count+1), - integer_to_list(Count+1) - end. - -main(_) -> - test_util:init_code_path(), - - etap:plan(16), - 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() -> - ok = test_util:start_couch(), - Addr = config:get("httpd", "bind_address", any), - put(addr, Addr), - put(port, mochiweb_socket_server:get(couch_httpd, port)), - timer:sleep(1000), - - couch_server:delete(test_db_name(), []), - couch_db:create(test_db_name(), []), - - test_identity_without_md5(), - test_chunked_without_md5(), - - test_identity_with_valid_md5(), - test_chunked_with_valid_md5_header(), - test_chunked_with_valid_md5_trailer(), - - test_identity_with_invalid_md5(), - test_chunked_with_invalid_md5_header(), - test_chunked_with_invalid_md5_trailer(), - - couch_server:delete(test_db_name(), []), - ok = test_util:stop_couch(), - ok. - -test_identity_without_md5() -> - Data = [ - "PUT /", test_db_name(), "/", docid(), "/readme.txt HTTP/1.1\r\n", - "Content-Type: text/plain\r\n", - "Content-Length: 34\r\n", - "\r\n", - "We all live in a yellow submarine!"], - - {Code, Json} = do_request(Data), - etap:is(Code, 201, "Stored with identity encoding and no MD5"), - etap:is(get_json(Json, [<<"ok">>]), true, "Body indicates success."). - -test_chunked_without_md5() -> - AttData = <<"We all live in a yellow submarine!">>, - <<Part1:21/binary, Part2:13/binary>> = AttData, - Data = [ - "PUT /", test_db_name(), "/", docid(), "/readme.txt HTTP/1.1\r\n", - "Content-Type: text/plain\r\n", - "Transfer-Encoding: chunked\r\n", - "\r\n", - to_hex(size(Part1)), "\r\n", - Part1, "\r\n", - to_hex(size(Part2)), "\r\n", - Part2, "\r\n" - "0\r\n" - "\r\n"], - - {Code, Json} = do_request(Data), - etap:is(Code, 201, "Stored with chunked encoding and no MD5"), - etap:is(get_json(Json, [<<"ok">>]), true, "Body indicates success."). - -test_identity_with_valid_md5() -> - AttData = "We all live in a yellow submarine!", - Data = [ - "PUT /", test_db_name(), "/", docid(), "/readme.txt HTTP/1.1\r\n", - "Content-Type: text/plain\r\n", - "Content-Length: 34\r\n", - "Content-MD5: ", base64:encode(couch_util:md5(AttData)), "\r\n", - "\r\n", - AttData], - - {Code, Json} = do_request(Data), - etap:is(Code, 201, "Stored with identity encoding and valid MD5"), - etap:is(get_json(Json, [<<"ok">>]), true, "Body indicates success."). - -test_chunked_with_valid_md5_header() -> - AttData = <<"We all live in a yellow submarine!">>, - <<Part1:21/binary, Part2:13/binary>> = AttData, - Data = [ - "PUT /", test_db_name(), "/", docid(), "/readme.txt HTTP/1.1\r\n", - "Content-Type: text/plain\r\n", - "Transfer-Encoding: chunked\r\n", - "Content-MD5: ", base64:encode(couch_util:md5(AttData)), "\r\n", - "\r\n", - to_hex(size(Part1)), "\r\n", - Part1, "\r\n", - to_hex(size(Part2)), "\r\n", - Part2, "\r\n", - "0\r\n", - "\r\n"], - - {Code, Json} = do_request(Data), - etap:is(Code, 201, "Stored with chunked encoding and valid MD5 header."), - etap:is(get_json(Json, [<<"ok">>]), true, "Body indicates success."). - -test_chunked_with_valid_md5_trailer() -> - AttData = <<"We all live in a yellow submarine!">>, - <<Part1:21/binary, Part2:13/binary>> = AttData, - Data = [ - "PUT /", test_db_name(), "/", docid(), "/readme.txt HTTP/1.1\r\n", - "Content-Type: text/plain\r\n", - "Transfer-Encoding: chunked\r\n", - "Trailer: Content-MD5\r\n", - "\r\n", - to_hex(size(Part1)), "\r\n", - Part1, "\r\n", - to_hex(size(Part2)), "\r\n", - Part2, "\r\n", - "0\r\n", - "Content-MD5: ", base64:encode(couch_util:md5(AttData)), "\r\n", - "\r\n"], - - {Code, Json} = do_request(Data), - etap:is(Code, 201, "Stored with chunked encoding and valid MD5 trailer."), - etap:is(get_json(Json, [<<"ok">>]), true, "Body indicates success."). - -test_identity_with_invalid_md5() -> - Data = [ - "PUT /", test_db_name(), "/", docid(), "/readme.txt HTTP/1.1\r\n", - "Content-Type: text/plain\r\n", - "Content-Length: 34\r\n", - "Content-MD5: ", base64:encode(<<"foobar!">>), "\r\n", - "\r\n", - "We all live in a yellow submarine!"], - - {Code, Json} = do_request(Data), - etap:is(Code, 400, "Invalid MD5 header causes an error: identity"), - etap:is( - get_json(Json, [<<"error">>]), - <<"content_md5_mismatch">>, - "Body indicates reason for failure." - ). - -test_chunked_with_invalid_md5_header() -> - AttData = <<"We all live in a yellow submarine!">>, - <<Part1:21/binary, Part2:13/binary>> = AttData, - Data = [ - "PUT /", test_db_name(), "/", docid(), "/readme.txt HTTP/1.1\r\n", - "Content-Type: text/plain\r\n", - "Transfer-Encoding: chunked\r\n", - "Content-MD5: ", base64:encode(<<"so sneaky...">>), "\r\n", - "\r\n", - to_hex(size(Part1)), "\r\n", - Part1, "\r\n", - to_hex(size(Part2)), "\r\n", - Part2, "\r\n", - "0\r\n", - "\r\n"], - - {Code, Json} = do_request(Data), - etap:is(Code, 400, "Invalid MD5 header causes an error: chunked"), - etap:is( - get_json(Json, [<<"error">>]), - <<"content_md5_mismatch">>, - "Body indicates reason for failure." - ). - -test_chunked_with_invalid_md5_trailer() -> - AttData = <<"We all live in a yellow submarine!">>, - <<Part1:21/binary, Part2:13/binary>> = AttData, - Data = [ - "PUT /", test_db_name(), "/", docid(), "/readme.txt HTTP/1.1\r\n", - "Content-Type: text/plain\r\n", - "Transfer-Encoding: chunked\r\n", - "Trailer: Content-MD5\r\n", - "\r\n", - to_hex(size(Part1)), "\r\n", - Part1, "\r\n", - to_hex(size(Part2)), "\r\n", - Part2, "\r\n", - "0\r\n", - "Content-MD5: ", base64:encode(<<"Kool-Aid Fountain!">>), "\r\n", - "\r\n"], - - {Code, Json} = do_request(Data), - etap:is(Code, 400, "Invalid MD5 Trailer causes an error"), - etap:is( - get_json(Json, [<<"error">>]), - <<"content_md5_mismatch">>, - "Body indicates reason for failure." - ). - - -get_socket() -> - Options = [binary, {packet, 0}, {active, false}], - {ok, Sock} = gen_tcp:connect(get(addr), get(port), Options), - Sock. - -do_request(Request) -> - Sock = get_socket(), - gen_tcp:send(Sock, list_to_binary(lists:flatten(Request))), - timer:sleep(1000), - {ok, R} = gen_tcp:recv(Sock, 0), - gen_tcp:close(Sock), - [Header, Body] = re:split(R, "\r\n\r\n", [{return, binary}]), - {ok, {http_response, _, Code, _}, _} = - erlang:decode_packet(http, Header, []), - Json = ejson:decode(Body), - {Code, Json}. - -get_json(Json, Path) -> - couch_util:get_nested_json_value(Json, Path). - -to_hex(Val) -> - to_hex(Val, []). - -to_hex(0, Acc) -> - Acc; -to_hex(Val, Acc) -> - to_hex(Val div 16, [hex_char(Val rem 16) | Acc]). - -hex_char(V) when V < 10 -> $0 + V; -hex_char(V) -> $A + V - 10. - http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/140-attachment-comp.t ---------------------------------------------------------------------- diff --git a/test/etap/140-attachment-comp.t b/test/etap/140-attachment-comp.t deleted file mode 100755 index a4de5a3..0000000 --- a/test/etap/140-attachment-comp.t +++ /dev/null @@ -1,728 +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. - -test_db_name() -> - <<"couch_test_atts_compression">>. - -main(_) -> - test_util:init_code_path(), - - etap:plan(85), - 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() -> - ok = test_util:start_couch(), - put(addr, config:get("httpd", "bind_address", "127.0.0.1")), - put(port, integer_to_list(mochiweb_socket_server:get(couch_httpd, port))), - timer:sleep(1000), - couch_server:delete(test_db_name(), []), - couch_db:create(test_db_name(), []), - - config:set("attachments", "compression_level", "8", false), - config:set("attachments", "compressible_types", "text/*", false), - - create_1st_text_att(), - create_1st_png_att(), - create_2nd_text_att(), - create_2nd_png_att(), - - tests_for_1st_text_att(), - tests_for_1st_png_att(), - tests_for_2nd_text_att(), - tests_for_2nd_png_att(), - - create_already_compressed_att(db_url() ++ "/doc_comp_att", "readme.txt"), - test_already_compressed_att(db_url() ++ "/doc_comp_att", "readme.txt"), - - test_create_already_compressed_att_with_invalid_content_encoding( - db_url() ++ "/doc_att_deflate", - "readme.txt", - zlib:compress(test_text_data()), - "deflate" - ), - - % COUCHDB-1711 - avoid weird timng/scheduling/request handling issue - timer:sleep(100), - - test_create_already_compressed_att_with_invalid_content_encoding( - db_url() ++ "/doc_att_compress", - "readme.txt", - % Note: As of OTP R13B04, it seems there's no LZW compression - % (i.e. UNIX compress utility implementation) lib in OTP. - % However there's a simple working Erlang implementation at: - % http://scienceblogs.com/goodmath/2008/01/simple_lempelziv_compression_i.php - test_text_data(), - "compress" - ), - - test_compressible_type_with_parameters(), - - timer:sleep(3000), % to avoid mochiweb socket closed exceptions - couch_server:delete(test_db_name(), []), - ok = test_util:stop_couch(), - ok. - -db_url() -> - "http://" ++ get(addr) ++ ":" ++ get(port) ++ "/" ++ - binary_to_list(test_db_name()). - -create_1st_text_att() -> - {ok, Code, _Headers, _Body} = test_util:request( - db_url() ++ "/testdoc1/readme.txt", - [{"Content-Type", "text/plain"}], - put, - test_text_data()), - etap:is(Code, 201, "Created text attachment using the standalone api"), - ok. - -create_1st_png_att() -> - {ok, Code, _Headers, _Body} = test_util:request( - db_url() ++ "/testdoc2/icon.png", - [{"Content-Type", "image/png"}], - put, - test_png_data()), - etap:is(Code, 201, "Created png attachment using the standalone api"), - ok. - -% create a text attachment using the non-standalone attachment api -create_2nd_text_att() -> - DocJson = {[ - {<<"_attachments">>, {[ - {<<"readme.txt">>, {[ - {<<"content_type">>, <<"text/plain">>}, - {<<"data">>, base64:encode(test_text_data())} - ]} - }]}} - ]}, - {ok, Code, _Headers, _Body} = test_util:request( - db_url() ++ "/testdoc3", - [{"Content-Type", "application/json"}], - put, - ejson:encode(DocJson)), - etap:is(Code, 201, "Created text attachment using the non-standalone api"), - ok. - -% create a png attachment using the non-standalone attachment api -create_2nd_png_att() -> - DocJson = {[ - {<<"_attachments">>, {[ - {<<"icon.png">>, {[ - {<<"content_type">>, <<"image/png">>}, - {<<"data">>, base64:encode(test_png_data())} - ]} - }]}} - ]}, - {ok, Code, _Headers, _Body} = test_util:request( - db_url() ++ "/testdoc4", - [{"Content-Type", "application/json"}], - put, - ejson:encode(DocJson)), - etap:is(Code, 201, "Created png attachment using the non-standalone api"), - ok. - -create_already_compressed_att(DocUri, AttName) -> - {ok, Code, _Headers, _Body} = test_util:request( - DocUri ++ "/" ++ AttName, - [{"Content-Type", "text/plain"}, {"Content-Encoding", "gzip"}], - put, - zlib:gzip(test_text_data())), - etap:is( - Code, - 201, - "Created already compressed attachment using the standalone api" - ), - ok. - -tests_for_1st_text_att() -> - test_get_1st_text_att_with_accept_encoding_gzip(), - test_get_1st_text_att_without_accept_encoding_header(), - test_get_1st_text_att_with_accept_encoding_deflate(), - test_get_1st_text_att_with_accept_encoding_deflate_only(), - test_get_doc_with_1st_text_att(), - test_1st_text_att_stub(). - -tests_for_1st_png_att() -> - test_get_1st_png_att_without_accept_encoding_header(), - test_get_1st_png_att_with_accept_encoding_gzip(), - test_get_1st_png_att_with_accept_encoding_deflate(), - test_get_doc_with_1st_png_att(), - test_1st_png_att_stub(). - -tests_for_2nd_text_att() -> - test_get_2nd_text_att_with_accept_encoding_gzip(), - test_get_2nd_text_att_without_accept_encoding_header(), - test_get_doc_with_2nd_text_att(), - test_2nd_text_att_stub(). - -tests_for_2nd_png_att() -> - test_get_2nd_png_att_without_accept_encoding_header(), - test_get_2nd_png_att_with_accept_encoding_gzip(), - test_get_doc_with_2nd_png_att(), - test_2nd_png_att_stub(). - -test_get_1st_text_att_with_accept_encoding_gzip() -> - {ok, Code, Headers, Body} = test_util:request( - db_url() ++ "/testdoc1/readme.txt", - [{"Accept-Encoding", "gzip"}], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), - etap:is(Gziped, true, "received body is gziped"), - Uncompressed = zlib:gunzip(iolist_to_binary(Body)), - etap:is( - Uncompressed, - test_text_data(), - "received data for the 1st text attachment is ok" - ), - ok. - -test_get_1st_text_att_without_accept_encoding_header() -> - {ok, Code, Headers, Body} = test_util:request( - db_url() ++ "/testdoc1/readme.txt", - [], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), - etap:is(Gziped, false, "received body is not gziped"), - etap:is( - iolist_to_binary(Body), - test_text_data(), - "received data for the 1st text attachment is ok" - ), - ok. - -test_get_1st_text_att_with_accept_encoding_deflate() -> - {ok, Code, Headers, Body} = test_util:request( - db_url() ++ "/testdoc1/readme.txt", - [{"Accept-Encoding", "deflate"}], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), - etap:is(Gziped, false, "received body is not gziped"), - Deflated = lists:member({"Content-Encoding", "deflate"}, Headers), - etap:is(Deflated, false, "received body is not deflated"), - etap:is( - iolist_to_binary(Body), - test_text_data(), - "received data for the 1st text attachment is ok" - ), - ok. - -test_get_1st_text_att_with_accept_encoding_deflate_only() -> - {ok, Code, _Headers, _Body} = test_util:request( - db_url() ++ "/testdoc1/readme.txt", - [{"Accept-Encoding", "deflate, *;q=0"}], - get), - etap:is( - Code, - 406, - "HTTP response code is 406 for an unsupported content encoding request" - ), - ok. - -test_get_1st_png_att_without_accept_encoding_header() -> - {ok, Code, Headers, Body} = test_util:request( - db_url() ++ "/testdoc2/icon.png", - [], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Encoding = couch_util:get_value("Content-Encoding", Headers), - etap:is(Encoding, undefined, "received body is not gziped"), - etap:is( - iolist_to_binary(Body), - test_png_data(), - "received data for the 1st png attachment is ok" - ), - ok. - -test_get_1st_png_att_with_accept_encoding_gzip() -> - {ok, Code, Headers, Body} = test_util:request( - db_url() ++ "/testdoc2/icon.png", - [{"Accept-Encoding", "gzip"}], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Encoding = couch_util:get_value("Content-Encoding", Headers), - etap:is(Encoding, undefined, "received body is not gziped"), - etap:is( - iolist_to_binary(Body), - test_png_data(), - "received data for the 1st png attachment is ok" - ), - ok. - -test_get_1st_png_att_with_accept_encoding_deflate() -> - {ok, Code, Headers, Body} = test_util:request( - db_url() ++ "/testdoc2/icon.png", - [{"Accept-Encoding", "deflate"}], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Encoding = couch_util:get_value("Content-Encoding", Headers), - etap:is(Encoding, undefined, "received body is in identity form"), - etap:is( - iolist_to_binary(Body), - test_png_data(), - "received data for the 1st png attachment is ok" - ), - ok. - -test_get_doc_with_1st_text_att() -> - {ok, Code, _Headers, Body} = test_util:request( - db_url() ++ "/testdoc1?attachments=true", - [{"Accept", "application/json"}], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Json = ejson:decode(Body), - TextAttJson = couch_util:get_nested_json_value( - Json, - [<<"_attachments">>, <<"readme.txt">>] - ), - TextAttType = couch_util:get_nested_json_value( - TextAttJson, - [<<"content_type">>] - ), - TextAttData = couch_util:get_nested_json_value( - TextAttJson, - [<<"data">>] - ), - etap:is( - TextAttType, - <<"text/plain">>, - "1st text attachment has type text/plain" - ), - %% check the attachment's data is the base64 encoding of the plain text - %% and not the base64 encoding of the gziped plain text - etap:is( - TextAttData, - base64:encode(test_text_data()), - "1st text attachment data is properly base64 encoded" - ), - ok. - -test_1st_text_att_stub() -> - {ok, Code, _Headers, Body} = test_util:request( - db_url() ++ "/testdoc1?att_encoding_info=true", - [], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Json = ejson:decode(Body), - {TextAttJson} = couch_util:get_nested_json_value( - Json, - [<<"_attachments">>, <<"readme.txt">>] - ), - TextAttLength = couch_util:get_value(<<"length">>, TextAttJson), - etap:is( - TextAttLength, - byte_size(test_text_data()), - "1st text attachment stub length matches the uncompressed length" - ), - TextAttEncoding = couch_util:get_value(<<"encoding">>, TextAttJson), - etap:is( - TextAttEncoding, - <<"gzip">>, - "1st text attachment stub has the encoding field set to gzip" - ), - TextAttEncLength = couch_util:get_value(<<"encoded_length">>, TextAttJson), - etap:is( - TextAttEncLength, - iolist_size(zlib:gzip(test_text_data())), - "1st text attachment stub encoded_length matches the compressed length" - ), - ok. - -test_get_doc_with_1st_png_att() -> - {ok, Code, _Headers, Body} = test_util:request( - db_url() ++ "/testdoc2?attachments=true", - [{"Accept", "application/json"}], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Json = ejson:decode(Body), - PngAttJson = couch_util:get_nested_json_value( - Json, - [<<"_attachments">>, <<"icon.png">>] - ), - PngAttType = couch_util:get_nested_json_value( - PngAttJson, - [<<"content_type">>] - ), - PngAttData = couch_util:get_nested_json_value( - PngAttJson, - [<<"data">>] - ), - etap:is(PngAttType, <<"image/png">>, "attachment has type image/png"), - etap:is( - PngAttData, - base64:encode(test_png_data()), - "1st png attachment data is properly base64 encoded" - ), - ok. - -test_1st_png_att_stub() -> - {ok, Code, _Headers, Body} = test_util:request( - db_url() ++ "/testdoc2?att_encoding_info=true", - [{"Accept", "application/json"}], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Json = ejson:decode(Body), - {PngAttJson} = couch_util:get_nested_json_value( - Json, - [<<"_attachments">>, <<"icon.png">>] - ), - PngAttLength = couch_util:get_value(<<"length">>, PngAttJson), - etap:is( - PngAttLength, - byte_size(test_png_data()), - "1st png attachment stub length matches the uncompressed length" - ), - PngEncoding = couch_util:get_value(<<"encoding">>, PngAttJson), - etap:is( - PngEncoding, - undefined, - "1st png attachment stub doesn't have an encoding field" - ), - PngEncLength = couch_util:get_value(<<"encoded_length">>, PngAttJson), - etap:is( - PngEncLength, - undefined, - "1st png attachment stub doesn't have an encoded_length field" - ), - ok. - -test_get_2nd_text_att_with_accept_encoding_gzip() -> - {ok, Code, Headers, Body} = test_util:request( - db_url() ++ "/testdoc3/readme.txt", - [{"Accept-Encoding", "gzip"}], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), - etap:is(Gziped, true, "received body is gziped"), - Uncompressed = zlib:gunzip(iolist_to_binary(Body)), - etap:is( - Uncompressed, - test_text_data(), - "received data for the 2nd text attachment is ok" - ), - ok. - -test_get_2nd_text_att_without_accept_encoding_header() -> - {ok, Code, Headers, Body} = test_util:request( - db_url() ++ "/testdoc3/readme.txt", - [], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), - etap:is(Gziped, false, "received body is not gziped"), - etap:is( - Body, - test_text_data(), - "received data for the 2nd text attachment is ok" - ), - ok. - -test_get_2nd_png_att_without_accept_encoding_header() -> - {ok, Code, Headers, Body} = test_util:request( - db_url() ++ "/testdoc4/icon.png", - [], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), - etap:is(Gziped, false, "received body is not gziped"), - etap:is( - Body, - test_png_data(), - "received data for the 2nd png attachment is ok" - ), - ok. - -test_get_2nd_png_att_with_accept_encoding_gzip() -> - {ok, Code, Headers, Body} = test_util:request( - db_url() ++ "/testdoc4/icon.png", - [{"Accept-Encoding", "gzip"}], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), - etap:is(Gziped, false, "received body is not gziped"), - etap:is( - Body, - test_png_data(), - "received data for the 2nd png attachment is ok" - ), - ok. - -test_get_doc_with_2nd_text_att() -> - {ok, Code, _Headers, Body} = test_util:request( - db_url() ++ "/testdoc3?attachments=true", - [{"Accept", "application/json"}], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Json = ejson:decode(Body), - TextAttJson = couch_util:get_nested_json_value( - Json, - [<<"_attachments">>, <<"readme.txt">>] - ), - TextAttType = couch_util:get_nested_json_value( - TextAttJson, - [<<"content_type">>] - ), - TextAttData = couch_util:get_nested_json_value( - TextAttJson, - [<<"data">>] - ), - etap:is(TextAttType, <<"text/plain">>, "attachment has type text/plain"), - %% check the attachment's data is the base64 encoding of the plain text - %% and not the base64 encoding of the gziped plain text - etap:is( - TextAttData, - base64:encode(test_text_data()), - "2nd text attachment data is properly base64 encoded" - ), - ok. - -test_2nd_text_att_stub() -> - {ok, Code, _Headers, Body} = test_util:request( - db_url() ++ "/testdoc3?att_encoding_info=true", - [], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Json = ejson:decode(Body), - {TextAttJson} = couch_util:get_nested_json_value( - Json, - [<<"_attachments">>, <<"readme.txt">>] - ), - TextAttLength = couch_util:get_value(<<"length">>, TextAttJson), - etap:is( - TextAttLength, - byte_size(test_text_data()), - "2nd text attachment stub length matches the uncompressed length" - ), - TextAttEncoding = couch_util:get_value(<<"encoding">>, TextAttJson), - etap:is( - TextAttEncoding, - <<"gzip">>, - "2nd text attachment stub has the encoding field set to gzip" - ), - TextAttEncLength = couch_util:get_value(<<"encoded_length">>, TextAttJson), - etap:is( - TextAttEncLength, - iolist_size(zlib:gzip(test_text_data())), - "2nd text attachment stub encoded_length matches the compressed length" - ), - ok. - -test_get_doc_with_2nd_png_att() -> - {ok, Code, _Headers, Body} = test_util:request( - db_url() ++ "/testdoc4?attachments=true", - [{"Accept", "application/json"}], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Json = ejson:decode(Body), - PngAttJson = couch_util:get_nested_json_value( - Json, - [<<"_attachments">>, <<"icon.png">>] - ), - PngAttType = couch_util:get_nested_json_value( - PngAttJson, - [<<"content_type">>] - ), - PngAttData = couch_util:get_nested_json_value( - PngAttJson, - [<<"data">>] - ), - etap:is(PngAttType, <<"image/png">>, "attachment has type image/png"), - etap:is( - PngAttData, - base64:encode(test_png_data()), - "2nd png attachment data is properly base64 encoded" - ), - ok. - -test_2nd_png_att_stub() -> - {ok, Code, _Headers, Body} = test_util:request( - db_url() ++ "/testdoc4?att_encoding_info=true", - [], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Json = ejson:decode(Body), - {PngAttJson} = couch_util:get_nested_json_value( - Json, - [<<"_attachments">>, <<"icon.png">>] - ), - PngAttLength = couch_util:get_value(<<"length">>, PngAttJson), - etap:is( - PngAttLength, - byte_size(test_png_data()), - "2nd png attachment stub length matches the uncompressed length" - ), - PngEncoding = couch_util:get_value(<<"encoding">>, PngAttJson), - etap:is( - PngEncoding, - undefined, - "2nd png attachment stub doesn't have an encoding field" - ), - PngEncLength = couch_util:get_value(<<"encoded_length">>, PngAttJson), - etap:is( - PngEncLength, - undefined, - "2nd png attachment stub doesn't have an encoded_length field" - ), - ok. - -test_already_compressed_att(DocUri, AttName) -> - test_get_already_compressed_att_with_accept_gzip(DocUri, AttName), - test_get_already_compressed_att_without_accept(DocUri, AttName), - test_get_already_compressed_att_stub(DocUri, AttName). - -test_get_already_compressed_att_with_accept_gzip(DocUri, AttName) -> - {ok, Code, Headers, Body} = test_util:request( - DocUri ++ "/" ++ AttName, - [{"Accept-Encoding", "gzip"}], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), - etap:is(Gziped, true, "received body is gziped"), - etap:is( - Body, - zlib:gzip(test_text_data()), - "received data for the already compressed attachment is ok" - ), - ok. - -test_get_already_compressed_att_without_accept(DocUri, AttName) -> - {ok, Code, Headers, Body} = test_util:request( - DocUri ++ "/" ++ AttName, - [], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Gziped = lists:member({"Content-Encoding", "gzip"}, Headers), - etap:is(Gziped, false, "received body is not gziped"), - etap:is( - Body, - test_text_data(), - "received data for the already compressed attachment is ok" - ), - ok. - -test_get_already_compressed_att_stub(DocUri, AttName) -> - {ok, Code, _Headers, Body} = test_util:request( - DocUri ++ "?att_encoding_info=true", - [], - get), - etap:is(Code, 200, "HTTP response code is 200"), - Json = ejson:decode(Body), - {AttJson} = couch_util:get_nested_json_value( - Json, - [<<"_attachments">>, iolist_to_binary(AttName)] - ), - AttLength = couch_util:get_value(<<"length">>, AttJson), - etap:is( - AttLength, - iolist_size((zlib:gzip(test_text_data()))), - "Already compressed attachment stub length matches the " - "compressed length" - ), - Encoding = couch_util:get_value(<<"encoding">>, AttJson), - etap:is( - Encoding, - <<"gzip">>, - "Already compressed attachment stub has the encoding field set to gzip" - ), - EncLength = couch_util:get_value(<<"encoded_length">>, AttJson), - etap:is( - EncLength, - AttLength, - "Already compressed attachment stub encoded_length matches the " - "length field value" - ), - ok. - -test_create_already_compressed_att_with_invalid_content_encoding( - DocUri, AttName, AttData, Encoding) -> - {ok, Code, _Headers, _Body} = test_util:request( - DocUri ++ "/" ++ AttName, - [{"Content-Encoding", Encoding}, {"Content-Type", "text/plain"}], - put, - AttData), - etap:is( - Code, - 415, - "Couldn't create an already compressed attachment using the " - "unsupported encoding '" ++ Encoding ++ "'" - ), - ok. - -test_compressible_type_with_parameters() -> - {ok, Code, _Headers, _Body} = test_util:request( - db_url() ++ "/testdoc5/readme.txt", - [{"Content-Type", "text/plain; charset=UTF-8"}], - put, - test_text_data()), - etap:is(Code, 201, "Created text attachment with MIME type " - "'text/plain; charset=UTF-8' using the standalone api"), - {ok, Code2, Headers2, Body} = test_util:request( - db_url() ++ "/testdoc5/readme.txt", - [{"Accept-Encoding", "gzip"}], - get), - etap:is(Code2, 200, "HTTP response code is 200"), - Gziped = lists:member({"Content-Encoding", "gzip"}, Headers2), - etap:is(Gziped, true, "received body is gziped"), - Uncompressed = zlib:gunzip(iolist_to_binary(Body)), - etap:is(Uncompressed, test_text_data(), "received data is gzipped"), - {ok, Code3, _Headers3, Body3} = test_util:request( - db_url() ++ "/testdoc5?att_encoding_info=true", - [], - get), - etap:is(Code3, 200, "HTTP response code is 200"), - Json = ejson:decode(Body3), - {TextAttJson} = couch_util:get_nested_json_value( - Json, - [<<"_attachments">>, <<"readme.txt">>] - ), - TextAttLength = couch_util:get_value(<<"length">>, TextAttJson), - etap:is( - TextAttLength, - byte_size(test_text_data()), - "text attachment stub length matches the uncompressed length" - ), - TextAttEncoding = couch_util:get_value(<<"encoding">>, TextAttJson), - etap:is( - TextAttEncoding, - <<"gzip">>, - "text attachment stub has the encoding field set to gzip" - ), - TextAttEncLength = couch_util:get_value(<<"encoded_length">>, TextAttJson), - etap:is( - TextAttEncLength, - iolist_size(zlib:gzip(test_text_data())), - "text attachment stub encoded_length matches the compressed length" - ), - ok. - -test_png_data() -> - {ok, Data} = file:read_file( - test_util:source_file("share/www/image/logo.png") - ), - Data. - -test_text_data() -> - {ok, Data} = file:read_file( - test_util:source_file("README.rst") - ), - Data. http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/150-invalid-view-seq.t ---------------------------------------------------------------------- diff --git a/test/etap/150-invalid-view-seq.t b/test/etap/150-invalid-view-seq.t deleted file mode 100755 index a2ac22c..0000000 --- a/test/etap/150-invalid-view-seq.t +++ /dev/null @@ -1,172 +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_invalid_view_seq">>. - -main(_) -> - test_util:run(10, fun() -> test() end). - -%% NOTE: since during the test we stop the server, -%% a huge and ugly but harmless stack trace is sent to stderr -%% -test() -> - test_util:start_couch(), - timer:sleep(1000), - delete_db(), - create_db(), - - create_docs(), - create_design_doc(), - - % make DB file backup - backup_db_file(), - - put(addr, config:get("httpd", "bind_address", "127.0.0.1")), - put(port, integer_to_list(mochiweb_socket_server:get(couch_httpd, port))), - - create_new_doc(), - query_view_before_restore_backup(), - - % restore DB file backup after querying view - restore_backup_db_file(), - - query_view_after_restore_backup(), - - delete_db(), - ok. - -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()]). - -create_docs() -> - {ok, Db} = couch_db:open(test_db_name(), [admin_user_ctx()]), - 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). - -create_design_doc() -> - {ok, Db} = couch_db:open(test_db_name(), [admin_user_ctx()]), - DDoc = couch_doc:from_json_obj({[ - {<<"_id">>, <<"_design/foo">>}, - {<<"language">>, <<"javascript">>}, - {<<"views">>, {[ - {<<"bar">>, {[ - {<<"map">>, <<"function(doc) { emit(doc.value, 1); }">>} - ]}} - ]}} - ]}), - {ok, _} = couch_db:update_docs(Db, [DDoc]), - couch_db:ensure_full_commit(Db), - couch_db:close(Db). - -backup_db_file() -> - DbFile = test_util:build_file("tmp/lib/" ++ - binary_to_list(test_db_name()) ++ ".couch"), - {ok, _} = file:copy(DbFile, DbFile ++ ".backup"), - ok. - -create_new_doc() -> - {ok, Db} = couch_db:open(test_db_name(), [admin_user_ctx()]), - Doc666 = couch_doc:from_json_obj({[ - {<<"_id">>, <<"doc666">>}, - {<<"value">>, 999} - - ]}), - {ok, _} = couch_db:update_docs(Db, [Doc666]), - couch_db:ensure_full_commit(Db), - couch_db:close(Db). - -db_url() -> - "http://" ++ get(addr) ++ ":" ++ get(port) ++ "/" ++ - binary_to_list(test_db_name()). - -query_view_before_restore_backup() -> - {ok, Code, _Headers, Body} = test_util:request( - db_url() ++ "/_design/foo/_view/bar", [], get), - etap:is(Code, 200, "Got view response before restoring backup."), - ViewJson = ejson:decode(Body), - Rows = couch_util:get_nested_json_value(ViewJson, [<<"rows">>]), - HasDoc1 = has_doc("doc1", Rows), - HasDoc2 = has_doc("doc2", Rows), - HasDoc3 = has_doc("doc3", Rows), - HasDoc666 = has_doc("doc666", Rows), - etap:is(HasDoc1, true, "Before backup restore, view has doc1"), - etap:is(HasDoc2, true, "Before backup restore, view has doc2"), - etap:is(HasDoc3, true, "Before backup restore, view has doc3"), - etap:is(HasDoc666, true, "Before backup restore, view has doc666"), - ok. - -has_doc(DocId1, Rows) -> - DocId = iolist_to_binary(DocId1), - lists:any( - fun({R}) -> lists:member({<<"id">>, DocId}, R) end, - Rows - ). - -restore_backup_db_file() -> - ok = test_util:stop_couch(), - timer:sleep(3000), - DbFile = test_util:build_file("tmp/lib/" ++ - binary_to_list(test_db_name()) ++ ".couch"), - ok = file:delete(DbFile), - ok = file:rename(DbFile ++ ".backup", DbFile), - ok = test_util:start_couch(), - timer:sleep(1000), - put(port, integer_to_list(mochiweb_socket_server:get(couch_httpd, port))), - ok. - -query_view_after_restore_backup() -> - {ok, Code, _Headers, Body} = test_util:request( - db_url() ++ "/_design/foo/_view/bar", [], get), - etap:is(Code, 200, "Got view response after restoring backup."), - ViewJson = ejson:decode(Body), - Rows = couch_util:get_nested_json_value(ViewJson, [<<"rows">>]), - HasDoc1 = has_doc("doc1", Rows), - HasDoc2 = has_doc("doc2", Rows), - HasDoc3 = has_doc("doc3", Rows), - HasDoc666 = has_doc("doc666", Rows), - etap:is(HasDoc1, true, "After backup restore, view has doc1"), - etap:is(HasDoc2, true, "After backup restore, view has doc2"), - etap:is(HasDoc3, true, "After backup restore, view has doc3"), - etap:is(HasDoc666, false, "After backup restore, view does not have doc666"), - ok. http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/160-vhosts.t ---------------------------------------------------------------------- diff --git a/test/etap/160-vhosts.t b/test/etap/160-vhosts.t deleted file mode 100755 index c83d359..0000000 --- a/test/etap/160-vhosts.t +++ /dev/null @@ -1,371 +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 -}). - -server() -> - lists:concat([ - "http://127.0.0.1:", mochiweb_socket_server:get(couch_httpd, port), "/" - ]). - -dbname() -> "etap-test-db". -admin_user_ctx() -> {user_ctx, #user_ctx{roles=[<<"_admin">>]}}. - -main(_) -> - test_util:init_code_path(), - - etap:plan(20), - 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() -> - ok = test_util:start_couch(), - ibrowse:start(), - crypto:start(), - - timer:sleep(1000), - couch_server:delete(list_to_binary(dbname()), [admin_user_ctx()]), - {ok, Db} = couch_db:create(list_to_binary(dbname()), [admin_user_ctx()]), - - 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), - - %% end boilerplate, start test - - ok = config:set("vhosts", "example.com", "/etap-test-db", false), - ok = config:set("vhosts", "*.example.com", - "/etap-test-db/_design/doc1/_rewrite", false), - ok = config:set("vhosts", "example.com/test", "/etap-test-db", false), - ok = config:set("vhosts", "example1.com", - "/etap-test-db/_design/doc1/_rewrite/", false), - ok = config:set("vhosts",":appname.:dbname.example1.com", - "/:dbname/_design/:appname/_rewrite/", false), - ok = config:set("vhosts", ":dbname.example1.com", "/:dbname", false), - - ok = config:set("vhosts", "*.example2.com", "/*", false), - ok = config:set("vhosts", "*.example2.com/test", "/*", false), - ok = config:set("vhosts", "*/test", "/etap-test-db", false), - ok = config:set("vhosts", "*/test1", - "/etap-test-db/_design/doc1/_show/test", false), - ok = config:set("vhosts", "example3.com", "/", false), - - %% reload rules - couch_httpd_vhost:reload(), - - test_regular_request(), - test_vhost_request(), - test_vhost_request_with_qs(), - test_vhost_request_with_global(), - test_vhost_requested_path(), - test_vhost_requested_path_path(), - test_vhost_request_wildcard(), - test_vhost_request_replace_var(), - test_vhost_request_replace_var1(), - test_vhost_request_replace_wildcard(), - test_vhost_request_path(), - test_vhost_request_path1(), - test_vhost_request_path2(), - test_vhost_request_path3(), - test_vhost_request_to_root(), - test_vhost_request_with_oauth(Db), - - %% restart boilerplate - couch_db:close(Db), - ok = couch_server:delete(couch_db:name(Db), [admin_user_ctx()]), - timer:sleep(3000), - ok = test_util:stop_couch(), - - ok. - -test_regular_request() -> - case ibrowse:send_req(server(), [], get, []) of - {ok, _, _, Body} -> - {Props} = ejson:decode(Body), - Couchdb = couch_util:get_value(<<"couchdb">>, Props), - Version = couch_util:get_value(<<"version">>, Props), - Vendor = couch_util:get_value(<<"vendor">>, Props), - etap:isnt(Couchdb, undefined, "Found couchdb property"), - etap:isnt(Version, undefined, "Found version property"), - etap:isnt(Vendor, undefined, "Found vendor property"); - _Else -> - etap:bail("http GET / request failed") - end. - -test_vhost_request() -> - case ibrowse:send_req(server(), [], get, [], [{host_header, "example.com"}]) of - {ok, _, _, Body} -> - {JsonBody} = ejson:decode(Body), - HasDbNameInfo = proplists:is_defined(<<"db_name">>, JsonBody), - etap:is(HasDbNameInfo, true, "should return database info"); - _Else -> - etap:is(false, true, <<"ibrowse fail">>) - end. - -test_vhost_request_with_qs() -> - Url = server() ++ "doc1?revs_info=true", - case ibrowse:send_req(Url, [], get, [], [{host_header, "example.com"}]) of - {ok, _, _, Body} -> - {JsonProps} = ejson:decode(Body), - HasRevsInfo = proplists:is_defined(<<"_revs_info">>, JsonProps), - etap:is(HasRevsInfo, true, "should return _revs_info"); - _Else -> - etap:is(false, true, <<"ibrowse fail">>) - end. - -test_vhost_request_with_global() -> - Url2 = server() ++ "_utils/index.html", - case ibrowse:send_req(Url2, [], get, [], [{host_header, "example.com"}]) of - {ok, _, _, Body2} -> - "<!DOCTYPE" ++ _Foo = Body2, - etap:is(true, true, "should serve /_utils even inside vhosts"); - _Else -> - etap:is(false, true, <<"ibrowse fail">>) - end. - -test_vhost_requested_path() -> - case ibrowse:send_req(server(), [], get, [], [{host_header, "example1.com"}]) of - {ok, _, _, Body} -> - {Json} = ejson:decode(Body), - etap:is(case proplists:get_value(<<"requested_path">>, Json) of - <<"/">> -> true; - _ -> false - end, true, <<"requested path in req ok">>); - _Else -> - etap:is(false, true, <<"ibrowse fail">>) - end. - -test_vhost_requested_path_path() -> - case ibrowse:send_req(server(), [], get, [], [{host_header, "example1.com"}]) of - {ok, _, _, Body} -> - {Json} = ejson:decode(Body), - etap:is(case proplists:get_value(<<"path">>, Json) of - <<"/etap-test-db/_design/doc1/_show/test">> -> true; - _ -> false - end, true, <<"path in req ok">>); - _Else -> - etap:is(false, true, <<"ibrowse fail">>) - end. - -test_vhost_request_wildcard()-> - case ibrowse:send_req(server(), [], get, [], [{host_header, "test.example.com"}]) of - {ok, _, _, Body} -> - {Json} = ejson:decode(Body), - etap:is(case proplists:get_value(<<"path">>, Json) of - <<"/etap-test-db/_design/doc1/_show/test">> -> true; - _ -> false - end, true, <<"wildcard ok">>); - _Else -> etap:is(false, true, <<"ibrowse fail">>) - end. - - -test_vhost_request_replace_var() -> - case ibrowse:send_req(server(), [], get, [], [{host_header,"etap-test-db.example1.com"}]) of - {ok, _, _, Body} -> - {JsonBody} = ejson:decode(Body), - HasDbNameInfo = proplists:is_defined(<<"db_name">>, JsonBody), - etap:is(HasDbNameInfo, true, "should return database info"); - _Else -> etap:is(false, true, <<"ibrowse fail">>) - end. - -test_vhost_request_replace_var1() -> - case ibrowse:send_req(server(), [], get, [], [{host_header, "doc1.etap-test-db.example1.com"}]) of - {ok, _, _, Body} -> - {Json} = ejson:decode(Body), - etap:is(case proplists:get_value(<<"path">>, Json) of - <<"/etap-test-db/_design/doc1/_show/test">> -> true; - _ -> false - end, true, <<"wildcard ok">>); - _Else -> etap:is(false, true, <<"ibrowse fail">>) - end. - -test_vhost_request_replace_wildcard() -> - case ibrowse:send_req(server(), [], get, [], [{host_header,"etap-test-db.example2.com"}]) of - {ok, _, _, Body} -> - {JsonBody} = ejson:decode(Body), - HasDbNameInfo = proplists:is_defined(<<"db_name">>, JsonBody), - etap:is(HasDbNameInfo, true, "should return database info"); - _Else -> etap:is(false, true, <<"ibrowse fail">>) - end. - -test_vhost_request_path() -> - Uri = server() ++ "test", - case ibrowse:send_req(Uri, [], get, [], [{host_header, "example.com"}]) of - {ok, _, _, Body} -> - {JsonBody} = ejson:decode(Body), - HasDbNameInfo = proplists:is_defined(<<"db_name">>, JsonBody), - etap:is(HasDbNameInfo, true, "should return database info"); - _Else -> etap:is(false, true, <<"ibrowse fail">>) - end. - -test_vhost_request_path1() -> - Url = server() ++ "test/doc1?revs_info=true", - case ibrowse:send_req(Url, [], get, [], []) of - {ok, _, _, Body} -> - {JsonProps} = ejson:decode(Body), - HasRevsInfo = proplists:is_defined(<<"_revs_info">>, JsonProps), - etap:is(HasRevsInfo, true, "should return _revs_info"); - _Else -> etap:is(false, true, <<"ibrowse fail">>) - end. - -test_vhost_request_path2() -> - Uri = server() ++ "test", - case ibrowse:send_req(Uri, [], get, [], [{host_header,"etap-test-db.example2.com"}]) of - {ok, _, _, Body} -> - {JsonBody} = ejson:decode(Body), - HasDbNameInfo = proplists:is_defined(<<"db_name">>, JsonBody), - etap:is(HasDbNameInfo, true, "should return database info"); - _Else -> etap:is(false, true, <<"ibrowse fail">>) - end. - -test_vhost_request_path3() -> - Uri = server() ++ "test1", - case ibrowse:send_req(Uri, [], get, [], []) of - {ok, _, _, Body} -> - {Json} = ejson:decode(Body), - etap:is(case proplists:get_value(<<"path">>, Json) of - <<"/etap-test-db/_design/doc1/_show/test">> -> true; - _ -> false - end, true, <<"path in req ok">>); - _Else -> etap:is(false, true, <<"ibrowse fail">>) - end. - -test_vhost_request_to_root() -> - Uri = server(), - case ibrowse:send_req(Uri, [], get, [], []) of - {ok, _, _, Body} -> - {JsonBody} = ejson:decode(Body), - HasCouchDBWelcome = proplists:is_defined(<<"couchdb">>, JsonBody), - etap:is(HasCouchDBWelcome, true, "should allow redirect to /"); - _Else -> etap:is(false, true, <<"ibrowse fail">>) - end. - -test_vhost_request_with_oauth(Db) -> - {ok, AuthDb} = couch_db:create( - <<"tap_test_sec_db">>, [admin_user_ctx(), overwrite]), - PrevAuthDbName = config:get("couch_httpd_auth", "authentication_db"), - config:set("couch_httpd_auth", "authentication_db", "tap_test_sec_db", false), - config:set("oauth_token_users", "otoksec1", "joe", false), - config:set("oauth_consumer_secrets", "consec1", "foo", false), - config:set("oauth_token_secrets", "otoksec1", "foobar", false), - config:set("couch_httpd_auth", "require_valid_user", "true", false), - - DDoc = couch_doc:from_json_obj({[ - {<<"_id">>, <<"_design/test">>}, - {<<"language">>, <<"javascript">>}, - {<<"rewrites">>, [ - {[ - {<<"from">>, <<"foobar">>}, - {<<"to">>, <<"_info">>} - ]} - ]} - ]}), - {ok, _} = couch_db:update_doc(Db, DDoc, []), - - RewritePath = "/etap-test-db/_design/test/_rewrite/foobar", - ok = config:set("vhosts", "oauth-example.com", RewritePath, false), - couch_httpd_vhost:reload(), - - case ibrowse:send_req(server(), [], get, [], [{host_header, "oauth-example.com"}]) of - {ok, "401", _, Body} -> - {JsonBody} = ejson:decode(Body), - etap:is( - couch_util:get_value(<<"error">>, JsonBody), - <<"unauthorized">>, - "Request without OAuth credentials failed"); - Error -> - etap:bail("Request without OAuth credentials did not fail: " ++ - couch_util:to_list(Error)) - end, - - JoeDoc = couch_doc:from_json_obj({[ - {<<"_id">>, <<"org.couchdb.user:joe">>}, - {<<"type">>, <<"user">>}, - {<<"name">>, <<"joe">>}, - {<<"roles">>, []}, - {<<"password_sha">>, <<"fe95df1ca59a9b567bdca5cbaf8412abd6e06121">>}, - {<<"salt">>, <<"4e170ffeb6f34daecfd814dfb4001a73">>} - ]}), - {ok, _} = couch_db:update_doc(AuthDb, JoeDoc, []), - - Url = "http://oauth-example.com/", - Consumer = {"consec1", "foo", hmac_sha1}, - SignedParams = oauth:sign( - "GET", Url, [], Consumer, "otoksec1", "foobar"), - OAuthUrl = oauth:uri(server(), SignedParams), - - case ibrowse:send_req(OAuthUrl, [], get, [], [{host_header, "oauth-example.com"}]) of - {ok, "200", _, Body2} -> - {JsonBody2} = ejson:decode(Body2), - etap:is(couch_util:get_value(<<"name">>, JsonBody2), <<"test">>, - "should return ddoc info with OAuth credentials"); - Error2 -> - etap:bail("Failed to access vhost with OAuth credentials: " ++ - couch_util:to_list(Error2)) - end, - - Consumer2 = {"consec1", "bad_secret", hmac_sha1}, - SignedParams2 = oauth:sign( - "GET", Url, [], Consumer2, "otoksec1", "foobar"), - OAuthUrl2 = oauth:uri(server(), SignedParams2), - - case ibrowse:send_req(OAuthUrl2, [], get, [], [{host_header, "oauth-example.com"}]) of - {ok, "401", _, Body3} -> - {JsonBody3} = ejson:decode(Body3), - etap:is( - couch_util:get_value(<<"error">>, JsonBody3), - <<"unauthorized">>, - "Request with bad OAuth credentials failed"); - Error3 -> - etap:bail("Failed to access vhost with bad OAuth credentials: " ++ - couch_util:to_list(Error3)) - end, - - config:set("couch_httpd_auth", "authentication_db", PrevAuthDbName, false), - config:set("couch_httpd_auth", "require_valid_user", "false", false), - ok = couch_server:delete(couch_db:name(AuthDb), [admin_user_ctx()]). http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/170-os-daemons.es ---------------------------------------------------------------------- diff --git a/test/etap/170-os-daemons.es b/test/etap/170-os-daemons.es deleted file mode 100755 index 73974e9..0000000 --- a/test/etap/170-os-daemons.es +++ /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/blob/0b7b43c9/test/etap/170-os-daemons.t ---------------------------------------------------------------------- diff --git a/test/etap/170-os-daemons.t b/test/etap/170-os-daemons.t deleted file mode 100755 index f1961a9..0000000 --- a/test/etap/170-os-daemons.t +++ /dev/null @@ -1,114 +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(daemon, { - port, - name, - cmd, - kill, - status=running, - cfg_patterns=[], - errors=[], - buf=[] -}). - -config_files() -> - lists:map(fun test_util:build_file/1, [ - "etc/couchdb/default_dev.ini" - ]). - -daemon_cmd() -> - test_util:source_file("test/etap/170-os-daemons.es"). - -main(_) -> - test_util:init_code_path(), - - etap:plan(49), - 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() -> - application:start(config), - couch_os_daemons:start_link(), - - etap:diag("Daemons boot after configuration added."), - config:set("os_daemons", "foo", daemon_cmd(), false), - timer:sleep(1000), - - {ok, [D1]} = couch_os_daemons:info([table]), - check_daemon(D1, "foo"), - - % Check table form - {ok, Tab1} = couch_os_daemons:info(), - [T1] = ets:tab2list(Tab1), - check_daemon(T1, "foo"), - - etap:diag("Daemons stop after configuration removed."), - config:delete("os_daemons", "foo", false), - timer:sleep(500), - - {ok, []} = couch_os_daemons:info([table]), - {ok, Tab2} = couch_os_daemons:info(), - etap:is(ets:tab2list(Tab2), [], "As table returns empty table."), - - etap:diag("Adding multiple daemons causes both to boot."), - config:set("os_daemons", "bar", daemon_cmd(), false), - config:set("os_daemons", "baz", daemon_cmd(), false), - timer:sleep(500), - {ok, Daemons} = couch_os_daemons:info([table]), - lists:foreach(fun(D) -> - check_daemon(D) - end, Daemons), - - {ok, Tab3} = couch_os_daemons:info(), - lists:foreach(fun(D) -> - check_daemon(D) - end, ets:tab2list(Tab3)), - - etap:diag("Removing one daemon leaves the other alive."), - config:delete("os_daemons", "bar", false), - timer:sleep(500), - - {ok, [D2]} = couch_os_daemons:info([table]), - check_daemon(D2, "baz"), - - % Check table version - {ok, Tab4} = couch_os_daemons:info(), - [T4] = ets:tab2list(Tab4), - check_daemon(T4, "baz"), - - ok. - -check_daemon(D) -> - check_daemon(D, D#daemon.name). - -check_daemon(D, Name) -> - BaseName = "170-os-daemons.es", - BaseLen = length(BaseName), - CmdLen = length(D#daemon.cmd), - CmdName = lists:sublist(D#daemon.cmd, CmdLen-BaseLen+1, BaseLen), - - etap:is(is_port(D#daemon.port), true, "Daemon port is a port."), - etap:is(D#daemon.name, Name, "Daemon name was set correctly."), - etap:is(CmdName, BaseName, "Command name was set correctly."), - etap:isnt(D#daemon.kill, undefined, "Kill command was set."), - etap:is(D#daemon.errors, [], "No errors occurred while booting."), - etap:is(D#daemon.buf, [], "No extra data left in the buffer."). http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/171-os-daemons-config.es ---------------------------------------------------------------------- diff --git a/test/etap/171-os-daemons-config.es b/test/etap/171-os-daemons-config.es deleted file mode 100755 index 15da0e9..0000000 --- a/test/etap/171-os-daemons-config.es +++ /dev/null @@ -1,85 +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. - -filename() -> - list_to_binary(test_util:source_file("test/etap/171-os-daemons-config.es")). - -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() -> - FileName = filename(), - {[{<<"foo">>, FileName}]} = get_cfg(<<"os_daemons">>). - -test_get_cfg2() -> - FileName = filename(), - FileName = get_cfg(<<"os_daemons">>, <<"foo">>), - <<"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([]) -> - test_util:init_code_path(), - application:start(config), - couch_drv:start_link(), - do_tests(). http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/171-os-daemons-config.t ---------------------------------------------------------------------- diff --git a/test/etap/171-os-daemons-config.t b/test/etap/171-os-daemons-config.t deleted file mode 100755 index c8348d5..0000000 --- a/test/etap/171-os-daemons-config.t +++ /dev/null @@ -1,72 +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(daemon, { - port, - name, - cmd, - kill, - status=running, - cfg_patterns=[], - errors=[], - buf=[] -}). - -config_files() -> - lists:map(fun test_util:build_file/1, [ - "etc/couchdb/default_dev.ini" - ]). - -daemon_cmd() -> - test_util:source_file("test/etap/171-os-daemons-config.es"). - -main(_) -> - test_util:init_code_path(), - - etap:plan(6), - 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() -> - test_util:start_couch(), - config:set("log", "level", "debug", false), - - % "foo" is a required name by this test. - config:set("os_daemons", "foo", daemon_cmd(), false), - timer:sleep(1000), - - {ok, [D1]} = couch_os_daemons:info([table]), - check_daemon(D1, "foo"), - - ok. - -check_daemon(D, Name) -> - BaseName = "171-os-daemons-config.es", - BaseLen = length(BaseName), - CmdLen = length(D#daemon.cmd), - CmdName = lists:sublist(D#daemon.cmd, CmdLen-BaseLen+1, BaseLen), - - etap:is(is_port(D#daemon.port), true, "Daemon port is a port."), - etap:is(D#daemon.name, Name, "Daemon name was set correctly."), - etap:is(CmdName, BaseName, "Command name was set correctly."), - etap:isnt(D#daemon.kill, undefined, "Kill command was set."), - etap:is(D#daemon.errors, [], "No errors occurred while booting."), - etap:is(D#daemon.buf, [], "No extra data left in the buffer."). http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/172-os-daemon-errors.1.sh ---------------------------------------------------------------------- diff --git a/test/etap/172-os-daemon-errors.1.sh b/test/etap/172-os-daemon-errors.1.sh deleted file mode 100644 index 345c8b4..0000000 --- a/test/etap/172-os-daemon-errors.1.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/blob/0b7b43c9/test/etap/172-os-daemon-errors.2.sh ---------------------------------------------------------------------- diff --git a/test/etap/172-os-daemon-errors.2.sh b/test/etap/172-os-daemon-errors.2.sh deleted file mode 100755 index 256ee79..0000000 --- a/test/etap/172-os-daemon-errors.2.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