summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJan Lehnardt <jan@apache.org>2019-09-25 13:51:25 +0200
committerGitHub <noreply@github.com>2019-09-25 13:51:25 +0200
commitf0719524f7c6af35525e6a6923e5ef3cb296358a (patch)
treeb2c84eae3c9052b1190ec98272da54d3b2afc587 /src
parent125ccc5688a634e54f2d6154ee33b6b3a18f4636 (diff)
parent7196a3c4b721158045af36e592ffdc7cc50abb3d (diff)
downloadcouchdb-feat/intervals.tar.gz
Merge branch 'master' into feat/intervalsfeat/intervals
Diffstat (limited to 'src')
-rw-r--r--src/chttpd/src/chttpd_auth_cache.erl3
-rw-r--r--src/chttpd/src/chttpd_view.erl26
-rw-r--r--src/chttpd/test/eunit/chttpd_cors_test.erl (renamed from src/chttpd/test/chttpd_cors_test.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_csp_tests.erl (renamed from src/chttpd/test/chttpd_csp_tests.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_db_attachment_size_tests.erl (renamed from src/chttpd/test/chttpd_db_attachment_size_tests.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_db_bulk_get_multipart_test.erl (renamed from src/chttpd/test/chttpd_db_bulk_get_multipart_test.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_db_bulk_get_test.erl (renamed from src/chttpd/test/chttpd_db_bulk_get_test.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_db_doc_size_tests.erl (renamed from src/chttpd/test/chttpd_db_doc_size_tests.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_db_test.erl (renamed from src/chttpd/test/chttpd_db_test.erl)109
-rw-r--r--src/chttpd/test/eunit/chttpd_dbs_info_test.erl (renamed from src/chttpd/test/chttpd_dbs_info_test.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_error_info_tests.erl (renamed from src/chttpd/test/chttpd_error_info_tests.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_handlers_tests.erl (renamed from src/chttpd/test/chttpd_handlers_tests.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_open_revs_error_test.erl (renamed from src/chttpd/test/chttpd_open_revs_error_test.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_plugin_tests.erl (renamed from src/chttpd/test/chttpd_plugin_tests.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_prefer_header_test.erl (renamed from src/chttpd/test/chttpd_prefer_header_test.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_purge_tests.erl (renamed from src/chttpd/test/chttpd_purge_tests.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_security_tests.erl (renamed from src/chttpd/test/chttpd_security_tests.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_socket_buffer_size_test.erl (renamed from src/chttpd/test/chttpd_socket_buffer_size_test.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_view_test.erl (renamed from src/chttpd/test/chttpd_view_test.erl)13
-rw-r--r--src/chttpd/test/eunit/chttpd_welcome_test.erl (renamed from src/chttpd/test/chttpd_welcome_test.erl)0
-rw-r--r--src/chttpd/test/eunit/chttpd_xframe_test.erl (renamed from src/chttpd/test/chttpd_xframe_test.erl)0
-rw-r--r--src/couch/include/couch_eunit.hrl2
-rw-r--r--src/couch/src/couch_db.erl11
-rw-r--r--src/couch/src/couch_file.erl29
-rw-r--r--src/couch/test/eunit/chttpd_endpoints_tests.erl (renamed from src/couch/test/chttpd_endpoints_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_auth_cache_tests.erl (renamed from src/couch/test/couch_auth_cache_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_base32_tests.erl (renamed from src/couch/test/couch_base32_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_bt_engine_compactor_tests.erl (renamed from src/couch/test/couch_bt_engine_compactor_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_bt_engine_tests.erl (renamed from src/couch/test/couch_bt_engine_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_bt_engine_upgrade_tests.erl (renamed from src/couch/test/couch_bt_engine_upgrade_tests.erl)17
-rw-r--r--src/couch/test/eunit/couch_btree_tests.erl (renamed from src/couch/test/couch_btree_tests.erl)9
-rw-r--r--src/couch/test/eunit/couch_changes_tests.erl (renamed from src/couch/test/couch_changes_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_compress_tests.erl (renamed from src/couch/test/couch_compress_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_db_doc_tests.erl (renamed from src/couch/test/couch_db_doc_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_db_mpr_tests.erl (renamed from src/couch/test/couch_db_mpr_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_db_plugin_tests.erl (renamed from src/couch/test/couch_db_plugin_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_db_props_upgrade_tests.erl (renamed from src/couch/test/couch_db_props_upgrade_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_db_split_tests.erl (renamed from src/couch/test/couch_db_split_tests.erl)5
-rw-r--r--src/couch/test/eunit/couch_db_tests.erl (renamed from src/couch/test/couch_db_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_doc_json_tests.erl (renamed from src/couch/test/couch_doc_json_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_doc_tests.erl (renamed from src/couch/test/couch_doc_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_ejson_size_tests.erl (renamed from src/couch/test/couch_ejson_size_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_etag_tests.erl (renamed from src/couch/test/couch_etag_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_file_tests.erl (renamed from src/couch/test/couch_file_tests.erl)33
-rw-r--r--src/couch/test/eunit/couch_flags_config_tests.erl (renamed from src/couch/test/couch_flags_config_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_flags_tests.erl (renamed from src/couch/test/couch_flags_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_hotp_tests.erl (renamed from src/couch/test/couch_hotp_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_index_tests.erl (renamed from src/couch/test/couch_index_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_key_tree_prop_tests.erl (renamed from src/couch/test/couch_key_tree_prop_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_key_tree_tests.erl (renamed from src/couch/test/couch_key_tree_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_passwords_tests.erl (renamed from src/couch/test/couch_passwords_tests.erl)2
-rw-r--r--src/couch/test/eunit/couch_query_servers_tests.erl (renamed from src/couch/test/couch_query_servers_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_server_tests.erl (renamed from src/couch/test/couch_server_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_stream_tests.erl (renamed from src/couch/test/couch_stream_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_task_status_tests.erl (renamed from src/couch/test/couch_task_status_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_totp_tests.erl (renamed from src/couch/test/couch_totp_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_util_tests.erl (renamed from src/couch/test/couch_util_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_uuids_tests.erl (renamed from src/couch/test/couch_uuids_tests.erl)0
-rw-r--r--src/couch/test/eunit/couch_work_queue_tests.erl (renamed from src/couch/test/couch_work_queue_tests.erl)0
-rw-r--r--src/couch/test/eunit/couchdb_attachments_tests.erl (renamed from src/couch/test/couchdb_attachments_tests.erl)0
-rw-r--r--src/couch/test/eunit/couchdb_auth_tests.erl (renamed from src/couch/test/couchdb_auth_tests.erl)0
-rwxr-xr-xsrc/couch/test/eunit/couchdb_cookie_domain_tests.erl (renamed from src/couch/test/couchdb_cookie_domain_tests.erl)0
-rw-r--r--src/couch/test/eunit/couchdb_cors_tests.erl (renamed from src/couch/test/couchdb_cors_tests.erl)0
-rw-r--r--src/couch/test/eunit/couchdb_db_tests.erl (renamed from src/couch/test/couchdb_db_tests.erl)0
-rw-r--r--src/couch/test/eunit/couchdb_design_doc_tests.erl (renamed from src/couch/test/couchdb_design_doc_tests.erl)0
-rw-r--r--src/couch/test/eunit/couchdb_file_compression_tests.erl (renamed from src/couch/test/couchdb_file_compression_tests.erl)0
-rw-r--r--src/couch/test/eunit/couchdb_location_header_tests.erl (renamed from src/couch/test/couchdb_location_header_tests.erl)0
-rw-r--r--src/couch/test/eunit/couchdb_mrview_cors_tests.erl (renamed from src/couch/test/couchdb_mrview_cors_tests.erl)0
-rw-r--r--src/couch/test/eunit/couchdb_mrview_tests.erl (renamed from src/couch/test/couchdb_mrview_tests.erl)0
-rw-r--r--src/couch/test/eunit/couchdb_os_proc_pool.erl (renamed from src/couch/test/couchdb_os_proc_pool.erl)0
-rw-r--r--src/couch/test/eunit/couchdb_update_conflicts_tests.erl (renamed from src/couch/test/couchdb_update_conflicts_tests.erl)0
-rw-r--r--src/couch/test/eunit/couchdb_vhosts_tests.erl (renamed from src/couch/test/couchdb_vhosts_tests.erl)0
-rw-r--r--src/couch/test/eunit/couchdb_views_tests.erl (renamed from src/couch/test/couchdb_views_tests.erl)0
-rw-r--r--src/couch/test/eunit/fixtures/3b835456c235b1827e012e25666152f3.view (renamed from src/couch/test/fixtures/3b835456c235b1827e012e25666152f3.view)bin4192 -> 4192 bytes
-rw-r--r--src/couch/test/eunit/fixtures/couch_stats_aggregates.cfg (renamed from src/couch/test/fixtures/couch_stats_aggregates.cfg)0
-rw-r--r--src/couch/test/eunit/fixtures/couch_stats_aggregates.ini (renamed from src/couch/test/fixtures/couch_stats_aggregates.ini)0
-rw-r--r--src/couch/test/eunit/fixtures/db_non_partitioned.couch (renamed from src/couch/test/fixtures/db_non_partitioned.couch)bin12479 -> 12479 bytes
-rw-r--r--src/couch/test/eunit/fixtures/db_v6_with_1_purge_req.couch (renamed from src/couch/test/fixtures/db_v6_with_1_purge_req.couch)bin12470 -> 12470 bytes
-rw-r--r--src/couch/test/eunit/fixtures/db_v6_with_1_purge_req_for_2_docs.couch (renamed from src/couch/test/fixtures/db_v6_with_1_purge_req_for_2_docs.couch)bin16557 -> 16557 bytes
-rw-r--r--src/couch/test/eunit/fixtures/db_v6_with_2_purge_req.couch (renamed from src/couch/test/fixtures/db_v6_with_2_purge_req.couch)bin16566 -> 16566 bytes
-rw-r--r--src/couch/test/eunit/fixtures/db_v6_without_purge_req.couch (renamed from src/couch/test/fixtures/db_v6_without_purge_req.couch)bin61644 -> 61644 bytes
-rw-r--r--src/couch/test/eunit/fixtures/db_v7_with_1_purge_req.couch (renamed from src/couch/test/fixtures/db_v7_with_1_purge_req.couch)bin16617 -> 16617 bytes
-rw-r--r--src/couch/test/eunit/fixtures/db_v7_with_1_purge_req_for_2_docs.couch (renamed from src/couch/test/fixtures/db_v7_with_1_purge_req_for_2_docs.couch)bin20705 -> 20705 bytes
-rw-r--r--src/couch/test/eunit/fixtures/db_v7_with_2_purge_req.couch (renamed from src/couch/test/fixtures/db_v7_with_2_purge_req.couch)bin20713 -> 20713 bytes
-rw-r--r--src/couch/test/eunit/fixtures/db_v7_without_purge_req.couch (renamed from src/couch/test/fixtures/db_v7_without_purge_req.couch)bin65781 -> 65781 bytes
-rw-r--r--src/couch/test/eunit/fixtures/logo.png (renamed from src/couch/test/fixtures/logo.png)bin3010 -> 3010 bytes
-rw-r--r--src/couch/test/eunit/fixtures/multipart.http (renamed from src/couch/test/fixtures/multipart.http)0
-rw-r--r--src/couch/test/eunit/fixtures/os_daemon_bad_perm.sh (renamed from src/couch/test/fixtures/os_daemon_bad_perm.sh)0
-rwxr-xr-xsrc/couch/test/eunit/fixtures/os_daemon_can_reboot.sh (renamed from src/couch/test/fixtures/os_daemon_can_reboot.sh)0
-rwxr-xr-xsrc/couch/test/eunit/fixtures/os_daemon_configer.escript (renamed from src/couch/test/fixtures/os_daemon_configer.escript)0
-rwxr-xr-xsrc/couch/test/eunit/fixtures/os_daemon_die_on_boot.sh (renamed from src/couch/test/fixtures/os_daemon_die_on_boot.sh)0
-rwxr-xr-xsrc/couch/test/eunit/fixtures/os_daemon_die_quickly.sh (renamed from src/couch/test/fixtures/os_daemon_die_quickly.sh)0
-rwxr-xr-xsrc/couch/test/eunit/fixtures/os_daemon_looper.escript (renamed from src/couch/test/fixtures/os_daemon_looper.escript)0
-rw-r--r--src/couch/test/eunit/fixtures/test.couch (renamed from src/couch/test/fixtures/test.couch)bin16482 -> 16482 bytes
-rw-r--r--src/couch/test/eunit/global_changes_tests.erl (renamed from src/couch/test/global_changes_tests.erl)0
-rw-r--r--src/couch/test/eunit/json_stream_parse_tests.erl (renamed from src/couch/test/json_stream_parse_tests.erl)0
-rw-r--r--src/couch/test/eunit/test_web.erl (renamed from src/couch/test/test_web.erl)0
-rw-r--r--src/couch/test/exunit/fabric_test.exs101
-rw-r--r--src/couch/test/exunit/test_helper.exs2
-rw-r--r--src/couch_epi/src/couch_epi_sup.erl5
-rw-r--r--src/couch_epi/test/eunit/couch_epi_basic_test.erl (renamed from src/couch_epi/test/couch_epi_basic_test.erl)34
-rw-r--r--src/couch_epi/test/eunit/couch_epi_tests.erl (renamed from src/couch_epi/test/couch_epi_tests.erl)4
-rw-r--r--src/couch_epi/test/eunit/fixtures/app_data1.cfg (renamed from src/couch_epi/test/fixtures/app_data1.cfg)0
-rw-r--r--src/couch_epi/test/eunit/fixtures/app_data2.cfg (renamed from src/couch_epi/test/fixtures/app_data2.cfg)0
-rw-r--r--src/couch_index/test/eunit/couch_index_compaction_tests.erl (renamed from src/couch_index/test/couch_index_compaction_tests.erl)0
-rw-r--r--src/couch_index/test/eunit/couch_index_ddoc_updated_tests.erl (renamed from src/couch_index/test/couch_index_ddoc_updated_tests.erl)0
-rw-r--r--src/couch_log/test/eunit/couch_log_config_listener_test.erl (renamed from src/couch_log/test/couch_log_config_listener_test.erl)0
-rw-r--r--src/couch_log/test/eunit/couch_log_config_test.erl (renamed from src/couch_log/test/couch_log_config_test.erl)0
-rw-r--r--src/couch_log/test/eunit/couch_log_error_logger_h_test.erl (renamed from src/couch_log/test/couch_log_error_logger_h_test.erl)0
-rw-r--r--src/couch_log/test/eunit/couch_log_formatter_test.erl (renamed from src/couch_log/test/couch_log_formatter_test.erl)0
-rw-r--r--src/couch_log/test/eunit/couch_log_monitor_test.erl (renamed from src/couch_log/test/couch_log_monitor_test.erl)0
-rw-r--r--src/couch_log/test/eunit/couch_log_server_test.erl (renamed from src/couch_log/test/couch_log_server_test.erl)0
-rw-r--r--src/couch_log/test/eunit/couch_log_test.erl (renamed from src/couch_log/test/couch_log_test.erl)0
-rw-r--r--src/couch_log/test/eunit/couch_log_test_util.erl (renamed from src/couch_log/test/couch_log_test_util.erl)0
-rw-r--r--src/couch_log/test/eunit/couch_log_trunc_io_fmt_test.erl (renamed from src/couch_log/test/couch_log_trunc_io_fmt_test.erl)0
-rw-r--r--src/couch_log/test/eunit/couch_log_util_test.erl (renamed from src/couch_log/test/couch_log_util_test.erl)0
-rw-r--r--src/couch_log/test/eunit/couch_log_writer_ets.erl (renamed from src/couch_log/test/couch_log_writer_ets.erl)0
-rw-r--r--src/couch_log/test/eunit/couch_log_writer_file_test.erl (renamed from src/couch_log/test/couch_log_writer_file_test.erl)0
-rw-r--r--src/couch_log/test/eunit/couch_log_writer_stderr_test.erl (renamed from src/couch_log/test/couch_log_writer_stderr_test.erl)0
-rw-r--r--src/couch_log/test/eunit/couch_log_writer_syslog_test.erl (renamed from src/couch_log/test/couch_log_writer_syslog_test.erl)0
-rw-r--r--src/couch_log/test/eunit/couch_log_writer_test.erl (renamed from src/couch_log/test/couch_log_writer_test.erl)0
-rw-r--r--src/couch_mrview/src/couch_mrview.erl2
-rw-r--r--src/couch_mrview/src/couch_mrview_index.erl2
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_all_docs_tests.erl (renamed from src/couch_mrview/test/couch_mrview_all_docs_tests.erl)0
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_changes_since_tests.erl (renamed from src/couch_mrview/test/couch_mrview_changes_since_tests.erl)0
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_collation_tests.erl (renamed from src/couch_mrview/test/couch_mrview_collation_tests.erl)0
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_compact_tests.erl (renamed from src/couch_mrview/test/couch_mrview_compact_tests.erl)0
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_ddoc_updated_tests.erl (renamed from src/couch_mrview/test/couch_mrview_ddoc_updated_tests.erl)0
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_ddoc_validation_tests.erl (renamed from src/couch_mrview/test/couch_mrview_ddoc_validation_tests.erl)0
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_design_docs_tests.erl (renamed from src/couch_mrview/test/couch_mrview_design_docs_tests.erl)0
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_http_tests.erl (renamed from src/couch_mrview/test/couch_mrview_http_tests.erl)0
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_index_changes_tests.erl (renamed from src/couch_mrview/test/couch_mrview_index_changes_tests.erl)0
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_index_info_tests.erl (renamed from src/couch_mrview/test/couch_mrview_index_info_tests.erl)10
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_local_docs_tests.erl (renamed from src/couch_mrview/test/couch_mrview_local_docs_tests.erl)0
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_map_views_tests.erl (renamed from src/couch_mrview/test/couch_mrview_map_views_tests.erl)0
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_purge_docs_fabric_tests.erl (renamed from src/couch_mrview/test/couch_mrview_purge_docs_fabric_tests.erl)10
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_purge_docs_tests.erl (renamed from src/couch_mrview/test/couch_mrview_purge_docs_tests.erl)0
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_red_views_tests.erl (renamed from src/couch_mrview/test/couch_mrview_red_views_tests.erl)0
-rw-r--r--src/couch_mrview/test/eunit/couch_mrview_util_tests.erl (renamed from src/couch_mrview/test/couch_mrview_util_tests.erl)0
-rw-r--r--src/couch_peruser/test/eunit/couch_peruser_test.erl (renamed from src/couch_peruser/test/couch_peruser_test.erl)0
-rw-r--r--src/couch_pse_tests/src/cpse_test_purge_replication.erl21
-rw-r--r--src/couch_replicator/src/couch_replicator.erl16
-rw-r--r--src/couch_replicator/src/couch_replicator_api_wrap.erl150
-rw-r--r--src/couch_replicator/src/couch_replicator_auth.erl6
-rw-r--r--src/couch_replicator/src/couch_replicator_doc_processor.erl12
-rw-r--r--src/couch_replicator/src/couch_replicator_doc_processor_worker.erl6
-rw-r--r--src/couch_replicator/src/couch_replicator_docs.erl41
-rw-r--r--src/couch_replicator/src/couch_replicator_filters.erl13
-rw-r--r--src/couch_replicator/src/couch_replicator_ids.erl44
-rw-r--r--src/couch_replicator/src/couch_replicator_scheduler.erl82
-rw-r--r--src/couch_replicator/src/couch_replicator_scheduler_job.erl31
-rw-r--r--src/couch_replicator/src/couch_replicator_utils.erl56
-rw-r--r--src/couch_replicator/src/couch_replicator_worker.erl143
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_attachments_too_large.erl (renamed from src/couch_replicator/test/couch_replicator_attachments_too_large.erl)4
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_compact_tests.erl (renamed from src/couch_replicator/test/couch_replicator_compact_tests.erl)5
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_connection_tests.erl (renamed from src/couch_replicator/test/couch_replicator_connection_tests.erl)0
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_create_target_with_options_tests.erl (renamed from src/couch_replicator/test/couch_replicator_create_target_with_options_tests.erl)0
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_filtered_tests.erl (renamed from src/couch_replicator/test/couch_replicator_filtered_tests.erl)10
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_httpc_pool_tests.erl (renamed from src/couch_replicator/test/couch_replicator_httpc_pool_tests.erl)0
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_id_too_long_tests.erl (renamed from src/couch_replicator/test/couch_replicator_id_too_long_tests.erl)5
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_large_atts_tests.erl (renamed from src/couch_replicator/test/couch_replicator_large_atts_tests.erl)5
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_many_leaves_tests.erl (renamed from src/couch_replicator/test/couch_replicator_many_leaves_tests.erl)6
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_missing_stubs_tests.erl (renamed from src/couch_replicator/test/couch_replicator_missing_stubs_tests.erl)5
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_proxy_tests.erl (renamed from src/couch_replicator/test/couch_replicator_proxy_tests.erl)0
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_rate_limiter_tests.erl (renamed from src/couch_replicator/test/couch_replicator_rate_limiter_tests.erl)0
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_retain_stats_between_job_runs.erl (renamed from src/couch_replicator/test/couch_replicator_retain_stats_between_job_runs.erl)0
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_selector_tests.erl (renamed from src/couch_replicator/test/couch_replicator_selector_tests.erl)5
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_small_max_request_size_target.erl (renamed from src/couch_replicator/test/couch_replicator_small_max_request_size_target.erl)5
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_test_helper.erl (renamed from src/couch_replicator/test/couch_replicator_test_helper.erl)0
-rw-r--r--src/couch_replicator/test/eunit/couch_replicator_use_checkpoints_tests.erl (renamed from src/couch_replicator/test/couch_replicator_use_checkpoints_tests.erl)5
-rw-r--r--src/ddoc_cache/test/eunit/ddoc_cache_basic_test.erl (renamed from src/ddoc_cache/test/ddoc_cache_basic_test.erl)0
-rw-r--r--src/ddoc_cache/test/eunit/ddoc_cache_coverage_test.erl (renamed from src/ddoc_cache/test/ddoc_cache_coverage_test.erl)0
-rw-r--r--src/ddoc_cache/test/eunit/ddoc_cache_disabled_test.erl (renamed from src/ddoc_cache/test/ddoc_cache_disabled_test.erl)0
-rw-r--r--src/ddoc_cache/test/eunit/ddoc_cache_entry_test.erl (renamed from src/ddoc_cache/test/ddoc_cache_entry_test.erl)0
-rw-r--r--src/ddoc_cache/test/eunit/ddoc_cache_ev.erl (renamed from src/ddoc_cache/test/ddoc_cache_ev.erl)0
-rw-r--r--src/ddoc_cache/test/eunit/ddoc_cache_eviction_test.erl (renamed from src/ddoc_cache/test/ddoc_cache_eviction_test.erl)0
-rw-r--r--src/ddoc_cache/test/eunit/ddoc_cache_lru_test.erl (renamed from src/ddoc_cache/test/ddoc_cache_lru_test.erl)19
-rw-r--r--src/ddoc_cache/test/eunit/ddoc_cache_no_cache_test.erl (renamed from src/ddoc_cache/test/ddoc_cache_no_cache_test.erl)76
-rw-r--r--src/ddoc_cache/test/eunit/ddoc_cache_open_error_test.erl (renamed from src/ddoc_cache/test/ddoc_cache_open_error_test.erl)0
-rw-r--r--src/ddoc_cache/test/eunit/ddoc_cache_open_test.erl (renamed from src/ddoc_cache/test/ddoc_cache_open_test.erl)0
-rw-r--r--src/ddoc_cache/test/eunit/ddoc_cache_opener_test.erl (renamed from src/ddoc_cache/test/ddoc_cache_opener_test.erl)0
-rw-r--r--src/ddoc_cache/test/eunit/ddoc_cache_refresh_test.erl (renamed from src/ddoc_cache/test/ddoc_cache_refresh_test.erl)0
-rw-r--r--src/ddoc_cache/test/eunit/ddoc_cache_remove_test.erl (renamed from src/ddoc_cache/test/ddoc_cache_remove_test.erl)0
-rw-r--r--src/ddoc_cache/test/eunit/ddoc_cache_test.hrl (renamed from src/ddoc_cache/test/ddoc_cache_test.hrl)0
-rw-r--r--src/ddoc_cache/test/eunit/ddoc_cache_tutil.erl (renamed from src/ddoc_cache/test/ddoc_cache_tutil.erl)0
-rw-r--r--src/dreyfus/src/dreyfus_fabric_cleanup.erl8
-rw-r--r--src/dreyfus/src/dreyfus_util.erl5
-rw-r--r--src/dreyfus/test/elixir/test/partition_search_test.exs4
-rw-r--r--src/fabric/src/fabric.erl30
-rw-r--r--src/fabric/src/fabric_db_info.erl17
-rw-r--r--src/fabric/src/fabric_group_info.erl4
-rw-r--r--src/fabric/src/fabric_view_all_docs.erl9
-rw-r--r--src/fabric/test/eunit/fabric_rpc_purge_tests.erl (renamed from src/fabric/test/fabric_rpc_purge_tests.erl)0
-rw-r--r--src/global_changes/test/eunit/global_changes_hooks_tests.erl (renamed from src/global_changes/test/global_changes_hooks_tests.erl)0
-rw-r--r--src/mango/src/mango_error.erl2
-rw-r--r--src/mem3/src/mem3_sync_event_listener.erl29
-rw-r--r--src/mem3/src/mem3_util.erl16
-rw-r--r--src/mem3/test/eunit/mem3_cluster_test.erl (renamed from src/mem3/test/mem3_cluster_test.erl)0
-rw-r--r--src/mem3/test/eunit/mem3_hash_test.erl (renamed from src/mem3/test/mem3_hash_test.erl)0
-rw-r--r--src/mem3/test/eunit/mem3_rep_test.erl (renamed from src/mem3/test/mem3_rep_test.erl)17
-rw-r--r--src/mem3/test/eunit/mem3_reshard_api_test.erl (renamed from src/mem3/test/mem3_reshard_api_test.erl)121
-rw-r--r--src/mem3/test/eunit/mem3_reshard_changes_feed_test.erl (renamed from src/mem3/test/mem3_reshard_changes_feed_test.erl)9
-rw-r--r--src/mem3/test/eunit/mem3_reshard_test.erl (renamed from src/mem3/test/mem3_reshard_test.erl)37
-rw-r--r--src/mem3/test/eunit/mem3_ring_prop_tests.erl (renamed from src/mem3/test/mem3_ring_prop_tests.erl)0
-rw-r--r--src/mem3/test/eunit/mem3_seeds_test.erl (renamed from src/mem3/test/mem3_seeds_test.erl)0
-rw-r--r--src/mem3/test/eunit/mem3_sync_security_test.erl54
-rw-r--r--src/mem3/test/eunit/mem3_util_test.erl (renamed from src/mem3/test/mem3_util_test.erl)0
-rw-r--r--src/mem3/test/mem3_sync_security_test.erl32
208 files changed, 778 insertions, 816 deletions
diff --git a/src/chttpd/src/chttpd_auth_cache.erl b/src/chttpd/src/chttpd_auth_cache.erl
index 638d8c748..fdae27b79 100644
--- a/src/chttpd/src/chttpd_auth_cache.erl
+++ b/src/chttpd/src/chttpd_auth_cache.erl
@@ -113,6 +113,9 @@ handle_info({'DOWN', _, _, Pid, Reason}, #state{changes_pid=Pid} = State) ->
Seq = case Reason of
{seq, EndSeq} ->
EndSeq;
+ {database_does_not_exist, _} ->
+ couch_log:notice("~p changes listener died because the _users database does not exist. Create the database to silence this notice.", [?MODULE]),
+ 0;
_ ->
couch_log:notice("~p changes listener died ~r", [?MODULE, Reason]),
0
diff --git a/src/chttpd/src/chttpd_view.erl b/src/chttpd/src/chttpd_view.erl
index 26107d7c5..0d3d86d1a 100644
--- a/src/chttpd/src/chttpd_view.erl
+++ b/src/chttpd/src/chttpd_view.erl
@@ -88,22 +88,16 @@ handle_view_req(#httpd{method='POST',
path_parts=[_, _, _, _, ViewName]}=Req, Db, DDoc) ->
chttpd:validate_ctype(Req, "application/json"),
Props = couch_httpd:json_body_obj(Req),
- Keys = couch_mrview_util:get_view_keys(Props),
- Queries = couch_mrview_util:get_view_queries(Props),
- case {Queries, Keys} of
- {Queries, undefined} when is_list(Queries) ->
- [couch_stats:increment_counter([couchdb, httpd, view_reads]) || _I <- Queries],
- multi_query_view(Req, Db, DDoc, ViewName, Queries);
- {undefined, Keys} when is_list(Keys) ->
+ assert_no_queries_param(couch_mrview_util:get_view_queries(Props)),
+ case couch_mrview_util:get_view_keys(Props) of
+ Keys when is_list(Keys) ->
couch_stats:increment_counter([couchdb, httpd, view_reads]),
design_doc_view(Req, Db, DDoc, ViewName, Keys);
- {undefined, undefined} ->
+ _ ->
throw({
bad_request,
- "POST body must contain `keys` or `queries` field"
- });
- {_, _} ->
- throw({bad_request, "`keys` and `queries` are mutually exclusive"})
+ "POST body must contain an array called `keys`"
+ })
end;
handle_view_req(Req, _Db, _DDoc) ->
@@ -113,6 +107,14 @@ handle_temp_view_req(Req, _Db) ->
Msg = <<"Temporary views are not supported in CouchDB">>,
chttpd:send_error(Req, 410, gone, Msg).
+% See https://github.com/apache/couchdb/issues/2168
+assert_no_queries_param(undefined) ->
+ ok;
+assert_no_queries_param(_) ->
+ throw({
+ bad_request,
+ "The `queries` parameter is no longer supported at this endpoint"
+ }).
-ifdef(TEST).
diff --git a/src/chttpd/test/chttpd_cors_test.erl b/src/chttpd/test/eunit/chttpd_cors_test.erl
index 19e851561..19e851561 100644
--- a/src/chttpd/test/chttpd_cors_test.erl
+++ b/src/chttpd/test/eunit/chttpd_cors_test.erl
diff --git a/src/chttpd/test/chttpd_csp_tests.erl b/src/chttpd/test/eunit/chttpd_csp_tests.erl
index e86436254..e86436254 100644
--- a/src/chttpd/test/chttpd_csp_tests.erl
+++ b/src/chttpd/test/eunit/chttpd_csp_tests.erl
diff --git a/src/chttpd/test/chttpd_db_attachment_size_tests.erl b/src/chttpd/test/eunit/chttpd_db_attachment_size_tests.erl
index 0ab08dd80..0ab08dd80 100644
--- a/src/chttpd/test/chttpd_db_attachment_size_tests.erl
+++ b/src/chttpd/test/eunit/chttpd_db_attachment_size_tests.erl
diff --git a/src/chttpd/test/chttpd_db_bulk_get_multipart_test.erl b/src/chttpd/test/eunit/chttpd_db_bulk_get_multipart_test.erl
index 8a95c92ac..8a95c92ac 100644
--- a/src/chttpd/test/chttpd_db_bulk_get_multipart_test.erl
+++ b/src/chttpd/test/eunit/chttpd_db_bulk_get_multipart_test.erl
diff --git a/src/chttpd/test/chttpd_db_bulk_get_test.erl b/src/chttpd/test/eunit/chttpd_db_bulk_get_test.erl
index 864e7079a..864e7079a 100644
--- a/src/chttpd/test/chttpd_db_bulk_get_test.erl
+++ b/src/chttpd/test/eunit/chttpd_db_bulk_get_test.erl
diff --git a/src/chttpd/test/chttpd_db_doc_size_tests.erl b/src/chttpd/test/eunit/chttpd_db_doc_size_tests.erl
index 88e2797a3..88e2797a3 100644
--- a/src/chttpd/test/chttpd_db_doc_size_tests.erl
+++ b/src/chttpd/test/eunit/chttpd_db_doc_size_tests.erl
diff --git a/src/chttpd/test/chttpd_db_test.erl b/src/chttpd/test/eunit/chttpd_db_test.erl
index 2708aa033..c819bdf6e 100644
--- a/src/chttpd/test/chttpd_db_test.erl
+++ b/src/chttpd/test/eunit/chttpd_db_test.erl
@@ -23,6 +23,7 @@
-define(DESTHEADER2, {"Destination", "foo%2Fbar%23baz%3Fpow%3Afiz"}).
-define(FIXTURE_TXT, ?ABS_PATH(?FILE)).
-define(i2l(I), integer_to_list(I)).
+-define(TIMEOUT, 60). % seconds
setup() ->
Hashed = couch_passwords:hash_admin_password(?PASS),
@@ -72,6 +73,7 @@ all_test_() ->
fun should_not_return_update_seq_when_unset_on_all_docs/1,
fun should_return_correct_id_on_doc_copy/1,
fun should_return_400_for_bad_engine/1,
+ fun should_not_change_db_proper_after_rewriting_shardmap/1,
fun should_succeed_on_all_docs_with_queries_keys/1,
fun should_succeed_on_all_docs_with_queries_limit_skip/1,
fun should_succeed_on_all_docs_with_multiple_queries/1,
@@ -88,7 +90,7 @@ all_test_() ->
should_return_ok_true_on_bulk_update(Url) ->
- ?_assertEqual(true,
+ {timeout, ?TIMEOUT, ?_assertEqual(true,
begin
{ok, _, _, Body} = create_doc(Url, "testdoc"),
{Json} = ?JSON_DECODE(Body),
@@ -99,27 +101,27 @@ should_return_ok_true_on_bulk_update(Url) ->
ResultJson = ?JSON_DECODE(ResultBody),
{InnerJson} = lists:nth(1, ResultJson),
couch_util:get_value(<<"ok">>, InnerJson, undefined)
- end).
+ end)}.
should_return_ok_true_on_ensure_full_commit(Url0) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
Url = Url0 ++ "/_ensure_full_commit",
{ok, RC, _, Body} = test_request:post(Url, [?CONTENT_JSON, ?AUTH], []),
{Json} = ?JSON_DECODE(Body),
?assertEqual(201, RC),
?assert(couch_util:get_value(<<"ok">>, Json))
- end).
+ end)}.
should_return_404_for_ensure_full_commit_on_no_db(Url0) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
Url = Url0 ++ "-missing-db" ++ "/_ensure_full_commit",
{ok, RC, _, Body} = test_request:post(Url, [?CONTENT_JSON, ?AUTH], []),
{Json} = ?JSON_DECODE(Body),
?assertEqual(404, RC),
?assertEqual(<<"not_found">>, couch_util:get_value(<<"error">>, Json))
- end).
+ end)}.
should_accept_live_as_an_alias_for_continuous(Url) ->
@@ -135,7 +137,7 @@ should_accept_live_as_an_alias_for_continuous(Url) ->
end,
couch_util:get_value(<<"last_seq">>, Result, undefined)
end,
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
{ok, _, _, ResultBody1} =
test_request:get(Url ++ "/_changes?feed=live&timeout=1", [?AUTH]),
LastSeq1 = GetLastSeq(ResultBody1),
@@ -146,11 +148,11 @@ should_accept_live_as_an_alias_for_continuous(Url) ->
LastSeq2 = GetLastSeq(ResultBody2),
?assertNotEqual(LastSeq1, LastSeq2)
- end).
+ end)}.
should_return_404_for_delete_att_on_notadoc(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
{ok, RC, _, RespBody} = test_request:delete(
Url ++ "/notadoc/att.pdf",
[?CONTENT_JSON, ?AUTH],
@@ -168,11 +170,11 @@ should_return_404_for_delete_att_on_notadoc(Url) ->
[]
),
?assertEqual(404, RC1)
- end).
+ end)}.
should_return_409_for_del_att_without_rev(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
{ok, RC, _, _} = test_request:put(
Url ++ "/testdoc3",
[?CONTENT_JSON, ?AUTH],
@@ -186,11 +188,11 @@ should_return_409_for_del_att_without_rev(Url) ->
[]
),
?assertEqual(409, RC1)
- end).
+ end)}.
should_return_200_for_del_att_with_rev(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
{ok, RC, _Headers, RespBody} = test_request:put(
Url ++ "/testdoc4",
[?CONTENT_JSON, ?AUTH],
@@ -207,11 +209,11 @@ should_return_200_for_del_att_with_rev(Url) ->
[]
),
?assertEqual(200, RC1)
- end).
+ end)}.
should_return_409_for_put_att_nonexistent_rev(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
{ok, RC, _Headers, RespBody} = test_request:put(
Url ++ "/should_return_404/file.erl?rev=1-000",
[?CONTENT_JSON, ?AUTH],
@@ -222,11 +224,11 @@ should_return_409_for_put_att_nonexistent_rev(Url) ->
{<<"error">>,<<"not_found">>},
{<<"reason">>,<<"missing_rev">>}]},
?JSON_DECODE(RespBody))
- end).
+ end)}.
should_return_update_seq_when_set_on_all_docs(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[create_doc(Url, "testdoc" ++ ?i2l(I)) || I <- lists:seq(1, 3)],
{ok, RC, _, RespBody} = test_request:get(Url ++ "/_all_docs/"
++ "?update_seq=true&keys=[\"testdoc1\"]",[?CONTENT_JSON, ?AUTH]),
@@ -236,11 +238,11 @@ should_return_update_seq_when_set_on_all_docs(Url) ->
couch_util:get_value(<<"update_seq">>, ResultJson)),
?assertNotEqual(undefined,
couch_util:get_value(<<"offset">>, ResultJson))
- end).
+ end)}.
should_not_return_update_seq_when_unset_on_all_docs(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[create_doc(Url, "testdoc" ++ ?i2l(I)) || I <- lists:seq(1, 3)],
{ok, RC, _, RespBody} = test_request:get(Url ++ "/_all_docs/"
++ "?update_seq=false&keys=[\"testdoc1\"]",[?CONTENT_JSON, ?AUTH]),
@@ -250,11 +252,11 @@ should_not_return_update_seq_when_unset_on_all_docs(Url) ->
couch_util:get_value(<<"update_seq">>, ResultJson)),
?assertNotEqual(undefined,
couch_util:get_value(<<"offset">>, ResultJson))
- end).
+ end)}.
should_return_correct_id_on_doc_copy(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
{ok, _, _, _} = create_doc(Url, "testdoc"),
{_, _, _, ResultBody1} = test_request:copy(Url ++ "/testdoc/",
[?CONTENT_JSON, ?AUTH, ?DESTHEADER1]),
@@ -269,7 +271,7 @@ should_return_correct_id_on_doc_copy(Url) ->
?assertEqual(<<102,111,111,229,149,138,98,97,114>>, Id1),
?assertEqual(<<"foo/bar#baz?pow:fiz">>, Id2)
]
- end).
+ end)}.
attachment_doc() ->
@@ -285,7 +287,7 @@ attachment_doc() ->
should_return_400_for_bad_engine(_) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
TmpDb = ?tempdb(),
Addr = config:get("chttpd", "bind_address", "127.0.0.1"),
Port = mochiweb_socket_server:get(chttpd, port),
@@ -293,11 +295,34 @@ should_return_400_for_bad_engine(_) ->
Url = BaseUrl ++ "?engine=cowabunga",
{ok, Status, _, _} = test_request:put(Url, [?CONTENT_JSON, ?AUTH], "{}"),
?assertEqual(400, Status)
- end).
+ end)}.
+
+
+should_not_change_db_proper_after_rewriting_shardmap(_) ->
+ {timeout, ?TIMEOUT, ?_test(begin
+ TmpDb = ?tempdb(),
+ Addr = config:get("chttpd", "bind_address", "127.0.0.1"),
+ Port = mochiweb_socket_server:get(chttpd, port),
+ AdmPort = mochiweb_socket_server:get(couch_httpd, port),
+
+ BaseUrl = lists:concat(["http://", Addr, ":", Port, "/", ?b2l(TmpDb)]),
+ Url = BaseUrl ++ "?partitioned=true&q=1",
+ {ok, 201, _, _} = test_request:put(Url, [?CONTENT_JSON, ?AUTH], "{}"),
+
+ ShardDbName = ?l2b(config:get("mem3", "shards_db", "_dbs")),
+ {ok, ShardDb} = mem3_util:ensure_exists(ShardDbName),
+ {ok, #doc{body = {Props}}} = couch_db:open_doc(
+ ShardDb, TmpDb, [ejson_body]),
+ Shards = mem3_util:build_shards(TmpDb, Props),
+
+ {Prop2} = ?JSON_DECODE(?JSON_ENCODE({Props})),
+ Shards2 = mem3_util:build_shards(TmpDb, Prop2),
+ ?assertEqual(Shards2, Shards)
+ end)}.
should_succeed_on_all_docs_with_queries_keys(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[create_doc(Url, "testdoc" ++ ?i2l(I)) || I <- lists:seq(1, 10)],
QueryDoc = "{\"queries\": [{\"keys\": [ \"testdoc3\", \"testdoc8\"]}]}",
{ok, RC, _, RespBody} = test_request:post(Url ++ "/_all_docs/queries/",
@@ -307,11 +332,11 @@ should_succeed_on_all_docs_with_queries_keys(Url) ->
ResultJsonBody = couch_util:get_value(<<"results">>, ResultJson),
{InnerJson} = lists:nth(1, ResultJsonBody),
?assertEqual(2, length(couch_util:get_value(<<"rows">>, InnerJson)))
- end).
+ end)}.
should_succeed_on_all_docs_with_queries_limit_skip(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[create_doc(Url, "testdoc" ++ ?i2l(I)) || I <- lists:seq(1, 10)],
QueryDoc = "{\"queries\": [{\"limit\": 5, \"skip\": 2}]}",
{ok, RC, _, RespBody} = test_request:post(Url ++ "/_all_docs/queries/",
@@ -322,11 +347,11 @@ should_succeed_on_all_docs_with_queries_limit_skip(Url) ->
{InnerJson} = lists:nth(1, ResultJsonBody),
?assertEqual(2, couch_util:get_value(<<"offset">>, InnerJson)),
?assertEqual(5, length(couch_util:get_value(<<"rows">>, InnerJson)))
- end).
+ end)}.
should_succeed_on_all_docs_with_multiple_queries(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[create_doc(Url, "testdoc" ++ ?i2l(I)) || I <- lists:seq(1, 10)],
QueryDoc = "{\"queries\": [{\"keys\": [ \"testdoc3\", \"testdoc8\"]},
{\"limit\": 5, \"skip\": 2}]}",
@@ -340,11 +365,11 @@ should_succeed_on_all_docs_with_multiple_queries(Url) ->
{InnerJson2} = lists:nth(2, ResultJsonBody),
?assertEqual(2, couch_util:get_value(<<"offset">>, InnerJson2)),
?assertEqual(5, length(couch_util:get_value(<<"rows">>, InnerJson2)))
- end).
+ end)}.
should_succeed_on_design_docs_with_queries_keys(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[create_doc(Url, "_design/ddoc" ++ ?i2l(I)) || I <- lists:seq(1, 10)],
QueryDoc = "{\"queries\": [{\"keys\": [ \"_design/ddoc3\",
\"_design/ddoc8\"]}]}",
@@ -355,11 +380,11 @@ should_succeed_on_design_docs_with_queries_keys(Url) ->
ResultJsonBody = couch_util:get_value(<<"results">>, ResultJson),
{InnerJson} = lists:nth(1, ResultJsonBody),
?assertEqual(2, length(couch_util:get_value(<<"rows">>, InnerJson)))
- end).
+ end)}.
should_succeed_on_design_docs_with_queries_limit_skip(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[create_doc(Url, "_design/ddoc" ++ ?i2l(I)) || I <- lists:seq(1, 10)],
QueryDoc = "{\"queries\": [{\"limit\": 5, \"skip\": 2}]}",
{ok, RC, _, RespBody} = test_request:post(Url ++
@@ -370,11 +395,11 @@ should_succeed_on_design_docs_with_queries_limit_skip(Url) ->
{InnerJson} = lists:nth(1, ResultJsonBody),
?assertEqual(2, couch_util:get_value(<<"offset">>, InnerJson)),
?assertEqual(5, length(couch_util:get_value(<<"rows">>, InnerJson)))
- end).
+ end)}.
should_succeed_on_design_docs_with_multiple_queries(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[create_doc(Url, "_design/ddoc" ++ ?i2l(I)) || I <- lists:seq(1, 10)],
QueryDoc = "{\"queries\": [{\"keys\": [ \"_design/ddoc3\",
\"_design/ddoc8\"]}, {\"limit\": 5, \"skip\": 2}]}",
@@ -388,11 +413,11 @@ should_succeed_on_design_docs_with_multiple_queries(Url) ->
{InnerJson2} = lists:nth(2, ResultJsonBody),
?assertEqual(2, couch_util:get_value(<<"offset">>, InnerJson2)),
?assertEqual(5, length(couch_util:get_value(<<"rows">>, InnerJson2)))
- end).
+ end)}.
should_succeed_on_local_docs_with_queries_keys(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[create_doc(Url, "_local/doc" ++ ?i2l(I)) || I <- lists:seq(1, 10)],
QueryDoc = "{\"queries\": [{\"keys\":
[ \"_local/doc3\", \"_local/doc8\"]}]}",
@@ -403,11 +428,11 @@ should_succeed_on_local_docs_with_queries_keys(Url) ->
ResultJsonBody = couch_util:get_value(<<"results">>, ResultJson),
{InnerJson} = lists:nth(1, ResultJsonBody),
?assertEqual(2, length(couch_util:get_value(<<"rows">>, InnerJson)))
- end).
+ end)}.
should_succeed_on_local_docs_with_queries_limit_skip(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[create_doc(Url, "_local/doc" ++ ?i2l(I)) || I <- lists:seq(1, 10)],
QueryDoc = "{\"queries\": [{\"limit\": 5, \"skip\": 2}]}",
{ok, RC, _, RespBody} = test_request:post(Url ++
@@ -417,11 +442,11 @@ should_succeed_on_local_docs_with_queries_limit_skip(Url) ->
ResultJsonBody = couch_util:get_value(<<"results">>, ResultJson),
{InnerJson} = lists:nth(1, ResultJsonBody),
?assertEqual(5, length(couch_util:get_value(<<"rows">>, InnerJson)))
- end).
+ end)}.
should_succeed_on_local_docs_with_multiple_queries(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[create_doc(Url, "_local/doc" ++ ?i2l(I)) || I <- lists:seq(1, 10)],
QueryDoc = "{\"queries\": [{\"keys\": [ \"_local/doc3\",
\"_local/doc8\"]}, {\"limit\": 5, \"skip\": 2}]}",
@@ -434,4 +459,4 @@ should_succeed_on_local_docs_with_multiple_queries(Url) ->
?assertEqual(2, length(couch_util:get_value(<<"rows">>, InnerJson1))),
{InnerJson2} = lists:nth(2, ResultJsonBody),
?assertEqual(5, length(couch_util:get_value(<<"rows">>, InnerJson2)))
- end).
+ end)}.
diff --git a/src/chttpd/test/chttpd_dbs_info_test.erl b/src/chttpd/test/eunit/chttpd_dbs_info_test.erl
index 5b61d8831..5b61d8831 100644
--- a/src/chttpd/test/chttpd_dbs_info_test.erl
+++ b/src/chttpd/test/eunit/chttpd_dbs_info_test.erl
diff --git a/src/chttpd/test/chttpd_error_info_tests.erl b/src/chttpd/test/eunit/chttpd_error_info_tests.erl
index fdb015c08..fdb015c08 100644
--- a/src/chttpd/test/chttpd_error_info_tests.erl
+++ b/src/chttpd/test/eunit/chttpd_error_info_tests.erl
diff --git a/src/chttpd/test/chttpd_handlers_tests.erl b/src/chttpd/test/eunit/chttpd_handlers_tests.erl
index f3e8f5dcd..f3e8f5dcd 100644
--- a/src/chttpd/test/chttpd_handlers_tests.erl
+++ b/src/chttpd/test/eunit/chttpd_handlers_tests.erl
diff --git a/src/chttpd/test/chttpd_open_revs_error_test.erl b/src/chttpd/test/eunit/chttpd_open_revs_error_test.erl
index d53d370f8..d53d370f8 100644
--- a/src/chttpd/test/chttpd_open_revs_error_test.erl
+++ b/src/chttpd/test/eunit/chttpd_open_revs_error_test.erl
diff --git a/src/chttpd/test/chttpd_plugin_tests.erl b/src/chttpd/test/eunit/chttpd_plugin_tests.erl
index 36572a419..36572a419 100644
--- a/src/chttpd/test/chttpd_plugin_tests.erl
+++ b/src/chttpd/test/eunit/chttpd_plugin_tests.erl
diff --git a/src/chttpd/test/chttpd_prefer_header_test.erl b/src/chttpd/test/eunit/chttpd_prefer_header_test.erl
index 0f43ba437..0f43ba437 100644
--- a/src/chttpd/test/chttpd_prefer_header_test.erl
+++ b/src/chttpd/test/eunit/chttpd_prefer_header_test.erl
diff --git a/src/chttpd/test/chttpd_purge_tests.erl b/src/chttpd/test/eunit/chttpd_purge_tests.erl
index dbd73de1f..dbd73de1f 100644
--- a/src/chttpd/test/chttpd_purge_tests.erl
+++ b/src/chttpd/test/eunit/chttpd_purge_tests.erl
diff --git a/src/chttpd/test/chttpd_security_tests.erl b/src/chttpd/test/eunit/chttpd_security_tests.erl
index 955b4ff01..955b4ff01 100644
--- a/src/chttpd/test/chttpd_security_tests.erl
+++ b/src/chttpd/test/eunit/chttpd_security_tests.erl
diff --git a/src/chttpd/test/chttpd_socket_buffer_size_test.erl b/src/chttpd/test/eunit/chttpd_socket_buffer_size_test.erl
index 937880621..937880621 100644
--- a/src/chttpd/test/chttpd_socket_buffer_size_test.erl
+++ b/src/chttpd/test/eunit/chttpd_socket_buffer_size_test.erl
diff --git a/src/chttpd/test/chttpd_view_test.erl b/src/chttpd/test/eunit/chttpd_view_test.erl
index 3457c6f30..4c224bb4e 100644
--- a/src/chttpd/test/chttpd_view_test.erl
+++ b/src/chttpd/test/eunit/chttpd_view_test.erl
@@ -24,6 +24,7 @@
-define(FIXTURE_TXT, ?ABS_PATH(?FILE)).
-define(i2l(I), integer_to_list(I)).
+-define(TIMEOUT, 60). % seconds
setup() ->
Hashed = couch_passwords:hash_admin_password(?PASS),
@@ -71,7 +72,7 @@ all_view_test_() ->
should_succeed_on_view_with_queries_keys(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[create_doc(Url, "testdoc" ++ ?i2l(I)) || I <- lists:seq(1, 10)],
{ok, _, _, _} = test_request:put(Url ++ "/_design/bar",
[?CONTENT_JSON, ?AUTH], ?DDOC),
@@ -83,11 +84,11 @@ should_succeed_on_view_with_queries_keys(Url) ->
ResultJsonBody = couch_util:get_value(<<"results">>, ResultJson),
{InnerJson} = lists:nth(1, ResultJsonBody),
?assertEqual(2, length(couch_util:get_value(<<"rows">>, InnerJson)))
- end).
+ end)}.
should_succeed_on_view_with_queries_limit_skip(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[create_doc(Url, "testdoc" ++ ?i2l(I)) || I <- lists:seq(1, 10)],
{ok, _, _, _} = test_request:put(Url ++ "/_design/bar",
[?CONTENT_JSON, ?AUTH], ?DDOC),
@@ -100,11 +101,11 @@ should_succeed_on_view_with_queries_limit_skip(Url) ->
{InnerJson} = lists:nth(1, ResultJsonBody),
?assertEqual(2, couch_util:get_value(<<"offset">>, InnerJson)),
?assertEqual(5, length(couch_util:get_value(<<"rows">>, InnerJson)))
- end).
+ end)}.
should_succeed_on_view_with_multiple_queries(Url) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[create_doc(Url, "testdoc" ++ ?i2l(I)) || I <- lists:seq(1, 10)],
{ok, _, _, _} = test_request:put(Url ++ "/_design/bar",
[?CONTENT_JSON, ?AUTH], ?DDOC),
@@ -120,4 +121,4 @@ should_succeed_on_view_with_multiple_queries(Url) ->
{InnerJson2} = lists:nth(2, ResultJsonBody),
?assertEqual(2, couch_util:get_value(<<"offset">>, InnerJson2)),
?assertEqual(5, length(couch_util:get_value(<<"rows">>, InnerJson2)))
- end).
+ end)}.
diff --git a/src/chttpd/test/chttpd_welcome_test.erl b/src/chttpd/test/eunit/chttpd_welcome_test.erl
index e427f4dff..e427f4dff 100644
--- a/src/chttpd/test/chttpd_welcome_test.erl
+++ b/src/chttpd/test/eunit/chttpd_welcome_test.erl
diff --git a/src/chttpd/test/chttpd_xframe_test.erl b/src/chttpd/test/eunit/chttpd_xframe_test.erl
index 1272c198c..1272c198c 100644
--- a/src/chttpd/test/chttpd_xframe_test.erl
+++ b/src/chttpd/test/eunit/chttpd_xframe_test.erl
diff --git a/src/couch/include/couch_eunit.hrl b/src/couch/include/couch_eunit.hrl
index f4617e1d3..d3611c88b 100644
--- a/src/couch/include/couch_eunit.hrl
+++ b/src/couch/include/couch_eunit.hrl
@@ -28,7 +28,7 @@
filename:join([?BUILDDIR(), "tmp", "etc", "local_eunit.ini"]),
filename:join([?BUILDDIR(), "tmp", "etc", "eunit.ini"])]).
-define(FIXTURESDIR,
- filename:join([?BUILDDIR(), "src", "couch", "test", "fixtures"])).
+ filename:join([?BUILDDIR(), "src", "couch", "test", "eunit", "fixtures"])).
-define(TEMPDIR,
filename:join([?BUILDDIR(), "tmp", "tmp_data"])).
diff --git a/src/couch/src/couch_db.erl b/src/couch/src/couch_db.erl
index 52c3fbb76..6135813ae 100644
--- a/src/couch/src/couch_db.erl
+++ b/src/couch/src/couch_db.erl
@@ -594,9 +594,6 @@ get_db_info(Db) ->
{ok, DocCount} = get_doc_count(Db),
{ok, DelDocCount} = get_del_doc_count(Db),
SizeInfo = couch_db_engine:get_size_info(Db),
- FileSize = couch_util:get_value(file, SizeInfo, null),
- ActiveSize = couch_util:get_value(active, SizeInfo, null),
- ExternalSize = couch_util:get_value(external, SizeInfo, null),
DiskVersion = couch_db_engine:get_disk_version(Db),
Uuid = case get_uuid(Db) of
undefined -> null;
@@ -619,14 +616,6 @@ get_db_info(Db) ->
{purge_seq, couch_db_engine:get_purge_seq(Db)},
{compact_running, Compactor /= nil},
{sizes, {SizeInfo}},
- % TODO: Remove this in 3.0
- % These are legacy and have been duplicated under
- % the sizes key since 2.0. We should make a note
- % in our release notes that we'll remove these
- % old versions in 3.0
- {disk_size, FileSize}, % legacy
- {data_size, ActiveSize},
- {other, {[{data_size, ExternalSize}]}},
{instance_start_time, StartTime},
{disk_format_version, DiskVersion},
{committed_update_seq, CommittedUpdateSeq},
diff --git a/src/couch/src/couch_file.erl b/src/couch/src/couch_file.erl
index d6e4066db..6db23eaa3 100644
--- a/src/couch/src/couch_file.erl
+++ b/src/couch/src/couch_file.erl
@@ -215,12 +215,26 @@ truncate(Fd, Pos) ->
sync(Filepath) when is_list(Filepath) ->
case file:open(Filepath, [append, raw]) of
{ok, Fd} ->
- try ok = file:sync(Fd) after ok = file:close(Fd) end;
+ try
+ case file:sync(Fd) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ erlang:error({fsync_error, Reason})
+ end
+ after
+ ok = file:close(Fd)
+ end;
{error, Error} ->
erlang:error(Error)
end;
sync(Fd) ->
- gen_server:call(Fd, sync, infinity).
+ case gen_server:call(Fd, sync, infinity) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ erlang:error({fsync_error, Reason})
+ end.
%%----------------------------------------------------------------------
%% Purpose: Close the file.
@@ -462,7 +476,16 @@ handle_call({set_db_pid, Pid}, _From, #file{db_monitor=OldRef}=File) ->
{reply, ok, File#file{db_monitor=Ref}};
handle_call(sync, _From, #file{fd=Fd}=File) ->
- {reply, file:sync(Fd), File};
+ case file:sync(Fd) of
+ ok ->
+ {reply, ok, File};
+ {error, _} = Error ->
+ % We're intentionally dropping all knowledge
+ % of this Fd so that we don't accidentally
+ % recover in some whacky edge case that I
+ % can't fathom.
+ {stop, Error, Error, #file{fd = nil}}
+ end;
handle_call({truncate, Pos}, _From, #file{fd=Fd}=File) ->
{ok, Pos} = file:position(Fd, Pos),
diff --git a/src/couch/test/chttpd_endpoints_tests.erl b/src/couch/test/eunit/chttpd_endpoints_tests.erl
index 9b7430823..9b7430823 100644
--- a/src/couch/test/chttpd_endpoints_tests.erl
+++ b/src/couch/test/eunit/chttpd_endpoints_tests.erl
diff --git a/src/couch/test/couch_auth_cache_tests.erl b/src/couch/test/eunit/couch_auth_cache_tests.erl
index 706c0cee9..706c0cee9 100644
--- a/src/couch/test/couch_auth_cache_tests.erl
+++ b/src/couch/test/eunit/couch_auth_cache_tests.erl
diff --git a/src/couch/test/couch_base32_tests.erl b/src/couch/test/eunit/couch_base32_tests.erl
index 7e4d59a09..7e4d59a09 100644
--- a/src/couch/test/couch_base32_tests.erl
+++ b/src/couch/test/eunit/couch_base32_tests.erl
diff --git a/src/couch/test/couch_bt_engine_compactor_tests.erl b/src/couch/test/eunit/couch_bt_engine_compactor_tests.erl
index 6c99ceb73..6c99ceb73 100644
--- a/src/couch/test/couch_bt_engine_compactor_tests.erl
+++ b/src/couch/test/eunit/couch_bt_engine_compactor_tests.erl
diff --git a/src/couch/test/couch_bt_engine_tests.erl b/src/couch/test/eunit/couch_bt_engine_tests.erl
index 3e3ecbf25..3e3ecbf25 100644
--- a/src/couch/test/couch_bt_engine_tests.erl
+++ b/src/couch/test/eunit/couch_bt_engine_tests.erl
diff --git a/src/couch/test/couch_bt_engine_upgrade_tests.erl b/src/couch/test/eunit/couch_bt_engine_upgrade_tests.erl
index 3a516f8f7..a2a972caf 100644
--- a/src/couch/test/couch_bt_engine_upgrade_tests.erl
+++ b/src/couch/test/eunit/couch_bt_engine_upgrade_tests.erl
@@ -15,6 +15,7 @@
-include_lib("couch/include/couch_eunit.hrl").
-include_lib("couch/include/couch_db.hrl").
+-define(TIMEOUT, 60). % seconds
setup(_) ->
Ctx = test_util:start_couch(),
@@ -63,7 +64,7 @@ upgrade_test_() ->
t_upgrade_without_purge_req(VersionFrom, {_Ctx, _NewPaths}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
% There are three documents in the fixture
% db with zero purge entries
DbName = ?l2b("db_v" ++ integer_to_list(VersionFrom)
@@ -99,11 +100,11 @@ t_upgrade_without_purge_req(VersionFrom, {_Ctx, _NewPaths}) ->
?assertEqual({ok, 4}, couch_db:get_doc_count(Db)),
?assertEqual(1, couch_db:get_purge_seq(Db))
end)
- end).
+ end)}.
t_upgrade_with_1_purge_req(VersionFrom, {_Ctx, _NewPaths}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
% There are two documents in the fixture database
% with a single purge entry
DbName = ?l2b("db_v" ++ integer_to_list(VersionFrom)
@@ -140,11 +141,11 @@ t_upgrade_with_1_purge_req(VersionFrom, {_Ctx, _NewPaths}) ->
?assertEqual({ok, 3}, couch_db:get_doc_count(Db)),
?assertEqual(2, couch_db:get_purge_seq(Db))
end)
- end).
+ end)}.
t_upgrade_with_N_purge_req(VersionFrom, {_Ctx, _NewPaths}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
% There is one document in the fixture database
% with two docs that have been purged
DbName = ?l2b("db_v" ++ integer_to_list(VersionFrom)
@@ -179,11 +180,11 @@ t_upgrade_with_N_purge_req(VersionFrom, {_Ctx, _NewPaths}) ->
?assertEqual({ok, 2}, couch_db:get_doc_count(Db)),
?assertEqual(3, couch_db:get_purge_seq(Db))
end)
- end).
+ end)}.
t_upgrade_with_1_purge_req_for_2_docs(VersionFrom, {_Ctx, _NewPaths}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
% There are two documents (Doc4 and Doc5) in the fixture database
% with three docs (Doc1, Doc2 and Doc3) that have been purged, and
% with one purge req for Doc1 and another purge req for Doc 2 and Doc3
@@ -219,7 +220,7 @@ t_upgrade_with_1_purge_req_for_2_docs(VersionFrom, {_Ctx, _NewPaths}) ->
?assertEqual({ok, 3}, couch_db:get_doc_count(Db)),
?assertEqual(4, couch_db:get_purge_seq(Db))
end)
- end).
+ end)}.
save_doc(DbName, Json) ->
diff --git a/src/couch/test/couch_btree_tests.erl b/src/couch/test/eunit/couch_btree_tests.erl
index 3c8840a60..c9b791d2c 100644
--- a/src/couch/test/couch_btree_tests.erl
+++ b/src/couch/test/eunit/couch_btree_tests.erl
@@ -16,6 +16,7 @@
-include_lib("couch/include/couch_db.hrl").
-define(ROWS, 1000).
+-define(TIMEOUT, 60). % seconds
setup() ->
@@ -276,7 +277,9 @@ should_add_every_odd_key_remove_every_even(KeyValues, {_, Btree}) ->
false -> {Count + 1, Left, [X | Right]}
end
end, {0, [], []}, KeyValues),
- ?_assert(test_add_remove(Btree1, Rem2Keys0, Rem2Keys1)).
+ {timeout, ?TIMEOUT,
+ ?_assert(test_add_remove(Btree1, Rem2Keys0, Rem2Keys1))
+ }.
should_add_every_even_key_remove_every_old(KeyValues, {_, Btree}) ->
{ok, Btree1} = couch_btree:add_remove(Btree, KeyValues, []),
@@ -286,7 +289,9 @@ should_add_every_even_key_remove_every_old(KeyValues, {_, Btree}) ->
false -> {Count + 1, Left, [X | Right]}
end
end, {0, [], []}, KeyValues),
- ?_assert(test_add_remove(Btree1, Rem2Keys1, Rem2Keys0)).
+ {timeout, ?TIMEOUT,
+ ?_assert(test_add_remove(Btree1, Rem2Keys1, Rem2Keys0))
+ }.
should_reduce_without_specified_direction({_, Btree}) ->
diff --git a/src/couch/test/couch_changes_tests.erl b/src/couch/test/eunit/couch_changes_tests.erl
index 0c2f5f91f..0c2f5f91f 100644
--- a/src/couch/test/couch_changes_tests.erl
+++ b/src/couch/test/eunit/couch_changes_tests.erl
diff --git a/src/couch/test/couch_compress_tests.erl b/src/couch/test/eunit/couch_compress_tests.erl
index addb9a0e2..addb9a0e2 100644
--- a/src/couch/test/couch_compress_tests.erl
+++ b/src/couch/test/eunit/couch_compress_tests.erl
diff --git a/src/couch/test/couch_db_doc_tests.erl b/src/couch/test/eunit/couch_db_doc_tests.erl
index cdcf81d15..cdcf81d15 100644
--- a/src/couch/test/couch_db_doc_tests.erl
+++ b/src/couch/test/eunit/couch_db_doc_tests.erl
diff --git a/src/couch/test/couch_db_mpr_tests.erl b/src/couch/test/eunit/couch_db_mpr_tests.erl
index bb97c66d7..bb97c66d7 100644
--- a/src/couch/test/couch_db_mpr_tests.erl
+++ b/src/couch/test/eunit/couch_db_mpr_tests.erl
diff --git a/src/couch/test/couch_db_plugin_tests.erl b/src/couch/test/eunit/couch_db_plugin_tests.erl
index 93551adbc..93551adbc 100644
--- a/src/couch/test/couch_db_plugin_tests.erl
+++ b/src/couch/test/eunit/couch_db_plugin_tests.erl
diff --git a/src/couch/test/couch_db_props_upgrade_tests.erl b/src/couch/test/eunit/couch_db_props_upgrade_tests.erl
index 40ad283cf..40ad283cf 100644
--- a/src/couch/test/couch_db_props_upgrade_tests.erl
+++ b/src/couch/test/eunit/couch_db_props_upgrade_tests.erl
diff --git a/src/couch/test/couch_db_split_tests.erl b/src/couch/test/eunit/couch_db_split_tests.erl
index 7d2bb4006..312b5f84d 100644
--- a/src/couch/test/couch_db_split_tests.erl
+++ b/src/couch/test/eunit/couch_db_split_tests.erl
@@ -16,6 +16,7 @@
-include_lib("couch/include/couch_db.hrl").
-define(RINGTOP, 2 bsl 31).
+-define(TIMEOUT, 60). % seconds
setup() ->
@@ -68,7 +69,7 @@ should_split_shard({Desc, TotalDocs, Q}, DbName) ->
TMap = make_targets(Ranges),
DocsPerRange = TotalDocs div Q,
PickFun = make_pickfun(DocsPerRange),
- {Desc, ?_test(begin
+ {Desc, timeout, ?TIMEOUT, ?_test(begin
{ok, UpdateSeq} = couch_db_split:split(DbName, TMap, PickFun),
?assertEqual(ExpectSeq, UpdateSeq),
maps:map(fun(Range, Name) ->
@@ -154,7 +155,7 @@ should_copy_local_docs({Desc, TotalDocs, Q}, DbName) ->
TMap = make_targets(Ranges),
DocsPerRange = TotalDocs div Q,
PickFun = make_pickfun(DocsPerRange),
- {Desc, ?_test(begin
+ {Desc, timeout, ?TIMEOUT, ?_test(begin
{ok, UpdateSeq} = couch_db_split:split(DbName, TMap, PickFun),
?assertEqual(ExpectSeq, UpdateSeq),
Response = couch_db_split:copy_local_docs(DbName, TMap, PickFun),
diff --git a/src/couch/test/couch_db_tests.erl b/src/couch/test/eunit/couch_db_tests.erl
index d64f7c640..d64f7c640 100644
--- a/src/couch/test/couch_db_tests.erl
+++ b/src/couch/test/eunit/couch_db_tests.erl
diff --git a/src/couch/test/couch_doc_json_tests.erl b/src/couch/test/eunit/couch_doc_json_tests.erl
index 51f228900..51f228900 100644
--- a/src/couch/test/couch_doc_json_tests.erl
+++ b/src/couch/test/eunit/couch_doc_json_tests.erl
diff --git a/src/couch/test/couch_doc_tests.erl b/src/couch/test/eunit/couch_doc_tests.erl
index cf41df61d..cf41df61d 100644
--- a/src/couch/test/couch_doc_tests.erl
+++ b/src/couch/test/eunit/couch_doc_tests.erl
diff --git a/src/couch/test/couch_ejson_size_tests.erl b/src/couch/test/eunit/couch_ejson_size_tests.erl
index df9168ed1..df9168ed1 100644
--- a/src/couch/test/couch_ejson_size_tests.erl
+++ b/src/couch/test/eunit/couch_ejson_size_tests.erl
diff --git a/src/couch/test/couch_etag_tests.erl b/src/couch/test/eunit/couch_etag_tests.erl
index 9d15e483f..9d15e483f 100644
--- a/src/couch/test/couch_etag_tests.erl
+++ b/src/couch/test/eunit/couch_etag_tests.erl
diff --git a/src/couch/test/couch_file_tests.erl b/src/couch/test/eunit/couch_file_tests.erl
index 34c1a1654..e9806c09a 100644
--- a/src/couch/test/couch_file_tests.erl
+++ b/src/couch/test/eunit/couch_file_tests.erl
@@ -498,3 +498,36 @@ make_delete_dir_test_case({RootDir, ViewDir}, DeleteAfterRename) ->
remove_dir(Dir) ->
[file:delete(File) || File <- filelib:wildcard(filename:join([Dir, "*"]))],
file:del_dir(Dir).
+
+
+fsync_error_test_() ->
+ {
+ "Test fsync raises errors",
+ {
+ setup,
+ fun() ->
+ test_util:start(?MODULE, [ioq])
+ end,
+ fun(Ctx) ->
+ test_util:stop(Ctx)
+ end,
+ [
+ fun fsync_raises_errors/0
+ ]
+ }
+ }.
+
+
+fsync_raises_errors() ->
+ Fd = spawn(fun() -> fake_fsync_fd() end),
+ ?assertError({fsync_error, eio}, couch_file:sync(Fd)).
+
+
+fake_fsync_fd() ->
+ % Mocking gen_server did not go very
+ % well so faking the couch_file pid
+ % will have to do.
+ receive
+ {'$gen_call', From, sync} ->
+ gen:reply(From, {error, eio})
+ end.
diff --git a/src/couch/test/couch_flags_config_tests.erl b/src/couch/test/eunit/couch_flags_config_tests.erl
index 1a66cdcff..1a66cdcff 100644
--- a/src/couch/test/couch_flags_config_tests.erl
+++ b/src/couch/test/eunit/couch_flags_config_tests.erl
diff --git a/src/couch/test/couch_flags_tests.erl b/src/couch/test/eunit/couch_flags_tests.erl
index 32ec57b77..32ec57b77 100644
--- a/src/couch/test/couch_flags_tests.erl
+++ b/src/couch/test/eunit/couch_flags_tests.erl
diff --git a/src/couch/test/couch_hotp_tests.erl b/src/couch/test/eunit/couch_hotp_tests.erl
index fee10ff5e..fee10ff5e 100644
--- a/src/couch/test/couch_hotp_tests.erl
+++ b/src/couch/test/eunit/couch_hotp_tests.erl
diff --git a/src/couch/test/couch_index_tests.erl b/src/couch/test/eunit/couch_index_tests.erl
index fab3806d0..fab3806d0 100644
--- a/src/couch/test/couch_index_tests.erl
+++ b/src/couch/test/eunit/couch_index_tests.erl
diff --git a/src/couch/test/couch_key_tree_prop_tests.erl b/src/couch/test/eunit/couch_key_tree_prop_tests.erl
index f8146926a..f8146926a 100644
--- a/src/couch/test/couch_key_tree_prop_tests.erl
+++ b/src/couch/test/eunit/couch_key_tree_prop_tests.erl
diff --git a/src/couch/test/couch_key_tree_tests.erl b/src/couch/test/eunit/couch_key_tree_tests.erl
index 5d9cc8372..5d9cc8372 100644
--- a/src/couch/test/couch_key_tree_tests.erl
+++ b/src/couch/test/eunit/couch_key_tree_tests.erl
diff --git a/src/couch/test/couch_passwords_tests.erl b/src/couch/test/eunit/couch_passwords_tests.erl
index dea6d6b7b..88de8530f 100644
--- a/src/couch/test/couch_passwords_tests.erl
+++ b/src/couch/test/eunit/couch_passwords_tests.erl
@@ -46,7 +46,7 @@ pbkdf2_test_()->
<<"sa\0lt">>,
4096, 16))},
- {timeout, 180, %% this may runs too long on slow hosts
+ {timeout, 600, %% this may runs too long on slow hosts
{"Iterations: 16777216 - this may take some time",
?_assertEqual(
{ok, <<"eefe3d61cd4da4e4e9945b3d6ba2158c2634e984">>},
diff --git a/src/couch/test/couch_query_servers_tests.erl b/src/couch/test/eunit/couch_query_servers_tests.erl
index f8df896c4..f8df896c4 100644
--- a/src/couch/test/couch_query_servers_tests.erl
+++ b/src/couch/test/eunit/couch_query_servers_tests.erl
diff --git a/src/couch/test/couch_server_tests.erl b/src/couch/test/eunit/couch_server_tests.erl
index 530b7efd0..530b7efd0 100644
--- a/src/couch/test/couch_server_tests.erl
+++ b/src/couch/test/eunit/couch_server_tests.erl
diff --git a/src/couch/test/couch_stream_tests.erl b/src/couch/test/eunit/couch_stream_tests.erl
index a7fedf0af..a7fedf0af 100644
--- a/src/couch/test/couch_stream_tests.erl
+++ b/src/couch/test/eunit/couch_stream_tests.erl
diff --git a/src/couch/test/couch_task_status_tests.erl b/src/couch/test/eunit/couch_task_status_tests.erl
index 0ec03563b..0ec03563b 100644
--- a/src/couch/test/couch_task_status_tests.erl
+++ b/src/couch/test/eunit/couch_task_status_tests.erl
diff --git a/src/couch/test/couch_totp_tests.erl b/src/couch/test/eunit/couch_totp_tests.erl
index 6817a092a..6817a092a 100644
--- a/src/couch/test/couch_totp_tests.erl
+++ b/src/couch/test/eunit/couch_totp_tests.erl
diff --git a/src/couch/test/couch_util_tests.erl b/src/couch/test/eunit/couch_util_tests.erl
index 3e145c4f6..3e145c4f6 100644
--- a/src/couch/test/couch_util_tests.erl
+++ b/src/couch/test/eunit/couch_util_tests.erl
diff --git a/src/couch/test/couch_uuids_tests.erl b/src/couch/test/eunit/couch_uuids_tests.erl
index a836eccc6..a836eccc6 100644
--- a/src/couch/test/couch_uuids_tests.erl
+++ b/src/couch/test/eunit/couch_uuids_tests.erl
diff --git a/src/couch/test/couch_work_queue_tests.erl b/src/couch/test/eunit/couch_work_queue_tests.erl
index a192230ef..a192230ef 100644
--- a/src/couch/test/couch_work_queue_tests.erl
+++ b/src/couch/test/eunit/couch_work_queue_tests.erl
diff --git a/src/couch/test/couchdb_attachments_tests.erl b/src/couch/test/eunit/couchdb_attachments_tests.erl
index 04859dbc9..04859dbc9 100644
--- a/src/couch/test/couchdb_attachments_tests.erl
+++ b/src/couch/test/eunit/couchdb_attachments_tests.erl
diff --git a/src/couch/test/couchdb_auth_tests.erl b/src/couch/test/eunit/couchdb_auth_tests.erl
index ed2c064de..ed2c064de 100644
--- a/src/couch/test/couchdb_auth_tests.erl
+++ b/src/couch/test/eunit/couchdb_auth_tests.erl
diff --git a/src/couch/test/couchdb_cookie_domain_tests.erl b/src/couch/test/eunit/couchdb_cookie_domain_tests.erl
index e66ab31e6..e66ab31e6 100755
--- a/src/couch/test/couchdb_cookie_domain_tests.erl
+++ b/src/couch/test/eunit/couchdb_cookie_domain_tests.erl
diff --git a/src/couch/test/couchdb_cors_tests.erl b/src/couch/test/eunit/couchdb_cors_tests.erl
index 82630bba7..82630bba7 100644
--- a/src/couch/test/couchdb_cors_tests.erl
+++ b/src/couch/test/eunit/couchdb_cors_tests.erl
diff --git a/src/couch/test/couchdb_db_tests.erl b/src/couch/test/eunit/couchdb_db_tests.erl
index 734bafb9f..734bafb9f 100644
--- a/src/couch/test/couchdb_db_tests.erl
+++ b/src/couch/test/eunit/couchdb_db_tests.erl
diff --git a/src/couch/test/couchdb_design_doc_tests.erl b/src/couch/test/eunit/couchdb_design_doc_tests.erl
index eef12e039..eef12e039 100644
--- a/src/couch/test/couchdb_design_doc_tests.erl
+++ b/src/couch/test/eunit/couchdb_design_doc_tests.erl
diff --git a/src/couch/test/couchdb_file_compression_tests.erl b/src/couch/test/eunit/couchdb_file_compression_tests.erl
index 8f0fe5bf1..8f0fe5bf1 100644
--- a/src/couch/test/couchdb_file_compression_tests.erl
+++ b/src/couch/test/eunit/couchdb_file_compression_tests.erl
diff --git a/src/couch/test/couchdb_location_header_tests.erl b/src/couch/test/eunit/couchdb_location_header_tests.erl
index c6c039eb0..c6c039eb0 100644
--- a/src/couch/test/couchdb_location_header_tests.erl
+++ b/src/couch/test/eunit/couchdb_location_header_tests.erl
diff --git a/src/couch/test/couchdb_mrview_cors_tests.erl b/src/couch/test/eunit/couchdb_mrview_cors_tests.erl
index 0f69048a0..0f69048a0 100644
--- a/src/couch/test/couchdb_mrview_cors_tests.erl
+++ b/src/couch/test/eunit/couchdb_mrview_cors_tests.erl
diff --git a/src/couch/test/couchdb_mrview_tests.erl b/src/couch/test/eunit/couchdb_mrview_tests.erl
index 1c96a0ae0..1c96a0ae0 100644
--- a/src/couch/test/couchdb_mrview_tests.erl
+++ b/src/couch/test/eunit/couchdb_mrview_tests.erl
diff --git a/src/couch/test/couchdb_os_proc_pool.erl b/src/couch/test/eunit/couchdb_os_proc_pool.erl
index 69f8051ad..69f8051ad 100644
--- a/src/couch/test/couchdb_os_proc_pool.erl
+++ b/src/couch/test/eunit/couchdb_os_proc_pool.erl
diff --git a/src/couch/test/couchdb_update_conflicts_tests.erl b/src/couch/test/eunit/couchdb_update_conflicts_tests.erl
index e92c73856..e92c73856 100644
--- a/src/couch/test/couchdb_update_conflicts_tests.erl
+++ b/src/couch/test/eunit/couchdb_update_conflicts_tests.erl
diff --git a/src/couch/test/couchdb_vhosts_tests.erl b/src/couch/test/eunit/couchdb_vhosts_tests.erl
index 1c4117215..1c4117215 100644
--- a/src/couch/test/couchdb_vhosts_tests.erl
+++ b/src/couch/test/eunit/couchdb_vhosts_tests.erl
diff --git a/src/couch/test/couchdb_views_tests.erl b/src/couch/test/eunit/couchdb_views_tests.erl
index 60bb5c975..60bb5c975 100644
--- a/src/couch/test/couchdb_views_tests.erl
+++ b/src/couch/test/eunit/couchdb_views_tests.erl
diff --git a/src/couch/test/fixtures/3b835456c235b1827e012e25666152f3.view b/src/couch/test/eunit/fixtures/3b835456c235b1827e012e25666152f3.view
index 9c67648be..9c67648be 100644
--- a/src/couch/test/fixtures/3b835456c235b1827e012e25666152f3.view
+++ b/src/couch/test/eunit/fixtures/3b835456c235b1827e012e25666152f3.view
Binary files differ
diff --git a/src/couch/test/fixtures/couch_stats_aggregates.cfg b/src/couch/test/eunit/fixtures/couch_stats_aggregates.cfg
index 30e475da8..30e475da8 100644
--- a/src/couch/test/fixtures/couch_stats_aggregates.cfg
+++ b/src/couch/test/eunit/fixtures/couch_stats_aggregates.cfg
diff --git a/src/couch/test/fixtures/couch_stats_aggregates.ini b/src/couch/test/eunit/fixtures/couch_stats_aggregates.ini
index cc5cd2187..cc5cd2187 100644
--- a/src/couch/test/fixtures/couch_stats_aggregates.ini
+++ b/src/couch/test/eunit/fixtures/couch_stats_aggregates.ini
diff --git a/src/couch/test/fixtures/db_non_partitioned.couch b/src/couch/test/eunit/fixtures/db_non_partitioned.couch
index 327d9bb5d..327d9bb5d 100644
--- a/src/couch/test/fixtures/db_non_partitioned.couch
+++ b/src/couch/test/eunit/fixtures/db_non_partitioned.couch
Binary files differ
diff --git a/src/couch/test/fixtures/db_v6_with_1_purge_req.couch b/src/couch/test/eunit/fixtures/db_v6_with_1_purge_req.couch
index b0d39c9ec..b0d39c9ec 100644
--- a/src/couch/test/fixtures/db_v6_with_1_purge_req.couch
+++ b/src/couch/test/eunit/fixtures/db_v6_with_1_purge_req.couch
Binary files differ
diff --git a/src/couch/test/fixtures/db_v6_with_1_purge_req_for_2_docs.couch b/src/couch/test/eunit/fixtures/db_v6_with_1_purge_req_for_2_docs.couch
index b584fce31..b584fce31 100644
--- a/src/couch/test/fixtures/db_v6_with_1_purge_req_for_2_docs.couch
+++ b/src/couch/test/eunit/fixtures/db_v6_with_1_purge_req_for_2_docs.couch
Binary files differ
diff --git a/src/couch/test/fixtures/db_v6_with_2_purge_req.couch b/src/couch/test/eunit/fixtures/db_v6_with_2_purge_req.couch
index ee4e11b7f..ee4e11b7f 100644
--- a/src/couch/test/fixtures/db_v6_with_2_purge_req.couch
+++ b/src/couch/test/eunit/fixtures/db_v6_with_2_purge_req.couch
Binary files differ
diff --git a/src/couch/test/fixtures/db_v6_without_purge_req.couch b/src/couch/test/eunit/fixtures/db_v6_without_purge_req.couch
index 814feb8e1..814feb8e1 100644
--- a/src/couch/test/fixtures/db_v6_without_purge_req.couch
+++ b/src/couch/test/eunit/fixtures/db_v6_without_purge_req.couch
Binary files differ
diff --git a/src/couch/test/fixtures/db_v7_with_1_purge_req.couch b/src/couch/test/eunit/fixtures/db_v7_with_1_purge_req.couch
index cab8331db..cab8331db 100644
--- a/src/couch/test/fixtures/db_v7_with_1_purge_req.couch
+++ b/src/couch/test/eunit/fixtures/db_v7_with_1_purge_req.couch
Binary files differ
diff --git a/src/couch/test/fixtures/db_v7_with_1_purge_req_for_2_docs.couch b/src/couch/test/eunit/fixtures/db_v7_with_1_purge_req_for_2_docs.couch
index b613646b1..b613646b1 100644
--- a/src/couch/test/fixtures/db_v7_with_1_purge_req_for_2_docs.couch
+++ b/src/couch/test/eunit/fixtures/db_v7_with_1_purge_req_for_2_docs.couch
Binary files differ
diff --git a/src/couch/test/fixtures/db_v7_with_2_purge_req.couch b/src/couch/test/eunit/fixtures/db_v7_with_2_purge_req.couch
index 126fc919e..126fc919e 100644
--- a/src/couch/test/fixtures/db_v7_with_2_purge_req.couch
+++ b/src/couch/test/eunit/fixtures/db_v7_with_2_purge_req.couch
Binary files differ
diff --git a/src/couch/test/fixtures/db_v7_without_purge_req.couch b/src/couch/test/eunit/fixtures/db_v7_without_purge_req.couch
index 762dc8dad..762dc8dad 100644
--- a/src/couch/test/fixtures/db_v7_without_purge_req.couch
+++ b/src/couch/test/eunit/fixtures/db_v7_without_purge_req.couch
Binary files differ
diff --git a/src/couch/test/fixtures/logo.png b/src/couch/test/eunit/fixtures/logo.png
index d21ac025b..d21ac025b 100644
--- a/src/couch/test/fixtures/logo.png
+++ b/src/couch/test/eunit/fixtures/logo.png
Binary files differ
diff --git a/src/couch/test/fixtures/multipart.http b/src/couch/test/eunit/fixtures/multipart.http
index fe9f271cc..fe9f271cc 100644
--- a/src/couch/test/fixtures/multipart.http
+++ b/src/couch/test/eunit/fixtures/multipart.http
diff --git a/src/couch/test/fixtures/os_daemon_bad_perm.sh b/src/couch/test/eunit/fixtures/os_daemon_bad_perm.sh
index 345c8b40b..345c8b40b 100644
--- a/src/couch/test/fixtures/os_daemon_bad_perm.sh
+++ b/src/couch/test/eunit/fixtures/os_daemon_bad_perm.sh
diff --git a/src/couch/test/fixtures/os_daemon_can_reboot.sh b/src/couch/test/eunit/fixtures/os_daemon_can_reboot.sh
index 5bc10e83f..5bc10e83f 100755
--- a/src/couch/test/fixtures/os_daemon_can_reboot.sh
+++ b/src/couch/test/eunit/fixtures/os_daemon_can_reboot.sh
diff --git a/src/couch/test/fixtures/os_daemon_configer.escript b/src/couch/test/eunit/fixtures/os_daemon_configer.escript
index f146b8314..f146b8314 100755
--- a/src/couch/test/fixtures/os_daemon_configer.escript
+++ b/src/couch/test/eunit/fixtures/os_daemon_configer.escript
diff --git a/src/couch/test/fixtures/os_daemon_die_on_boot.sh b/src/couch/test/eunit/fixtures/os_daemon_die_on_boot.sh
index 256ee7935..256ee7935 100755
--- a/src/couch/test/fixtures/os_daemon_die_on_boot.sh
+++ b/src/couch/test/eunit/fixtures/os_daemon_die_on_boot.sh
diff --git a/src/couch/test/fixtures/os_daemon_die_quickly.sh b/src/couch/test/eunit/fixtures/os_daemon_die_quickly.sh
index f5a13684e..f5a13684e 100755
--- a/src/couch/test/fixtures/os_daemon_die_quickly.sh
+++ b/src/couch/test/eunit/fixtures/os_daemon_die_quickly.sh
diff --git a/src/couch/test/fixtures/os_daemon_looper.escript b/src/couch/test/eunit/fixtures/os_daemon_looper.escript
index 73974e905..73974e905 100755
--- a/src/couch/test/fixtures/os_daemon_looper.escript
+++ b/src/couch/test/eunit/fixtures/os_daemon_looper.escript
diff --git a/src/couch/test/fixtures/test.couch b/src/couch/test/eunit/fixtures/test.couch
index 32c79af32..32c79af32 100644
--- a/src/couch/test/fixtures/test.couch
+++ b/src/couch/test/eunit/fixtures/test.couch
Binary files differ
diff --git a/src/couch/test/global_changes_tests.erl b/src/couch/test/eunit/global_changes_tests.erl
index 4392aafac..4392aafac 100644
--- a/src/couch/test/global_changes_tests.erl
+++ b/src/couch/test/eunit/global_changes_tests.erl
diff --git a/src/couch/test/json_stream_parse_tests.erl b/src/couch/test/eunit/json_stream_parse_tests.erl
index e690d7728..e690d7728 100644
--- a/src/couch/test/json_stream_parse_tests.erl
+++ b/src/couch/test/eunit/json_stream_parse_tests.erl
diff --git a/src/couch/test/test_web.erl b/src/couch/test/eunit/test_web.erl
index b1b3e65c9..b1b3e65c9 100644
--- a/src/couch/test/test_web.erl
+++ b/src/couch/test/eunit/test_web.erl
diff --git a/src/couch/test/exunit/fabric_test.exs b/src/couch/test/exunit/fabric_test.exs
new file mode 100644
index 000000000..bdb84e9a2
--- /dev/null
+++ b/src/couch/test/exunit/fabric_test.exs
@@ -0,0 +1,101 @@
+defmodule Couch.Test.Fabric do
+ use Couch.Test.ExUnit.Case
+ alias Couch.Test.Utils
+
+ alias Couch.Test.Setup
+
+ alias Couch.Test.Setup.Step
+
+ import Couch.DBTest
+
+ import Utils
+
+ @admin {:user_ctx, user_ctx(roles: ["_admin"])}
+
+ def with_db(context, setup) do
+ setup =
+ setup
+ |> Setup.Common.with_db()
+ |> Setup.run()
+
+ context =
+ Map.merge(context, %{
+ db_name: setup |> Setup.get(:db) |> Step.Create.DB.name()
+ })
+
+ {context, setup}
+ end
+
+ describe "Fabric miscellaneous API" do
+ @describetag setup: &__MODULE__.with_db/2
+ test "Get inactive_index_files", ctx do
+ {:ok, _rev} = update_doc(ctx.db_name, %{"_id" => "doc1"})
+
+ design_doc = %{
+ "_id" => "_design/test",
+ "language" => "javascript",
+ "views" => %{
+ "view" => %{
+ "map" => "function(doc){emit(doc._id, doc._rev)}"
+ }
+ }
+ }
+
+ {:ok, rev1} = update_doc(ctx.db_name, design_doc)
+ wait_sig_update(ctx.db_name, "test", "")
+ prev_active = get_active_sig(ctx.db_name, "test")
+
+ updated_design_doc =
+ put_in(design_doc, ["views", "view", "map"], "function(doc){emit(doc._id, null)}")
+
+ {:ok, rev2} =
+ update_doc(
+ ctx.db_name,
+ Map.put(updated_design_doc, "_rev", rev1)
+ )
+
+ assert rev1 != rev2
+ wait_sig_update(ctx.db_name, "test", prev_active)
+
+ {:ok, info} = :fabric.get_view_group_info(ctx.db_name, "_design/test")
+ active = info[:signature]
+
+ files = Enum.map(:fabric.inactive_index_files(ctx.db_name), &List.to_string/1)
+
+ assert [] != files, "We should have some inactive"
+
+ assert not Enum.any?(files, fn
+ file_path -> String.contains?(file_path, active)
+ end),
+ "We are not suppose to return active views"
+
+ assert Enum.all?(files, fn
+ file_path -> String.contains?(file_path, prev_active)
+ end),
+ "We expect all files to contain previous active signature"
+ end
+ end
+
+ defp update_doc(db_name, body) do
+ json_body = :jiffy.decode(:jiffy.encode(body))
+
+ case :fabric.update_doc(db_name, json_body, [@admin]) do
+ {:ok, rev} ->
+ {:ok, :couch_doc.rev_to_str(rev)}
+
+ error ->
+ error
+ end
+ end
+
+ defp get_active_sig(db_name, ddoc_id) do
+ {:ok, info} = :fabric.get_view_group_info(db_name, "_design/#{ddoc_id}")
+ info[:signature]
+ end
+
+ defp wait_sig_update(db_name, ddoc_id, prev_active) do
+ retry_until(fn ->
+ get_active_sig(db_name, ddoc_id) != prev_active
+ end)
+ end
+end
diff --git a/src/couch/test/exunit/test_helper.exs b/src/couch/test/exunit/test_helper.exs
new file mode 100644
index 000000000..314050085
--- /dev/null
+++ b/src/couch/test/exunit/test_helper.exs
@@ -0,0 +1,2 @@
+ExUnit.configure(formatters: [JUnitFormatter, ExUnit.CLIFormatter])
+ExUnit.start()
diff --git a/src/couch_epi/src/couch_epi_sup.erl b/src/couch_epi/src/couch_epi_sup.erl
index 218db5445..477cbe79e 100644
--- a/src/couch_epi/src/couch_epi_sup.erl
+++ b/src/couch_epi/src/couch_epi_sup.erl
@@ -136,4 +136,7 @@ modules(#couch_epi_spec{kind = data_subscriptions, behaviour = Module}) ->
merge([], Children) ->
Children;
merge([{Id, _, _, _, _, _} = Spec | Rest], Children) ->
- merge(Rest, lists:keystore(Id, 1, Children, Spec)).
+ merge(Rest, lists:keystore(Id, 1, Children, Spec));
+merge([#{id := Id} = Spec | Rest], Children) ->
+ Replace = fun(#{id := I}) when I == Id -> Spec; (E) -> E end,
+ merge(Rest, lists:map(Replace, Children)).
diff --git a/src/couch_epi/test/couch_epi_basic_test.erl b/src/couch_epi/test/eunit/couch_epi_basic_test.erl
index 587d1564e..5ba6c9f87 100644
--- a/src/couch_epi/test/couch_epi_basic_test.erl
+++ b/src/couch_epi/test/eunit/couch_epi_basic_test.erl
@@ -67,7 +67,9 @@ processes() ->
[
{?MODULE, [?CHILD(extra_process, worker)]},
{?MODULE, [{to_replace, {new, start_link, [bar]},
- permanent, 5000, worker, [bar]}]}
+ permanent, 5000, worker, [bar]}]},
+ {?MODULE, [#{id => to_replace_map,
+ start => {new, start_link, [bar]}, modules => [bar]}]}
].
@@ -95,9 +97,10 @@ parse_child_id(Id) ->
-include_lib("eunit/include/eunit.hrl").
basic_test() ->
- Expected = lists:sort([
+ Expected = [
{extra_process, [], [extra_process]},
{to_replace, [bar], [bar]},
+ {to_replace_map, [bar], [bar]},
{{my_service, providers},
[couch_epi_functions_gen_my_service],
[couch_epi_codechange_monitor, couch_epi_functions_gen_my_service,
@@ -114,18 +117,23 @@ basic_test() ->
[couch_epi_data_gen_test_app_descriptions],
lists:sort([couch_epi_codechange_monitor,
couch_epi_data_gen_test_app_descriptions, ?MODULE])}
- ]),
+ ],
- ToReplace = {to_replace,
- {old, start_link, [foo]}, permanent, 5000, worker, [foo]},
- Children = lists:sort(couch_epi_sup:plugin_childspecs(
- ?MODULE, [?MODULE], [ToReplace])),
- Results = [
- {parse_child_id(Id), Args, lists:sort(Modules)}
- || {Id, {_M, _F, Args}, _, _, _, Modules} <- Children
+ ToReplace = [
+ {to_replace, {old, start_link, [foo]}, permanent, 5000, worker, [foo]},
+ #{id => to_replace_map, start => {old, start_link, [foo]}}
],
+ Children = lists:sort(couch_epi_sup:plugin_childspecs(
+ ?MODULE, [?MODULE], ToReplace)),
+
+ Results = lists:map(fun
+ ({Id, {_M, _F, Args}, _, _, _, Modules}) ->
+ {parse_child_id(Id), Args, lists:sort(Modules)};
+ (#{id := Id, start := {_M, _F, Args}, modules := Modules}) ->
+ {parse_child_id(Id), Args, lists:sort(Modules)}
+ end, Children),
- Tests = lists:zip(Expected, Results),
+ Tests = lists:zip(lists:sort(Expected), lists:sort(Results)),
[?assertEqual(Expect, Result) || {Expect, Result} <- Tests],
ExpectedChild = {to_replace, {new, start_link, [bar]},
@@ -134,4 +142,8 @@ basic_test() ->
ExpectedChild,
lists:keyfind(to_replace, 1, Children)),
+ ExpectedMapChildSpec = #{id => to_replace_map,
+ start => {new, start_link, [bar]}, modules => [bar]},
+ [MapChildSpec] = [E || #{id := to_replace_map} = E <- Children],
+ ?assertEqual(ExpectedMapChildSpec, MapChildSpec),
ok.
diff --git a/src/couch_epi/test/couch_epi_tests.erl b/src/couch_epi/test/eunit/couch_epi_tests.erl
index 042753215..12d8610c1 100644
--- a/src/couch_epi/test/couch_epi_tests.erl
+++ b/src/couch_epi/test/eunit/couch_epi_tests.erl
@@ -14,8 +14,8 @@
-include_lib("couch/include/couch_eunit.hrl").
--define(DATA_FILE1, ?ABS_PATH("test/fixtures/app_data1.cfg")).
--define(DATA_FILE2, ?ABS_PATH("test/fixtures/app_data2.cfg")).
+-define(DATA_FILE1, ?ABS_PATH("test/eunit/fixtures/app_data1.cfg")).
+-define(DATA_FILE2, ?ABS_PATH("test/eunit/fixtures/app_data2.cfg")).
-export([notify_cb/4, save/3, get/2]).
diff --git a/src/couch_epi/test/fixtures/app_data1.cfg b/src/couch_epi/test/eunit/fixtures/app_data1.cfg
index 4c9f3fe2d..4c9f3fe2d 100644
--- a/src/couch_epi/test/fixtures/app_data1.cfg
+++ b/src/couch_epi/test/eunit/fixtures/app_data1.cfg
diff --git a/src/couch_epi/test/fixtures/app_data2.cfg b/src/couch_epi/test/eunit/fixtures/app_data2.cfg
index e5a5ffb8c..e5a5ffb8c 100644
--- a/src/couch_epi/test/fixtures/app_data2.cfg
+++ b/src/couch_epi/test/eunit/fixtures/app_data2.cfg
diff --git a/src/couch_index/test/couch_index_compaction_tests.erl b/src/couch_index/test/eunit/couch_index_compaction_tests.erl
index 53316d944..53316d944 100644
--- a/src/couch_index/test/couch_index_compaction_tests.erl
+++ b/src/couch_index/test/eunit/couch_index_compaction_tests.erl
diff --git a/src/couch_index/test/couch_index_ddoc_updated_tests.erl b/src/couch_index/test/eunit/couch_index_ddoc_updated_tests.erl
index 0e23adf91..0e23adf91 100644
--- a/src/couch_index/test/couch_index_ddoc_updated_tests.erl
+++ b/src/couch_index/test/eunit/couch_index_ddoc_updated_tests.erl
diff --git a/src/couch_log/test/couch_log_config_listener_test.erl b/src/couch_log/test/eunit/couch_log_config_listener_test.erl
index 07abae1ff..07abae1ff 100644
--- a/src/couch_log/test/couch_log_config_listener_test.erl
+++ b/src/couch_log/test/eunit/couch_log_config_listener_test.erl
diff --git a/src/couch_log/test/couch_log_config_test.erl b/src/couch_log/test/eunit/couch_log_config_test.erl
index c4677f37f..c4677f37f 100644
--- a/src/couch_log/test/couch_log_config_test.erl
+++ b/src/couch_log/test/eunit/couch_log_config_test.erl
diff --git a/src/couch_log/test/couch_log_error_logger_h_test.erl b/src/couch_log/test/eunit/couch_log_error_logger_h_test.erl
index b78598fa4..b78598fa4 100644
--- a/src/couch_log/test/couch_log_error_logger_h_test.erl
+++ b/src/couch_log/test/eunit/couch_log_error_logger_h_test.erl
diff --git a/src/couch_log/test/couch_log_formatter_test.erl b/src/couch_log/test/eunit/couch_log_formatter_test.erl
index 795efcf29..795efcf29 100644
--- a/src/couch_log/test/couch_log_formatter_test.erl
+++ b/src/couch_log/test/eunit/couch_log_formatter_test.erl
diff --git a/src/couch_log/test/couch_log_monitor_test.erl b/src/couch_log/test/eunit/couch_log_monitor_test.erl
index eec008522..eec008522 100644
--- a/src/couch_log/test/couch_log_monitor_test.erl
+++ b/src/couch_log/test/eunit/couch_log_monitor_test.erl
diff --git a/src/couch_log/test/couch_log_server_test.erl b/src/couch_log/test/eunit/couch_log_server_test.erl
index 7af570e90..7af570e90 100644
--- a/src/couch_log/test/couch_log_server_test.erl
+++ b/src/couch_log/test/eunit/couch_log_server_test.erl
diff --git a/src/couch_log/test/couch_log_test.erl b/src/couch_log/test/eunit/couch_log_test.erl
index c7195f65f..c7195f65f 100644
--- a/src/couch_log/test/couch_log_test.erl
+++ b/src/couch_log/test/eunit/couch_log_test.erl
diff --git a/src/couch_log/test/couch_log_test_util.erl b/src/couch_log/test/eunit/couch_log_test_util.erl
index 00f3981fc..00f3981fc 100644
--- a/src/couch_log/test/couch_log_test_util.erl
+++ b/src/couch_log/test/eunit/couch_log_test_util.erl
diff --git a/src/couch_log/test/couch_log_trunc_io_fmt_test.erl b/src/couch_log/test/eunit/couch_log_trunc_io_fmt_test.erl
index 77d555440..77d555440 100644
--- a/src/couch_log/test/couch_log_trunc_io_fmt_test.erl
+++ b/src/couch_log/test/eunit/couch_log_trunc_io_fmt_test.erl
diff --git a/src/couch_log/test/couch_log_util_test.erl b/src/couch_log/test/eunit/couch_log_util_test.erl
index e97911aa9..e97911aa9 100644
--- a/src/couch_log/test/couch_log_util_test.erl
+++ b/src/couch_log/test/eunit/couch_log_util_test.erl
diff --git a/src/couch_log/test/couch_log_writer_ets.erl b/src/couch_log/test/eunit/couch_log_writer_ets.erl
index d5fd327ac..d5fd327ac 100644
--- a/src/couch_log/test/couch_log_writer_ets.erl
+++ b/src/couch_log/test/eunit/couch_log_writer_ets.erl
diff --git a/src/couch_log/test/couch_log_writer_file_test.erl b/src/couch_log/test/eunit/couch_log_writer_file_test.erl
index ba042610a..ba042610a 100644
--- a/src/couch_log/test/couch_log_writer_file_test.erl
+++ b/src/couch_log/test/eunit/couch_log_writer_file_test.erl
diff --git a/src/couch_log/test/couch_log_writer_stderr_test.erl b/src/couch_log/test/eunit/couch_log_writer_stderr_test.erl
index 1e99263dd..1e99263dd 100644
--- a/src/couch_log/test/couch_log_writer_stderr_test.erl
+++ b/src/couch_log/test/eunit/couch_log_writer_stderr_test.erl
diff --git a/src/couch_log/test/couch_log_writer_syslog_test.erl b/src/couch_log/test/eunit/couch_log_writer_syslog_test.erl
index c32b5c6bf..c32b5c6bf 100644
--- a/src/couch_log/test/couch_log_writer_syslog_test.erl
+++ b/src/couch_log/test/eunit/couch_log_writer_syslog_test.erl
diff --git a/src/couch_log/test/couch_log_writer_test.erl b/src/couch_log/test/eunit/couch_log_writer_test.erl
index d0bb347fe..d0bb347fe 100644
--- a/src/couch_log/test/couch_log_writer_test.erl
+++ b/src/couch_log/test/eunit/couch_log_writer_test.erl
diff --git a/src/couch_mrview/src/couch_mrview.erl b/src/couch_mrview/src/couch_mrview.erl
index ae1d8d6f5..d549568ec 100644
--- a/src/couch_mrview/src/couch_mrview.erl
+++ b/src/couch_mrview/src/couch_mrview.erl
@@ -224,7 +224,7 @@ validate(Db, DDoc) ->
couch_query_servers:ret_os_process(Proc)
end
catch {unknown_query_language, _Lang} ->
- %% Allow users to save ddocs written in uknown languages
+ %% Allow users to save ddocs written in unknown languages
ok
end.
diff --git a/src/couch_mrview/src/couch_mrview_index.erl b/src/couch_mrview/src/couch_mrview_index.erl
index 03701693f..91703bd4d 100644
--- a/src/couch_mrview/src/couch_mrview_index.erl
+++ b/src/couch_mrview/src/couch_mrview_index.erl
@@ -80,8 +80,6 @@ get(info, State) ->
{ok, [
{signature, list_to_binary(couch_index_util:hexsig(Sig))},
{language, Lang},
- {disk_size, FileSize}, % legacy
- {data_size, ExternalSize}, % legacy
{sizes, {[
{file, FileSize},
{active, ActiveSize},
diff --git a/src/couch_mrview/test/couch_mrview_all_docs_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_all_docs_tests.erl
index bf8eb7e5b..bf8eb7e5b 100644
--- a/src/couch_mrview/test/couch_mrview_all_docs_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_all_docs_tests.erl
diff --git a/src/couch_mrview/test/couch_mrview_changes_since_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_changes_since_tests.erl
index d670e109b..d670e109b 100644
--- a/src/couch_mrview/test/couch_mrview_changes_since_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_changes_since_tests.erl
diff --git a/src/couch_mrview/test/couch_mrview_collation_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_collation_tests.erl
index 5c8cb54b1..5c8cb54b1 100644
--- a/src/couch_mrview/test/couch_mrview_collation_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_collation_tests.erl
diff --git a/src/couch_mrview/test/couch_mrview_compact_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_compact_tests.erl
index 7664becdc..7664becdc 100644
--- a/src/couch_mrview/test/couch_mrview_compact_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_compact_tests.erl
diff --git a/src/couch_mrview/test/couch_mrview_ddoc_updated_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_ddoc_updated_tests.erl
index 4310157eb..4310157eb 100644
--- a/src/couch_mrview/test/couch_mrview_ddoc_updated_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_ddoc_updated_tests.erl
diff --git a/src/couch_mrview/test/couch_mrview_ddoc_validation_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_ddoc_validation_tests.erl
index ce2be8904..ce2be8904 100644
--- a/src/couch_mrview/test/couch_mrview_ddoc_validation_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_ddoc_validation_tests.erl
diff --git a/src/couch_mrview/test/couch_mrview_design_docs_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_design_docs_tests.erl
index aedd42865..aedd42865 100644
--- a/src/couch_mrview/test/couch_mrview_design_docs_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_design_docs_tests.erl
diff --git a/src/couch_mrview/test/couch_mrview_http_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_http_tests.erl
index bd11c7ad8..bd11c7ad8 100644
--- a/src/couch_mrview/test/couch_mrview_http_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_http_tests.erl
diff --git a/src/couch_mrview/test/couch_mrview_index_changes_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_index_changes_tests.erl
index f0be1b9b1..f0be1b9b1 100644
--- a/src/couch_mrview/test/couch_mrview_index_changes_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_index_changes_tests.erl
diff --git a/src/couch_mrview/test/couch_mrview_index_info_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_index_info_tests.erl
index efa03e7c0..c4c765feb 100644
--- a/src/couch_mrview/test/couch_mrview_index_info_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_index_info_tests.erl
@@ -48,8 +48,6 @@ view_info_test_() ->
fun file_size_is_non_neg_int/1,
fun active_size_is_non_neg_int/1,
fun external_size_is_non_neg_int/1,
- fun disk_size_is_file_size/1,
- fun data_size_is_external_size/1,
fun active_size_less_than_file_size/1,
fun update_seq_is_non_neg_int/1,
fun purge_seq_is_non_neg_int/1,
@@ -80,14 +78,6 @@ external_size_is_non_neg_int({_, Info}) ->
?_assert(check_non_neg_int([sizes, external], Info)).
-disk_size_is_file_size({_, Info}) ->
- ?_assertEqual(prop([sizes, file], Info), prop(disk_size, Info)).
-
-
-data_size_is_external_size({_, Info}) ->
- ?_assertEqual(prop([sizes, external], Info), prop(data_size, Info)).
-
-
active_size_less_than_file_size({_, Info}) ->
?_assert(prop([sizes, active], Info) < prop([sizes, file], Info)).
diff --git a/src/couch_mrview/test/couch_mrview_local_docs_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_local_docs_tests.erl
index b0d25469a..b0d25469a 100644
--- a/src/couch_mrview/test/couch_mrview_local_docs_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_local_docs_tests.erl
diff --git a/src/couch_mrview/test/couch_mrview_map_views_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_map_views_tests.erl
index 805dc6c74..805dc6c74 100644
--- a/src/couch_mrview/test/couch_mrview_map_views_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_map_views_tests.erl
diff --git a/src/couch_mrview/test/couch_mrview_purge_docs_fabric_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_purge_docs_fabric_tests.erl
index 213acac0b..a593f54e3 100644
--- a/src/couch_mrview/test/couch_mrview_purge_docs_fabric_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_purge_docs_fabric_tests.erl
@@ -17,7 +17,7 @@
-include_lib("mem3/include/mem3.hrl").
-include_lib("couch_mrview/include/couch_mrview.hrl").
--define(TIMEOUT, 1000).
+-define(TIMEOUT, 60). % seconds
setup() ->
@@ -56,7 +56,7 @@ view_purge_fabric_test_() ->
test_purge_verify_index(DbName) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
Docs1 = couch_mrview_test_util:make_docs(normal, 5),
{ok, _} = fabric:update_docs(DbName, Docs1, [?ADMIN_CTX]),
{ok, _} = fabric:update_doc(
@@ -99,11 +99,11 @@ test_purge_verify_index(DbName) ->
?assertEqual(1, couch_util:get_value(<<"purge_seq">>, Props2)),
?assertEqual(true, couch_mrview_index:verify_index_exists(
ShardDbName, Props2))
- end).
+ end)}.
test_purge_hook_before_compaction(DbName) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
Docs1 = couch_mrview_test_util:make_docs(normal, 5),
{ok, _} = fabric:update_docs(DbName, Docs1, [?ADMIN_CTX]),
{ok, _} = fabric:update_doc(
@@ -198,7 +198,7 @@ test_purge_hook_before_compaction(DbName) ->
{ok, #doc{body = {Props4}}} = get_local_purge_doc(DbName),
?assertEqual(2, couch_util:get_value(<<"purge_seq">>, Props4))
- end).
+ end)}.
get_local_purge_doc(DbName) ->
diff --git a/src/couch_mrview/test/couch_mrview_purge_docs_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_purge_docs_tests.erl
index 1020607a4..1020607a4 100644
--- a/src/couch_mrview/test/couch_mrview_purge_docs_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_purge_docs_tests.erl
diff --git a/src/couch_mrview/test/couch_mrview_red_views_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_red_views_tests.erl
index b83686113..b83686113 100644
--- a/src/couch_mrview/test/couch_mrview_red_views_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_red_views_tests.erl
diff --git a/src/couch_mrview/test/couch_mrview_util_tests.erl b/src/couch_mrview/test/eunit/couch_mrview_util_tests.erl
index 7046c9bb2..7046c9bb2 100644
--- a/src/couch_mrview/test/couch_mrview_util_tests.erl
+++ b/src/couch_mrview/test/eunit/couch_mrview_util_tests.erl
diff --git a/src/couch_peruser/test/couch_peruser_test.erl b/src/couch_peruser/test/eunit/couch_peruser_test.erl
index 8501cc36f..8501cc36f 100644
--- a/src/couch_peruser/test/couch_peruser_test.erl
+++ b/src/couch_peruser/test/eunit/couch_peruser_test.erl
diff --git a/src/couch_pse_tests/src/cpse_test_purge_replication.erl b/src/couch_pse_tests/src/cpse_test_purge_replication.erl
index fb09eeba6..20dcc2f81 100644
--- a/src/couch_pse_tests/src/cpse_test_purge_replication.erl
+++ b/src/couch_pse_tests/src/cpse_test_purge_replication.erl
@@ -48,8 +48,8 @@ cpse_purge_http_replication({Source, Target}) ->
]),
RepObject = {[
- {<<"source">>, Source},
- {<<"target">>, Target}
+ {<<"source">>, db_url(Source)},
+ {<<"target">>, db_url(Target)}
]},
{ok, _} = couch_replicator:replicate(RepObject, ?ADMIN_USER),
@@ -100,8 +100,8 @@ cpse_purge_http_replication({Source, Target}) ->
% Show that replicating from the target
% back to the source reintroduces the doc
RepObject2 = {[
- {<<"source">>, Target},
- {<<"target">>, Source}
+ {<<"source">>, db_url(Target)},
+ {<<"target">>, db_url(Source)}
]},
{ok, _} = couch_replicator:replicate(RepObject2, ?ADMIN_USER),
@@ -200,3 +200,16 @@ make_shard(DbName) ->
dbname = DbName,
range = [0, 16#FFFFFFFF]
}.
+
+
+db_url(DbName) ->
+ Addr = config:get("httpd", "bind_address", "127.0.0.1"),
+ Port = mochiweb_socket_server:get(couch_httpd, port),
+ Url = ?l2b(io_lib:format("http://~s:~b/~s", [Addr, Port, DbName])),
+ test_util:wait(fun() ->
+ case test_request:get(?b2l(Url)) of
+ {ok, 200, _, _} -> ok;
+ _ -> wait
+ end
+ end),
+ Url.
diff --git a/src/couch_replicator/src/couch_replicator.erl b/src/couch_replicator/src/couch_replicator.erl
index 39141c301..9c7e318b6 100644
--- a/src/couch_replicator/src/couch_replicator.erl
+++ b/src/couch_replicator/src/couch_replicator.erl
@@ -144,11 +144,13 @@ replication_states() ->
-spec strip_url_creds(binary() | {[_]}) -> binary().
strip_url_creds(Endpoint) ->
- case couch_replicator_docs:parse_rep_db(Endpoint, [], []) of
- #httpdb{url=Url} ->
- iolist_to_binary(couch_util:url_strip_password(Url));
- LocalDb when is_binary(LocalDb) ->
- LocalDb
+ try
+ couch_replicator_docs:parse_rep_db(Endpoint, [], []) of
+ #httpdb{url = Url} ->
+ iolist_to_binary(couch_util:url_strip_password(Url))
+ catch
+ throw:{error, local_endpoints_not_supported} ->
+ Endpoint
end.
@@ -358,9 +360,9 @@ strip_url_creds_test_() ->
end,
fun (_) -> meck:unload() end,
[
- t_strip_local_db_creds(),
t_strip_http_basic_creds(),
- t_strip_http_props_creds()
+ t_strip_http_props_creds(),
+ t_strip_local_db_creds()
]
}.
diff --git a/src/couch_replicator/src/couch_replicator_api_wrap.erl b/src/couch_replicator/src/couch_replicator_api_wrap.erl
index 44c290d33..ab1de7df9 100644
--- a/src/couch_replicator/src/couch_replicator_api_wrap.erl
+++ b/src/couch_replicator/src/couch_replicator_api_wrap.erl
@@ -23,8 +23,8 @@
-include("couch_replicator_api_wrap.hrl").
-export([
- db_open/2,
- db_open/4,
+ db_open/1,
+ db_open/3,
db_close/1,
get_db_info/1,
get_pending_count/2,
@@ -67,10 +67,10 @@ db_uri(Db) ->
db_uri(couch_db:name(Db)).
-db_open(Db, Options) ->
- db_open(Db, Options, false, []).
+db_open(Db) ->
+ db_open(Db, false, []).
-db_open(#httpdb{} = Db1, _Options, Create, CreateParams) ->
+db_open(#httpdb{} = Db1, Create, CreateParams) ->
{ok, Db} = couch_replicator_httpc:setup(Db1),
try
case Create of
@@ -118,51 +118,19 @@ db_open(#httpdb{} = Db1, _Options, Create, CreateParams) ->
exit:Error ->
db_close(Db),
erlang:exit(Error)
- end;
-db_open(DbName, Options, Create, _CreateParams) ->
- try
- case Create of
- false ->
- ok;
- true ->
- ok = couch_httpd:verify_is_server_admin(
- get_value(user_ctx, Options)),
- couch_db:create(DbName, Options)
- end,
- case couch_db:open(DbName, Options) of
- {error, {illegal_database_name, _}} ->
- throw({db_not_found, DbName});
- {not_found, _Reason} ->
- throw({db_not_found, DbName});
- {ok, _Db} = Success ->
- Success
- end
- catch
- throw:{unauthorized, _} ->
- throw({unauthorized, DbName})
end.
db_close(#httpdb{httpc_pool = Pool} = HttpDb) ->
couch_replicator_auth:cleanup(HttpDb),
unlink(Pool),
- ok = couch_replicator_httpc_pool:stop(Pool);
-db_close(DbName) ->
- catch couch_db:close(DbName).
+ ok = couch_replicator_httpc_pool:stop(Pool).
get_db_info(#httpdb{} = Db) ->
send_req(Db, [],
fun(200, _, {Props}) ->
{ok, Props}
- end);
-get_db_info(Db) ->
- DbName = couch_db:name(Db),
- UserCtx = couch_db:get_user_ctx(Db),
- {ok, InfoDb} = couch_db:open(DbName, [{user_ctx, UserCtx}]),
- {ok, Info} = couch_db:get_db_info(InfoDb),
- couch_db:close(InfoDb),
- {ok, [{couch_util:to_binary(K), V} || {K, V} <- Info]}.
-
+ end).
get_pending_count(#httpdb{} = Db, Seq) when is_number(Seq) ->
% Source looks like Apache CouchDB and not Cloudant so we fall
@@ -179,14 +147,7 @@ get_pending_count(#httpdb{} = Db, Seq) ->
Options = [{path, "_changes"}, {qs, [{"since", ?JSON_ENCODE(Seq)}, {"limit", "0"}]}],
send_req(Db, Options, fun(200, _, {Props}) ->
{ok, couch_util:get_value(<<"pending">>, Props, null)}
- end);
-get_pending_count(Db, Seq) when is_number(Seq) ->
- DbName = couch_db:name(Db),
- UserCtx = couch_db:get_user_ctx(Db),
- {ok, CountDb} = couch_db:open(DbName, [{user_ctx, UserCtx}]),
- Pending = couch_db:count_changes_since(CountDb, Seq),
- couch_db:close(CountDb),
- {ok, Pending}.
+ end).
get_view_info(#httpdb{} = Db, DDocId, ViewName) ->
Path = io_lib:format("~s/_view/~s/_info", [DDocId, ViewName]),
@@ -194,11 +155,7 @@ get_view_info(#httpdb{} = Db, DDocId, ViewName) ->
fun(200, _, {Props}) ->
{VInfo} = couch_util:get_value(<<"view_index">>, Props, {[]}),
{ok, VInfo}
- end);
-get_view_info(Db, DDocId, ViewName) ->
- DbName = couch_db:name(Db),
- {ok, VInfo} = couch_mrview:get_view_info(DbName, DDocId, ViewName),
- {ok, [{couch_util:to_binary(K), V} || {K, V} <- VInfo]}.
+ end).
ensure_full_commit(#httpdb{} = Db) ->
@@ -210,9 +167,7 @@ ensure_full_commit(#httpdb{} = Db) ->
{ok, get_value(<<"instance_start_time">>, Props)};
(_, _, {Props}) ->
{error, get_value(<<"error">>, Props)}
- end);
-ensure_full_commit(Db) ->
- couch_db:ensure_full_commit(Db).
+ end).
get_missing_revs(#httpdb{} = Db, IdRevs) ->
@@ -232,10 +187,7 @@ get_missing_revs(#httpdb{} = Db, IdRevs) ->
{Id, MissingRevs, PossibleAncestors}
end,
{ok, lists:map(ConvertToNativeFun, Props)}
- end);
-get_missing_revs(Db, IdRevs) ->
- couch_db:get_missing_revs(Db, IdRevs).
-
+ end).
open_doc_revs(#httpdb{retries = 0} = HttpDb, Id, Revs, Options, _Fun, _Acc) ->
@@ -331,10 +283,8 @@ open_doc_revs(#httpdb{} = HttpDb, Id, Revs, Options, Fun, Acc) ->
wait = Wait
},
open_doc_revs(RetryDb, Id, Revs, Options, Fun, Acc)
- end;
-open_doc_revs(Db, Id, Revs, Options, Fun, Acc) ->
- {ok, Results} = couch_db:open_doc_revs(Db, Id, Revs, Options),
- {ok, lists:foldl(fun(R, A) -> {_, A2} = Fun(R, A), A2 end, Acc, Results)}.
+ end.
+
error_reason({http_request_failed, "GET", _Url, {error, timeout}}) ->
timeout;
@@ -353,14 +303,7 @@ open_doc(#httpdb{} = Db, Id, Options) ->
{ok, couch_doc:from_json_obj(Body)};
(_, _, {Props}) ->
{error, get_value(<<"error">>, Props)}
- end);
-open_doc(Db, Id, Options) ->
- case couch_db:open_doc(Db, Id, Options) of
- {ok, _} = Ok ->
- Ok;
- {not_found, _Reason} ->
- {error, <<"not_found">>}
- end.
+ end).
update_doc(Db, Doc, Options) ->
@@ -411,9 +354,7 @@ update_doc(#httpdb{} = HttpDb, #doc{id = DocId} = Doc, Options, Type) ->
{_, Error} ->
{error, Error}
end
- end);
-update_doc(Db, Doc, Options, Type) ->
- couch_db:update_doc(Db, Doc, Options, Type).
+ end).
update_docs(Db, DocList, Options) ->
@@ -468,10 +409,7 @@ update_docs(#httpdb{} = HttpDb, DocList, Options, UpdateType) ->
{error, request_body_too_large};
(417, _, Results) when is_list(Results) ->
{ok, bulk_results_to_errors(DocList, Results, remote)}
- end);
-update_docs(Db, DocList, Options, UpdateType) ->
- Result = couch_db:update_docs(Db, DocList, Options, UpdateType),
- {ok, bulk_results_to_errors(DocList, Result, UpdateType)}.
+ end).
changes_since(#httpdb{headers = Headers1, timeout = InactiveTimeout} = HttpDb,
@@ -538,38 +476,7 @@ changes_since(#httpdb{headers = Headers1, timeout = InactiveTimeout} = HttpDb,
throw(retry_no_limit);
exit:{http_request_failed, _, _, _} = Error ->
throw({retry_limit, Error})
- end;
-changes_since(Db, Style, StartSeq, UserFun, Options) ->
- DocIds = get_value(doc_ids, Options),
- Selector = get_value(selector, Options),
- Filter = case {DocIds, Selector} of
- {undefined, undefined} ->
- ?b2l(get_value(filter, Options, <<>>));
- {_, undefined} ->
- "_doc_ids";
- {undefined, _} ->
- "_selector"
- end,
- Args = #changes_args{
- style = Style,
- since = StartSeq,
- filter = Filter,
- feed = case get_value(continuous, Options, false) of
- true ->
- "continuous";
- false ->
- "normal"
- end,
- timeout = infinity
- },
- QueryParams = get_value(query_params, Options, {[]}),
- Req = changes_json_req(Db, Filter, QueryParams, Options),
- ChangesFeedFun = couch_changes:handle_db_changes(Args, {json_req, Req}, Db),
- ChangesFeedFun(fun({change, Change, _}, _) ->
- UserFun(json_to_doc_info(Change));
- (_, _) ->
- ok
- end).
+ end.
% internal functions
@@ -614,29 +521,6 @@ parse_changes_feed(Options, UserFun, DataStreamFun) ->
json_stream_parse:events(DataStreamFun, EventFun)
end.
-changes_json_req(_Db, "", _QueryParams, _Options) ->
- {[]};
-changes_json_req(_Db, "_doc_ids", _QueryParams, Options) ->
- {[{<<"doc_ids">>, get_value(doc_ids, Options)}]};
-changes_json_req(_Db, "_selector", _QueryParams, Options) ->
- {[{<<"selector">>, get_value(selector, Options)}]};
-changes_json_req(Db, FilterName, {QueryParams}, _Options) ->
- {ok, Info} = couch_db:get_db_info(Db),
- % simulate a request to db_name/_changes
- {[
- {<<"info">>, {Info}},
- {<<"id">>, null},
- {<<"method">>, 'GET'},
- {<<"path">>, [couch_db:name(Db), <<"_changes">>]},
- {<<"query">>, {[{<<"filter">>, FilterName} | QueryParams]}},
- {<<"headers">>, []},
- {<<"body">>, []},
- {<<"peer">>, <<"replicator">>},
- {<<"form">>, []},
- {<<"cookie">>, []},
- {<<"userCtx">>, couch_util:json_user_ctx(Db)}
- ]}.
-
options_to_query_args(HttpDb, Path, Options0) ->
case lists:keytake(max_url_len, 1, Options0) of
diff --git a/src/couch_replicator/src/couch_replicator_auth.erl b/src/couch_replicator/src/couch_replicator_auth.erl
index 7f51cdd1c..272e10af5 100644
--- a/src/couch_replicator/src/couch_replicator_auth.erl
+++ b/src/couch_replicator/src/couch_replicator_auth.erl
@@ -33,6 +33,12 @@
% Behavior API
+% Note for plugin developers: consider using the "auth" field in the source and
+% target objects to store credentials. In that case non-owner and non-admin
+% users will have those credentials stripped when they read the replication
+% document, which mimicks the behavior for "headers" and user and pass fields
+% in endpoint URLs".
+
-callback initialize(#httpdb{}) ->
{ok, #httpdb{}, term()} | {error, term()} | ignore.
diff --git a/src/couch_replicator/src/couch_replicator_doc_processor.erl b/src/couch_replicator/src/couch_replicator_doc_processor.erl
index 1b43598da..772037d8d 100644
--- a/src/couch_replicator/src/couch_replicator_doc_processor.erl
+++ b/src/couch_replicator/src/couch_replicator_doc_processor.erl
@@ -886,8 +886,8 @@ change() ->
{<<"id">>, ?DOC1},
{doc, {[
{<<"_id">>, ?DOC1},
- {<<"source">>, <<"src">>},
- {<<"target">>, <<"tgt">>}
+ {<<"source">>, <<"http://srchost.local/src">>},
+ {<<"target">>, <<"http://tgthost.local/tgt">>}
]}}
]}.
@@ -897,8 +897,8 @@ change(State) ->
{<<"id">>, ?DOC1},
{doc, {[
{<<"_id">>, ?DOC1},
- {<<"source">>, <<"src">>},
- {<<"target">>, <<"tgt">>},
+ {<<"source">>, <<"http://srchost.local/src">>},
+ {<<"target">>, <<"http://tgthost.local/tgt">>},
{<<"_replication_state">>, State}
]}}
]}.
@@ -910,8 +910,8 @@ deleted_change() ->
{<<"deleted">>, true},
{doc, {[
{<<"_id">>, ?DOC1},
- {<<"source">>, <<"src">>},
- {<<"target">>, <<"tgt">>}
+ {<<"source">>, <<"http://srchost.local/src">>},
+ {<<"target">>, <<"http://tgthost.local/tgt">>}
]}}
]}.
diff --git a/src/couch_replicator/src/couch_replicator_doc_processor_worker.erl b/src/couch_replicator/src/couch_replicator_doc_processor_worker.erl
index aa048bfab..a4c829323 100644
--- a/src/couch_replicator/src/couch_replicator_doc_processor_worker.erl
+++ b/src/couch_replicator/src/couch_replicator_doc_processor_worker.erl
@@ -137,7 +137,7 @@ maybe_add_job_to_scheduler({DbName, DocId}, Rep, WRef) ->
-define(DB, <<"db">>).
-define(DOC1, <<"doc1">>).
--define(R1, {"0b7831e9a41f9322a8600ccfa02245f2", ""}).
+-define(R1, {"ad08e05057046eabe898a2572bbfb573", ""}).
doc_processor_worker_test_() ->
@@ -277,8 +277,8 @@ did_not_add_job() ->
change() ->
{[
{<<"_id">>, ?DOC1},
- {<<"source">>, <<"src">>},
- {<<"target">>, <<"tgt">>}
+ {<<"source">>, <<"http://srchost.local/src">>},
+ {<<"target">>, <<"http://tgthost.local/tgt">>}
]}.
-endif.
diff --git a/src/couch_replicator/src/couch_replicator_docs.erl b/src/couch_replicator/src/couch_replicator_docs.erl
index bbf9694d7..81685cd48 100644
--- a/src/couch_replicator/src/couch_replicator_docs.erl
+++ b/src/couch_replicator/src/couch_replicator_docs.erl
@@ -423,8 +423,8 @@ parse_rep_db(<<"http://", _/binary>> = Url, Proxy, Options) ->
parse_rep_db(<<"https://", _/binary>> = Url, Proxy, Options) ->
parse_rep_db({[{<<"url">>, Url}]}, Proxy, Options);
-parse_rep_db(<<DbName/binary>>, _Proxy, _Options) ->
- DbName;
+parse_rep_db(<<_/binary>>, _Proxy, _Options) ->
+ throw({error, local_endpoints_not_supported});
parse_rep_db(undefined, _Proxy, _Options) ->
throw({error, <<"Missing replicator database">>}).
@@ -683,8 +683,12 @@ strip_credentials(Url) when is_binary(Url) ->
"http(s)?://(?:[^:]+):[^@]+@(.*)$",
"http\\1://\\2",
[{return, binary}]);
-strip_credentials({Props}) ->
- {lists:keydelete(<<"headers">>, 1, Props)}.
+strip_credentials({Props0}) ->
+ Props1 = lists:keydelete(<<"headers">>, 1, Props0),
+ % Strip "auth" just like headers, for replication plugins it can be a place
+ % to stash credential that are not necessarily in headers
+ Props2 = lists:keydelete(<<"auth">>, 1, Props1),
+ {Props2}.
error_reason({shutdown, Error}) ->
@@ -773,6 +777,10 @@ check_strip_credentials_test() ->
{
{[{<<"_id">>, <<"foo">>}]},
{[{<<"_id">>, <<"foo">>}, {<<"headers">>, <<"baz">>}]}
+ },
+ {
+ {[{<<"_id">>, <<"foo">>}]},
+ {[{<<"_id">>, <<"foo">>}, {<<"auth">>, <<"pluginsecret">>}]}
}
]].
@@ -822,4 +830,29 @@ t_vdu_does_not_crash_on_save(DbName) ->
?assertEqual({ok, forbidden}, save_rep_doc(DbName, Doc))
end).
+
+local_replication_endpoint_error_test_() ->
+ {
+ foreach,
+ fun () -> meck:expect(config, get,
+ fun(_, _, Default) -> Default end)
+ end,
+ fun (_) -> meck:unload() end,
+ [
+ t_error_on_local_endpoint()
+ ]
+ }.
+
+
+t_error_on_local_endpoint() ->
+ ?_test(begin
+ RepDoc = {[
+ {<<"_id">>, <<"someid">>},
+ {<<"source">>, <<"localdb">>},
+ {<<"target">>, <<"http://somehost.local/tgt">>}
+ ]},
+ Expect = local_endpoints_not_supported,
+ ?assertThrow({bad_rep_doc, Expect}, parse_rep_doc_without_id(RepDoc))
+ end).
+
-endif.
diff --git a/src/couch_replicator/src/couch_replicator_filters.erl b/src/couch_replicator/src/couch_replicator_filters.erl
index 5668820d1..c8980001a 100644
--- a/src/couch_replicator/src/couch_replicator_filters.erl
+++ b/src/couch_replicator/src/couch_replicator_filters.erl
@@ -14,7 +14,7 @@
-export([
parse/1,
- fetch/4,
+ fetch/3,
view_type/2,
ejsort/1
]).
@@ -63,11 +63,11 @@ parse(Options) ->
% Fetches body of filter function from source database. Guaranteed to either
% return {ok, Body} or an {error, Reason}. Also assume this function might
% block due to network / socket issues for an undeterminted amount of time.
--spec fetch(binary(), binary(), binary(), #user_ctx{}) ->
+-spec fetch(binary(), binary(), binary()) ->
{ok, {[_]}} | {error, binary()}.
-fetch(DDocName, FilterName, Source, UserCtx) ->
+fetch(DDocName, FilterName, Source) ->
{Pid, Ref} = spawn_monitor(fun() ->
- try fetch_internal(DDocName, FilterName, Source, UserCtx) of
+ try fetch_internal(DDocName, FilterName, Source) of
Resp ->
exit({exit_ok, Resp})
catch
@@ -108,9 +108,8 @@ view_type(Props, Options) ->
% Private functions
-fetch_internal(DDocName, FilterName, Source, UserCtx) ->
- Db = case (catch couch_replicator_api_wrap:db_open(Source,
- [{user_ctx, UserCtx}])) of
+fetch_internal(DDocName, FilterName, Source) ->
+ Db = case (catch couch_replicator_api_wrap:db_open(Source)) of
{ok, Db0} ->
Db0;
DbError ->
diff --git a/src/couch_replicator/src/couch_replicator_ids.erl b/src/couch_replicator/src/couch_replicator_ids.erl
index e10b98082..04e71c3ef 100644
--- a/src/couch_replicator/src/couch_replicator_ids.erl
+++ b/src/couch_replicator/src/couch_replicator_ids.erl
@@ -39,19 +39,19 @@ replication_id(#rep{options = Options} = Rep) ->
% If a change is made to how replications are identified,
% please add a new clause and increase ?REP_ID_VERSION.
-replication_id(#rep{user_ctx = UserCtx} = Rep, 4) ->
+replication_id(#rep{} = Rep, 4) ->
UUID = couch_server:get_uuid(),
- SrcInfo = get_v4_endpoint(UserCtx, Rep#rep.source),
- TgtInfo = get_v4_endpoint(UserCtx, Rep#rep.target),
+ SrcInfo = get_v4_endpoint(Rep#rep.source),
+ TgtInfo = get_v4_endpoint(Rep#rep.target),
maybe_append_filters([UUID, SrcInfo, TgtInfo], Rep);
-replication_id(#rep{user_ctx = UserCtx} = Rep, 3) ->
+replication_id(#rep{} = Rep, 3) ->
UUID = couch_server:get_uuid(),
- Src = get_rep_endpoint(UserCtx, Rep#rep.source),
- Tgt = get_rep_endpoint(UserCtx, Rep#rep.target),
+ Src = get_rep_endpoint(Rep#rep.source),
+ Tgt = get_rep_endpoint(Rep#rep.target),
maybe_append_filters([UUID, Src, Tgt], Rep);
-replication_id(#rep{user_ctx = UserCtx} = Rep, 2) ->
+replication_id(#rep{} = Rep, 2) ->
{ok, HostName} = inet:gethostname(),
Port = case (catch mochiweb_socket_server:get(couch_httpd, port)) of
P when is_number(P) ->
@@ -64,14 +64,14 @@ replication_id(#rep{user_ctx = UserCtx} = Rep, 2) ->
% ... mochiweb_socket_server:get(https, port)
list_to_integer(config:get("httpd", "port", "5984"))
end,
- Src = get_rep_endpoint(UserCtx, Rep#rep.source),
- Tgt = get_rep_endpoint(UserCtx, Rep#rep.target),
+ Src = get_rep_endpoint(Rep#rep.source),
+ Tgt = get_rep_endpoint(Rep#rep.target),
maybe_append_filters([HostName, Port, Src, Tgt], Rep);
-replication_id(#rep{user_ctx = UserCtx} = Rep, 1) ->
+replication_id(#rep{} = Rep, 1) ->
{ok, HostName} = inet:gethostname(),
- Src = get_rep_endpoint(UserCtx, Rep#rep.source),
- Tgt = get_rep_endpoint(UserCtx, Rep#rep.target),
+ Src = get_rep_endpoint(Rep#rep.source),
+ Tgt = get_rep_endpoint(Rep#rep.target),
maybe_append_filters([HostName, Src, Tgt], Rep).
@@ -91,7 +91,7 @@ convert({BaseId, Ext} = Id) when is_list(BaseId), is_list(Ext) ->
% Private functions
maybe_append_filters(Base,
- #rep{source = Source, user_ctx = UserCtx, options = Options}) ->
+ #rep{source = Source, options = Options}) ->
Base2 = Base ++
case couch_replicator_filters:parse(Options) of
{ok, nil} ->
@@ -99,7 +99,7 @@ maybe_append_filters(Base,
{ok, {view, Filter, QueryParams}} ->
[Filter, QueryParams];
{ok, {user, {Doc, Filter}, QueryParams}} ->
- case couch_replicator_filters:fetch(Doc, Filter, Source, UserCtx) of
+ case couch_replicator_filters:fetch(Doc, Filter, Source) of
{ok, Code} ->
[Code, QueryParams];
{error, Error} ->
@@ -127,23 +127,19 @@ maybe_append_options(Options, RepOptions) ->
end, [], Options).
-get_rep_endpoint(_UserCtx, #httpdb{url=Url, headers=Headers}) ->
+get_rep_endpoint(#httpdb{url=Url, headers=Headers}) ->
DefaultHeaders = (#httpdb{})#httpdb.headers,
- {remote, Url, Headers -- DefaultHeaders};
-get_rep_endpoint(UserCtx, <<DbName/binary>>) ->
- {local, DbName, UserCtx}.
+ {remote, Url, Headers -- DefaultHeaders}.
-get_v4_endpoint(UserCtx, #httpdb{} = HttpDb) ->
- {remote, Url, Headers} = get_rep_endpoint(UserCtx, HttpDb),
+get_v4_endpoint(#httpdb{} = HttpDb) ->
+ {remote, Url, Headers} = get_rep_endpoint(HttpDb),
{{UserFromHeaders, _}, HeadersWithoutBasicAuth} =
couch_replicator_utils:remove_basic_auth_from_headers(Headers),
{UserFromUrl, Host, NonDefaultPort, Path} = get_v4_url_info(Url),
User = pick_defined_value([UserFromUrl, UserFromHeaders]),
OAuth = undefined, % Keep this to ensure checkpoints don't change
- {remote, User, Host, NonDefaultPort, Path, HeadersWithoutBasicAuth, OAuth};
-get_v4_endpoint(UserCtx, <<DbName/binary>>) ->
- {local, DbName, UserCtx}.
+ {remote, User, Host, NonDefaultPort, Path, HeadersWithoutBasicAuth, OAuth}.
pick_defined_value(Values) ->
@@ -201,7 +197,7 @@ replication_id_convert_test_() ->
http_v4_endpoint_test_() ->
[?_assertMatch({remote, User, Host, Port, Path, HeadersNoAuth, undefined},
- get_v4_endpoint(nil, #httpdb{url = Url, headers = Headers})) ||
+ get_v4_endpoint(#httpdb{url = Url, headers = Headers})) ||
{{User, Host, Port, Path, HeadersNoAuth}, {Url, Headers}} <- [
{
{undefined, "host", default, "/", []},
diff --git a/src/couch_replicator/src/couch_replicator_scheduler.erl b/src/couch_replicator/src/couch_replicator_scheduler.erl
index e3dbede83..7fe417a53 100644
--- a/src/couch_replicator/src/couch_replicator_scheduler.erl
+++ b/src/couch_replicator/src/couch_replicator_scheduler.erl
@@ -494,7 +494,10 @@ start_jobs(Count, State) ->
-spec stop_jobs(non_neg_integer(), boolean(), #state{}) -> non_neg_integer().
-stop_jobs(Count, IsContinuous, State) ->
+stop_jobs(Count, _, _) when is_integer(Count), Count =< 0 ->
+ 0;
+
+stop_jobs(Count, IsContinuous, State) when is_integer(Count) ->
Running0 = running_jobs(),
ContinuousPred = fun(Job) -> is_continuous(Job) =:= IsContinuous end,
Running1 = lists:filter(ContinuousPred, Running0),
@@ -723,35 +726,25 @@ reset_job_process(#job{} = Job) ->
-spec reschedule(#state{}) -> ok.
reschedule(State) ->
- Running = running_job_count(),
- Pending = pending_job_count(),
- stop_excess_jobs(State, Running),
- start_pending_jobs(State, Running, Pending),
- rotate_jobs(State, Running, Pending),
- update_running_jobs_stats(State#state.stats_pid),
- ok.
+ StopCount = stop_excess_jobs(State, running_job_count()),
+ rotate_jobs(State, StopCount),
+ update_running_jobs_stats(State#state.stats_pid).
--spec stop_excess_jobs(#state{}, non_neg_integer()) -> ok.
+-spec stop_excess_jobs(#state{}, non_neg_integer()) -> non_neg_integer().
stop_excess_jobs(State, Running) ->
#state{max_jobs=MaxJobs} = State,
- StopCount = Running - MaxJobs,
- if StopCount =< 0 -> ok; true ->
- Stopped = stop_jobs(StopCount, true, State),
- OneshotLeft = StopCount - Stopped,
- if OneshotLeft =< 0 -> ok; true ->
- stop_jobs(OneshotLeft, false, State),
- ok
- end
- end.
+ StopCount = max(0, Running - MaxJobs),
+ Stopped = stop_jobs(StopCount, true, State),
+ OneshotLeft = StopCount - Stopped,
+ stop_jobs(OneshotLeft, false, State),
+ StopCount.
start_pending_jobs(State) ->
- start_pending_jobs(State, running_job_count(), pending_job_count()).
-
-
-start_pending_jobs(State, Running, Pending) ->
#state{max_jobs=MaxJobs} = State,
+ Running = running_job_count(),
+ Pending = pending_job_count(),
if Running < MaxJobs, Pending > 0 ->
start_jobs(MaxJobs - Running, State);
true ->
@@ -759,13 +752,19 @@ start_pending_jobs(State, Running, Pending) ->
end.
--spec rotate_jobs(#state{}, non_neg_integer(), non_neg_integer()) -> ok.
-rotate_jobs(State, Running, Pending) ->
+-spec rotate_jobs(#state{}, non_neg_integer()) -> ok.
+rotate_jobs(State, ChurnSoFar) ->
#state{max_jobs=MaxJobs, max_churn=MaxChurn} = State,
- if Running == MaxJobs, Pending > 0 ->
- RotateCount = lists:min([Pending, Running, MaxChurn]),
- StopCount = stop_jobs(RotateCount, true, State),
- start_jobs(StopCount, State);
+ Running = running_job_count(),
+ Pending = pending_job_count(),
+ % Reduce MaxChurn by the number of already stopped jobs in the
+ % current rescheduling cycle.
+ Churn = max(0, MaxChurn - ChurnSoFar),
+ if Running =< MaxJobs ->
+ StopCount = lists:min([Pending, Running, Churn]),
+ stop_jobs(StopCount, true, State),
+ StartCount = max(0, MaxJobs - running_job_count()),
+ start_jobs(StartCount, State);
true ->
ok
end.
@@ -1047,6 +1046,7 @@ scheduler_test_() ->
t_excess_prefer_continuous_first(),
t_stop_oldest_first(),
t_start_oldest_first(),
+ t_jobs_churn_even_if_not_all_max_jobs_are_running(),
t_dont_stop_if_nothing_pending(),
t_max_churn_limits_number_of_rotated_jobs(),
t_existing_jobs(),
@@ -1056,7 +1056,7 @@ scheduler_test_() ->
t_rotate_continuous_only_if_mixed(),
t_oneshot_dont_get_starting_priority(),
t_oneshot_will_hog_the_scheduler(),
- t_if_excess_is_trimmed_rotation_doesnt_happen(),
+ t_if_excess_is_trimmed_rotation_still_happens(),
t_if_transient_job_crashes_it_gets_removed(),
t_if_permanent_job_crashes_it_stays_in_ets(),
t_job_summary_running(),
@@ -1177,10 +1177,10 @@ t_stop_oldest_first() ->
continuous_running(5)
],
setup_jobs(Jobs),
- reschedule(mock_state(2)),
+ reschedule(mock_state(2, 1)),
?assertEqual({2, 1}, run_stop_count()),
?assertEqual([4], jobs_stopped()),
- reschedule(mock_state(1)),
+ reschedule(mock_state(1, 1)),
?assertEqual([7], jobs_running())
end).
@@ -1192,6 +1192,22 @@ t_start_oldest_first() ->
?assertEqual({1, 2}, run_stop_count()),
?assertEqual([2], jobs_running()),
reschedule(mock_state(2)),
+ ?assertEqual({2, 1}, run_stop_count()),
+ % After rescheduling with max_jobs = 2, 2 was stopped and 5, 7 should
+ % be running.
+ ?assertEqual([2], jobs_stopped())
+ end).
+
+
+t_jobs_churn_even_if_not_all_max_jobs_are_running() ->
+ ?_test(begin
+ setup_jobs([
+ continuous_running(7),
+ continuous(2),
+ continuous(5)
+ ]),
+ reschedule(mock_state(2, 2)),
+ ?assertEqual({2, 1}, run_stop_count()),
?assertEqual([7], jobs_stopped())
end).
@@ -1289,7 +1305,7 @@ t_oneshot_will_hog_the_scheduler() ->
end).
-t_if_excess_is_trimmed_rotation_doesnt_happen() ->
+t_if_excess_is_trimmed_rotation_still_happens() ->
?_test(begin
Jobs = [
continuous(1),
@@ -1298,7 +1314,7 @@ t_if_excess_is_trimmed_rotation_doesnt_happen() ->
],
setup_jobs(Jobs),
reschedule(mock_state(1)),
- ?assertEqual([3], jobs_running())
+ ?assertEqual([1], jobs_running())
end).
diff --git a/src/couch_replicator/src/couch_replicator_scheduler_job.erl b/src/couch_replicator/src/couch_replicator_scheduler_job.erl
index 412ff7d05..565a2bd97 100644
--- a/src/couch_replicator/src/couch_replicator_scheduler_job.erl
+++ b/src/couch_replicator/src/couch_replicator_scheduler_job.erl
@@ -40,8 +40,6 @@
]).
-import(couch_replicator_utils, [
- start_db_compaction_notifier/2,
- stop_db_compaction_notifier/1,
pp_rep_id/1
]).
@@ -75,8 +73,6 @@
workers,
stats = couch_replicator_stats:new(),
session_id,
- source_db_compaction_notifier = nil,
- target_db_compaction_notifier = nil,
source_monitor = nil,
target_monitor = nil,
source_seq = nil,
@@ -226,21 +222,6 @@ handle_call({report_seq_done, Seq, StatsInc}, From,
update_task(NewState),
{noreply, NewState}.
-handle_cast({db_compacted, DbName}, State) ->
- #rep_state{
- source = Source,
- target = Target
- } = State,
- SourceName = couch_replicator_utils:local_db_name(Source),
- TargetName = couch_replicator_utils:local_db_name(Target),
- case DbName of
- SourceName ->
- {ok, NewSource} = couch_db:reopen(Source),
- {noreply, State#rep_state{source = NewSource}};
- TargetName ->
- {ok, NewTarget} = couch_db:reopen(Target),
- {noreply, State#rep_state{target = NewTarget}}
- end;
handle_cast(checkpoint, State) ->
case do_checkpoint(State) of
@@ -412,8 +393,6 @@ terminate(Reason, State) ->
terminate_cleanup(State) ->
update_task(State),
- stop_db_compaction_notifier(State#rep_state.source_db_compaction_notifier),
- stop_db_compaction_notifier(State#rep_state.target_db_compaction_notifier),
couch_replicator_api_wrap:db_close(State#rep_state.source),
couch_replicator_api_wrap:db_close(State#rep_state.target).
@@ -572,16 +551,16 @@ init_state(Rep) ->
#rep{
id = {BaseId, _Ext},
source = Src0, target = Tgt,
- options = Options, user_ctx = UserCtx,
+ options = Options,
type = Type, view = View,
start_time = StartTime,
stats = Stats
} = Rep,
% Adjust minimum number of http source connections to 2 to avoid deadlock
Src = adjust_maxconn(Src0, BaseId),
- {ok, Source} = couch_replicator_api_wrap:db_open(Src, [{user_ctx, UserCtx}]),
+ {ok, Source} = couch_replicator_api_wrap:db_open(Src),
{CreateTargetParams} = get_value(create_target_params, Options, {[]}),
- {ok, Target} = couch_replicator_api_wrap:db_open(Tgt, [{user_ctx, UserCtx}],
+ {ok, Target} = couch_replicator_api_wrap:db_open(Tgt,
get_value(create_target, Options, false), CreateTargetParams),
{ok, SourceInfo} = couch_replicator_api_wrap:get_db_info(Source),
@@ -613,10 +592,6 @@ init_state(Rep) ->
src_starttime = get_value(<<"instance_start_time">>, SourceInfo),
tgt_starttime = get_value(<<"instance_start_time">>, TargetInfo),
session_id = couch_uuids:random(),
- source_db_compaction_notifier =
- start_db_compaction_notifier(Source, self()),
- target_db_compaction_notifier =
- start_db_compaction_notifier(Target, self()),
source_monitor = db_monitor(Source),
target_monitor = db_monitor(Target),
source_seq = SourceSeq,
diff --git a/src/couch_replicator/src/couch_replicator_utils.erl b/src/couch_replicator/src/couch_replicator_utils.erl
index b0d706953..ccf241324 100644
--- a/src/couch_replicator/src/couch_replicator_utils.erl
+++ b/src/couch_replicator/src/couch_replicator_utils.erl
@@ -14,11 +14,6 @@
-export([
parse_rep_doc/2,
- open_db/1,
- close_db/1,
- local_db_name/1,
- start_db_compaction_notifier/2,
- stop_db_compaction_notifier/1,
replication_id/2,
sum_stats/2,
is_deleted/1,
@@ -32,9 +27,6 @@
normalize_rep/1
]).
--export([
- handle_db_event/3
-]).
-include_lib("couch/include/couch_db.hrl").
-include("couch_replicator.hrl").
@@ -46,50 +38,6 @@
]).
-open_db(#httpdb{} = HttpDb) ->
- HttpDb;
-open_db(Db) ->
- DbName = couch_db:name(Db),
- UserCtx = couch_db:get_user_ctx(Db),
- {ok, NewDb} = couch_db:open(DbName, [{user_ctx, UserCtx}]),
- NewDb.
-
-
-close_db(#httpdb{}) ->
- ok;
-close_db(Db) ->
- couch_db:close(Db).
-
-
-local_db_name(#httpdb{}) ->
- undefined;
-local_db_name(Db) ->
- couch_db:name(Db).
-
-
-start_db_compaction_notifier(#httpdb{}, _) ->
- nil;
-start_db_compaction_notifier(Db, Server) ->
- DbName = couch_db:name(Db),
- {ok, Pid} = couch_event:link_listener(
- ?MODULE, handle_db_event, Server, [{dbname, DbName}]
- ),
- Pid.
-
-
-stop_db_compaction_notifier(nil) ->
- ok;
-stop_db_compaction_notifier(Listener) ->
- couch_event:stop_listener(Listener).
-
-
-handle_db_event(DbName, compacted, Server) ->
- gen_server:cast(Server, {db_compacted, DbName}),
- {ok, Server};
-handle_db_event(_DbName, _Event, Server) ->
- {ok, Server}.
-
-
rep_error_to_binary(Error) ->
couch_util:to_binary(error_reason(Error)).
@@ -289,14 +237,14 @@ normalize_rep_test_() ->
?_test(begin
EJson1 = {[
{<<"source">>, <<"http://host.com/source_db">>},
- {<<"target">>, <<"local">>},
+ {<<"target">>, <<"http://target.local/db">>},
{<<"doc_ids">>, [<<"a">>, <<"c">>, <<"b">>]},
{<<"other_field">>, <<"some_value">>}
]},
Rep1 = couch_replicator_docs:parse_rep_doc_without_id(EJson1),
EJson2 = {[
{<<"other_field">>, <<"unrelated">>},
- {<<"target">>, <<"local">>},
+ {<<"target">>, <<"http://target.local/db">>},
{<<"source">>, <<"http://host.com/source_db">>},
{<<"doc_ids">>, [<<"c">>, <<"a">>, <<"b">>]},
{<<"other_field2">>, <<"unrelated2">>}
diff --git a/src/couch_replicator/src/couch_replicator_worker.erl b/src/couch_replicator/src/couch_replicator_worker.erl
index ec98fa0f3..986c32c0a 100644
--- a/src/couch_replicator/src/couch_replicator_worker.erl
+++ b/src/couch_replicator/src/couch_replicator_worker.erl
@@ -28,18 +28,11 @@
% TODO: maybe make both buffer max sizes configurable
-define(DOC_BUFFER_BYTE_SIZE, 512 * 1024). % for remote targets
--define(DOC_BUFFER_LEN, 10). % for local targets, # of documents
-define(MAX_BULK_ATT_SIZE, 64 * 1024).
-define(MAX_BULK_ATTS_PER_DOC, 8).
-define(STATS_DELAY, 10000000). % 10 seconds (in microseconds)
-define(MISSING_DOC_RETRY_MSEC, 2000).
--import(couch_replicator_utils, [
- open_db/1,
- close_db/1,
- start_db_compaction_notifier/2,
- stop_db_compaction_notifier/1
-]).
-import(couch_util, [
to_binary/1,
get_value/3
@@ -62,8 +55,6 @@
pending_fetch = nil,
flush_waiter = nil,
stats = couch_replicator_stats:new(),
- source_db_compaction_notifier = nil,
- target_db_compaction_notifier = nil,
batch = #batch{}
}).
@@ -71,14 +62,7 @@
start_link(Cp, #httpdb{} = Source, Target, ChangesManager, MaxConns) ->
gen_server:start_link(
- ?MODULE, {Cp, Source, Target, ChangesManager, MaxConns}, []);
-
-start_link(Cp, Source, Target, ChangesManager, _MaxConns) ->
- Pid = spawn_link(fun() ->
- erlang:put(last_stats_report, os:timestamp()),
- queue_fetch_loop(Source, Target, Cp, Cp, ChangesManager)
- end),
- {ok, Pid}.
+ ?MODULE, {Cp, Source, Target, ChangesManager, MaxConns}, []).
init({Cp, Source, Target, ChangesManager, MaxConns}) ->
@@ -92,12 +76,8 @@ init({Cp, Source, Target, ChangesManager, MaxConns}) ->
cp = Cp,
max_parallel_conns = MaxConns,
loop = LoopPid,
- source = open_db(Source),
- target = open_db(Target),
- source_db_compaction_notifier =
- start_db_compaction_notifier(Source, self()),
- target_db_compaction_notifier =
- start_db_compaction_notifier(Target, self())
+ source = Source,
+ target = Target
},
{ok, State}.
@@ -141,24 +121,6 @@ handle_call(flush, {Pid, _} = From,
{noreply, State2#state{flush_waiter = From}}.
-handle_cast({db_compacted, DbName} = Msg, #state{} = State) ->
- #state{
- source = Source,
- target = Target
- } = State,
- SourceName = couch_replicator_utils:local_db_name(Source),
- TargetName = couch_replicator_utils:local_db_name(Target),
- case DbName of
- SourceName ->
- {ok, NewSource} = couch_db:reopen(Source),
- {noreply, State#state{source = NewSource}};
- TargetName ->
- {ok, NewTarget} = couch_db:reopen(Target),
- {noreply, State#state{target = NewTarget}};
- _Else ->
- {stop, {unexpected_async_call, Msg}, State}
- end;
-
handle_cast(Msg, State) ->
{stop, {unexpected_async_call, Msg}, State}.
@@ -213,11 +175,8 @@ handle_info({'EXIT', Pid, Reason}, State) ->
{stop, {process_died, Pid, Reason}, State}.
-terminate(_Reason, State) ->
- close_db(State#state.source),
- close_db(State#state.target),
- stop_db_compaction_notifier(State#state.source_db_compaction_notifier),
- stop_db_compaction_notifier(State#state.target_db_compaction_notifier).
+terminate(_Reason, _State) ->
+ ok.
format_status(_Opt, [_PDict, State]) ->
#state{
@@ -253,20 +212,10 @@ queue_fetch_loop(Source, Target, Parent, Cp, ChangesManager) ->
ok = gen_server:call(Cp, {report_seq_done, ReportSeq, Stats}, infinity),
queue_fetch_loop(Source, Target, Parent, Cp, ChangesManager);
{changes, ChangesManager, Changes, ReportSeq} ->
- Target2 = open_db(Target),
- {IdRevs, Stats0} = find_missing(Changes, Target2),
- case Source of
- #httpdb{} ->
- ok = gen_server:call(Parent, {add_stats, Stats0}, infinity),
- remote_process_batch(IdRevs, Parent),
- {ok, Stats} = gen_server:call(Parent, flush, infinity);
- _Db ->
- Source2 = open_db(Source),
- Stats = local_process_batch(
- IdRevs, Cp, Source2, Target2, #batch{}, Stats0),
- close_db(Source2)
- end,
- close_db(Target2),
+ {IdRevs, Stats0} = find_missing(Changes, Target),
+ ok = gen_server:call(Parent, {add_stats, Stats0}, infinity),
+ remote_process_batch(IdRevs, Parent),
+ {ok, Stats} = gen_server:call(Parent, flush, infinity),
ok = gen_server:call(Cp, {report_seq_done, ReportSeq, Stats}, infinity),
erlang:put(last_stats_report, os:timestamp()),
couch_log:debug("Worker reported completion of seq ~p", [ReportSeq]),
@@ -274,32 +223,6 @@ queue_fetch_loop(Source, Target, Parent, Cp, ChangesManager) ->
end.
-local_process_batch([], _Cp, _Src, _Tgt, #batch{docs = []}, Stats) ->
- Stats;
-
-local_process_batch([], Cp, Source, Target, #batch{docs = Docs, size = Size}, Stats) ->
- case Target of
- #httpdb{} ->
- couch_log:debug("Worker flushing doc batch of size ~p bytes", [Size]);
- _Db ->
- couch_log:debug("Worker flushing doc batch of ~p docs", [Size])
- end,
- Stats2 = flush_docs(Target, Docs),
- Stats3 = couch_replicator_utils:sum_stats(Stats, Stats2),
- local_process_batch([], Cp, Source, Target, #batch{}, Stats3);
-
-local_process_batch([IdRevs | Rest], Cp, Source, Target, Batch, Stats) ->
- {ok, {_, DocList, Stats2, _}} = fetch_doc(
- Source, IdRevs, fun local_doc_handler/2, {Target, [], Stats, Cp}),
- {Batch2, Stats3} = lists:foldl(
- fun(Doc, {Batch0, Stats0}) ->
- {Batch1, S} = maybe_flush_docs(Target, Batch0, Doc),
- {Batch1, couch_replicator_utils:sum_stats(Stats0, S)}
- end,
- {Batch, Stats2}, DocList),
- local_process_batch(Rest, Cp, Source, Target, Batch2, Stats3).
-
-
remote_process_batch([], _Parent) ->
ok;
@@ -319,10 +242,8 @@ remote_process_batch([{Id, Revs, PAs} | Rest], Parent) ->
spawn_doc_reader(Source, Target, FetchParams) ->
Parent = self(),
spawn_link(fun() ->
- Source2 = open_db(Source),
fetch_doc(
- Source2, FetchParams, fun remote_doc_handler/2, {Parent, Target}),
- close_db(Source2)
+ Source, FetchParams, fun remote_doc_handler/2, {Parent, Target})
end).
@@ -350,29 +271,6 @@ fetch_doc(Source, {Id, Revs, PAs}, DocHandler, Acc) ->
end.
-local_doc_handler({ok, Doc}, {Target, DocList, Stats, Cp}) ->
- Stats2 = couch_replicator_stats:increment(docs_read, Stats),
- case batch_doc(Doc) of
- true ->
- {ok, {Target, [Doc | DocList], Stats2, Cp}};
- false ->
- couch_log:debug("Worker flushing doc with attachments", []),
- Target2 = open_db(Target),
- Success = (flush_doc(Target2, Doc) =:= ok),
- close_db(Target2),
- Stats3 = case Success of
- true ->
- couch_replicator_stats:increment(docs_written, Stats2);
- false ->
- couch_replicator_stats:increment(doc_write_failures, Stats2)
- end,
- Stats4 = maybe_report_stats(Cp, Stats3),
- {ok, {Target, DocList, Stats4, Cp}}
- end;
-local_doc_handler(_, Acc) ->
- {ok, Acc}.
-
-
remote_doc_handler({ok, #doc{atts = []} = Doc}, {Parent, _} = Acc) ->
ok = gen_server:call(Parent, {batch_doc, Doc}, infinity),
{ok, Acc};
@@ -383,9 +281,7 @@ remote_doc_handler({ok, Doc}, {Parent, Target} = Acc) ->
% convenient to call it ASAP to avoid ibrowse inactivity timeouts.
Stats = couch_replicator_stats:new([{docs_read, 1}]),
couch_log:debug("Worker flushing doc with attachments", []),
- Target2 = open_db(Target),
- Success = (flush_doc(Target2, Doc) =:= ok),
- close_db(Target2),
+ Success = (flush_doc(Target, Doc) =:= ok),
{Result, Stats2} = case Success of
true ->
{{ok, Acc}, couch_replicator_stats:increment(docs_written, Stats)};
@@ -402,17 +298,13 @@ spawn_writer(Target, #batch{docs = DocList, size = Size}) ->
case {Target, Size > 0} of
{#httpdb{}, true} ->
couch_log:debug("Worker flushing doc batch of size ~p bytes", [Size]);
- {_Db, true} ->
- couch_log:debug("Worker flushing doc batch of ~p docs", [Size]);
_ ->
ok
end,
Parent = self(),
spawn_link(
fun() ->
- Target2 = open_db(Target),
- Stats = flush_docs(Target2, DocList),
- close_db(Target2),
+ Stats = flush_docs(Target, DocList),
ok = gen_server:call(Parent, {add_stats, Stats}, infinity)
end).
@@ -462,17 +354,6 @@ maybe_flush_docs(#httpdb{} = Target, Batch, Doc) ->
Stats = couch_replicator_stats:new(),
{#batch{docs = [JsonDoc | DocAcc], size = SizeAcc2}, Stats}
end
- end;
-
-maybe_flush_docs(Target, #batch{docs = DocAcc, size = SizeAcc}, Doc) ->
- case SizeAcc + 1 of
- SizeAcc2 when SizeAcc2 >= ?DOC_BUFFER_LEN ->
- couch_log:debug("Worker flushing doc batch of ~p docs", [SizeAcc2]),
- Stats = flush_docs(Target, [Doc | DocAcc]),
- {#batch{}, Stats};
- SizeAcc2 ->
- Stats = couch_replicator_stats:new(),
- {#batch{docs = [Doc | DocAcc], size = SizeAcc2}, Stats}
end.
diff --git a/src/couch_replicator/test/couch_replicator_attachments_too_large.erl b/src/couch_replicator/test/eunit/couch_replicator_attachments_too_large.erl
index 7fe84d2d9..ac4bb84f3 100644
--- a/src/couch_replicator/test/couch_replicator_attachments_too_large.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_attachments_too_large.erl
@@ -33,7 +33,7 @@ teardown(_, {Ctx, {Source, Target}}) ->
attachment_too_large_replication_test_() ->
- Pairs = [{local, remote}, {remote, local}, {remote, remote}],
+ Pairs = [{remote, remote}],
{
"Attachment size too large replication tests",
{
@@ -96,8 +96,6 @@ delete_db(DbName) ->
ok = couch_server:delete(DbName, [?ADMIN_CTX]).
-db_url(local, DbName) ->
- DbName;
db_url(remote, DbName) ->
Addr = config:get("httpd", "bind_address", "127.0.0.1"),
Port = mochiweb_socket_server:get(couch_httpd, port),
diff --git a/src/couch_replicator/test/couch_replicator_compact_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_compact_tests.erl
index 7cc530c19..eb3fc82c5 100644
--- a/src/couch_replicator/test/couch_replicator_compact_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_compact_tests.erl
@@ -33,8 +33,6 @@ setup() ->
ok = couch_db:close(Db),
DbName.
-setup(local) ->
- setup();
setup(remote) ->
{remote, setup()};
setup({A, B}) ->
@@ -56,8 +54,7 @@ teardown(_, {Ctx, {Source, Target}}) ->
ok = test_util:stop_couch(Ctx).
compact_test_() ->
- Pairs = [{local, local}, {local, remote},
- {remote, local}, {remote, remote}],
+ Pairs = [{remote, remote}],
{
"Compaction during replication tests",
{
diff --git a/src/couch_replicator/test/couch_replicator_connection_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_connection_tests.erl
index e75cc5a63..e75cc5a63 100644
--- a/src/couch_replicator/test/couch_replicator_connection_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_connection_tests.erl
diff --git a/src/couch_replicator/test/couch_replicator_create_target_with_options_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_create_target_with_options_tests.erl
index 63310d39e..63310d39e 100644
--- a/src/couch_replicator/test/couch_replicator_create_target_with_options_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_create_target_with_options_tests.erl
diff --git a/src/couch_replicator/test/couch_replicator_filtered_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_filtered_tests.erl
index d34e9f020..70b25a31b 100644
--- a/src/couch_replicator/test/couch_replicator_filtered_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_filtered_tests.erl
@@ -60,8 +60,7 @@ teardown(_, {Ctx, {Source, Target}}) ->
ok = test_util:stop_couch(Ctx).
filtered_replication_test_() ->
- Pairs = [{local, local}, {local, remote},
- {remote, local}, {remote, remote}],
+ Pairs = [{remote, remote}],
{
"Filtered replication tests",
{
@@ -72,8 +71,7 @@ filtered_replication_test_() ->
}.
query_filtered_replication_test_() ->
- Pairs = [{local, local}, {local, remote},
- {remote, local}, {remote, remote}],
+ Pairs = [{remote, remote}],
{
"Filtered with query replication tests",
{
@@ -84,7 +82,7 @@ query_filtered_replication_test_() ->
}.
view_filtered_replication_test_() ->
- Pairs = [{local, local}],
+ Pairs = [{remote, remote}],
{
"Filtered with a view replication tests",
{
@@ -236,8 +234,6 @@ create_docs(DbName) ->
delete_db(DbName) ->
ok = couch_server:delete(DbName, [?ADMIN_CTX]).
-db_url(local, DbName) ->
- DbName;
db_url(remote, DbName) ->
Addr = config:get("httpd", "bind_address", "127.0.0.1"),
Port = mochiweb_socket_server:get(couch_httpd, port),
diff --git a/src/couch_replicator/test/couch_replicator_httpc_pool_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_httpc_pool_tests.erl
index c4ad4e9b6..c4ad4e9b6 100644
--- a/src/couch_replicator/test/couch_replicator_httpc_pool_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_httpc_pool_tests.erl
diff --git a/src/couch_replicator/test/couch_replicator_id_too_long_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_id_too_long_tests.erl
index 70eda0566..1447acfa7 100644
--- a/src/couch_replicator/test/couch_replicator_id_too_long_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_id_too_long_tests.erl
@@ -33,8 +33,7 @@ teardown(_, {Ctx, {Source, Target}}) ->
id_too_long_replication_test_() ->
- Pairs = [{local, local}, {local, remote},
- {remote, local}, {remote, remote}],
+ Pairs = [{remote, remote}],
{
"Doc id too long tests",
{
@@ -86,8 +85,6 @@ delete_db(DbName) ->
ok = couch_server:delete(DbName, [?ADMIN_CTX]).
-db_url(local, DbName) ->
- DbName;
db_url(remote, DbName) ->
Addr = config:get("httpd", "bind_address", "127.0.0.1"),
Port = mochiweb_socket_server:get(couch_httpd, port),
diff --git a/src/couch_replicator/test/couch_replicator_large_atts_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_large_atts_tests.erl
index b9adf5c4b..27c89a0cd 100644
--- a/src/couch_replicator/test/couch_replicator_large_atts_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_large_atts_tests.erl
@@ -33,8 +33,6 @@ setup() ->
ok = couch_db:close(Db),
DbName.
-setup(local) ->
- setup();
setup(remote) ->
{remote, setup()};
setup({A, B}) ->
@@ -58,8 +56,7 @@ teardown(_, {Ctx, {Source, Target}}) ->
ok = test_util:stop_couch(Ctx).
large_atts_test_() ->
- Pairs = [{local, local}, {local, remote},
- {remote, local}, {remote, remote}],
+ Pairs = [{remote, remote}],
{
"Replicate docs with large attachments",
{
diff --git a/src/couch_replicator/test/couch_replicator_many_leaves_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_many_leaves_tests.erl
index eee5b1647..be1bfa344 100644
--- a/src/couch_replicator/test/couch_replicator_many_leaves_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_many_leaves_tests.erl
@@ -37,8 +37,7 @@ setup() ->
ok = couch_db:close(Db),
DbName.
-setup(local) ->
- setup();
+
setup(remote) ->
{remote, setup()};
setup({A, B}) ->
@@ -60,8 +59,7 @@ teardown(_, {Ctx, {Source, Target}}) ->
ok = test_util:stop_couch(Ctx).
docs_with_many_leaves_test_() ->
- Pairs = [{local, local}, {local, remote},
- {remote, local}, {remote, remote}],
+ Pairs = [{remote, remote}],
{
"Replicate documents with many leaves",
{
diff --git a/src/couch_replicator/test/couch_replicator_missing_stubs_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_missing_stubs_tests.erl
index c1681781f..ff08b5ee5 100644
--- a/src/couch_replicator/test/couch_replicator_missing_stubs_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_missing_stubs_tests.erl
@@ -30,8 +30,6 @@ setup() ->
ok = couch_db:close(Db),
DbName.
-setup(local) ->
- setup();
setup(remote) ->
{remote, setup()};
setup({A, B}) ->
@@ -53,8 +51,7 @@ teardown(_, {Ctx, {Source, Target}}) ->
ok = test_util:stop_couch(Ctx).
missing_stubs_test_() ->
- Pairs = [{local, local}, {local, remote},
- {remote, local}, {remote, remote}],
+ Pairs = [{remote, remote}],
{
"Replicate docs with missing stubs (COUCHDB-1365)",
{
diff --git a/src/couch_replicator/test/couch_replicator_proxy_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_proxy_tests.erl
index 4f545bcb5..4f545bcb5 100644
--- a/src/couch_replicator/test/couch_replicator_proxy_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_proxy_tests.erl
diff --git a/src/couch_replicator/test/couch_replicator_rate_limiter_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_rate_limiter_tests.erl
index 034550aec..034550aec 100644
--- a/src/couch_replicator/test/couch_replicator_rate_limiter_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_rate_limiter_tests.erl
diff --git a/src/couch_replicator/test/couch_replicator_retain_stats_between_job_runs.erl b/src/couch_replicator/test/eunit/couch_replicator_retain_stats_between_job_runs.erl
index 3b7377b78..3b7377b78 100644
--- a/src/couch_replicator/test/couch_replicator_retain_stats_between_job_runs.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_retain_stats_between_job_runs.erl
diff --git a/src/couch_replicator/test/couch_replicator_selector_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_selector_tests.erl
index a7f4c5df3..7d92bdcb1 100644
--- a/src/couch_replicator/test/couch_replicator_selector_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_selector_tests.erl
@@ -31,8 +31,7 @@ teardown(_, {Ctx, {Source, Target}}) ->
ok = test_util:stop_couch(Ctx).
selector_replication_test_() ->
- Pairs = [{local, local}, {local, remote},
- {remote, local}, {remote, remote}],
+ Pairs = [{remote, remote}],
{
"Selector filtered replication tests",
{
@@ -113,8 +112,6 @@ create_docs(DbName) ->
delete_db(DbName) ->
ok = couch_server:delete(DbName, [?ADMIN_CTX]).
-db_url(local, DbName) ->
- DbName;
db_url(remote, DbName) ->
Addr = config:get("httpd", "bind_address", "127.0.0.1"),
Port = mochiweb_socket_server:get(couch_httpd, port),
diff --git a/src/couch_replicator/test/couch_replicator_small_max_request_size_target.erl b/src/couch_replicator/test/eunit/couch_replicator_small_max_request_size_target.erl
index af3a285f5..8aebbe151 100644
--- a/src/couch_replicator/test/couch_replicator_small_max_request_size_target.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_small_max_request_size_target.erl
@@ -19,9 +19,6 @@ setup() ->
DbName.
-setup(local) ->
- setup();
-
setup(remote) ->
{remote, setup()};
@@ -47,7 +44,7 @@ teardown(_, {Ctx, {Source, Target}}) ->
reduce_max_request_size_test_() ->
- Pairs = [{local, remote}, {remote, remote}],
+ Pairs = [{remote, remote}],
{
"Replicate docs when target has a small max_http_request_size",
{
diff --git a/src/couch_replicator/test/couch_replicator_test_helper.erl b/src/couch_replicator/test/eunit/couch_replicator_test_helper.erl
index fd0409164..fd0409164 100644
--- a/src/couch_replicator/test/couch_replicator_test_helper.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_test_helper.erl
diff --git a/src/couch_replicator/test/couch_replicator_use_checkpoints_tests.erl b/src/couch_replicator/test/eunit/couch_replicator_use_checkpoints_tests.erl
index c2fcf8bf1..8e4a21dbb 100644
--- a/src/couch_replicator/test/couch_replicator_use_checkpoints_tests.erl
+++ b/src/couch_replicator/test/eunit/couch_replicator_use_checkpoints_tests.erl
@@ -51,8 +51,6 @@ setup() ->
ok = couch_db:close(Db),
DbName.
-setup(local) ->
- setup();
setup(remote) ->
{remote, setup()};
setup({_, Fun, {A, B}}) ->
@@ -88,8 +86,7 @@ use_checkpoints_test_() ->
}.
use_checkpoints_tests(UseCheckpoints, Fun) ->
- Pairs = [{local, local}, {local, remote},
- {remote, local}, {remote, remote}],
+ Pairs = [{remote, remote}],
{
"use_checkpoints: " ++ atom_to_list(UseCheckpoints),
{
diff --git a/src/ddoc_cache/test/ddoc_cache_basic_test.erl b/src/ddoc_cache/test/eunit/ddoc_cache_basic_test.erl
index b576d88bb..b576d88bb 100644
--- a/src/ddoc_cache/test/ddoc_cache_basic_test.erl
+++ b/src/ddoc_cache/test/eunit/ddoc_cache_basic_test.erl
diff --git a/src/ddoc_cache/test/ddoc_cache_coverage_test.erl b/src/ddoc_cache/test/eunit/ddoc_cache_coverage_test.erl
index b1a185bdc..b1a185bdc 100644
--- a/src/ddoc_cache/test/ddoc_cache_coverage_test.erl
+++ b/src/ddoc_cache/test/eunit/ddoc_cache_coverage_test.erl
diff --git a/src/ddoc_cache/test/ddoc_cache_disabled_test.erl b/src/ddoc_cache/test/eunit/ddoc_cache_disabled_test.erl
index d46bdde32..d46bdde32 100644
--- a/src/ddoc_cache/test/ddoc_cache_disabled_test.erl
+++ b/src/ddoc_cache/test/eunit/ddoc_cache_disabled_test.erl
diff --git a/src/ddoc_cache/test/ddoc_cache_entry_test.erl b/src/ddoc_cache/test/eunit/ddoc_cache_entry_test.erl
index c992bea8d..c992bea8d 100644
--- a/src/ddoc_cache/test/ddoc_cache_entry_test.erl
+++ b/src/ddoc_cache/test/eunit/ddoc_cache_entry_test.erl
diff --git a/src/ddoc_cache/test/ddoc_cache_ev.erl b/src/ddoc_cache/test/eunit/ddoc_cache_ev.erl
index a451342cf..a451342cf 100644
--- a/src/ddoc_cache/test/ddoc_cache_ev.erl
+++ b/src/ddoc_cache/test/eunit/ddoc_cache_ev.erl
diff --git a/src/ddoc_cache/test/ddoc_cache_eviction_test.erl b/src/ddoc_cache/test/eunit/ddoc_cache_eviction_test.erl
index bd61afc37..bd61afc37 100644
--- a/src/ddoc_cache/test/ddoc_cache_eviction_test.erl
+++ b/src/ddoc_cache/test/eunit/ddoc_cache_eviction_test.erl
diff --git a/src/ddoc_cache/test/ddoc_cache_lru_test.erl b/src/ddoc_cache/test/eunit/ddoc_cache_lru_test.erl
index e37f1c090..9a5391587 100644
--- a/src/ddoc_cache/test/ddoc_cache_lru_test.erl
+++ b/src/ddoc_cache/test/eunit/ddoc_cache_lru_test.erl
@@ -47,14 +47,17 @@ stop_couch(Ctx) ->
check_not_started_test() ->
% Starting couch, but not ddoc_cache
- Ctx = test_util:start_couch(),
- try
- Key = {ddoc_cache_entry_custom, {<<"dbname">>, ?MODULE}},
- ?assertEqual({ok, <<"dbname">>}, ddoc_cache_lru:open(Key))
- after
- test_util:stop_couch(Ctx)
- end.
-
+ {
+ setup,
+ fun test_util:start_couch/0,
+ fun test_util:stop_couch/1,
+ [
+ fun(_) ->
+ Key = {ddoc_cache_entry_custom, {<<"dbname">>, ?MODULE}},
+ ?assertEqual({ok, <<"dbname">>}, ddoc_cache_lru:open(Key))
+ end
+ ]
+ }.
check_lru_test_() ->
{
diff --git a/src/ddoc_cache/test/ddoc_cache_no_cache_test.erl b/src/ddoc_cache/test/eunit/ddoc_cache_no_cache_test.erl
index 637a6e872..a1937a088 100644
--- a/src/ddoc_cache/test/ddoc_cache_no_cache_test.erl
+++ b/src/ddoc_cache/test/eunit/ddoc_cache_no_cache_test.erl
@@ -35,45 +35,43 @@ return_error(_DDocId) ->
{error, timeout}.
-start(Resp) ->
- Ctx = ddoc_cache_tutil:start_couch(),
+no_cache_test_() ->
+ {
+ "ddoc_cache no cache test",
+ {
+ setup,
+ fun ddoc_cache_tutil:start_couch/0, fun ddoc_cache_tutil:stop_couch/1,
+ {
+ foreachx,
+ fun setup/1, fun teardown/2,
+ [
+ {fun ddoc/1, fun no_cache_open_ok_test/2},
+ {fun not_found/1, fun no_cache_open_not_found_test/2},
+ {fun return_error/1, fun no_cache_open_error_test/2}
+ ]
+ }
+ }
+ }.
+
+setup(Resp) ->
meck:new(fabric),
meck:expect(fabric, open_doc, fun(_, DDocId, _) ->
Resp(DDocId)
- end),
- Ctx.
-
-
-stop(Ctx) ->
- meck:unload(),
- ddoc_cache_tutil:stop_couch(Ctx).
-
-
-no_cache_open_ok_test() ->
- Ctx = start(fun ddoc/1),
- try
- Resp = ddoc_cache:open_doc(<<"foo">>, <<"bar">>),
- ?assertEqual(ddoc(<<"bar">>), Resp)
- after
- stop(Ctx)
- end.
-
-
-no_cache_open_not_found_test() ->
- Ctx = start(fun not_found/1),
- try
- Resp = ddoc_cache:open_doc(<<"foo">>, <<"bar">>),
- ?assertEqual(not_found(<<"bar">>), Resp)
- after
- stop(Ctx)
- end.
-
-
-no_cache_open_error_test() ->
- Ctx = start(fun return_error/1),
- try
- Resp = ddoc_cache:open_doc(<<"foo">>, <<"bar">>),
- ?assertEqual(return_error(<<"bar">>), Resp)
- after
- stop(Ctx)
- end.
+ end).
+
+teardown(_, _) ->
+ meck:unload().
+
+no_cache_open_ok_test(_, _) ->
+ Resp = ddoc_cache:open_doc(<<"foo">>, <<"bar">>),
+ ?_assertEqual(ddoc(<<"bar">>), Resp).
+
+
+no_cache_open_not_found_test(_, _) ->
+ Resp = ddoc_cache:open_doc(<<"foo">>, <<"baz">>),
+ ?_assertEqual(not_found(<<"baz">>), Resp).
+
+
+no_cache_open_error_test(_, _) ->
+ Resp = ddoc_cache:open_doc(<<"foo">>, <<"bif">>),
+ ?_assertEqual(return_error(<<"bif">>), Resp).
diff --git a/src/ddoc_cache/test/ddoc_cache_open_error_test.erl b/src/ddoc_cache/test/eunit/ddoc_cache_open_error_test.erl
index c7379d26a..c7379d26a 100644
--- a/src/ddoc_cache/test/ddoc_cache_open_error_test.erl
+++ b/src/ddoc_cache/test/eunit/ddoc_cache_open_error_test.erl
diff --git a/src/ddoc_cache/test/ddoc_cache_open_test.erl b/src/ddoc_cache/test/eunit/ddoc_cache_open_test.erl
index 73d644f71..73d644f71 100644
--- a/src/ddoc_cache/test/ddoc_cache_open_test.erl
+++ b/src/ddoc_cache/test/eunit/ddoc_cache_open_test.erl
diff --git a/src/ddoc_cache/test/ddoc_cache_opener_test.erl b/src/ddoc_cache/test/eunit/ddoc_cache_opener_test.erl
index c3846360c..c3846360c 100644
--- a/src/ddoc_cache/test/ddoc_cache_opener_test.erl
+++ b/src/ddoc_cache/test/eunit/ddoc_cache_opener_test.erl
diff --git a/src/ddoc_cache/test/ddoc_cache_refresh_test.erl b/src/ddoc_cache/test/eunit/ddoc_cache_refresh_test.erl
index 24ae346d4..24ae346d4 100644
--- a/src/ddoc_cache/test/ddoc_cache_refresh_test.erl
+++ b/src/ddoc_cache/test/eunit/ddoc_cache_refresh_test.erl
diff --git a/src/ddoc_cache/test/ddoc_cache_remove_test.erl b/src/ddoc_cache/test/eunit/ddoc_cache_remove_test.erl
index e40518529..e40518529 100644
--- a/src/ddoc_cache/test/ddoc_cache_remove_test.erl
+++ b/src/ddoc_cache/test/eunit/ddoc_cache_remove_test.erl
diff --git a/src/ddoc_cache/test/ddoc_cache_test.hrl b/src/ddoc_cache/test/eunit/ddoc_cache_test.hrl
index 73f7bc217..73f7bc217 100644
--- a/src/ddoc_cache/test/ddoc_cache_test.hrl
+++ b/src/ddoc_cache/test/eunit/ddoc_cache_test.hrl
diff --git a/src/ddoc_cache/test/ddoc_cache_tutil.erl b/src/ddoc_cache/test/eunit/ddoc_cache_tutil.erl
index b34d4b163..b34d4b163 100644
--- a/src/ddoc_cache/test/ddoc_cache_tutil.erl
+++ b/src/ddoc_cache/test/eunit/ddoc_cache_tutil.erl
diff --git a/src/dreyfus/src/dreyfus_fabric_cleanup.erl b/src/dreyfus/src/dreyfus_fabric_cleanup.erl
index b5e030db0..2840a2f2d 100644
--- a/src/dreyfus/src/dreyfus_fabric_cleanup.erl
+++ b/src/dreyfus/src/dreyfus_fabric_cleanup.erl
@@ -53,12 +53,12 @@ cleanup_local_purge_doc(DbName, ActiveSigs) ->
end, [], LocalShards),
DeadDirs = DirList -- ActiveDirs,
- lists:foldl(fun(IdxDir) ->
+ lists:foreach(fun(IdxDir) ->
Sig = dreyfus_util:get_signature_from_idxdir(IdxDir),
case Sig of undefined -> ok; _ ->
DocId = dreyfus_util:get_local_purge_doc_id(Sig),
LocalShards = mem3:local_shards(DbName),
- lists:foldl(fun(LS, _AccOuter) ->
+ lists:foreach(fun(LS) ->
ShardDbName = LS#shard.name,
{ok, ShardDb} = couch_db:open_int(ShardDbName, []),
case couch_db:open_doc(ShardDb, DocId, []) of
@@ -69,6 +69,6 @@ cleanup_local_purge_doc(DbName, ActiveSigs) ->
ok
end,
couch_db:close(ShardDb)
- end, [], LocalShards)
+ end, LocalShards)
end
- end, [], DeadDirs).
+ end, DeadDirs).
diff --git a/src/dreyfus/src/dreyfus_util.erl b/src/dreyfus/src/dreyfus_util.erl
index ae3133e7d..6832299db 100644
--- a/src/dreyfus/src/dreyfus_util.erl
+++ b/src/dreyfus/src/dreyfus_util.erl
@@ -332,7 +332,10 @@ get_local_purge_doc_id(Sig) ->
get_signature_from_idxdir(IdxDir) ->
IdxDirList = filename:split(IdxDir),
Sig = lists:last(IdxDirList),
- case [Ch || Ch <- Sig, not (((Ch >= $0) and (Ch =< $9))
+ Sig2 = if not is_binary(Sig) -> Sig; true ->
+ binary_to_list(Sig)
+ end,
+ case [Ch || Ch <- Sig2, not (((Ch >= $0) and (Ch =< $9))
orelse ((Ch >= $a) and (Ch =< $f))
orelse ((Ch >= $A) and (Ch =< $F)))] == [] of
true -> Sig;
diff --git a/src/dreyfus/test/elixir/test/partition_search_test.exs b/src/dreyfus/test/elixir/test/partition_search_test.exs
index 052a41ad1..4400d7b7f 100644
--- a/src/dreyfus/test/elixir/test/partition_search_test.exs
+++ b/src/dreyfus/test/elixir/test/partition_search_test.exs
@@ -26,12 +26,12 @@ defmodule PartitionSearchTest do
end
def create_ddoc(db_name, opts \\ %{}) do
- indexFn = "function(doc) {\n if (doc.some) {\n index('some', doc.some);\n }\n}"
+ index_fn = "function(doc) {\n if (doc.some) {\n index('some', doc.some);\n }\n}"
default_ddoc = %{
indexes: %{
books: %{
analyzer: %{name: "standard"},
- index: indexFn
+ index: index_fn
}
}
}
diff --git a/src/fabric/src/fabric.erl b/src/fabric/src/fabric.erl
index 6d04184e6..27fa8c045 100644
--- a/src/fabric/src/fabric.erl
+++ b/src/fabric/src/fabric.erl
@@ -36,7 +36,8 @@
% miscellany
-export([design_docs/1, reset_validation_funs/1, cleanup_index_files/0,
- cleanup_index_files/1, cleanup_index_files_all_nodes/1, dbname/1]).
+ cleanup_index_files/1, cleanup_index_files_all_nodes/1, dbname/1,
+ inactive_index_files/1]).
-include_lib("fabric/include/fabric.hrl").
@@ -503,26 +504,33 @@ cleanup_index_files() ->
%% @doc clean up index files for a specific db
-spec cleanup_index_files(dbname()) -> ok.
cleanup_index_files(DbName) ->
+ lists:foreach(fun(File) ->
+ file:delete(File)
+ end, inactive_index_files(DbName)).
+
+%% @doc inactive index files for a specific db
+-spec inactive_index_files(dbname()) -> ok.
+inactive_index_files(DbName) ->
{ok, DesignDocs} = fabric:design_docs(DbName),
- ActiveSigs = lists:map(fun(#doc{id = GroupId}) ->
+ ActiveSigs = maps:from_list(lists:map(fun(#doc{id = GroupId}) ->
{ok, Info} = fabric:get_view_group_info(DbName, GroupId),
- binary_to_list(couch_util:get_value(signature, Info))
- end, [couch_doc:from_json_obj(DD) || DD <- DesignDocs]),
+ {binary_to_list(couch_util:get_value(signature, Info)), nil}
+ end, [couch_doc:from_json_obj(DD) || DD <- DesignDocs])),
FileList = lists:flatmap(fun(#shard{name = ShardName}) ->
IndexDir = couch_index_util:index_dir(mrview, ShardName),
filelib:wildcard([IndexDir, "/*"])
end, mem3:local_shards(dbname(DbName))),
- DeleteFiles = if ActiveSigs =:= [] -> FileList; true ->
- {ok, RegExp} = re:compile([$(, string:join(ActiveSigs, "|"), $)]),
+ if ActiveSigs =:= [] -> FileList; true ->
+ %% <sig>.view and <sig>.compact.view where <sig> is in ActiveSigs
+ %% will be excluded from FileList because they are active view
+ %% files and should not be deleted.
lists:filter(fun(FilePath) ->
- re:run(FilePath, RegExp, [{capture, none}]) == nomatch
+ not maps:is_key(get_view_sig_from_filename(FilePath), ActiveSigs)
end, FileList)
- end,
- [file:delete(File) || File <- DeleteFiles],
- ok.
+ end.
%% @doc clean up index files for a specific db on all nodes
-spec cleanup_index_files_all_nodes(dbname()) -> [reference()].
@@ -657,6 +665,8 @@ kl_to_record(KeyList,RecName) ->
set_namespace(NS, #mrargs{extra = Extra} = Args) ->
Args#mrargs{extra = [{namespace, NS} | Extra]}.
+get_view_sig_from_filename(FilePath) ->
+ filename:basename(filename:basename(FilePath, ".view"), ".compact").
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
diff --git a/src/fabric/src/fabric_db_info.erl b/src/fabric/src/fabric_db_info.erl
index bb7a3530e..ed14e3e20 100644
--- a/src/fabric/src/fabric_db_info.erl
+++ b/src/fabric/src/fabric_db_info.erl
@@ -99,14 +99,8 @@ merge_results(Info) ->
[{doc_del_count, lists:sum(X)} | Acc];
(compact_running, X, Acc) ->
[{compact_running, lists:member(true, X)} | Acc];
- (disk_size, X, Acc) -> % legacy
- [{disk_size, lists:sum(X)} | Acc];
- (data_size, X, Acc) -> % legacy
- [{data_size, lists:sum(X)} | Acc];
(sizes, X, Acc) ->
[{sizes, {merge_object(X)}} | Acc];
- (other, X, Acc) -> % legacy
- [{other, {merge_other_results(X)}} | Acc];
(disk_format_version, X, Acc) ->
[{disk_format_version, lists:max(X)} | Acc];
(cluster, [X], Acc) ->
@@ -117,17 +111,6 @@ merge_results(Info) ->
Acc
end, [{instance_start_time, <<"0">>}], Dict).
-merge_other_results(Results) ->
- Dict = lists:foldl(fun({Props}, D) ->
- lists:foldl(fun({K,V},D0) -> orddict:append(K,V,D0) end, D, Props)
- end, orddict:new(), Results),
- orddict:fold(fun
- (data_size, X, Acc) ->
- [{data_size, lists:sum(X)} | Acc];
- (_, _, Acc) ->
- Acc
- end, [], Dict).
-
merge_object(Objects) ->
Dict = lists:foldl(fun({Props}, D) ->
lists:foldl(fun({K,V},D0) -> orddict:append(K,V,D0) end, D, Props)
diff --git a/src/fabric/src/fabric_group_info.erl b/src/fabric/src/fabric_group_info.erl
index be507420e..91bdf01b0 100644
--- a/src/fabric/src/fabric_group_info.erl
+++ b/src/fabric/src/fabric_group_info.erl
@@ -111,10 +111,6 @@ merge_results(Info) ->
[{signature, X} | Acc];
(language, [X | _], Acc) ->
[{language, X} | Acc];
- (disk_size, X, Acc) -> % legacy
- [{disk_size, lists:sum(X)} | Acc];
- (data_size, X, Acc) -> % legacy
- [{data_size, lists:sum(X)} | Acc];
(sizes, X, Acc) ->
[{sizes, {merge_object(X)}} | Acc];
(compact_running, X, Acc) ->
diff --git a/src/fabric/src/fabric_view_all_docs.erl b/src/fabric/src/fabric_view_all_docs.erl
index 1d87e3ddd..5fe143731 100644
--- a/src/fabric/src/fabric_view_all_docs.erl
+++ b/src/fabric/src/fabric_view_all_docs.erl
@@ -104,10 +104,15 @@ go(DbName, Options, QueryArgs, Callback, Acc0) ->
[{total, TotalRows}, {offset, null}, {update_seq, null}]
end,
{ok, Acc1} = Callback({meta, Meta}, Acc0),
- {ok, Acc2} = doc_receive_loop(
+ Resp = doc_receive_loop(
Keys3, queue:new(), SpawnFun, MaxJobs, Callback, Acc1
),
- Callback(complete, Acc2);
+ case Resp of
+ {ok, Acc2} ->
+ Callback(complete, Acc2);
+ timeout ->
+ Callback(timeout, Acc0)
+ end;
{'DOWN', Ref, _, _, Error} ->
Callback({error, Error}, Acc0)
after Timeout ->
diff --git a/src/fabric/test/fabric_rpc_purge_tests.erl b/src/fabric/test/eunit/fabric_rpc_purge_tests.erl
index 4eafb2bc4..4eafb2bc4 100644
--- a/src/fabric/test/fabric_rpc_purge_tests.erl
+++ b/src/fabric/test/eunit/fabric_rpc_purge_tests.erl
diff --git a/src/global_changes/test/global_changes_hooks_tests.erl b/src/global_changes/test/eunit/global_changes_hooks_tests.erl
index 23fa2c87f..23fa2c87f 100644
--- a/src/global_changes/test/global_changes_hooks_tests.erl
+++ b/src/global_changes/test/eunit/global_changes_hooks_tests.erl
diff --git a/src/mango/src/mango_error.erl b/src/mango/src/mango_error.erl
index 2f22552c9..bb545ad67 100644
--- a/src/mango/src/mango_error.erl
+++ b/src/mango/src/mango_error.erl
@@ -69,7 +69,7 @@ info(mango_cursor_text, {text_search_error, {error, {bad_request, Msg}}})
};
info(mango_cursor_text, {text_search_error, {error, Error}}) ->
{
- 400,
+ 500,
<<"text_search_error">>,
fmt("~p", [Error])
};
diff --git a/src/mem3/src/mem3_sync_event_listener.erl b/src/mem3/src/mem3_sync_event_listener.erl
index e3368e23f..69a7a6017 100644
--- a/src/mem3/src/mem3_sync_event_listener.erl
+++ b/src/mem3/src/mem3_sync_event_listener.erl
@@ -258,14 +258,16 @@ subscribe_for_config_test_() ->
should_set_sync_delay(Pid) ->
?_test(begin
config:set("mem3", "sync_delay", "123", false),
- ?assertMatch(#state{delay = 123}, capture(Pid)),
+ wait_state(Pid, #state.delay, 123),
+ ?assertMatch(#state{delay = 123}, get_state(Pid)),
ok
end).
should_set_sync_frequency(Pid) ->
?_test(begin
config:set("mem3", "sync_frequency", "456", false),
- ?assertMatch(#state{frequency = 456}, capture(Pid)),
+ wait_state(Pid, #state.frequency, 456),
+ ?assertMatch(#state{frequency = 456}, get_state(Pid)),
ok
end).
@@ -293,17 +295,26 @@ should_terminate(Pid) ->
ok
end).
-capture(Pid) ->
+
+get_state(Pid) ->
Ref = make_ref(),
+ Pid ! {get_state, Ref, self()},
+ receive
+ {Ref, State} -> State
+ after 500 ->
+ timeout
+ end.
+
+
+wait_state(Pid, Field, Val) when is_pid(Pid), is_integer(Field) ->
WaitFun = fun() ->
- Pid ! {get_state, Ref, self()},
- receive
- {Ref, State} -> State
- after 0 ->
- wait
+ case get_state(Pid) of
+ #state{} = S when element(Field, S) == Val ->
+ true;
+ _ ->
+ wait
end
end,
test_util:wait(WaitFun).
-
-endif.
diff --git a/src/mem3/src/mem3_util.erl b/src/mem3/src/mem3_util.erl
index e8cba5d7b..3fc9b4f8e 100644
--- a/src/mem3/src/mem3_util.erl
+++ b/src/mem3/src/mem3_util.erl
@@ -221,11 +221,25 @@ get_engine_opt(DocProps) ->
get_props_opt(DocProps) ->
case couch_util:get_value(<<"props">>, DocProps) of
{Props} when is_list(Props) ->
- [{props, Props}];
+ [{props, db_props_from_json(Props)}];
_ ->
[]
end.
+db_props_from_json([]) ->
+ [];
+
+db_props_from_json([{<<"partitioned">>, Value} | Rest]) ->
+ [{partitioned, Value} | db_props_from_json(Rest)];
+
+db_props_from_json([{<<"hash">>, [MBin, FBin, A]} | Rest]) ->
+ M = binary_to_existing_atom(MBin, utf8),
+ F = binary_to_existing_atom(FBin, utf8),
+ [{hash, [M, F, A]} | db_props_from_json(Rest)];
+
+db_props_from_json([{K, V} | Rest]) ->
+ [{K, V} | db_props_from_json(Rest)].
+
n_val(undefined, NodeCount) ->
n_val(config:get("cluster", "n", "3"), NodeCount);
n_val(N, NodeCount) when is_list(N) ->
diff --git a/src/mem3/test/mem3_cluster_test.erl b/src/mem3/test/eunit/mem3_cluster_test.erl
index 4610d64bd..4610d64bd 100644
--- a/src/mem3/test/mem3_cluster_test.erl
+++ b/src/mem3/test/eunit/mem3_cluster_test.erl
diff --git a/src/mem3/test/mem3_hash_test.erl b/src/mem3/test/eunit/mem3_hash_test.erl
index 7a40c5366..7a40c5366 100644
--- a/src/mem3/test/mem3_hash_test.erl
+++ b/src/mem3/test/eunit/mem3_hash_test.erl
diff --git a/src/mem3/test/mem3_rep_test.erl b/src/mem3/test/eunit/mem3_rep_test.erl
index 7e8856f7c..4a46e7b93 100644
--- a/src/mem3/test/mem3_rep_test.erl
+++ b/src/mem3/test/eunit/mem3_rep_test.erl
@@ -20,6 +20,7 @@
-define(ID, <<"_id">>).
+-define(TIMEOUT, 60). % seconds
setup() ->
{AllSrc, AllTgt} = {?tempdb(), ?tempdb()},
@@ -65,7 +66,7 @@ mem3_reshard_db_test_() ->
replicate_basics(#{allsrc := AllSrc, alltgt := AllTgt}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
DocSpec = #{docs => 10, delete => [5, 9]},
add_test_docs(AllSrc, DocSpec),
SDocs = get_all_docs(AllSrc),
@@ -79,11 +80,11 @@ replicate_basics(#{allsrc := AllSrc, alltgt := AllTgt}) ->
?assertMatch({ok, 0}, mem3_rep:go(Src, TMap, Opts)),
?assertEqual(SDocs, get_all_docs(AllTgt))
- end).
+ end)}.
replicate_small_batches(#{allsrc := AllSrc, alltgt := AllTgt}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
DocSpec = #{docs => 10, delete => [5, 9]},
add_test_docs(AllSrc, DocSpec),
SDocs = get_all_docs(AllSrc),
@@ -97,11 +98,11 @@ replicate_small_batches(#{allsrc := AllSrc, alltgt := AllTgt}) ->
?assertMatch({ok, 0}, mem3_rep:go(Src, TMap, Opts)),
?assertEqual(SDocs, get_all_docs(AllTgt))
- end).
+ end)}.
replicate_low_batch_count(#{allsrc := AllSrc, alltgt := AllTgt}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
DocSpec = #{docs => 10, delete => [5, 9]},
add_test_docs(AllSrc, DocSpec),
SDocs = get_all_docs(AllSrc),
@@ -122,11 +123,11 @@ replicate_low_batch_count(#{allsrc := AllSrc, alltgt := AllTgt}) ->
?assertMatch({ok, 0}, mem3_rep:go(Src, TMap, Opts3)),
?assertEqual(SDocs, get_all_docs(AllTgt))
- end).
+ end)}.
replicate_with_partitions(#{partsrc := PartSrc, parttgt := PartTgt}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
DocSpec = #{
pdocs => #{
<<"PX">> => 15,
@@ -149,7 +150,7 @@ replicate_with_partitions(#{partsrc := PartSrc, parttgt := PartTgt}) ->
?assertEqual(PXSrc, get_partition_info(PartTgt, <<"PX">>)),
?assertEqual(PYSrc, get_partition_info(PartTgt, <<"PY">>)),
?assertEqual(SDocs, get_all_docs(PartTgt))
- end).
+ end)}.
get_partition_info(DbName, Partition) ->
diff --git a/src/mem3/test/mem3_reshard_api_test.erl b/src/mem3/test/eunit/mem3_reshard_api_test.erl
index 982fed173..c4df24ad3 100644
--- a/src/mem3/test/mem3_reshard_api_test.erl
+++ b/src/mem3/test/eunit/mem3_reshard_api_test.erl
@@ -27,6 +27,7 @@
-define(STATE, "_reshard/state").
-define(ID, <<"id">>).
-define(OK, <<"ok">>).
+-define(TIMEOUT, 60). % seconds
setup() ->
@@ -110,7 +111,7 @@ mem3_reshard_api_test_() ->
basics({Top, _}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
% GET /_reshard
?assertMatch({200, #{
<<"state">> := <<"running">>,
@@ -137,11 +138,11 @@ basics({Top, _}) ->
?assertMatch({404, _}, req(get, Top ++ ?RESHARD ++ "/invalidpath")),
?assertMatch({405, _}, req(put, Top ++ ?RESHARD, #{dont => thinkso})),
?assertMatch({405, _}, req(post, Top ++ ?RESHARD, #{nope => nope}))
- end).
+ end)}.
create_job_basic({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
% POST /_reshard/jobs
{C1, R1} = req(post, Top ++ ?JOBS, #{type => split, db => Db1}),
?assertEqual(201, C1),
@@ -192,11 +193,11 @@ create_job_basic({Top, {Db1, _, _}}) ->
% DELETE /_reshard/jobs/$jobid should be a 404 as well
?assertMatch({404, #{}}, req(delete, Top ++ ?JOBS ++ ?b2l(Id)))
- end).
+ end)}.
create_two_jobs({Top, {Db1, Db2, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
Jobs = Top ++ ?JOBS,
?assertMatch({201, [#{?OK := true}]},
@@ -218,20 +219,20 @@ create_two_jobs({Top, {Db1, Db2, _}}) ->
?assertMatch({200, #{<<"total">> := 1}}, req(get, Top ++ ?RESHARD)),
{200, #{?OK := true}} = req(delete, Jobs ++ ?b2l(Id2)),
?assertMatch({200, #{<<"total">> := 0}}, req(get, Top ++ ?RESHARD))
- end).
+ end)}.
create_multiple_jobs_from_one_post({Top, {_, _, Db3}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
Jobs = Top ++ ?JOBS,
{C1, R1} = req(post, Jobs, #{type => split, db => Db3}),
?assertMatch({201, [#{?OK := true}, #{?OK := true}]}, {C1, R1}),
?assertMatch({200, #{<<"total">> := 2}}, req(get, Top ++ ?RESHARD))
- end).
+ end)}.
start_stop_cluster_basic({Top, _}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
Url = Top ++ ?STATE,
?assertMatch({200, #{
@@ -261,11 +262,11 @@ start_stop_cluster_basic({Top, _}) ->
}}, req(get, Top ++ ?RESHARD)),
?assertMatch({200, _}, req(put, Url, #{state => running})),
?assertMatch({200, #{<<"state">> := <<"running">>}}, req(get, Url))
- end).
+ end)}.
test_disabled({Top, _}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
application:set_env(mem3, reshard_disabled, true),
?assertMatch({501, _}, req(get, Top ++ ?RESHARD)),
?assertMatch({501, _}, req(put, Top ++ ?STATE, #{state => running})),
@@ -273,11 +274,11 @@ test_disabled({Top, _}) ->
application:unset_env(mem3, reshard_disabled),
?assertMatch({200, _}, req(get, Top ++ ?RESHARD)),
?assertMatch({200, _}, req(put, Top ++ ?STATE, #{state => running}))
- end).
+ end)}.
start_stop_cluster_with_a_job({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
Url = Top ++ ?STATE,
?assertMatch({200, _}, req(put, Url, #{state => stopped})),
@@ -316,11 +317,11 @@ start_stop_cluster_with_a_job({Top, {Db1, _, _}}) ->
?assertMatch({200, _}, req(put, Url, #{state => running})),
?assertMatch({200, #{?ID := Id2, <<"job_state">> := JSt}}
when JSt =/= <<"stopped">>, req(get, Top ++ ?JOBS ++ ?b2l(Id2)))
- end).
+ end)}.
individual_job_start_stop({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
intercept_state(topoff1),
Body = #{type => split, db => Db1},
@@ -352,11 +353,11 @@ individual_job_start_stop({Top, {Db1, _, _}}) ->
% Let it continue running and it should complete eventually
JobPid2 ! continue,
wait_state(StUrl, <<"completed">>)
- end).
+ end)}.
individual_job_stop_when_cluster_stopped({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
intercept_state(topoff1),
Body = #{type => split, db => Db1},
@@ -397,11 +398,11 @@ individual_job_stop_when_cluster_stopped({Top, {Db1, _, _}}) ->
% Let it continue running and it should complete eventually
JobPid2 ! continue,
wait_state(StUrl, <<"completed">>)
- end).
+ end)}.
create_job_with_invalid_arguments({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
Jobs = Top ++ ?JOBS,
% Nothing in the body
@@ -434,11 +435,11 @@ create_job_with_invalid_arguments({Top, {Db1, _, _}}) ->
% Can't have both db and shard
?assertMatch({400, _}, req(post, Jobs, #{type => split, db => Db1,
shard => <<"blah">>}))
- end).
+ end)}.
create_job_with_db({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
Jobs = Top ++ ?JOBS,
Body1 = #{type => split, db => Db1},
@@ -465,11 +466,11 @@ create_job_with_db({Top, {Db1, _, _}}) ->
[16#80000000, 16#bfffffff],
[16#c0000000, 16#ffffffff]
], [mem3:range(S) || S <- lists:sort(mem3:shards(Db1))])
- end).
+ end)}.
create_job_with_shard_name({Top, {_, _, Db3}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
Jobs = Top ++ ?JOBS,
[S1, S2] = [mem3:name(S) || S <- lists:sort(mem3:shards(Db3))],
@@ -490,11 +491,11 @@ create_job_with_shard_name({Top, {_, _, Db3}}) ->
[16#80000000, 16#bfffffff],
[16#c0000000, 16#ffffffff]
], [mem3:range(S) || S <- lists:sort(mem3:shards(Db3))])
- end).
+ end)}.
completed_job_handling({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
Jobs = Top ++ ?JOBS,
% Run job to completion
@@ -542,109 +543,109 @@ completed_job_handling({Top, {Db1, _, _}}) ->
?assertMatch({200, #{<<"state">> := <<"completed">>}}, req(get, StUrl)),
?assertMatch({200, #{?OK := true}}, req(delete, JobUrl))
- end).
+ end)}.
handle_db_deletion_in_topoff1({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
JobId = delete_source_in_state(Top, Db1, topoff1),
wait_state(Top ++ ?JOBS ++ ?b2l(JobId) ++ "/state", <<"failed">>)
- end).
+ end)}.
handle_db_deletion_in_initial_copy({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
JobId = delete_source_in_state(Top, Db1, initial_copy),
wait_state(Top ++ ?JOBS ++ ?b2l(JobId) ++ "/state", <<"failed">>)
- end).
+ end)}.
handle_db_deletion_in_copy_local_docs({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
JobId = delete_source_in_state(Top, Db1, copy_local_docs),
wait_state(Top ++ ?JOBS ++ ?b2l(JobId) ++ "/state", <<"failed">>)
- end).
+ end)}.
handle_db_deletion_in_build_indices({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
JobId = delete_source_in_state(Top, Db1, build_indices),
wait_state(Top ++ ?JOBS ++ ?b2l(JobId) ++ "/state", <<"failed">>)
- end).
+ end)}.
handle_db_deletion_in_update_shard_map({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
JobId = delete_source_in_state(Top, Db1, update_shardmap),
wait_state(Top ++ ?JOBS ++ ?b2l(JobId) ++ "/state", <<"failed">>)
- end).
+ end)}.
handle_db_deletion_in_wait_source_close({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
JobId = delete_source_in_state(Top, Db1, wait_source_close),
wait_state(Top ++ ?JOBS ++ ?b2l(JobId) ++ "/state", <<"failed">>)
- end).
+ end)}.
recover_in_topoff1({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
JobId = recover_in_state(Top, Db1, topoff1),
wait_state(Top ++ ?JOBS ++ ?b2l(JobId) ++ "/state", <<"completed">>)
- end).
+ end)}.
recover_in_initial_copy({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
JobId = recover_in_state(Top, Db1, initial_copy),
wait_state(Top ++ ?JOBS ++ ?b2l(JobId) ++ "/state", <<"completed">>)
- end).
+ end)}.
recover_in_copy_local_docs({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
JobId = recover_in_state(Top, Db1, copy_local_docs),
wait_state(Top ++ ?JOBS ++ ?b2l(JobId) ++ "/state", <<"completed">>)
- end).
+ end)}.
recover_in_build_indices({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
JobId = recover_in_state(Top, Db1, build_indices),
wait_state(Top ++ ?JOBS ++ ?b2l(JobId) ++ "/state", <<"completed">>)
- end).
+ end)}.
recover_in_update_shard_map({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
JobId = recover_in_state(Top, Db1, update_shardmap),
wait_state(Top ++ ?JOBS ++ ?b2l(JobId) ++ "/state", <<"completed">>)
- end).
+ end)}.
recover_in_wait_source_close({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
JobId = recover_in_state(Top, Db1, wait_source_close),
wait_state(Top ++ ?JOBS ++ ?b2l(JobId) ++ "/state", <<"completed">>)
- end).
+ end)}.
recover_in_topoff3({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
JobId = recover_in_state(Top, Db1, topoff3),
wait_state(Top ++ ?JOBS ++ ?b2l(JobId) ++ "/state", <<"completed">>)
- end).
+ end)}.
recover_in_source_delete({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
JobId = recover_in_state(Top, Db1, source_delete),
wait_state(Top ++ ?JOBS ++ ?b2l(JobId) ++ "/state", <<"completed">>)
- end).
+ end)}.
check_max_jobs({Top, {Db1, Db2, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
Jobs = Top ++ ?JOBS,
config:set("reshard", "max_jobs", "0", _Persist=false),
@@ -678,11 +679,11 @@ check_max_jobs({Top, {Db1, Db2, _}}) ->
% Jobs that have been created already are not removed if max jobs is lowered
% so make sure the job completes
wait_to_complete(Top, R4)
- end).
+ end)}.
check_node_and_range_required_params({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
Jobs = Top ++ ?JOBS,
Node = atom_to_binary(node(), utf8),
@@ -704,18 +705,18 @@ check_node_and_range_required_params({Top, {Db1, _, _}}) ->
{C3, R3} = req(post, Jobs, Body),
?assertMatch({201, [#{?OK := true}]}, {C3, R3}),
wait_to_complete_then_cleanup(Top, R3)
- end).
+ end)}.
cleanup_completed_jobs({Top, {Db1, _, _}}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
Body = #{type => split, db => Db1},
{201, [#{?ID := Id}]} = req(post, Top ++ ?JOBS, Body),
JobUrl = Top ++ ?JOBS ++ ?b2l(Id),
wait_state(JobUrl ++ "/state", <<"completed">>),
delete_db(Top, Db1),
wait_for_http_code(JobUrl, 404)
- end).
+ end)}.
% Test help functions
diff --git a/src/mem3/test/mem3_reshard_changes_feed_test.erl b/src/mem3/test/eunit/mem3_reshard_changes_feed_test.erl
index 52e18fb26..4b9e2a34a 100644
--- a/src/mem3/test/mem3_reshard_changes_feed_test.erl
+++ b/src/mem3/test/eunit/mem3_reshard_changes_feed_test.erl
@@ -17,6 +17,7 @@
-include_lib("couch/include/couch_db.hrl").
-include_lib("mem3/src/mem3_reshard.hrl").
+-define(TIMEOUT, 60). % seconds
-define(assertChanges(Expected, Received),
begin
@@ -66,7 +67,7 @@ mem3_reshard_changes_feed_test_() ->
normal_feed_should_work_after_split(#{db1 := Db}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
DocSpec = #{
docs => [1, 10],
delete => [5, 6]
@@ -141,11 +142,11 @@ normal_feed_should_work_after_split(#{db1 := Db}) ->
?assertEqual(4, length(Changes7)),
[#{seq := Seq7} | _] = Changes7,
?assertEqual(EndSeq7, Seq7)
- end).
+ end)}.
continuous_feed_should_work_during_split(#{db1 := Db}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
{UpdaterPid, UpdaterRef} = spawn_monitor(fun() ->
Updater = fun U({State, I}) ->
receive
@@ -233,7 +234,7 @@ continuous_feed_should_work_during_split(#{db1 := Db}) ->
DocIDs = [Id || #{id := Id} <- StopChanges ++ AfterChanges],
ExpectedDocIDs = [doc_id(<<>>, N) || N <- lists:seq(1, DocCount)],
?assertEqual(ExpectedDocIDs, lists:usort(DocIDs))
- end).
+ end)}.
split_and_wait(Db) ->
diff --git a/src/mem3/test/mem3_reshard_test.erl b/src/mem3/test/eunit/mem3_reshard_test.erl
index 8c4479656..ab6202115 100644
--- a/src/mem3/test/mem3_reshard_test.erl
+++ b/src/mem3/test/eunit/mem3_reshard_test.erl
@@ -19,6 +19,7 @@
-include_lib("couch_mrview/include/couch_mrview.hrl"). % for all_docs function
-define(ID, <<"_id">>).
+-define(TIMEOUT, 60).
setup() ->
HaveDreyfus = code:lib_dir(dreyfus) /= {error, bad_name},
@@ -81,7 +82,7 @@ mem3_reshard_db_test_() ->
% This is a basic test to check that shard splitting preserves documents, and
% db meta props like revs limits and security.
split_one_shard(#{db1 := Db}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
DocSpec = #{docs => 10, delete => [5, 9], mrview => 1, local => 1},
add_test_docs(Db, DocSpec),
@@ -135,13 +136,13 @@ split_one_shard(#{db1 := Db}) ->
% Don't forget about the local but don't include internal checkpoints
% as some of those are munged and transformed during the split
?assertEqual(without_meta_locals(Local0), without_meta_locals(Local1))
- end).
+ end)}.
% This test checks that document added while the shard is being split are not
% lost. Topoff1 state happens before indices are built
update_docs_before_topoff1(#{db1 := Db}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
add_test_docs(Db, #{docs => 10}),
intercept_state(topoff1),
@@ -177,12 +178,12 @@ update_docs_before_topoff1(#{db1 := Db}) ->
?assertEqual(Docs0, Docs1),
?assertEqual(without_meta_locals(Local0), without_meta_locals(Local1))
- end).
+ end)}.
% This test that indices are built during shard splitting.
indices_are_built(#{db1 := Db}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
HaveDreyfus = code:lib_dir(dreyfus) /= {error, bad_name},
HaveHastings = code:lib_dir(hastings) /= {error, bad_name},
@@ -206,7 +207,7 @@ indices_are_built(#{db1 := Db}) ->
% 4 because there are 2 indices and 2 target shards
?assertEqual(4, meck:num_calls(hastings_index, await, 2))
end
- end).
+ end)}.
mock_dreyfus_indices() ->
@@ -238,7 +239,7 @@ mock_hastings_indices() ->
% Split partitioned database
split_partitioned_db(#{db2 := Db}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
DocSpec = #{
pdocs => #{
<<"PX">> => 5,
@@ -304,14 +305,14 @@ split_partitioned_db(#{db2 := Db}) ->
% Don't forget about the local but don't include internal checkpoints
% as some of those are munged and transformed during the split
?assertEqual(without_meta_locals(Local0), without_meta_locals(Local1))
- end).
+ end)}.
% Make sure a shard can be split again after it was split once. This checks that
% too many got added to some range, such that on next split they'd fail to fit
% in to any of the new target ranges.
split_twice(#{db1 := Db}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
DocSpec = #{docs => 100, delete => [80, 99], mrview => 2, local => 100},
add_test_docs(Db, DocSpec),
@@ -390,11 +391,11 @@ split_twice(#{db1 := Db}) ->
?assertEqual(trunc(UpdateSeq1 * 1.5), UpdateSeq2),
?assertEqual(Docs1, Docs2),
?assertEqual(without_meta_locals(Local1), without_meta_locals(Local2))
- end).
+ end)}.
couch_events_are_emitted(#{db1 := Db}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
couch_event:register_all(self()),
% Split the one shard
@@ -425,11 +426,11 @@ couch_events_are_emitted(#{db1 := Db}) ->
StartAtDeleted = lists:dropwhile(fun(E) -> E =/= deleted end, Events),
?assertMatch([deleted, deleted, updated, updated | _], StartAtDeleted),
couch_event:unregister(self())
- end).
+ end)}.
retries_work(#{db1 := Db}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
meck:expect(couch_db_split, split, fun(_, _, _) ->
error(kapow)
end),
@@ -439,11 +440,11 @@ retries_work(#{db1 := Db}) ->
wait_state(JobId, failed),
?assertEqual(3, meck:num_calls(couch_db_split, split, 3))
- end).
+ end)}.
target_reset_in_initial_copy(#{db1 := Db}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[#shard{} = Src] = lists:sort(mem3:local_shards(Db)),
Job = #job{
source = Src,
@@ -465,17 +466,17 @@ target_reset_in_initial_copy(#{db1 := Db}) ->
exit(JobPid, kill),
exit(BogusParent, kill),
?assertEqual(2, meck:num_calls(couch_db_split, cleanup_target, 2))
- end).
+ end)}.
split_an_incomplete_shard_map(#{db1 := Db}) ->
- ?_test(begin
+ {timeout, ?TIMEOUT, ?_test(begin
[#shard{} = Src] = lists:sort(mem3:local_shards(Db)),
[#shard{name=Shard}] = lists:sort(mem3:local_shards(Db)),
meck:expect(mem3_util, calculate_max_n, 1, 0),
?assertMatch({error, {not_enough_shard_copies, _}},
mem3_reshard:start_split_job(Shard))
- end).
+ end)}.
intercept_state(State) ->
diff --git a/src/mem3/test/mem3_ring_prop_tests.erl b/src/mem3/test/eunit/mem3_ring_prop_tests.erl
index 9f4f86f5f..9f4f86f5f 100644
--- a/src/mem3/test/mem3_ring_prop_tests.erl
+++ b/src/mem3/test/eunit/mem3_ring_prop_tests.erl
diff --git a/src/mem3/test/mem3_seeds_test.erl b/src/mem3/test/eunit/mem3_seeds_test.erl
index ba83b66be..ba83b66be 100644
--- a/src/mem3/test/mem3_seeds_test.erl
+++ b/src/mem3/test/eunit/mem3_seeds_test.erl
diff --git a/src/mem3/test/eunit/mem3_sync_security_test.erl b/src/mem3/test/eunit/mem3_sync_security_test.erl
new file mode 100644
index 000000000..e67a72017
--- /dev/null
+++ b/src/mem3/test/eunit/mem3_sync_security_test.erl
@@ -0,0 +1,54 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+% http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
+-module(mem3_sync_security_test).
+
+-include_lib("couch/include/couch_eunit.hrl").
+-include_lib("couch/include/couch_db.hrl").
+-include("mem3.hrl").
+-include_lib("eunit/include/eunit.hrl").
+
+-define(TIMEOUT, 5). % seconds
+
+go_test_() ->
+ {
+ "security property sync test",
+ {
+ setup,
+ fun start_couch/0, fun stop_couch/1,
+ {
+ foreach,
+ fun setup/0, fun teardown/1,
+ [
+ fun sync_security_ok/1
+ ]
+ }
+ }
+ }.
+
+start_couch() ->
+ test_util:start_couch([fabric, mem3]).
+
+stop_couch(Ctx) ->
+ test_util:stop_couch(Ctx).
+
+setup() ->
+ ok = meck:new(fabric, [passthrough]),
+ meck:expect(fabric, all_dbs, fun() ->
+ {ok, [<<"NoExistDb1">>, <<"NoExistDb2">>]}
+ end).
+
+teardown(_) ->
+ meck:unload().
+
+sync_security_ok(_) ->
+ {timeout, ?TIMEOUT, ?_assertEqual(ok, mem3_sync_security:go())}.
diff --git a/src/mem3/test/mem3_util_test.erl b/src/mem3/test/eunit/mem3_util_test.erl
index 8b74c4b2b..8b74c4b2b 100644
--- a/src/mem3/test/mem3_util_test.erl
+++ b/src/mem3/test/eunit/mem3_util_test.erl
diff --git a/src/mem3/test/mem3_sync_security_test.erl b/src/mem3/test/mem3_sync_security_test.erl
deleted file mode 100644
index 4e06dd807..000000000
--- a/src/mem3/test/mem3_sync_security_test.erl
+++ /dev/null
@@ -1,32 +0,0 @@
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-% http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
--module(mem3_sync_security_test).
-
--include_lib("couch/include/couch_eunit.hrl").
--include_lib("couch/include/couch_db.hrl").
--include("mem3.hrl").
--include_lib("eunit/include/eunit.hrl").
-
-go_test() ->
- Ctx = test_util:start_couch([fabric, mem3]),
- try
- ok = meck:new(fabric, [passthrough]),
- meck:expect(fabric, all_dbs, fun() ->
- {ok, [<<"NoExistDb1">>, <<"NoExistDb2">>]}
- end),
- Result = mem3_sync_security:go(),
- ?assertEqual(ok, Result)
- after
- meck:unload(),
- test_util:stop_couch(Ctx)
- end.