Goodbye, etap! This closes #296
Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/0b7b43c9 Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/0b7b43c9 Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/0b7b43c9 Branch: refs/heads/developer-preview-2.0 Commit: 0b7b43c9060aa98f38ee00dbf1c5c243b2ce67ad Parents: 8337d7e Author: Alexander Shorin <[email protected]> Authored: Tue Jan 13 05:25:24 2015 +0300 Committer: Alexander Shorin <[email protected]> Committed: Tue Jan 13 20:10:46 2015 +0300 ---------------------------------------------------------------------- test/etap/001-load.t | 86 --- test/etap/002-icu-driver.t | 33 - test/etap/010-file-basics.t | 114 --- test/etap/011-file-headers.t | 152 ---- test/etap/020-btree-basics.t | 265 ------- test/etap/021-btree-reductions.t | 237 ------ test/etap/022-emsort-basics.t | 72 -- test/etap/030-doc-from-json.t | 232 ------ test/etap/031-doc-to-json.t | 193 ----- test/etap/040-util.t | 80 -- test/etap/041-uuid-gen.t | 130 ---- test/etap/042-work-queue.t | 500 ------------- test/etap/043-find-in-binary.t | 68 -- test/etap/050-stream.t | 87 --- test/etap/060-kt-merging.t | 175 ----- test/etap/061-kt-missing-leaves.t | 65 -- test/etap/062-kt-remove-leaves.t | 69 -- test/etap/063-kt-get-leaves.t | 98 --- test/etap/064-kt-counting.t | 46 -- test/etap/065-kt-stemming.t | 42 -- test/etap/070-couch-db.t | 74 -- test/etap/071-couchdb-rapid-cycle.t | 74 -- test/etap/072-cleanup.t | 126 ---- test/etap/073-changes.t | 550 -------------- test/etap/074-doc-update-conflicts.t | 208 ------ test/etap/075-auth-cache.t | 274 ------- test/etap/076-file-compression.t | 183 ----- test/etap/077-couch-db-fast-db-delete-create.t | 50 -- test/etap/080-config-get-set.t | 128 ---- test/etap/081-config-override.1.ini | 22 - test/etap/081-config-override.2.ini | 22 - test/etap/081-config-override.t | 208 ------ test/etap/082-config-register.t | 79 -- test/etap/083-config-no-files.t | 53 -- test/etap/090-task-status.t | 279 ------- test/etap/120-stats-collect.t | 150 ---- test/etap/121-stats-aggregates.cfg | 19 - test/etap/121-stats-aggregates.ini | 20 - test/etap/121-stats-aggregates.t | 162 ----- test/etap/130-attachments-md5.t | 248 ------- test/etap/140-attachment-comp.t | 728 ------------------- test/etap/150-invalid-view-seq.t | 172 ----- test/etap/160-vhosts.t | 371 ---------- test/etap/170-os-daemons.es | 26 - test/etap/170-os-daemons.t | 114 --- test/etap/171-os-daemons-config.es | 85 --- test/etap/171-os-daemons-config.t | 72 -- test/etap/172-os-daemon-errors.1.sh | 17 - test/etap/172-os-daemon-errors.2.sh | 15 - test/etap/172-os-daemon-errors.3.sh | 15 - test/etap/172-os-daemon-errors.4.sh | 15 - test/etap/172-os-daemon-errors.t | 126 ---- test/etap/173-os-daemon-cfg-register.t | 116 --- test/etap/180-http-proxy.ini | 20 - test/etap/180-http-proxy.t | 366 ---------- test/etap/190-json-stream-parse.t | 184 ----- test/etap/200-view-group-no-db-leaks.t | 271 ------- test/etap/201-view-group-shutdown.t | 291 -------- test/etap/210-os-proc-pool.t | 163 ----- test/etap/220-compaction-daemon.t | 225 ------ test/etap/230-pbkfd2.t | 38 - test/etap/231-cors.t | 430 ----------- test/etap/232-csp.t | 85 --- test/etap/250-upgrade-legacy-view-files.t | 168 ----- test/etap/etap.erl | 614 ---------------- .../3b835456c235b1827e012e25666152f3.view | Bin 4192 -> 0 bytes test/etap/fixtures/test.couch | Bin 16482 -> 0 bytes test/etap/run.tpl | 32 - test/etap/test_cfg_register.c | 31 - test/etap/test_util.erl.in | 115 --- test/etap/test_web.erl | 99 --- 71 files changed, 10677 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/001-load.t ---------------------------------------------------------------------- diff --git a/test/etap/001-load.t b/test/etap/001-load.t deleted file mode 100755 index 3645f53..0000000 --- a/test/etap/001-load.t +++ /dev/null @@ -1,86 +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 that we can load each module. - -main(_) -> - test_util:init_code_path(), - Modules = [ - couch, - couch_app, - couch_auth_cache, - couch_btree, - couch_changes, - couch_compaction_daemon, - couch_compress, - couch_config, - couch_config_writer, - couch_db, - couch_db_update_notifier, - couch_db_update_notifier_sup, - couch_db_updater, - couch_doc, - couch_drv, - % Fails unless couch_config gen_server is started. - % couch_ejson_compare, - couch_emsort, - couch_event_sup, - couch_external_manager, - couch_external_server, - couch_file, - couch_httpd, - couch_httpd_auth, - couch_httpd_cors, - couch_httpd_db, - couch_httpd_external, - couch_httpd_misc_handlers, - couch_httpd_oauth, - couch_httpd_proxy, - couch_httpd_rewrite, - couch_httpd_stats_handlers, - couch_httpd_vhost, - couch_key_tree, - couch_log, - couch_lru, - couch_native_process, - couch_os_daemons, - couch_os_process, - couch_passwords, - couch_primary_sup, - couch_proc_manager, - couch_query_servers, - couch_secondary_sup, - couch_server, - couch_stats_aggregator, - couch_stats_collector, - couch_stream, - couch_sup, - couch_task_status, - couch_users_db, - couch_util, - couch_uuids, - couch_work_queue, - json_stream_parse - ], - - etap:plan(length(Modules)), - lists:foreach( - fun(Module) -> - etap:loaded_ok( - Module, - lists:concat(["Loaded: ", Module]) - ) - end, Modules), - etap:end_tests(). http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/002-icu-driver.t ---------------------------------------------------------------------- diff --git a/test/etap/002-icu-driver.t b/test/etap/002-icu-driver.t deleted file mode 100755 index 2ce47d9..0000000 --- a/test/etap/002-icu-driver.t +++ /dev/null @@ -1,33 +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. - -main(_) -> - test_util:init_code_path(), - application:start(config), - etap:plan(3), - etap:is( - element(1, couch_drv:start_link()), - ok, - "Started couch_icu_driver." - ), - etap:is( - couch_util:collate(<<"foo">>, <<"bar">>), - 1, - "Can collate stuff" - ), - etap:is( - couch_util:collate(<<"A">>, <<"aa">>), - -1, - "Collate's non-ascii style." - ), - etap:end_tests(). http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/010-file-basics.t ---------------------------------------------------------------------- diff --git a/test/etap/010-file-basics.t b/test/etap/010-file-basics.t deleted file mode 100755 index a337717..0000000 --- a/test/etap/010-file-basics.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. - --define(etap_match(Got, Expected, Desc), - etap:fun_is(fun(XXXXXX) -> - case XXXXXX of Expected -> true; _ -> false end - end, Got, Desc)). - -filename() -> test_util:build_file("test/etap/temp.010"). - -main(_) -> - test_util:init_code_path(), - etap:plan(19), - case (catch test()) of - ok -> - etap:end_tests(); - Other -> - etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), - timer:sleep(1000), - etap:bail() - end, - ok. - -test() -> - etap:is({error, enoent}, couch_file:open("not a real file"), - "Opening a non-existant file should return an enoent error."), - - etap:fun_is( - fun({ok, _}) -> true; (_) -> false end, - couch_file:open(filename() ++ ".1", [create, invalid_option]), - "Invalid flags to open are ignored." - ), - - {ok, Fd} = couch_file:open(filename() ++ ".0", [create, overwrite]), - etap:ok(is_pid(Fd), - "Returned file descriptor is a Pid"), - - etap:is({ok, 0}, couch_file:bytes(Fd), - "Newly created files have 0 bytes."), - - ?etap_match(couch_file:append_term(Fd, foo), {ok, 0, _}, - "Appending a term returns the previous end of file position."), - - {ok, Size} = couch_file:bytes(Fd), - etap:is_greater(Size, 0, - "Writing a term increased the file size."), - - ?etap_match(couch_file:append_binary(Fd, <<"fancy!">>), {ok, Size, _}, - "Appending a binary returns the current file size."), - - etap:is({ok, foo}, couch_file:pread_term(Fd, 0), - "Reading the first term returns what we wrote: foo"), - - etap:is({ok, <<"fancy!">>}, couch_file:pread_binary(Fd, Size), - "Reading back the binary returns what we wrote: <<\"fancy\">>."), - - etap:is({ok, couch_compress:compress(foo, snappy)}, - couch_file:pread_binary(Fd, 0), - "Reading a binary at a term position returns the term as binary." - ), - - {ok, BinPos, _} = couch_file:append_binary(Fd, <<131,100,0,3,102,111,111>>), - etap:is({ok, foo}, couch_file:pread_term(Fd, BinPos), - "Reading a term from a written binary term representation succeeds."), - - BigBin = list_to_binary(lists:duplicate(100000, 0)), - {ok, BigBinPos, _} = couch_file:append_binary(Fd, BigBin), - etap:is({ok, BigBin}, couch_file:pread_binary(Fd, BigBinPos), - "Reading a large term from a written representation succeeds."), - - ok = couch_file:write_header(Fd, hello), - etap:is({ok, hello}, couch_file:read_header(Fd), - "Reading a header succeeds."), - - {ok, BigBinPos2, _} = couch_file:append_binary(Fd, BigBin), - etap:is({ok, BigBin}, couch_file:pread_binary(Fd, BigBinPos2), - "Reading a large term from a written representation succeeds 2."), - - % append_binary == append_iolist? - % Possible bug in pread_iolist or iolist() -> append_binary - {ok, IOLPos, _} = couch_file:append_binary(Fd, ["foo", $m, <<"bam">>]), - {ok, IoList} = couch_file:pread_iolist(Fd, IOLPos), - etap:is(<<"foombam">>, iolist_to_binary(IoList), - "Reading an results in a binary form of the written iolist()"), - - % XXX: How does on test fsync? - etap:is(ok, couch_file:sync(Fd), - "Syncing does not cause an error."), - - etap:is(ok, couch_file:truncate(Fd, Size), - "Truncating a file succeeds."), - - %etap:is(eof, (catch couch_file:pread_binary(Fd, Size)), - % "Reading data that was truncated fails.") - etap:skip(fun() -> ok end, - "No idea how to test reading beyond EOF"), - - etap:is({ok, foo}, couch_file:pread_term(Fd, 0), - "Truncating does not affect data located before the truncation mark."), - - etap:is(ok, couch_file:close(Fd), - "Files close properly."), - ok. http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/011-file-headers.t ---------------------------------------------------------------------- diff --git a/test/etap/011-file-headers.t b/test/etap/011-file-headers.t deleted file mode 100755 index a26b032..0000000 --- a/test/etap/011-file-headers.t +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env escript -%% -*- erlang -*- -%%! -pa ./src/couchdb -sasl errlog_type error -boot start_sasl -noshell - -% 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() -> test_util:build_file("test/etap/temp.011"). -sizeblock() -> 4096. % Need to keep this in sync with couch_file.erl - -main(_) -> - test_util:init_code_path(), - {S1, S2, S3} = now(), - random:seed(S1, S2, S3), - - etap:plan(18), - case (catch test()) of - ok -> - etap:end_tests(); - Other -> - etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), - etap:bail() - end, - ok. - -test() -> - {ok, Fd} = couch_file:open(filename(), [create,overwrite]), - - etap:is({ok, 0}, couch_file:bytes(Fd), - "File should be initialized to contain zero bytes."), - - etap:is(ok, couch_file:write_header(Fd, {<<"some_data">>, 32}), - "Writing a header succeeds."), - - {ok, Size1} = couch_file:bytes(Fd), - etap:is_greater(Size1, 0, - "Writing a header allocates space in the file."), - - etap:is({ok, {<<"some_data">>, 32}}, couch_file:read_header(Fd), - "Reading the header returns what we wrote."), - - etap:is(ok, couch_file:write_header(Fd, [foo, <<"more">>]), - "Writing a second header succeeds."), - - {ok, Size2} = couch_file:bytes(Fd), - etap:is_greater(Size2, Size1, - "Writing a second header allocates more space."), - - etap:is({ok, [foo, <<"more">>]}, couch_file:read_header(Fd), - "Reading the second header does not return the first header."), - - % Delete the second header. - ok = couch_file:truncate(Fd, Size1), - - etap:is({ok, {<<"some_data">>, 32}}, couch_file:read_header(Fd), - "Reading the header after a truncation returns a previous header."), - - couch_file:write_header(Fd, [foo, <<"more">>]), - etap:is({ok, Size2}, couch_file:bytes(Fd), - "Rewriting the same second header returns the same second size."), - - couch_file:write_header(Fd, erlang:make_tuple(5000, <<"CouchDB">>)), - etap:is( - couch_file:read_header(Fd), - {ok, erlang:make_tuple(5000, <<"CouchDB">>)}, - "Headers larger than the block size can be saved (COUCHDB-1319)" - ), - - ok = couch_file:close(Fd), - - % Now for the fun stuff. Try corrupting the second header and see - % if we recover properly. - - % Destroy the 0x1 byte that marks a header - check_header_recovery(fun(CouchFd, RawFd, Expect, HeaderPos) -> - etap:isnt(Expect, couch_file:read_header(CouchFd), - "Should return a different header before corruption."), - file:pwrite(RawFd, HeaderPos, <<0>>), - etap:is(Expect, couch_file:read_header(CouchFd), - "Corrupting the byte marker should read the previous header.") - end), - - % Corrupt the size. - check_header_recovery(fun(CouchFd, RawFd, Expect, HeaderPos) -> - etap:isnt(Expect, couch_file:read_header(CouchFd), - "Should return a different header before corruption."), - % +1 for 0x1 byte marker - file:pwrite(RawFd, HeaderPos+1, <<10/integer>>), - etap:is(Expect, couch_file:read_header(CouchFd), - "Corrupting the size should read the previous header.") - end), - - % Corrupt the MD5 signature - check_header_recovery(fun(CouchFd, RawFd, Expect, HeaderPos) -> - etap:isnt(Expect, couch_file:read_header(CouchFd), - "Should return a different header before corruption."), - % +5 = +1 for 0x1 byte and +4 for term size. - file:pwrite(RawFd, HeaderPos+5, <<"F01034F88D320B22">>), - etap:is(Expect, couch_file:read_header(CouchFd), - "Corrupting the MD5 signature should read the previous header.") - end), - - % Corrupt the data - check_header_recovery(fun(CouchFd, RawFd, Expect, HeaderPos) -> - etap:isnt(Expect, couch_file:read_header(CouchFd), - "Should return a different header before corruption."), - % +21 = +1 for 0x1 byte, +4 for term size and +16 for MD5 sig - file:pwrite(RawFd, HeaderPos+21, <<"some data goes here!">>), - etap:is(Expect, couch_file:read_header(CouchFd), - "Corrupting the header data should read the previous header.") - end), - - ok. - -check_header_recovery(CheckFun) -> - {ok, Fd} = couch_file:open(filename(), [create,overwrite]), - {ok, RawFd} = file:open(filename(), [read, write, raw, binary]), - - {ok, _} = write_random_data(Fd), - ExpectHeader = {some_atom, <<"a binary">>, 756}, - ok = couch_file:write_header(Fd, ExpectHeader), - - {ok, HeaderPos} = write_random_data(Fd), - ok = couch_file:write_header(Fd, {2342, <<"corruption! greed!">>}), - - CheckFun(Fd, RawFd, {ok, ExpectHeader}, HeaderPos), - - ok = file:close(RawFd), - ok = couch_file:close(Fd), - ok. - -write_random_data(Fd) -> - write_random_data(Fd, 100 + random:uniform(1000)). - -write_random_data(Fd, 0) -> - {ok, Bytes} = couch_file:bytes(Fd), - {ok, (1 + Bytes div sizeblock()) * sizeblock()}; -write_random_data(Fd, N) -> - Choices = [foo, bar, <<"bizzingle">>, "bank", ["rough", stuff]], - Term = lists:nth(random:uniform(4) + 1, Choices), - {ok, _, _} = couch_file:append_term(Fd, Term), - write_random_data(Fd, N-1). - http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/020-btree-basics.t ---------------------------------------------------------------------- diff --git a/test/etap/020-btree-basics.t b/test/etap/020-btree-basics.t deleted file mode 100755 index b0fb2d2..0000000 --- a/test/etap/020-btree-basics.t +++ /dev/null @@ -1,265 +0,0 @@ -#!/usr/bin/env escript -%% -*- erlang -*- -%%! -pa ./src/couchdb -sasl errlog_type error -boot start_sasl -noshell - -% 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() -> test_util:build_file("test/etap/temp.020"). -rows() -> 250. - --record(btree, { - fd, - root, - extract_kv, - assemble_kv, - less, - reduce, - compression -}). - -main(_) -> - test_util:init_code_path(), - etap:plan(75), - case (catch test()) of - ok -> - etap:end_tests(); - Other -> - etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), - etap:bail() - end, - ok. - -%% @todo Determine if this number should be greater to see if the btree was -%% broken into multiple nodes. AKA "How do we appropiately detect if multiple -%% nodes were created." -test()-> - Sorted = [{Seq, random:uniform()} || Seq <- lists:seq(1, rows())], - etap:ok(test_kvs(Sorted), "Testing sorted keys"), - etap:ok(test_kvs(lists:reverse(Sorted)), "Testing reversed sorted keys"), - etap:ok(test_kvs(shuffle(Sorted)), "Testing shuffled keys."), - ok. - -test_kvs(KeyValues) -> - ReduceFun = fun - (reduce, KVs) -> - length(KVs); - (rereduce, Reds) -> - lists:sum(Reds) - end, - - Keys = [K || {K, _} <- KeyValues], - - {ok, Fd} = couch_file:open(filename(), [create,overwrite]), - {ok, Btree} = couch_btree:open(nil, Fd, [{compression, none}]), - etap:ok(is_record(Btree, btree), "Created btree is really a btree record"), - etap:is(Btree#btree.fd, Fd, "Btree#btree.fd is set correctly."), - etap:is(Btree#btree.root, nil, "Btree#btree.root is set correctly."), - etap:is(0, couch_btree:size(Btree), "Empty btrees have a 0 size."), - - Btree1 = couch_btree:set_options(Btree, [{reduce, ReduceFun}]), - etap:is(Btree1#btree.reduce, ReduceFun, "Reduce function was set"), - {ok, _, EmptyRes} = couch_btree:foldl(Btree1, fun(_, X) -> {ok, X+1} end, 0), - etap:is(EmptyRes, 0, "Folding over an empty btree"), - - {ok, Btree2} = couch_btree:add_remove(Btree1, KeyValues, []), - etap:ok(test_btree(Btree2, KeyValues), - "Adding all keys at once returns a complete btree."), - - etap:is((couch_btree:size(Btree2) > 0), true, - "Non empty btrees have a size > 0."), - etap:is((couch_btree:size(Btree2) =< couch_file:bytes(Fd)), true, - "Btree size is <= file size."), - - etap:fun_is( - fun - ({ok, {kp_node, _}}) -> true; - (_) -> false - end, - couch_file:pread_term(Fd, element(1, Btree2#btree.root)), - "Btree root pointer is a kp_node." - ), - - {ok, Btree3} = couch_btree:add_remove(Btree2, [], Keys), - etap:ok(test_btree(Btree3, []), - "Removing all keys at once returns an empty btree."), - - etap:is(0, couch_btree:size(Btree3), - "After removing all keys btree size is 0."), - - {Btree4, _} = lists:foldl(fun(KV, {BtAcc, PrevSize}) -> - {ok, BtAcc2} = couch_btree:add_remove(BtAcc, [KV], []), - case couch_btree:size(BtAcc2) > PrevSize of - true -> - ok; - false -> - etap:bail("After inserting a value, btree size did not increase.") - end, - {BtAcc2, couch_btree:size(BtAcc2)} - end, {Btree3, couch_btree:size(Btree3)}, KeyValues), - - etap:ok(test_btree(Btree4, KeyValues), - "Adding all keys one at a time returns a complete btree."), - etap:is((couch_btree:size(Btree4) > 0), true, - "Non empty btrees have a size > 0."), - - {Btree5, _} = lists:foldl(fun({K, _}, {BtAcc, PrevSize}) -> - {ok, BtAcc2} = couch_btree:add_remove(BtAcc, [], [K]), - case couch_btree:size(BtAcc2) < PrevSize of - true -> - ok; - false -> - etap:bail("After removing a key, btree size did not decrease.") - end, - {BtAcc2, couch_btree:size(BtAcc2)} - end, {Btree4, couch_btree:size(Btree4)}, KeyValues), - etap:ok(test_btree(Btree5, []), - "Removing all keys one at a time returns an empty btree."), - etap:is(0, couch_btree:size(Btree5), - "After removing all keys, one by one, btree size is 0."), - - KeyValuesRev = lists:reverse(KeyValues), - {Btree6, _} = lists:foldl(fun(KV, {BtAcc, PrevSize}) -> - {ok, BtAcc2} = couch_btree:add_remove(BtAcc, [KV], []), - case couch_btree:size(BtAcc2) > PrevSize of - true -> - ok; - false -> - etap:is(false, true, - "After inserting a value, btree size did not increase.") - end, - {BtAcc2, couch_btree:size(BtAcc2)} - end, {Btree5, couch_btree:size(Btree5)}, KeyValuesRev), - etap:ok(test_btree(Btree6, KeyValues), - "Adding all keys in reverse order returns a complete btree."), - - {_, Rem2Keys0, Rem2Keys1} = lists:foldl(fun(X, {Count, Left, Right}) -> - case Count rem 2 == 0 of - true-> {Count+1, [X | Left], Right}; - false -> {Count+1, Left, [X | Right]} - end - end, {0, [], []}, KeyValues), - - etap:ok(test_add_remove(Btree6, Rem2Keys0, Rem2Keys1), - "Add/Remove every other key."), - - etap:ok(test_add_remove(Btree6, Rem2Keys1, Rem2Keys0), - "Add/Remove opposite every other key."), - - Size1 = couch_btree:size(Btree6), - {ok, Btree7} = couch_btree:add_remove(Btree6, [], [K||{K,_}<-Rem2Keys1]), - Size2 = couch_btree:size(Btree7), - etap:is((Size2 < Size1), true, "Btree size decreased"), - {ok, Btree8} = couch_btree:add_remove(Btree7, [], [K||{K,_}<-Rem2Keys0]), - Size3 = couch_btree:size(Btree8), - etap:is((Size3 < Size2), true, "Btree size decreased"), - etap:is(Size3, 0, "Empty btree has size 0."), - etap:ok(test_btree(Btree8, []), - "Removing both halves of every other key returns an empty btree."), - - %% Third chunk (close out) - etap:is(couch_file:close(Fd), ok, "closing out"), - true. - -test_btree(Btree, KeyValues) -> - ok = test_key_access(Btree, KeyValues), - ok = test_lookup_access(Btree, KeyValues), - ok = test_final_reductions(Btree, KeyValues), - ok = test_traversal_callbacks(Btree, KeyValues), - true. - -test_add_remove(Btree, OutKeyValues, RemainingKeyValues) -> - Btree2 = lists:foldl(fun({K, _}, BtAcc) -> - {ok, BtAcc2} = couch_btree:add_remove(BtAcc, [], [K]), - BtAcc2 - end, Btree, OutKeyValues), - true = test_btree(Btree2, RemainingKeyValues), - - Btree3 = lists:foldl(fun(KV, BtAcc) -> - {ok, BtAcc2} = couch_btree:add_remove(BtAcc, [KV], []), - BtAcc2 - end, Btree2, OutKeyValues), - true = test_btree(Btree3, OutKeyValues ++ RemainingKeyValues). - -test_key_access(Btree, List) -> - FoldFun = fun(Element, {[HAcc|TAcc], Count}) -> - case Element == HAcc of - true -> {ok, {TAcc, Count + 1}}; - _ -> {ok, {TAcc, Count + 1}} - end - end, - Length = length(List), - Sorted = lists:sort(List), - {ok, _, {[], Length}} = couch_btree:foldl(Btree, FoldFun, {Sorted, 0}), - {ok, _, {[], Length}} = couch_btree:fold(Btree, FoldFun, {Sorted, 0}, [{dir, rev}]), - ok. - -test_lookup_access(Btree, KeyValues) -> - FoldFun = fun({Key, Value}, {Key, Value}) -> {stop, true} end, - lists:foreach(fun({Key, Value}) -> - [{ok, {Key, Value}}] = couch_btree:lookup(Btree, [Key]), - {ok, _, true} = couch_btree:foldl(Btree, FoldFun, {Key, Value}, [{start_key, Key}]) - end, KeyValues). - -test_final_reductions(Btree, KeyValues) -> - KVLen = length(KeyValues), - FoldLFun = fun(_X, LeadingReds, Acc) -> - CountToStart = KVLen div 3 + Acc, - CountToStart = couch_btree:final_reduce(Btree, LeadingReds), - {ok, Acc+1} - end, - FoldRFun = fun(_X, LeadingReds, Acc) -> - CountToEnd = KVLen - KVLen div 3 + Acc, - CountToEnd = couch_btree:final_reduce(Btree, LeadingReds), - {ok, Acc+1} - end, - {LStartKey, _} = case KVLen of - 0 -> {nil, nil}; - _ -> lists:nth(KVLen div 3 + 1, lists:sort(KeyValues)) - end, - {RStartKey, _} = case KVLen of - 0 -> {nil, nil}; - _ -> lists:nth(KVLen div 3, lists:sort(KeyValues)) - end, - {ok, _, FoldLRed} = couch_btree:foldl(Btree, FoldLFun, 0, [{start_key, LStartKey}]), - {ok, _, FoldRRed} = couch_btree:fold(Btree, FoldRFun, 0, [{dir, rev}, {start_key, RStartKey}]), - KVLen = FoldLRed + FoldRRed, - ok. - -test_traversal_callbacks(Btree, _KeyValues) -> - FoldFun = - fun - (visit, _GroupedKey, _Unreduced, Acc) -> - {ok, Acc andalso false}; - (traverse, _LK, _Red, Acc) -> - {skip, Acc andalso true} - end, - % With 250 items the root is a kp. Always skipping should reduce to true. - {ok, _, true} = couch_btree:fold(Btree, FoldFun, true, [{dir, fwd}]), - ok. - -shuffle(List) -> - randomize(round(math:log(length(List)) + 0.5), List). - -randomize(1, List) -> - randomize(List); -randomize(T, List) -> - lists:foldl(fun(_E, Acc) -> - randomize(Acc) - end, randomize(List), lists:seq(1, (T - 1))). - -randomize(List) -> - D = lists:map(fun(A) -> - {random:uniform(), A} - end, List), - {_, D1} = lists:unzip(lists:keysort(1, D)), - D1. http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/021-btree-reductions.t ---------------------------------------------------------------------- diff --git a/test/etap/021-btree-reductions.t b/test/etap/021-btree-reductions.t deleted file mode 100755 index e80ac2d..0000000 --- a/test/etap/021-btree-reductions.t +++ /dev/null @@ -1,237 +0,0 @@ -#!/usr/bin/env escript -%% -*- erlang -*- -%%! -pa ./src/couchdb -sasl errlog_type error -boot start_sasl -noshell - -% 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() -> "./test/etap/temp.021". -rows() -> 1000. - -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() - end, - ok. - -test()-> - ReduceFun = fun - (reduce, KVs) -> length(KVs); - (rereduce, Reds) -> lists:sum(Reds) - end, - - {ok, Fd} = couch_file:open(filename(), [create,overwrite]), - {ok, Btree} = couch_btree:open(nil, Fd, [{reduce, ReduceFun}]), - - % Create a list, of {"even", Value} or {"odd", Value} pairs. - {_, EvenOddKVs} = lists:foldl(fun(Idx, {Key, Acc}) -> - case Key of - "even" -> {"odd", [{{Key, Idx}, 1} | Acc]}; - _ -> {"even", [{{Key, Idx}, 1} | Acc]} - end - end, {"odd", []}, lists:seq(1, rows())), - - {ok, Btree2} = couch_btree:add_remove(Btree, EvenOddKVs, []), - - GroupFun = fun({K1, _}, {K2, _}) -> K1 == K2 end, - FoldFun = fun(GroupedKey, Unreduced, Acc) -> - {ok, [{GroupedKey, couch_btree:final_reduce(Btree2, Unreduced)} | Acc]} - end, - - {SK1, EK1} = {{"even", -1}, {"even", foo}}, - {SK2, EK2} = {{"odd", -1}, {"odd", foo}}, - - etap:fun_is( - fun - ({ok, [{{"odd", _}, 500}, {{"even", _}, 500}]}) -> - true; - (_) -> - false - end, - couch_btree:fold_reduce(Btree2, FoldFun, [], [{key_group_fun, GroupFun}]), - "Reduction works with no specified direction, startkey, or endkey." - ), - - etap:fun_is( - fun - ({ok, [{{"odd", _}, 500}, {{"even", _}, 500}]}) -> - true; - (_) -> - false - end, - couch_btree:fold_reduce(Btree2, FoldFun, [], [{key_group_fun, GroupFun}, {dir, fwd}]), - "Reducing forward works with no startkey or endkey." - ), - - etap:fun_is( - fun - ({ok, [{{"even", _}, 500}, {{"odd", _}, 500}]}) -> - true; - (_) -> - false - end, - couch_btree:fold_reduce(Btree2, FoldFun, [], [{key_group_fun, GroupFun}, {dir, rev}]), - "Reducing backwards works with no startkey or endkey." - ), - - etap:fun_is( - fun - ({ok, [{{"odd", _}, 500}, {{"even", _}, 500}]}) -> - true; - (_) -> - false - end, - couch_btree:fold_reduce(Btree2, FoldFun, [], [{dir, fwd}, {key_group_fun, GroupFun}, {start_key, SK1}, {end_key, EK2}]), - "Reducing works over the entire range with startkey and endkey set." - ), - - etap:fun_is( - fun - ({ok, [{{"even", _}, 500}]}) -> true; - (_) -> false - end, - couch_btree:fold_reduce(Btree2, FoldFun, [], [{dir, fwd}, {key_group_fun, GroupFun}, {start_key, SK1}, {end_key, EK1}]), - "Reducing forward over first half works with a startkey and endkey." - ), - - etap:fun_is( - fun - ({ok, [{{"odd", _}, 500}]}) -> true; - (_) -> false - end, - couch_btree:fold_reduce(Btree2, FoldFun, [], [{dir, fwd}, {key_group_fun, GroupFun}, {start_key, SK2}, {end_key, EK2}]), - "Reducing forward over second half works with second startkey and endkey" - ), - - etap:fun_is( - fun - ({ok, [{{"odd", _}, 500}]}) -> true; - (_) -> false - end, - couch_btree:fold_reduce(Btree2, FoldFun, [], [{dir, rev}, {key_group_fun, GroupFun}, {start_key, EK2}, {end_key, SK2}]), - "Reducing in reverse works after swapping the startkey and endkey." - ), - - etap:fun_is( - fun - ({ok, [{{"even", _}, 500}, {{"odd", _}, 500}]}) -> - true; - (_) -> - false - end, - couch_btree:fold_reduce(Btree2, FoldFun, [], [{dir, rev}, {key_group_fun, GroupFun}, {start_key, EK2}, {end_key, SK1}]), - "Reducing in reverse results in reversed accumulator." - ), - - etap:is( - couch_btree:fold_reduce(Btree2, FoldFun, [], [ - {dir, fwd}, {key_group_fun, GroupFun}, - {start_key, {"even", 0}}, {end_key, {"odd", rows() + 1}} - ]), - {ok, [{{"odd", 1}, 500}, {{"even", 2}, 500}]}, - "Right fold reduce value for whole range with inclusive end key"), - - etap:is( - couch_btree:fold_reduce(Btree2, FoldFun, [], [ - {dir, fwd}, {key_group_fun, GroupFun}, - {start_key, {"even", 0}}, {end_key_gt, {"odd", 999}} - ]), - {ok, [{{"odd", 1}, 499}, {{"even", 2}, 500}]}, - "Right fold reduce value for whole range without inclusive end key"), - - etap:is( - couch_btree:fold_reduce(Btree2, FoldFun, [], [ - {dir, rev}, {key_group_fun, GroupFun}, - {start_key, {"odd", 999}}, {end_key, {"even", 2}} - ]), - {ok, [{{"even", 1000}, 500}, {{"odd", 999}, 500}]}, - "Right fold reduce value for whole reversed range with inclusive end key"), - - etap:is( - couch_btree:fold_reduce(Btree2, FoldFun, [], [ - {dir, rev}, {key_group_fun, GroupFun}, - {start_key, {"odd", 999}}, {end_key_gt, {"even", 2}} - ]), - {ok, [{{"even", 1000}, 499}, {{"odd", 999}, 500}]}, - "Right fold reduce value for whole reversed range without inclusive end key"), - - etap:is( - couch_btree:fold_reduce(Btree2, FoldFun, [], [ - {dir, fwd}, {key_group_fun, GroupFun}, - {start_key, {"even", 0}}, {end_key, {"odd", 499}} - ]), - {ok, [{{"odd", 1}, 250}, {{"even", 2}, 500}]}, - "Right fold reduce value for first half with inclusive end key"), - - etap:is( - couch_btree:fold_reduce(Btree2, FoldFun, [], [ - {dir, fwd}, {key_group_fun, GroupFun}, - {start_key, {"even", 0}}, {end_key_gt, {"odd", 499}} - ]), - {ok, [{{"odd", 1}, 249}, {{"even", 2}, 500}]}, - "Right fold reduce value for first half without inclusive end key"), - - etap:is( - couch_btree:fold_reduce(Btree2, FoldFun, [], [ - {dir, rev}, {key_group_fun, GroupFun}, - {start_key, {"odd", 999}}, {end_key, {"even", 500}} - ]), - {ok, [{{"even", 1000}, 251}, {{"odd", 999}, 500}]}, - "Right fold reduce value for first half reversed with inclusive end key"), - - etap:is( - couch_btree:fold_reduce(Btree2, FoldFun, [], [ - {dir, rev}, {key_group_fun, GroupFun}, - {start_key, {"odd", 999}}, {end_key_gt, {"even", 500}} - ]), - {ok, [{{"even", 1000}, 250}, {{"odd", 999}, 500}]}, - "Right fold reduce value for first half reversed without inclusive end key"), - - etap:is( - couch_btree:fold_reduce(Btree2, FoldFun, [], [ - {dir, fwd}, {key_group_fun, GroupFun}, - {start_key, {"even", 500}}, {end_key, {"odd", 999}} - ]), - {ok, [{{"odd", 1}, 500}, {{"even", 500}, 251}]}, - "Right fold reduce value for second half with inclusive end key"), - - etap:is( - couch_btree:fold_reduce(Btree2, FoldFun, [], [ - {dir, fwd}, {key_group_fun, GroupFun}, - {start_key, {"even", 500}}, {end_key_gt, {"odd", 999}} - ]), - {ok, [{{"odd", 1}, 499}, {{"even", 500}, 251}]}, - "Right fold reduce value for second half without inclusive end key"), - - etap:is( - couch_btree:fold_reduce(Btree2, FoldFun, [], [ - {dir, rev}, {key_group_fun, GroupFun}, - {start_key, {"odd", 501}}, {end_key, {"even", 2}} - ]), - {ok, [{{"even", 1000}, 500}, {{"odd", 501}, 251}]}, - "Right fold reduce value for second half reversed with inclusive end key"), - - etap:is( - couch_btree:fold_reduce(Btree2, FoldFun, [], [ - {dir, rev}, {key_group_fun, GroupFun}, - {start_key, {"odd", 501}}, {end_key_gt, {"even", 2}} - ]), - {ok, [{{"even", 1000}, 499}, {{"odd", 501}, 251}]}, - "Right fold reduce value for second half reversed without inclusive end key"), - - couch_file:close(Fd). http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/022-emsort-basics.t ---------------------------------------------------------------------- diff --git a/test/etap/022-emsort-basics.t b/test/etap/022-emsort-basics.t deleted file mode 100755 index 1f212f4..0000000 --- a/test/etap/022-emsort-basics.t +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env escript -%% -*- erlang -*- -%%! -pa ./src/couchdb -sasl errlog_type error -boot start_sasl -noshell - -% 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() -> "./test/etap/temp.022". -group() -> 100. -rows() -> 1000. -total() -> group() * rows(). - -main(_) -> - test_util:init_code_path(), - etap:plan(4), - case (catch test()) of - ok -> - etap:end_tests(); - Other -> - etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), - timer:sleep(1000), - etap:bail() - end, - ok. - -test()-> - {ok, Fd} = couch_file:open(filename(), [create,overwrite]), - - test_basic(Fd), - - couch_file:close(Fd). - -test_basic(Fd) -> - {ok, Ems} = couch_emsort:open(Fd), - Ems1 = lists:foldl(fun(_, EAcc0) -> - KVs = [{random:uniform(), val_here} || _ <- lists:seq(1, group())], - {ok, EAcc1} = couch_emsort:add(EAcc0, KVs), - EAcc1 - end, Ems, lists:seq(1, rows())), - - {ok, Iter1} = couch_emsort:sort(Ems1), - {Bad1, Total1} = read_sorted(Iter1, {-1, 0, 0}), - etap:is(Bad1, 0, "No rows out of order."), - etap:is(Total1, total(), "Found exactly as many rows as expected."), - - {ok, Ems2} = couch_emsort:merge(Ems1), - {ok, Iter2} = couch_emsort:iter(Ems2), - {Bad2, Total2} = read_sorted(Iter2, {-1, 0, 0}), - etap:is(Bad2, 0, "No rows out of order."), - etap:is(Total2, total(), "Found exactly as many rows as expected."), - - ok. - -read_sorted(Iter, {Prev, Bad, Count}) -> - case couch_emsort:next(Iter) of - {ok, {K, _}, NextIter} when K > Prev -> - read_sorted(NextIter, {K, Bad, Count+1}); - {ok, {K, _}, NextIter} -> - read_sorted(NextIter, {K, Bad+1, Count+1}); - finished -> - {Bad, Count} - end. - http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/030-doc-from-json.t ---------------------------------------------------------------------- diff --git a/test/etap/030-doc-from-json.t b/test/etap/030-doc-from-json.t deleted file mode 100755 index 1a11d8d..0000000 --- a/test/etap/030-doc-from-json.t +++ /dev/null @@ -1,232 +0,0 @@ -#!/usr/bin/env escript -%% -*- erlang -*- -%%! -pa ./src/couchdb -pa ./src/mochiweb -sasl errlog_type false -noshell - -% 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_lib("couch/include/couch_db.hrl"). - -main(_) -> - test_util:init_code_path(), - etap:plan(26), - case (catch test()) of - ok -> - etap:end_tests(); - Other -> - etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), - etap:bail() - end, - ok. - -test() -> - application:start(config), - config:set("attachments", "compression_level", "0", false), - ok = test_from_json_success(), - ok = test_from_json_errors(), - ok. - -test_from_json_success() -> - Cases = [ - { - {[]}, - #doc{}, - "Return an empty document for an empty JSON object." - }, - { - {[{<<"_id">>, <<"zing!">>}]}, - #doc{id= <<"zing!">>}, - "Parses document ids." - }, - { - {[{<<"_id">>, <<"_design/foo">>}]}, - #doc{id= <<"_design/foo">>}, - "_design/document ids." - }, - { - {[{<<"_id">>, <<"_local/bam">>}]}, - #doc{id= <<"_local/bam">>}, - "_local/document ids." - }, - { - {[{<<"_rev">>, <<"4-230234">>}]}, - #doc{revs={4, [<<"230234">>]}}, - "_rev stored in revs." - }, - { - {[{<<"soap">>, 35}]}, - #doc{body={[{<<"soap">>, 35}]}}, - "Non underscore prefixed fields stored in body." - }, - { - {[{<<"_attachments">>, {[ - {<<"my_attachment.fu">>, {[ - {<<"stub">>, true}, - {<<"content_type">>, <<"application/awesome">>}, - {<<"length">>, 45} - ]}}, - {<<"noahs_private_key.gpg">>, {[ - {<<"data">>, <<"SSBoYXZlIGEgcGV0IGZpc2gh">>}, - {<<"content_type">>, <<"application/pgp-signature">>} - ]}} - ]}}]}, - #doc{atts=[ - couch_att:new([ - {name, <<"my_attachment.fu">>}, - {data, stub}, - {type, <<"application/awesome">>}, - {att_len, 45}, - {disk_len, 45}, - {revpos, undefined} - ]), - couch_att:new([ - {name, <<"noahs_private_key.gpg">>}, - {data, <<"I have a pet fish!">>}, - {type, <<"application/pgp-signature">>}, - {att_len, 18}, - {disk_len, 18}, - {revpos, 0} - ]) - ]}, - "Attachments are parsed correctly." - }, - { - {[{<<"_deleted">>, true}]}, - #doc{deleted=true}, - "_deleted controls the deleted field." - }, - { - {[{<<"_deleted">>, false}]}, - #doc{}, - "{\"_deleted\": false} is ok." - }, - { - {[ - {<<"_revisions">>, {[ - {<<"start">>, 4}, - {<<"ids">>, [<<"foo1">>, <<"phi3">>, <<"omega">>]} - ]}}, - {<<"_rev">>, <<"6-something">>} - ]}, - #doc{revs={4, [<<"foo1">>, <<"phi3">>, <<"omega">>]}}, - "_revisions attribute are preferred to _rev." - }, - { - {[{<<"_revs_info">>, dropping}]}, - #doc{}, - "Drops _revs_info." - }, - { - {[{<<"_local_seq">>, dropping}]}, - #doc{}, - "Drops _local_seq." - }, - { - {[{<<"_conflicts">>, dropping}]}, - #doc{}, - "Drops _conflicts." - }, - { - {[{<<"_deleted_conflicts">>, dropping}]}, - #doc{}, - "Drops _deleted_conflicts." - } - ], - - lists:foreach(fun({EJson, Expect, Mesg}) -> - etap:is(couch_doc:from_json_obj(EJson), Expect, Mesg) - end, Cases), - ok. - -test_from_json_errors() -> - Cases = [ - { - [], - {bad_request, "Document must be a JSON object"}, - "arrays are invalid" - }, - { - 4, - {bad_request, "Document must be a JSON object"}, - "integers are invalid" - }, - { - true, - {bad_request, "Document must be a JSON object"}, - "literals are invalid" - }, - { - {[{<<"_id">>, {[{<<"foo">>, 5}]}}]}, - {bad_request, <<"Document id must be a string">>}, - "Document id must be a string." - }, - { - {[{<<"_id">>, <<"_random">>}]}, - {bad_request, - <<"Only reserved document ids may start with underscore.">>}, - "Disallow arbitrary underscore prefixed docids." - }, - { - {[{<<"_rev">>, 5}]}, - {bad_request, <<"Invalid rev format">>}, - "_rev must be a string" - }, - { - {[{<<"_rev">>, "foobar"}]}, - {bad_request, <<"Invalid rev format">>}, - "_rev must be %d-%s" - }, - { - {[{<<"_rev">>, "foo-bar"}]}, - "Error if _rev's integer expection is broken." - }, - { - {[{<<"_revisions">>, {[{<<"start">>, true}]}}]}, - {doc_validation, "_revisions.start isn't an integer."}, - "_revisions.start must be an integer." - }, - { - {[{<<"_revisions">>, {[ - {<<"start">>, 0}, - {<<"ids">>, 5} - ]}}]}, - {doc_validation, "_revisions.ids isn't a array."}, - "_revions.ids must be a list." - }, - { - {[{<<"_revisions">>, {[ - {<<"start">>, 0}, - {<<"ids">>, [5]} - ]}}]}, - {doc_validation, "RevId isn't a string"}, - "Revision ids must be strings." - }, - { - {[{<<"_something">>, 5}]}, - {doc_validation, <<"Bad special document member: _something">>}, - "Underscore prefix fields are reserved." - } - ], - - lists:foreach(fun - ({EJson, Expect, Mesg}) -> - Error = (catch couch_doc:from_json_obj(EJson)), - etap:is(Error, Expect, Mesg); - ({EJson, Mesg}) -> - try - couch_doc:from_json_obj(EJson), - etap:ok(false, "Conversion failed to raise an exception.") - catch - _:_ -> etap:ok(true, Mesg) - end - end, Cases), - ok. http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/031-doc-to-json.t ---------------------------------------------------------------------- diff --git a/test/etap/031-doc-to-json.t b/test/etap/031-doc-to-json.t deleted file mode 100755 index d4227e7..0000000 --- a/test/etap/031-doc-to-json.t +++ /dev/null @@ -1,193 +0,0 @@ -#!/usr/bin/env escript -%% -*- erlang -*- -%%! -pa ./src/couchdb -pa ./src/mochiweb -sasl errlog_type false -noshell - -% 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_lib("couch/include/couch_db.hrl"). - -main(_) -> - test_util:init_code_path(), - etap:plan(12), - case (catch test()) of - ok -> - etap:end_tests(); - Other -> - etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), - etap:bail() - end, - ok. - -test() -> - application:start(config), - config:set("attachments", "compression_level", "0", false), - ok = test_to_json_success(), - ok. - -test_to_json_success() -> - Cases = [ - { - #doc{}, - {[{<<"_id">>, <<"">>}]}, - "Empty docs are {\"_id\": \"\"}" - }, - { - #doc{id= <<"foo">>}, - {[{<<"_id">>, <<"foo">>}]}, - "_id is added." - }, - { - #doc{revs={5, ["foo"]}}, - {[{<<"_id">>, <<>>}, {<<"_rev">>, <<"5-foo">>}]}, - "_rev is added." - }, - { - [revs], - #doc{revs={5, [<<"first">>, <<"second">>]}}, - {[ - {<<"_id">>, <<>>}, - {<<"_rev">>, <<"5-first">>}, - {<<"_revisions">>, {[ - {<<"start">>, 5}, - {<<"ids">>, [<<"first">>, <<"second">>]} - ]}} - ]}, - "_revisions include with revs option" - }, - { - #doc{body={[{<<"foo">>, <<"bar">>}]}}, - {[{<<"_id">>, <<>>}, {<<"foo">>, <<"bar">>}]}, - "Arbitrary fields are added." - }, - { - #doc{deleted=true, body={[{<<"foo">>, <<"bar">>}]}}, - {[{<<"_id">>, <<>>}, {<<"foo">>, <<"bar">>}, {<<"_deleted">>, true}]}, - "Deleted docs no longer drop body members." - }, - { - #doc{meta=[ - {revs_info, 4, [{<<"fin">>, deleted}, {<<"zim">>, missing}]} - ]}, - {[ - {<<"_id">>, <<>>}, - {<<"_revs_info">>, [ - {[{<<"rev">>, <<"4-fin">>}, {<<"status">>, <<"deleted">>}]}, - {[{<<"rev">>, <<"3-zim">>}, {<<"status">>, <<"missing">>}]} - ]} - ]}, - "_revs_info field is added correctly." - }, - { - #doc{meta=[{local_seq, 5}]}, - {[{<<"_id">>, <<>>}, {<<"_local_seq">>, 5}]}, - "_local_seq is added as an integer." - }, - { - #doc{meta=[{conflicts, [{3, <<"yep">>}, {1, <<"snow">>}]}]}, - {[ - {<<"_id">>, <<>>}, - {<<"_conflicts">>, [<<"3-yep">>, <<"1-snow">>]} - ]}, - "_conflicts is added as an array of strings." - }, - { - #doc{meta=[{deleted_conflicts, [{10923, <<"big_cowboy_hat">>}]}]}, - {[ - {<<"_id">>, <<>>}, - {<<"_deleted_conflicts">>, [<<"10923-big_cowboy_hat">>]} - ]}, - "_deleted_conflicsts is added as an array of strings." - }, - { - #doc{atts=[ - couch_att:new([ - {name, <<"big.xml">>}, - {type, <<"xml/sucks">>}, - {data, fun() -> ok end}, - {revpos, 1}, - {att_len, 400}, - {disk_len, 400} - ]), - couch_att:new([ - {name, <<"fast.json">>}, - {type, <<"json/ftw">>}, - {data, <<"{\"so\": \"there!\"}">>}, - {revpos, 1}, - {att_len, 16}, - {disk_len, 16} - ]) - ]}, - {[ - {<<"_id">>, <<>>}, - {<<"_attachments">>, {[ - {<<"big.xml">>, {[ - {<<"content_type">>, <<"xml/sucks">>}, - {<<"revpos">>, 1}, - {<<"length">>, 400}, - {<<"stub">>, true} - ]}}, - {<<"fast.json">>, {[ - {<<"content_type">>, <<"json/ftw">>}, - {<<"revpos">>, 1}, - {<<"length">>, 16}, - {<<"stub">>, true} - ]}} - ]}} - ]}, - "Attachments attached as stubs only include a length." - }, - { - [attachments], - #doc{atts=[ - couch_att:new([ - {name, <<"stuff.txt">>}, - {type, <<"text/plain">>}, - {data, fun() -> <<"diet pepsi">> end}, - {revpos, 1}, - {att_len, 10}, - {disk_len, 10} - ]), - couch_att:new([ - {name, <<"food.now">>}, - {type, <<"application/food">>}, - {revpos, 1}, - {data, <<"sammich">>} - ]) - ]}, - {[ - {<<"_id">>, <<>>}, - {<<"_attachments">>, {[ - {<<"stuff.txt">>, {[ - {<<"content_type">>, <<"text/plain">>}, - {<<"revpos">>, 1}, - {<<"data">>, <<"ZGlldCBwZXBzaQ==">>} - ]}}, - {<<"food.now">>, {[ - {<<"content_type">>, <<"application/food">>}, - {<<"revpos">>, 1}, - {<<"data">>, <<"c2FtbWljaA==">>} - ]}} - ]}} - ]}, - "Attachments included inline with attachments option." - } - ], - - lists:foreach(fun - ({Doc, EJson, Mesg}) -> - etap:is(couch_doc:to_json_obj(Doc, []), EJson, Mesg); - ({Options, Doc, EJson, Mesg}) -> - etap:is(couch_doc:to_json_obj(Doc, Options), EJson, Mesg) - end, Cases), - ok. - http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/040-util.t ---------------------------------------------------------------------- diff --git a/test/etap/040-util.t b/test/etap/040-util.t deleted file mode 100755 index d57a32e..0000000 --- a/test/etap/040-util.t +++ /dev/null @@ -1,80 +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(), - application:start(crypto), - - etap:plan(14), - 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() -> - % to_existing_atom - etap:is(true, couch_util:to_existing_atom(true), "An atom is an atom."), - etap:is(foo, couch_util:to_existing_atom(<<"foo">>), - "A binary foo is the atom foo."), - etap:is(foobarbaz, couch_util:to_existing_atom("foobarbaz"), - "A list of atoms is one munged atom."), - - % implode - etap:is([1, 38, 2, 38, 3], couch_util:implode([1,2,3],"&"), - "use & as separator in list."), - - % trim - Strings = [" foo", "foo ", "\tfoo", " foo ", "foo\t", "foo\n", "\nfoo"], - etap:ok(lists:all(fun(S) -> couch_util:trim(S) == "foo" end, Strings), - "everything here trimmed should be foo."), - - % abs_pathname - {ok, Cwd} = file:get_cwd(), - etap:is(Cwd ++ "/foo", couch_util:abs_pathname("./foo"), - "foo is in this directory."), - - % should_flush - etap:ok(not couch_util:should_flush(), - "Not using enough memory to flush."), - AcquireMem = fun() -> - _IntsToAGazillion = lists:seq(1, 200000), - _LotsOfData = lists:map( - fun(Int) -> {Int, <<"foobar">>} end, - lists:seq(1, 500000)), - etap:ok(couch_util:should_flush(), - "Allocation 200K tuples puts us above the memory threshold.") - end, - AcquireMem(), - - etap:ok(not couch_util:should_flush(), - "Checking to flush invokes GC."), - - % verify - etap:is(true, couch_util:verify("It4Vooya", "It4Vooya"), - "String comparison."), - etap:is(false, couch_util:verify("It4VooyaX", "It4Vooya"), - "String comparison (unequal lengths)."), - etap:is(true, couch_util:verify(<<"ahBase3r">>, <<"ahBase3r">>), - "Binary comparison."), - etap:is(false, couch_util:verify(<<"ahBase3rX">>, <<"ahBase3r">>), - "Binary comparison (unequal lengths)."), - etap:is(false, couch_util:verify(nil, <<"ahBase3r">>), - "Binary comparison with atom."), - - ok. http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/041-uuid-gen.t ---------------------------------------------------------------------- diff --git a/test/etap/041-uuid-gen.t b/test/etap/041-uuid-gen.t deleted file mode 100755 index da1ded1..0000000 --- a/test/etap/041-uuid-gen.t +++ /dev/null @@ -1,130 +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. - -% Run tests and wait for the gen_servers to shutdown -run_test(Config, Test) -> - lists:foreach(fun({Key, Value}) -> - config:set("uuids", Key, Value, false) - end, Config), - couch_uuids:start(), - Test(), - couch_uuids:stop(). - -main(_) -> - test_util:init_code_path(), - application:start(crypto), - application:start(config), - etap:plan(9), - - 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() -> - TestUnique = fun() -> - etap:is( - test_unique(10000, couch_uuids:new()), - true, - "Can generate 10K unique IDs" - ) - end, - run_test([{"algorithm", "random"}], TestUnique), - run_test([{"algorithm", "sequential"}], TestUnique), - run_test([{"algorithm", "utc_random"}], TestUnique), - run_test([{"algorithm", "utc_id"}, {"utc_id_suffix", "bozo"}], TestUnique), - - TestMonotonic = fun () -> - etap:is( - couch_uuids:new() < couch_uuids:new(), - true, - "should produce monotonically increasing ids" - ) - end, - run_test([{"algorithm", "sequential"}], TestMonotonic), - run_test([{"algorithm", "utc_random"}], TestMonotonic), - run_test([{"algorithm", "utc_id"}, {"utc_id_suffix", "bozo"}], - TestMonotonic), - - % Pretty sure that the average of a uniform distribution is the - % midpoint of the range. Thus, to exceed a threshold, we need - % approximately Total / (Range/2 + RangeMin) samples. - % - % In our case this works out to be 8194. (0xFFF000 / 0x7FF) - % These tests just fudge the limits for a good generator at 25% - % in either direction. Technically it should be possible to generate - % bounds that will show if your random number generator is not - % sufficiently random but I hated statistics in school. - TestRollOver = fun() -> - UUID = binary_to_list(couch_uuids:new()), - Prefix = element(1, lists:split(26, UUID)), - N = gen_until_pref_change(Prefix,0), - etap:diag("N is: ~p~n",[N]), - etap:is( - N >= 5000 andalso N =< 11000, - true, - "should roll over every so often." - ) - end, - run_test([{"algorithm", "sequential"}], TestRollOver), - - TestSuffix = fun() -> - UUID = binary_to_list(couch_uuids:new()), - Suffix = get_suffix(UUID), - etap:is( - test_same_suffix(100, Suffix), - true, - "utc_id ids should have the same suffix." - ) - end, - run_test([{"algorithm", "utc_id"}, {"utc_id_suffix", "bozo"}], TestSuffix). - -test_unique(0, _) -> - true; -test_unique(N, UUID) -> - case couch_uuids:new() of - UUID -> - etap:diag("N: ~p~n", [N]), - false; - Else -> test_unique(N-1, Else) - end. - -get_prefix(UUID) -> - element(1, lists:split(26, binary_to_list(UUID))). - -gen_until_pref_change(_, Count) when Count > 8251 -> - Count; -gen_until_pref_change(Prefix, N) -> - case get_prefix(couch_uuids:new()) of - Prefix -> gen_until_pref_change(Prefix, N+1); - _ -> N - end. - -get_suffix(UUID) when is_binary(UUID)-> - get_suffix(binary_to_list(UUID)); -get_suffix(UUID) -> - element(2, lists:split(14, UUID)). - -test_same_suffix(0, _) -> - true; -test_same_suffix(N, Suffix) -> - case get_suffix(couch_uuids:new()) of - Suffix -> test_same_suffix(N-1, Suffix); - _ -> false - end. http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/042-work-queue.t ---------------------------------------------------------------------- diff --git a/test/etap/042-work-queue.t b/test/etap/042-work-queue.t deleted file mode 100755 index 8594a6f..0000000 --- a/test/etap/042-work-queue.t +++ /dev/null @@ -1,500 +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(155), - 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 = crypto:start(), - test_single_consumer_max_item_count(), - test_single_consumer_max_size(), - test_single_consumer_max_item_count_and_size(), - test_multiple_consumers(), - ok. - - -test_single_consumer_max_item_count() -> - etap:diag("Spawning a queue with 3 max items, 1 producer and 1 consumer"), - - {ok, Q} = couch_work_queue:new([{max_items, 3}]), - Producer = spawn_producer(Q), - Consumer = spawn_consumer(Q), - - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - - consume(Consumer, 1), - etap:is(ping(Consumer), timeout, - "Consumer blocked when attempting to dequeue 1 item from empty queue"), - - Item1 = produce(Producer, 10), - etap:is(ping(Producer), ok, "Producer not blocked"), - - etap:is(ping(Consumer), ok, "Consumer unblocked"), - etap:is(last_consumer_items(Consumer), {ok, [Item1]}, - "Consumer received the right item"), - - Item2 = produce(Producer, 20), - etap:is(ping(Producer), ok, "Producer not blocked with non full queue"), - etap:is(couch_work_queue:item_count(Q), 1, "Queue item count is 1"), - - Item3 = produce(Producer, 15), - etap:is(ping(Producer), ok, "Producer not blocked with non full queue"), - etap:is(couch_work_queue:item_count(Q), 2, "Queue item count is 2"), - - Item4 = produce(Producer, 3), - etap:is(couch_work_queue:item_count(Q), 3, "Queue item count is 3"), - etap:is(ping(Producer), timeout, "Producer blocked with full queue"), - - consume(Consumer, 2), - etap:is(ping(Consumer), ok, - "Consumer not blocked when attempting to dequeue 2 items from queue"), - etap:is(last_consumer_items(Consumer), {ok, [Item2, Item3]}, - "Consumer received the right items"), - etap:is(couch_work_queue:item_count(Q), 1, "Queue item count is 1"), - - consume(Consumer, 2), - etap:is(ping(Consumer), ok, - "Consumer not blocked when attempting to dequeue 2 items from queue"), - etap:is(last_consumer_items(Consumer), {ok, [Item4]}, - "Consumer received the right item"), - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - - consume(Consumer, 100), - etap:is(ping(Consumer), timeout, - "Consumer blocked when attempting to dequeue 100 items from empty queue"), - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - - Item5 = produce(Producer, 11), - etap:is(ping(Producer), ok, "Producer not blocked with empty queue"), - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - - Item6 = produce(Producer, 19), - etap:is(ping(Producer), ok, "Producer not blocked with non full queue"), - etap:is(couch_work_queue:item_count(Q), 1, "Queue item count is 1"), - - Item7 = produce(Producer, 2), - etap:is(ping(Producer), ok, "Producer not blocked with non full queue"), - etap:is(couch_work_queue:item_count(Q), 2, "Queue item count is 2"), - - Item8 = produce(Producer, 33), - etap:is(ping(Producer), timeout, "Producer blocked with full queue"), - etap:is(couch_work_queue:item_count(Q), 3, "Queue item count is 3"), - - etap:is(ping(Consumer), ok, "Consumer unblocked"), - etap:is(last_consumer_items(Consumer), {ok, [Item5]}, - "Consumer received the first queued item"), - etap:is(couch_work_queue:item_count(Q), 3, "Queue item count is 3"), - - consume(Consumer, all), - etap:is(ping(Consumer), ok, - "Consumer not blocked when attempting to dequeue all items from queue"), - etap:is(last_consumer_items(Consumer), {ok, [Item6, Item7, Item8]}, - "Consumer received all queued items"), - - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - - etap:is(close_queue(Q), ok, "Closed queue"), - consume(Consumer, 1), - etap:is(last_consumer_items(Consumer), closed, "Consumer got closed queue"), - etap:is(couch_work_queue:item_count(Q), closed, "Queue closed"), - etap:is(couch_work_queue:size(Q), closed, "Queue closed"), - - stop(Producer, "producer"), - stop(Consumer, "consumer"). - - - -test_single_consumer_max_size() -> - etap:diag("Spawning a queue with max size of 160 bytes, " - "1 producer and 1 consumer"), - - {ok, Q} = couch_work_queue:new([{max_size, 160}]), - Producer = spawn_producer(Q), - Consumer = spawn_consumer(Q), - - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - etap:is(couch_work_queue:size(Q), 0, "Queue size is 0 bytes"), - - consume(Consumer, 1), - etap:is(ping(Consumer), timeout, - "Consumer blocked when attempting to dequeue 1 item from empty queue"), - - Item1 = produce(Producer, 50), - etap:is(ping(Producer), ok, "Producer not blocked"), - - etap:is(ping(Consumer), ok, "Consumer unblocked"), - etap:is(last_consumer_items(Consumer), {ok, [Item1]}, - "Consumer received the right item"), - - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - etap:is(couch_work_queue:size(Q), 0, "Queue size is 0 bytes"), - - Item2 = produce(Producer, 50), - etap:is(ping(Producer), ok, "Producer not blocked"), - etap:is(couch_work_queue:item_count(Q), 1, "Queue item count is 1"), - etap:is(couch_work_queue:size(Q), 50, "Queue size is 50 bytes"), - - Item3 = produce(Producer, 50), - etap:is(ping(Producer), ok, "Producer not blocked"), - etap:is(couch_work_queue:item_count(Q), 2, "Queue item count is 2"), - etap:is(couch_work_queue:size(Q), 100, "Queue size is 100 bytes"), - - Item4 = produce(Producer, 61), - etap:is(ping(Producer), timeout, "Producer blocked"), - etap:is(couch_work_queue:item_count(Q), 3, "Queue item count is 3"), - etap:is(couch_work_queue:size(Q), 161, "Queue size is 161 bytes"), - - consume(Consumer, 1), - etap:is(ping(Consumer), ok, - "Consumer not blocked when attempting to dequeue 1 item from full queue"), - etap:is(last_consumer_items(Consumer), {ok, [Item2]}, - "Consumer received the right item"), - etap:is(couch_work_queue:item_count(Q), 2, "Queue item count is 2"), - etap:is(couch_work_queue:size(Q), 111, "Queue size is 111 bytes"), - - Item5 = produce(Producer, 20), - etap:is(ping(Producer), ok, "Producer not blocked"), - etap:is(couch_work_queue:item_count(Q), 3, "Queue item count is 3"), - etap:is(couch_work_queue:size(Q), 131, "Queue size is 131 bytes"), - - Item6 = produce(Producer, 40), - etap:is(ping(Producer), timeout, "Producer blocked"), - etap:is(couch_work_queue:item_count(Q), 4, "Queue item count is 4"), - etap:is(couch_work_queue:size(Q), 171, "Queue size is 171 bytes"), - - etap:is(close_queue(Q), timeout, - "Timeout when trying to close non-empty queue"), - - consume(Consumer, 2), - etap:is(ping(Consumer), ok, - "Consumer not blocked when attempting to dequeue 2 items from full queue"), - etap:is(last_consumer_items(Consumer), {ok, [Item3, Item4]}, - "Consumer received the right items"), - etap:is(couch_work_queue:item_count(Q), 2, "Queue item count is 2"), - etap:is(couch_work_queue:size(Q), 60, "Queue size is 60 bytes"), - - etap:is(close_queue(Q), timeout, - "Timeout when trying to close non-empty queue"), - - consume(Consumer, all), - etap:is(ping(Consumer), ok, - "Consumer not blocked when attempting to dequeue all items from queue"), - etap:is(last_consumer_items(Consumer), {ok, [Item5, Item6]}, - "Consumer received the right items"), - - etap:is(couch_work_queue:item_count(Q), closed, "Queue closed"), - etap:is(couch_work_queue:size(Q), closed, "Queue closed"), - - consume(Consumer, all), - etap:is(last_consumer_items(Consumer), closed, "Consumer got closed queue"), - - stop(Producer, "producer"), - stop(Consumer, "consumer"). - - -test_single_consumer_max_item_count_and_size() -> - etap:diag("Spawning a queue with 3 max items, max size of 200 bytes, " - "1 producer and 1 consumer"), - - {ok, Q} = couch_work_queue:new([{max_items, 3}, {max_size, 200}]), - Producer = spawn_producer(Q), - Consumer = spawn_consumer(Q), - - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - etap:is(couch_work_queue:size(Q), 0, "Queue size is 0 bytes"), - - Item1 = produce(Producer, 100), - etap:is(ping(Producer), ok, "Producer not blocked"), - etap:is(couch_work_queue:item_count(Q), 1, "Queue item count is 1"), - etap:is(couch_work_queue:size(Q), 100, "Queue size is 100 bytes"), - - Item2 = produce(Producer, 110), - etap:is(ping(Producer), timeout, - "Producer blocked when queue size >= max_size"), - etap:is(couch_work_queue:item_count(Q), 2, "Queue item count is 2"), - etap:is(couch_work_queue:size(Q), 210, "Queue size is 210 bytes"), - - consume(Consumer, all), - etap:is(ping(Consumer), ok, - "Consumer not blocked when attempting to dequeue all items from queue"), - etap:is(last_consumer_items(Consumer), {ok, [Item1, Item2]}, - "Consumer received the right items"), - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - etap:is(couch_work_queue:size(Q), 0, "Queue size is 0 bytes"), - - etap:is(ping(Producer), ok, "Producer not blocked anymore"), - - Item3 = produce(Producer, 10), - etap:is(ping(Producer), ok, "Producer not blocked"), - etap:is(couch_work_queue:item_count(Q), 1, "Queue item count is 1"), - etap:is(couch_work_queue:size(Q), 10, "Queue size is 10 bytes"), - - Item4 = produce(Producer, 4), - etap:is(ping(Producer), ok, "Producer not blocked"), - etap:is(couch_work_queue:item_count(Q), 2, "Queue item count is 2"), - etap:is(couch_work_queue:size(Q), 14, "Queue size is 14 bytes"), - - Item5 = produce(Producer, 2), - etap:is(ping(Producer), timeout, - "Producer blocked when queue item count = max_items"), - etap:is(couch_work_queue:item_count(Q), 3, "Queue item count is 3"), - etap:is(couch_work_queue:size(Q), 16, "Queue size is 16 bytes"), - - consume(Consumer, 1), - etap:is(ping(Consumer), ok, - "Consumer not blocked when attempting to dequeue 1 item from queue"), - etap:is(last_consumer_items(Consumer), {ok, [Item3]}, - "Consumer received 1 item"), - etap:is(couch_work_queue:item_count(Q), 2, "Queue item count is 2"), - etap:is(couch_work_queue:size(Q), 6, "Queue size is 6 bytes"), - - etap:is(close_queue(Q), timeout, - "Timeout when trying to close non-empty queue"), - - consume(Consumer, 1), - etap:is(ping(Consumer), ok, - "Consumer not blocked when attempting to dequeue 1 item from queue"), - etap:is(last_consumer_items(Consumer), {ok, [Item4]}, - "Consumer received 1 item"), - etap:is(couch_work_queue:item_count(Q), 1, "Queue item count is 1"), - etap:is(couch_work_queue:size(Q), 2, "Queue size is 2 bytes"), - - Item6 = produce(Producer, 50), - etap:is(ping(Producer), ok, - "Producer not blocked when queue is not full and already received" - " a close request"), - etap:is(couch_work_queue:item_count(Q), 2, "Queue item count is 2"), - etap:is(couch_work_queue:size(Q), 52, "Queue size is 52 bytes"), - - consume(Consumer, all), - etap:is(ping(Consumer), ok, - "Consumer not blocked when attempting to dequeue all items from queue"), - etap:is(last_consumer_items(Consumer), {ok, [Item5, Item6]}, - "Consumer received all queued items"), - - etap:is(couch_work_queue:item_count(Q), closed, "Queue closed"), - etap:is(couch_work_queue:size(Q), closed, "Queue closed"), - - consume(Consumer, 1), - etap:is(last_consumer_items(Consumer), closed, "Consumer got closed queue"), - - stop(Producer, "producer"), - stop(Consumer, "consumer"). - - -test_multiple_consumers() -> - etap:diag("Spawning a queue with 3 max items, max size of 200 bytes, " - "1 producer and 3 consumers"), - - {ok, Q} = couch_work_queue:new( - [{max_items, 3}, {max_size, 200}, {multi_workers, true}]), - Producer = spawn_producer(Q), - Consumer1 = spawn_consumer(Q), - Consumer2 = spawn_consumer(Q), - Consumer3 = spawn_consumer(Q), - - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - etap:is(couch_work_queue:size(Q), 0, "Queue size is 0 bytes"), - - consume(Consumer1, 1), - etap:is(ping(Consumer1), timeout, - "Consumer 1 blocked when attempting to dequeue 1 item from empty queue"), - consume(Consumer2, 2), - etap:is(ping(Consumer2), timeout, - "Consumer 2 blocked when attempting to dequeue 2 items from empty queue"), - consume(Consumer3, 1), - etap:is(ping(Consumer3), timeout, - "Consumer 3 blocked when attempting to dequeue 1 item from empty queue"), - - Item1 = produce(Producer, 50), - etap:is(ping(Producer), ok, "Producer not blocked"), - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - etap:is(couch_work_queue:size(Q), 0, "Queue size is 0 bytes"), - - Item2 = produce(Producer, 50), - etap:is(ping(Producer), ok, "Producer not blocked"), - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - etap:is(couch_work_queue:size(Q), 0, "Queue size is 0 bytes"), - - Item3 = produce(Producer, 50), - etap:is(ping(Producer), ok, "Producer not blocked"), - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - etap:is(couch_work_queue:size(Q), 0, "Queue size is 0 bytes"), - - etap:is(ping(Consumer1), ok, "Consumer 1 unblocked"), - etap:is(last_consumer_items(Consumer1), {ok, [Item1]}, - "Consumer 1 received 1 item"), - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - etap:is(couch_work_queue:size(Q), 0, "Queue size is 0 bytes"), - - etap:is(ping(Consumer2), ok, "Consumer 2 unblocked"), - etap:is(last_consumer_items(Consumer2), {ok, [Item2]}, - "Consumer 2 received 1 item"), - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - etap:is(couch_work_queue:size(Q), 0, "Queue size is 0 bytes"), - - etap:is(ping(Consumer3), ok, "Consumer 3 unblocked"), - etap:is(last_consumer_items(Consumer3), {ok, [Item3]}, - "Consumer 3 received 1 item"), - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - etap:is(couch_work_queue:size(Q), 0, "Queue size is 0 bytes"), - - consume(Consumer1, 1), - etap:is(ping(Consumer1), timeout, - "Consumer 1 blocked when attempting to dequeue 1 item from empty queue"), - consume(Consumer2, 2), - etap:is(ping(Consumer2), timeout, - "Consumer 2 blocked when attempting to dequeue 1 item from empty queue"), - consume(Consumer3, 1), - etap:is(ping(Consumer3), timeout, - "Consumer 3 blocked when attempting to dequeue 1 item from empty queue"), - - Item4 = produce(Producer, 50), - etap:is(ping(Producer), ok, "Producer not blocked"), - etap:is(couch_work_queue:item_count(Q), 0, "Queue item count is 0"), - etap:is(couch_work_queue:size(Q), 0, "Queue size is 0 bytes"), - - etap:is(close_queue(Q), ok, "Closed queue"), - - etap:is(ping(Consumer1), ok, "Consumer 1 unblocked"), - etap:is(last_consumer_items(Consumer1), {ok, [Item4]}, - "Consumer 1 received 1 item"), - - etap:is(couch_work_queue:item_count(Q), closed, "Queue closed"), - etap:is(couch_work_queue:size(Q), closed, "Queue closed"), - - etap:is(ping(Consumer2), ok, "Consumer 2 unblocked"), - etap:is(last_consumer_items(Consumer2), closed, - "Consumer 2 received 'closed' atom"), - - etap:is(ping(Consumer3), ok, "Consumer 3 unblocked"), - etap:is(last_consumer_items(Consumer3), closed, - "Consumer 3 received 'closed' atom"), - - stop(Producer, "producer"), - stop(Consumer1, "consumer 1"), - stop(Consumer2, "consumer 2"), - stop(Consumer3, "consumer 3"). - - -close_queue(Q) -> - ok = couch_work_queue:close(Q), - MonRef = erlang:monitor(process, Q), - receive - {'DOWN', MonRef, process, Q, _Reason} -> - etap:diag("Queue closed") - after 3000 -> - erlang:demonitor(MonRef), - timeout - end. - - -spawn_consumer(Q) -> - Parent = self(), - spawn(fun() -> consumer_loop(Parent, Q, nil) end). - - -consumer_loop(Parent, Q, PrevItem) -> - receive - {stop, Ref} -> - Parent ! {ok, Ref}; - {ping, Ref} -> - Parent ! {pong, Ref}, - consumer_loop(Parent, Q, PrevItem); - {last_item, Ref} -> - Parent ! {item, Ref, PrevItem}, - consumer_loop(Parent, Q, PrevItem); - {consume, N} -> - Result = couch_work_queue:dequeue(Q, N), - consumer_loop(Parent, Q, Result) - end. - - -spawn_producer(Q) -> - Parent = self(), - spawn(fun() -> producer_loop(Parent, Q) end). - - -producer_loop(Parent, Q) -> - receive - {stop, Ref} -> - Parent ! {ok, Ref}; - {ping, Ref} -> - Parent ! {pong, Ref}, - producer_loop(Parent, Q); - {produce, Ref, Size} -> - Item = crypto:rand_bytes(Size), - Parent ! {item, Ref, Item}, - ok = couch_work_queue:queue(Q, Item), - producer_loop(Parent, Q) - end. - - -consume(Consumer, N) -> - Consumer ! {consume, N}. - - -last_consumer_items(Consumer) -> - Ref = make_ref(), - Consumer ! {last_item, Ref}, - receive - {item, Ref, Items} -> - Items - after 3000 -> - timeout - end. - - -produce(Producer, Size) -> - Ref = make_ref(), - Producer ! {produce, Ref, Size}, - receive - {item, Ref, Item} -> - Item - after 3000 -> - etap:bail("Timeout asking producer to produce an item") - end. - - -ping(Pid) -> - Ref = make_ref(), - Pid ! {ping, Ref}, - receive - {pong, Ref} -> - ok - after 3000 -> - timeout - end. - - -stop(Pid, Name) -> - Ref = make_ref(), - Pid ! {stop, Ref}, - receive - {ok, Ref} -> - etap:diag("Stopped " ++ Name) - after 3000 -> - etap:bail("Timeout stopping " ++ Name) - end. http://git-wip-us.apache.org/repos/asf/couchdb/blob/0b7b43c9/test/etap/043-find-in-binary.t ---------------------------------------------------------------------- diff --git a/test/etap/043-find-in-binary.t b/test/etap/043-find-in-binary.t deleted file mode 100755 index dca1d9c..0000000 --- a/test/etap/043-find-in-binary.t +++ /dev/null @@ -1,68 +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(length(cases())), - 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() -> - lists:foreach(fun({Needle, Haystack, Result}) -> - try - Msg = io_lib:format("Looking for ~s in ~s", [Needle, Haystack]), - etap:is(couch_util:find_in_binary(Needle, Haystack), Result, Msg) - catch _T:_R -> - etap:diag("~p", [{_T, _R}]) - end - end, cases()), - ok. - - -cases() -> - [ - {<<"foo">>, <<"foobar">>, {exact, 0}}, - {<<"foo">>, <<"foofoo">>, {exact, 0}}, - {<<"foo">>, <<"barfoo">>, {exact, 3}}, - {<<"foo">>, <<"barfo">>, {partial, 3}}, - {<<"f">>, <<"fobarfff">>, {exact, 0}}, - {<<"f">>, <<"obarfff">>, {exact, 4}}, - {<<"f">>, <<"obarggf">>, {exact, 6}}, - {<<"f">>, <<"f">>, {exact, 0}}, - {<<"f">>, <<"g">>, not_found}, - {<<"foo">>, <<"f">>, {partial, 0}}, - {<<"foo">>, <<"g">>, not_found}, - {<<"foo">>, <<"">>, not_found}, - {<<"fofo">>, <<"foofo">>, {partial, 3}}, - {<<"foo">>, <<"gfobarfo">>, {partial, 6}}, - {<<"foo">>, <<"gfobarf">>, {partial, 6}}, - {<<"foo">>, <<"gfobar">>, not_found}, - {<<"fog">>, <<"gbarfogquiz">>, {exact, 4}}, - {<<"ggg">>, <<"ggg">>, {exact, 0}}, - {<<"ggg">>, <<"ggggg">>, {exact, 0}}, - {<<"ggg">>, <<"bggg">>, {exact, 1}}, - {<<"ggg">>, <<"bbgg">>, {partial, 2}}, - {<<"ggg">>, <<"bbbg">>, {partial, 3}}, - {<<"ggg">>, <<"bgbggbggg">>, {exact, 6}}, - {<<"ggg">>, <<"bgbggb">>, not_found} - ].
