summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoan Touzet <joant@atypical.net>2020-10-06 14:35:33 -0400
committerJoan Touzet <joant@atypical.net>2020-10-06 14:35:33 -0400
commite955a49daa3732afb4eb63737b940c464bbcc1ca (patch)
tree7b9f3e5c986a8e658591775987dc3f2dd68f8b3c
parent990a3bd7240971cc0274b26fa496b88fd6c66f44 (diff)
downloadcouchdb-remove-js-harness.tar.gz
Remove JS tests + support for harnessremove-js-harness
-rw-r--r--INSTALL.Unix.md27
-rw-r--r--INSTALL.Windows.md4
-rw-r--r--Makefile.win2
-rw-r--r--build-aux/Jenkinsfile.full8
-rw-r--r--build-aux/Jenkinsfile.pr4
-rwxr-xr-xconfigure12
-rw-r--r--configure.ps14
-rw-r--r--src/couch/priv/couch_js/1.8.5/help.h7
-rw-r--r--src/couch/priv/couch_js/1.8.5/http.c701
-rw-r--r--src/couch/priv/couch_js/1.8.5/http.h27
-rw-r--r--src/couch/priv/couch_js/1.8.5/main.c182
-rw-r--r--src/couch/priv/couch_js/1.8.5/util.c2
-rw-r--r--src/couch/priv/couch_js/1.8.5/util.h2
-rw-r--r--src/couch/priv/couch_js/60/help.h7
-rw-r--r--src/couch/priv/couch_js/60/http.cpp649
-rw-r--r--src/couch/priv/couch_js/60/http.h27
-rw-r--r--src/couch/priv/couch_js/60/main.cpp193
-rw-r--r--src/couch/priv/couch_js/60/util.cpp10
-rw-r--r--src/couch/priv/couch_js/60/util.h4
-rw-r--r--src/couch/priv/couch_js/68/help.h5
-rw-r--r--src/couch/priv/couch_js/68/http.cpp650
-rw-r--r--src/couch/priv/couch_js/68/http.h27
-rw-r--r--src/couch/priv/couch_js/68/main.cpp198
-rw-r--r--src/couch/priv/couch_js/68/util.cpp10
-rw-r--r--src/couch/rebar.config.script31
-rw-r--r--test/javascript/cli_runner.js63
-rw-r--r--test/javascript/couch.js557
-rw-r--r--test/javascript/couch_http.js73
-rw-r--r--test/javascript/couch_test_runner.js489
-rw-r--r--test/javascript/couchdb.uri1
-rw-r--r--test/javascript/json2.js482
-rw-r--r--test/javascript/replicator_db_inc.js97
-rwxr-xr-xtest/javascript/run284
-rw-r--r--test/javascript/sha1.js202
-rw-r--r--test/javascript/test_setup.js127
-rw-r--r--test/javascript/tests-cluster/with-quorum/attachments.js37
-rw-r--r--test/javascript/tests-cluster/with-quorum/attachments_delete.js33
-rw-r--r--test/javascript/tests-cluster/with-quorum/attachments_delete_overridden_quorum.js38
-rw-r--r--test/javascript/tests-cluster/with-quorum/attachments_overridden_quorum.js42
-rw-r--r--test/javascript/tests-cluster/with-quorum/db_creation.js28
-rw-r--r--test/javascript/tests-cluster/with-quorum/db_creation_overridden_quorum.js30
-rw-r--r--test/javascript/tests-cluster/with-quorum/db_deletion.js31
-rw-r--r--test/javascript/tests-cluster/with-quorum/db_deletion_overridden_quorum.js24
-rw-r--r--test/javascript/tests-cluster/with-quorum/doc_bulk.js26
-rw-r--r--test/javascript/tests-cluster/with-quorum/doc_bulk_overridden_quorum.js26
-rw-r--r--test/javascript/tests-cluster/with-quorum/doc_copy.js28
-rw-r--r--test/javascript/tests-cluster/with-quorum/doc_copy_overridden_quorum.js32
-rw-r--r--test/javascript/tests-cluster/with-quorum/doc_crud.js32
-rw-r--r--test/javascript/tests-cluster/with-quorum/doc_crud_overridden_quorum.js32
-rw-r--r--test/javascript/tests-cluster/without-quorum/attachments.js40
-rw-r--r--test/javascript/tests-cluster/without-quorum/attachments_delete.js39
-rw-r--r--test/javascript/tests-cluster/without-quorum/attachments_delete_overridden_quorum.js38
-rw-r--r--test/javascript/tests-cluster/without-quorum/attachments_overridden_quorum.js43
-rw-r--r--test/javascript/tests-cluster/without-quorum/db_creation.js28
-rw-r--r--test/javascript/tests-cluster/without-quorum/db_creation_overridden_quorum.js32
-rw-r--r--test/javascript/tests-cluster/without-quorum/db_deletion.js31
-rw-r--r--test/javascript/tests-cluster/without-quorum/db_deletion_overridden_quorum.js26
-rw-r--r--test/javascript/tests-cluster/without-quorum/doc_bulk.js29
-rw-r--r--test/javascript/tests-cluster/without-quorum/doc_bulk_overridden_quorum.js29
-rw-r--r--test/javascript/tests-cluster/without-quorum/doc_copy.js31
-rw-r--r--test/javascript/tests-cluster/without-quorum/doc_copy_overridden_quorum.js35
-rw-r--r--test/javascript/tests-cluster/without-quorum/doc_crud.js36
-rw-r--r--test/javascript/tests-cluster/without-quorum/doc_crud_overridden_quorum.js35
-rw-r--r--test/javascript/tests/all_docs.js167
-rw-r--r--test/javascript/tests/attachment_names.js99
-rw-r--r--test/javascript/tests/attachment_paths.js156
-rw-r--r--test/javascript/tests/attachment_ranges.js164
-rw-r--r--test/javascript/tests/attachment_views.js145
-rw-r--r--test/javascript/tests/attachments.js358
-rw-r--r--test/javascript/tests/attachments_multipart.js426
-rw-r--r--test/javascript/tests/auth_cache.js274
-rw-r--r--test/javascript/tests/basics.js302
-rw-r--r--test/javascript/tests/batch_save.js52
-rw-r--r--test/javascript/tests/bulk_docs.js153
-rw-r--r--test/javascript/tests/changes.js812
-rw-r--r--test/javascript/tests/coffee.js72
-rw-r--r--test/javascript/tests/compact.js71
-rw-r--r--test/javascript/tests/config.js222
-rw-r--r--test/javascript/tests/conflicts.js123
-rw-r--r--test/javascript/tests/cookie_auth.js303
-rw-r--r--test/javascript/tests/copy_doc.js70
-rw-r--r--test/javascript/tests/design_docs.js447
-rw-r--r--test/javascript/tests/design_docs_query.js156
-rw-r--r--test/javascript/tests/design_options.js78
-rw-r--r--test/javascript/tests/design_paths.js74
-rw-r--r--test/javascript/tests/erlang_views.js137
-rw-r--r--test/javascript/tests/etags_head.js87
-rw-r--r--test/javascript/tests/etags_views.js224
-rw-r--r--test/javascript/tests/form_submit.js31
-rw-r--r--test/javascript/tests/http.js82
-rw-r--r--test/javascript/tests/invalid_docids.js82
-rw-r--r--test/javascript/tests/jsonp.js87
-rw-r--r--test/javascript/tests/large_docs.js38
-rw-r--r--test/javascript/tests/list_views.js502
-rw-r--r--test/javascript/tests/lorem.txt103
-rw-r--r--test/javascript/tests/lorem_b64.txt1
-rw-r--r--test/javascript/tests/lots_of_docs.js60
-rw-r--r--test/javascript/tests/method_override.js45
-rw-r--r--test/javascript/tests/multiple_rows.js85
-rw-r--r--test/javascript/tests/proxyauth.js136
-rw-r--r--test/javascript/tests/purge.js140
-rw-r--r--test/javascript/tests/reader_acl.js222
-rw-r--r--test/javascript/tests/recreate_doc.js157
-rw-r--r--test/javascript/tests/reduce.js423
-rw-r--r--test/javascript/tests/reduce_builtin.js206
-rw-r--r--test/javascript/tests/reduce_false.js50
-rw-r--r--test/javascript/tests/reduce_false_temp.js41
-rw-r--r--test/javascript/tests/replicator_db_bad_rep_id.js104
-rw-r--r--test/javascript/tests/replicator_db_by_doc_id.js129
-rw-r--r--test/javascript/tests/replicator_db_compact_rep_db.js119
-rw-r--r--test/javascript/tests/replicator_db_continuous.js137
-rw-r--r--test/javascript/tests/replicator_db_credential_delegation.js149
-rw-r--r--test/javascript/tests/replicator_db_field_validation.js178
-rw-r--r--test/javascript/tests/replicator_db_filtered.js105
-rw-r--r--test/javascript/tests/replicator_db_identical.js87
-rw-r--r--test/javascript/tests/replicator_db_identical_continuous.js139
-rw-r--r--test/javascript/tests/replicator_db_invalid_filter.js119
-rw-r--r--test/javascript/tests/replicator_db_security.js371
-rw-r--r--test/javascript/tests/replicator_db_simple.js114
-rw-r--r--test/javascript/tests/replicator_db_successive.js127
-rw-r--r--test/javascript/tests/replicator_db_survives.js126
-rw-r--r--test/javascript/tests/replicator_db_swap_rep_db.js170
-rw-r--r--test/javascript/tests/replicator_db_update_security.js92
-rw-r--r--test/javascript/tests/replicator_db_user_ctx.js272
-rw-r--r--test/javascript/tests/replicator_db_write_auth.js102
-rw-r--r--test/javascript/tests/rev_stemming.js124
-rw-r--r--test/javascript/tests/rewrite.js513
-rw-r--r--test/javascript/tests/rewrite_js.js351
-rw-r--r--test/javascript/tests/security_validation.js330
-rw-r--r--test/javascript/tests/show_documents.js376
-rw-r--r--test/javascript/tests/stats.js358
-rw-r--r--test/javascript/tests/update_documents.js236
-rw-r--r--test/javascript/tests/users_db.js222
-rw-r--r--test/javascript/tests/users_db_security.js418
-rw-r--r--test/javascript/tests/utf8.js46
-rw-r--r--test/javascript/tests/uuids.js148
-rw-r--r--test/javascript/tests/view_collation.js121
-rw-r--r--test/javascript/tests/view_collation_raw.js134
-rw-r--r--test/javascript/tests/view_compaction.js112
-rw-r--r--test/javascript/tests/view_conflicts.js57
-rw-r--r--test/javascript/tests/view_errors.js211
-rw-r--r--test/javascript/tests/view_include_docs.js196
-rw-r--r--test/javascript/tests/view_multi_key_all_docs.js99
-rw-r--r--test/javascript/tests/view_multi_key_design.js235
-rw-r--r--test/javascript/tests/view_multi_key_temp.js44
-rw-r--r--test/javascript/tests/view_offsets.js118
-rw-r--r--test/javascript/tests/view_pagination.js151
-rw-r--r--test/javascript/tests/view_sandboxing.js169
-rw-r--r--test/javascript/tests/view_update_seq.js119
149 files changed, 26 insertions, 21244 deletions
diff --git a/INSTALL.Unix.md b/INSTALL.Unix.md
index cb45e9ad4..0c82628be 100644
--- a/INSTALL.Unix.md
+++ b/INSTALL.Unix.md
@@ -45,8 +45,6 @@ You should have the following installed:
* https://archive.mozilla.org/pub/firefox/releases/60.9.0esr/source/ (src/js)
* GNU Make (http://www.gnu.org/software/make/)
* GNU Compiler Collection (http://gcc.gnu.org/)
- * libcurl (http://curl.haxx.se/libcurl/)
- * help2man (http://www.gnu.org/s/help2man/)
* Python (>=2.7) (http://python.org/)
To build Fauxton, you should have the following installed:
@@ -56,12 +54,10 @@ To build Fauxton, you should have the following installed:
To build the documentation, you should have the following installed:
* Python Sphinx (>=1.5) (http://pypi.python.org/pypi/Sphinx)
-It is recommended that you install Erlang OTP R16B03-1 or above where
-possible. You will only need libcurl if you plan to run the
-JavaScript test suite. And help2man is only need if you plan on
-installing the CouchDB man pages. Python and Sphinx are only required
-for building the online documentation. Documentation build can be disabled
-by adding the `--disable-docs` flag to the `configure` script.
+It is recommended that you install Erlang OTP R16B03-1 or above where possible.
+Python and Sphinx are only required for building the online documentation.
+Documentation build can be disabled by adding the `--disable-docs` flag to the
+`configure` script.
### Debian-based Systems
@@ -69,7 +65,9 @@ You can install the dependencies by running:
sudo apt-get --no-install-recommends -y install \
build-essential pkg-config erlang erlang-reltool \
- libicu-dev libmozjs185-dev libcurl4-openssl-dev
+ libicu-dev libmozjs-60-dev
+
+Your distribution may have libmozjs-68-dev instead of 60. Both are supported.
You can install the Node.JS dependencies via [NodeSource](https://github.com/nodesource/distributions#installation-instructions).
@@ -89,9 +87,8 @@ packages.
You can install the dependencies by running:
sudo yum install autoconf autoconf-archive automake \
- curl-devel erlang-asn1 erlang-erts erlang-eunit \
- erlang-xmerl help2man \
- js-devel-1.8.5 libicu-devel libtool perl-Test-Harness
+ erlang-asn1 erlang-erts erlang-eunit erlang-xmerl \
+ libmozjs-60-dev libicu-devel libtool perl-Test-Harness
You can install the Node.JS dependencies via [NodeSource](https://github.com/nodesource/distributions#rpminstall).
@@ -111,7 +108,7 @@ the Command Line Tools:
You can then install the other dependencies by running:
brew install autoconf autoconf-archive automake libtool \
- erlang icu4c spidermonkey curl pkg-config
+ erlang icu4c spidermonkey pkg-config
You can install the Node.JS dependencies via the
[official Macintosh installer](https://nodejs.org/en/download/).
@@ -143,8 +140,8 @@ You can install this by running:
You can install the remaining dependencies by running:
- pkg install help2man openssl icu curl git bash \
- autoconf automake libtool node spidermonkey185 \
+ pkg install openssl icu git bash \
+ autoconf automake libtool node spidermonkey60 \
erlang node8 npm-node8 lang/python py27-sphinx py27-pip
pip install --upgrade sphinx_rtd_theme nose requests hypothesis
diff --git a/INSTALL.Windows.md b/INSTALL.Windows.md
index 9ba84b745..6cf148c90 100644
--- a/INSTALL.Windows.md
+++ b/INSTALL.Windows.md
@@ -13,9 +13,9 @@ Build & Test
Once all dependencies are built and installed per the documentation in
couchdb-glazier, these commands will configure and build CouchDB:
- powershell -ExecutionPolicy Bypass .\configure.ps1 -WithCurl
+ powershell -ExecutionPolicy Bypass .\configure.ps1
make -f Makefile.win check
This will build couchdb, as well as run the eunit and javascript tests.
-As of CouchDB 2.0 RC1, all eunit and javascript tests should pass.
+As of CouchDB 2.0 RC1, all tests should pass.
diff --git a/Makefile.win b/Makefile.win
index edfc1bf3b..527872285 100644
--- a/Makefile.win
+++ b/Makefile.win
@@ -428,7 +428,7 @@ devclean:
config.erl:
@echo Apache CouchDB has not been configured.
@echo Try "powershell -ExecutionPolicy Bypass .\configure.ps1 -?" for help.
- @echo You probably want "powershell -ExecutionPolicy Bypass .\configure.ps1 -WithCurl".
+ @echo You probably want "powershell -ExecutionPolicy Bypass .\configure.ps1".
@echo.
@false
diff --git a/build-aux/Jenkinsfile.full b/build-aux/Jenkinsfile.full
index d7a7657b4..5f99da6cf 100644
--- a/build-aux/Jenkinsfile.full
+++ b/build-aux/Jenkinsfile.full
@@ -21,7 +21,7 @@ mkdir build
cd build
tar -xf ${WORKSPACE}/apache-couchdb-*.tar.gz
cd apache-couchdb-*
-./configure --with-curl --spidermonkey-version ${sm_ver}
+./configure --spidermonkey-version ${sm_ver}
make check || (make build-report && false)
'''
@@ -93,7 +93,7 @@ pipeline {
sh '''
set
rm -rf apache-couchdb-*
- ./configure --with-curl
+ ./configure
make dist
chmod -R a+w * .
'''
@@ -140,7 +140,7 @@ pipeline {
cd build
tar -xf $WORKSPACE/apache-couchdb-*.tar.gz
cd apache-couchdb-*
- ./configure --with-curl
+ ./configure
gmake check || (build-aux/logfile-uploader.py && false)
# No package build for FreeBSD at this time
@@ -177,7 +177,7 @@ pipeline {
cd build
tar -xzf $WORKSPACE/apache-couchdb-*.tar.gz
cd apache-couchdb-*
- ./configure --with-curl --spidermonkey-version 60
+ ./configure --spidermonkey-version 60
make check || (build-aux/logfile-uploader.py && false)
# No package build for macOS at this time
diff --git a/build-aux/Jenkinsfile.pr b/build-aux/Jenkinsfile.pr
index ca548ff27..114dfd849 100644
--- a/build-aux/Jenkinsfile.pr
+++ b/build-aux/Jenkinsfile.pr
@@ -21,7 +21,7 @@ cd build
tar -xf ${WORKSPACE}/apache-couchdb-*.tar.gz
cd apache-couchdb-*
. /usr/local/kerl/${KERL_VER}/activate
-./configure --with-curl
+./configure
make check || (make build-report && false)
'''
@@ -80,7 +80,7 @@ pipeline {
set
rm -rf apache-couchdb-*
. /usr/local/kerl/${LOW_ERLANG_VER}/activate
- ./configure --with-curl
+ ./configure
make dist
chmod -R a+w * .
'''
diff --git a/configure b/configure
index b91b18da7..0793d6837 100755
--- a/configure
+++ b/configure
@@ -22,7 +22,6 @@ basename=`basename $0`
PACKAGE_AUTHOR_NAME="The Apache Software Foundation"
# TEST=0
-WITH_CURL="false"
WITH_PROPER="true"
WITH_FAUXTON=1
WITH_DOCS=1
@@ -47,11 +46,10 @@ Options:
-h | --help display a short help message and exit
-u | --user USER set the username to run as (defaults to $COUCHDB_USER)
- -c | --with-curl request that couchjs is linked to cURL (default false)
--disable-fauxton do not build Fauxton
--disable-docs do not build any documentation or manpages
--erlang-md5 use erlang for md5 hash operations
- --dev alias for --with-curl --disable-docs --disable-fauxton
+ --dev alias for --disable-docs --disable-fauxton
--spidermonkey-version VSN specify the version of SpiderMonkey to use (defaults to $SM_VSN)
--skip-deps do not update erlang dependencies
--rebar=PATH use rebar by specified path (version >=2.6.0 && <3.0 required)
@@ -66,12 +64,6 @@ parse_opts() {
exit
;;
- --with-curl|-c)
- WITH_CURL="true"
- shift
- continue
- ;;
-
--without-proper)
WITH_PROPER="false"
shift
@@ -117,7 +109,6 @@ parse_opts() {
--dev)
WITH_DOCS=0
WITH_FAUXTON=0
- WITH_CURL="true"
shift
continue
;;
@@ -256,7 +247,6 @@ spidermonkey_version = $SM_VSN
EOF
cat > $rootdir/config.erl << EOF
-{with_curl, $WITH_CURL}.
{with_proper, $WITH_PROPER}.
{erlang_md5, $ERLANG_MD5}.
{aegis_key_manager, "$AEGIS_KEY_MANAGER"}.
diff --git a/configure.ps1 b/configure.ps1
index 65f8517d6..8935c3ce4 100644
--- a/configure.ps1
+++ b/configure.ps1
@@ -5,7 +5,6 @@
This command is responsible for generating the build
system for Apache CouchDB.
- -WithCurl request that couchjs is linked to cURL (default false)
-DisableFauxton request build process skip building Fauxton (default false)
-DisableDocs request build process skip building documentation (default false)
-SkipDeps do not update Erlang dependencies (default false)
@@ -42,7 +41,6 @@
Param(
[switch]$Test = $false,
- [switch]$WithCurl = $false, # request that couchjs is linked to cURL (default false)
[switch]$DisableFauxton = $false, # do not build Fauxton
[switch]$DisableDocs = $false, # do not build any documentation or manpages
[switch]$SkipDeps = $false, # do not update erlang dependencies
@@ -183,9 +181,7 @@ spidermonkey_version = $SpiderMonkeyVersion
"@
$InstallMk | Out-File "$rootdir\install.mk" -encoding ascii
-$lowercurl = "$WithCurl".ToLower()
$ConfigERL = @"
-{with_curl, $lowercurl}.
{spidermonkey_version, "$SpiderMonkeyVersion"}.
"@
$ConfigERL | Out-File "$rootdir\config.erl" -encoding ascii
diff --git a/src/couch/priv/couch_js/1.8.5/help.h b/src/couch/priv/couch_js/1.8.5/help.h
index 335935ed0..3a19901f0 100644
--- a/src/couch/priv/couch_js/1.8.5/help.h
+++ b/src/couch/priv/couch_js/1.8.5/help.h
@@ -46,15 +46,9 @@ static const char USAGE_TEMPLATE[] =
"\n"
" -h display a short help message and exit\n"
" -V display version information and exit\n"
- " -H enable %s cURL bindings (only avaiable\n"
- " if package was built with cURL available)\n"
- " -T enable test suite specific functions (these\n"
- " should not be enabled for production systems)\n"
" -S SIZE specify that the runtime should allow at\n"
" most SIZE bytes of memory to be allocated\n"
" default is 64 MiB\n"
- " -u FILE path to a .uri file containing the address\n"
- " (or addresses) of one or more servers\n"
" --eval Enable runtime code evaluation (dangerous!)\n"
"\n"
"Report bugs at <%s>.\n";
@@ -78,7 +72,6 @@ static const char USAGE_TEMPLATE[] =
basename, \
basename, \
PACKAGE_NAME, \
- basename, \
PACKAGE_BUGREPORT)
#define DISPLAY_USAGE couch_usage(BASENAME)
diff --git a/src/couch/priv/couch_js/1.8.5/http.c b/src/couch/priv/couch_js/1.8.5/http.c
deleted file mode 100644
index c4b389659..000000000
--- a/src/couch/priv/couch_js/1.8.5/http.c
+++ /dev/null
@@ -1,701 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <jsapi.h>
-#include "config.h"
-#include "utf8.h"
-#include "util.h"
-
-// Soft dependency on cURL bindings because they're
-// only used when running the JS tests from the
-// command line which is rare.
-#ifndef HAVE_CURL
-
-void
-http_check_enabled()
-{
- fprintf(stderr, "HTTP API was disabled at compile time.\n");
- exit(3);
-}
-
-
-JSBool
-http_ctor(JSContext* cx, JSObject* req)
-{
- return JS_FALSE;
-}
-
-
-JSBool
-http_dtor(JSContext* cx, JSObject* req)
-{
- return JS_FALSE;
-}
-
-
-JSBool
-http_open(JSContext* cx, JSObject* req, jsval mth, jsval url, jsval snc)
-{
- return JS_FALSE;
-}
-
-
-JSBool
-http_set_hdr(JSContext* cx, JSObject* req, jsval name, jsval val)
-{
- return JS_FALSE;
-}
-
-
-JSBool
-http_send(JSContext* cx, JSObject* req, jsval body)
-{
- return JS_FALSE;
-}
-
-
-int
-http_status(JSContext* cx, JSObject* req, jsval body)
-{
- return -1;
-}
-
-JSBool
-http_uri(JSContext* cx, JSObject* req, couch_args* args, jsval* uri_val)
-{
- return JS_FALSE;
-}
-
-
-#else
-#include <curl/curl.h>
-#ifndef XP_WIN
-#include <unistd.h>
-#endif
-
-
-void
-http_check_enabled()
-{
- return;
-}
-
-
-// Map some of the string function names to things which exist on Windows
-#ifdef XP_WIN
-#define strcasecmp _strcmpi
-#define strncasecmp _strnicmp
-#define snprintf _snprintf
-#endif
-
-
-typedef struct curl_slist CurlHeaders;
-
-
-typedef struct {
- int method;
- char* url;
- CurlHeaders* req_headers;
- jsint last_status;
-} HTTPData;
-
-
-char* METHODS[] = {"GET", "HEAD", "POST", "PUT", "DELETE", "COPY", "OPTIONS", NULL};
-
-
-#define GET 0
-#define HEAD 1
-#define POST 2
-#define PUT 3
-#define DELETE 4
-#define COPY 5
-#define OPTIONS 6
-
-
-static JSBool
-go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t blen);
-
-
-static JSString*
-str_from_binary(JSContext* cx, char* data, size_t length);
-
-
-JSBool
-http_ctor(JSContext* cx, JSObject* req)
-{
- HTTPData* http = NULL;
- JSBool ret = JS_FALSE;
-
- http = (HTTPData*) malloc(sizeof(HTTPData));
- if(!http)
- {
- JS_ReportError(cx, "Failed to create CouchHTTP instance.");
- goto error;
- }
-
- http->method = -1;
- http->url = NULL;
- http->req_headers = NULL;
- http->last_status = -1;
-
- if(!JS_SetPrivate(cx, req, http))
- {
- JS_ReportError(cx, "Failed to set private CouchHTTP data.");
- goto error;
- }
-
- ret = JS_TRUE;
- goto success;
-
-error:
- if(http) free(http);
-
-success:
- return ret;
-}
-
-
-void
-http_dtor(JSContext* cx, JSObject* obj)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(cx, obj);
- if(http) {
- if(http->url) free(http->url);
- if(http->req_headers) curl_slist_free_all(http->req_headers);
- free(http);
- }
-}
-
-
-JSBool
-http_open(JSContext* cx, JSObject* req, jsval mth, jsval url, jsval snc)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(cx, req);
- char* method = NULL;
- int methid;
- JSBool ret = JS_FALSE;
-
- if(!http) {
- JS_ReportError(cx, "Invalid CouchHTTP instance.");
- goto done;
- }
-
- if(JSVAL_IS_VOID(mth)) {
- JS_ReportError(cx, "You must specify a method.");
- goto done;
- }
-
- method = enc_string(cx, mth, NULL);
- if(!method) {
- JS_ReportError(cx, "Failed to encode method.");
- goto done;
- }
-
- for(methid = 0; METHODS[methid] != NULL; methid++) {
- if(strcasecmp(METHODS[methid], method) == 0) break;
- }
-
- if(methid > OPTIONS) {
- JS_ReportError(cx, "Invalid method specified.");
- goto done;
- }
-
- http->method = methid;
-
- if(JSVAL_IS_VOID(url)) {
- JS_ReportError(cx, "You must specify a URL.");
- goto done;
- }
-
- if(http->url != NULL) {
- free(http->url);
- http->url = NULL;
- }
-
- http->url = enc_string(cx, url, NULL);
- if(http->url == NULL) {
- JS_ReportError(cx, "Failed to encode URL.");
- goto done;
- }
-
- if(JSVAL_IS_BOOLEAN(snc) && JSVAL_TO_BOOLEAN(snc)) {
- JS_ReportError(cx, "Synchronous flag must be false.");
- goto done;
- }
-
- if(http->req_headers) {
- curl_slist_free_all(http->req_headers);
- http->req_headers = NULL;
- }
-
- // Disable Expect: 100-continue
- http->req_headers = curl_slist_append(http->req_headers, "Expect:");
-
- ret = JS_TRUE;
-
-done:
- if(method) free(method);
- return ret;
-}
-
-
-JSBool
-http_set_hdr(JSContext* cx, JSObject* req, jsval name, jsval val)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(cx, req);
- char* keystr = NULL;
- char* valstr = NULL;
- char* hdrbuf = NULL;
- size_t hdrlen = -1;
- JSBool ret = JS_FALSE;
-
- if(!http) {
- JS_ReportError(cx, "Invalid CouchHTTP instance.");
- goto done;
- }
-
- if(JSVAL_IS_VOID(name))
- {
- JS_ReportError(cx, "You must speciy a header name.");
- goto done;
- }
-
- keystr = enc_string(cx, name, NULL);
- if(!keystr)
- {
- JS_ReportError(cx, "Failed to encode header name.");
- goto done;
- }
-
- if(JSVAL_IS_VOID(val))
- {
- JS_ReportError(cx, "You must specify a header value.");
- goto done;
- }
-
- valstr = enc_string(cx, val, NULL);
- if(!valstr)
- {
- JS_ReportError(cx, "Failed to encode header value.");
- goto done;
- }
-
- hdrlen = strlen(keystr) + strlen(valstr) + 3;
- hdrbuf = (char*) malloc(hdrlen * sizeof(char));
- if(!hdrbuf) {
- JS_ReportError(cx, "Failed to allocate header buffer.");
- goto done;
- }
-
- snprintf(hdrbuf, hdrlen, "%s: %s", keystr, valstr);
- http->req_headers = curl_slist_append(http->req_headers, hdrbuf);
-
- ret = JS_TRUE;
-
-done:
- if(keystr) free(keystr);
- if(valstr) free(valstr);
- if(hdrbuf) free(hdrbuf);
- return ret;
-}
-
-JSBool
-http_send(JSContext* cx, JSObject* req, jsval body)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(cx, req);
- char* bodystr = NULL;
- size_t bodylen = 0;
- JSBool ret = JS_FALSE;
-
- if(!http) {
- JS_ReportError(cx, "Invalid CouchHTTP instance.");
- goto done;
- }
-
- if(!JSVAL_IS_VOID(body)) {
- bodystr = enc_string(cx, body, &bodylen);
- if(!bodystr) {
- JS_ReportError(cx, "Failed to encode body.");
- goto done;
- }
- }
-
- ret = go(cx, req, http, bodystr, bodylen);
-
-done:
- if(bodystr) free(bodystr);
- return ret;
-}
-
-int
-http_status(JSContext* cx, JSObject* req)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(cx, req);
-
- if(!http) {
- JS_ReportError(cx, "Invalid CouchHTTP instance.");
- return JS_FALSE;
- }
-
- return http->last_status;
-}
-
-JSBool
-http_uri(JSContext* cx, JSObject* req, couch_args* args, jsval* uri_val)
-{
- FILE* uri_fp = NULL;
- JSString* uri_str;
-
- // Default is http://localhost:15986/ when no uri file is specified
- if (!args->uri_file) {
- uri_str = JS_InternString(cx, "http://localhost:15986/");
- *uri_val = STRING_TO_JSVAL(uri_str);
- JS_SetReservedSlot(cx, req, 0, *uri_val);
- return JS_TRUE;
- }
-
- // Else check to see if the base url is cached in a reserved slot
- if (JS_GetReservedSlot(cx, req, 0, uri_val) && !JSVAL_IS_VOID(*uri_val)) {
- return JS_TRUE;
- }
-
- // Read the first line of the couch.uri file.
- if(!((uri_fp = fopen(args->uri_file, "r")) &&
- (uri_str = couch_readline(cx, uri_fp)))) {
- JS_ReportError(cx, "Failed to read couch.uri file.");
- goto error;
- }
-
- fclose(uri_fp);
- *uri_val = STRING_TO_JSVAL(uri_str);
- JS_SetReservedSlot(cx, req, 0, *uri_val);
- return JS_TRUE;
-
-error:
- if(uri_fp) fclose(uri_fp);
- return JS_FALSE;
-}
-
-
-// Curl Helpers
-
-typedef struct {
- HTTPData* http;
- JSContext* cx;
- JSObject* resp_headers;
- char* sendbuf;
- size_t sendlen;
- size_t sent;
- int sent_once;
- char* recvbuf;
- size_t recvlen;
- size_t read;
-} CurlState;
-
-/*
- * I really hate doing this but this doesn't have to be
- * uber awesome, it just has to work.
- */
-CURL* HTTP_HANDLE = NULL;
-char ERRBUF[CURL_ERROR_SIZE];
-
-static size_t send_body(void *ptr, size_t size, size_t nmem, void *data);
-static int seek_body(void *ptr, curl_off_t offset, int origin);
-static size_t recv_body(void *ptr, size_t size, size_t nmem, void *data);
-static size_t recv_header(void *ptr, size_t size, size_t nmem, void *data);
-
-static JSBool
-go(JSContext* cx, JSObject* obj, HTTPData* http, char* body, size_t bodylen)
-{
- CurlState state;
- char* referer;
- JSString* jsbody;
- JSBool ret = JS_FALSE;
- jsval tmp;
-
- state.cx = cx;
- state.http = http;
-
- state.sendbuf = body;
- state.sendlen = bodylen;
- state.sent = 0;
- state.sent_once = 0;
-
- state.recvbuf = NULL;
- state.recvlen = 0;
- state.read = 0;
-
- if(HTTP_HANDLE == NULL) {
- HTTP_HANDLE = curl_easy_init();
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_READFUNCTION, send_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKFUNCTION,
- (curl_seek_callback) seek_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_HEADERFUNCTION, recv_header);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEFUNCTION, recv_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOPROGRESS, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_ERRORBUFFER, ERRBUF);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_COOKIEFILE, "");
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_USERAGENT,
- "CouchHTTP Client - Relax");
- }
-
- if(!HTTP_HANDLE) {
- JS_ReportError(cx, "Failed to initialize cURL handle.");
- goto done;
- }
-
- if(!JS_GetReservedSlot(cx, obj, 0, &tmp)) {
- JS_ReportError(cx, "Failed to readreserved slot.");
- goto done;
- }
-
- if(!(referer = enc_string(cx, tmp, NULL))) {
- JS_ReportError(cx, "Failed to encode referer.");
- goto done;
- }
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_REFERER, referer);
- free(referer);
-
- if(http->method < 0 || http->method > OPTIONS) {
- JS_ReportError(cx, "INTERNAL: Unknown method.");
- goto done;
- }
-
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_CUSTOMREQUEST, METHODS[http->method]);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 0);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 0);
-
- if(http->method == HEAD) {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0);
- } else if(http->method == POST || http->method == PUT) {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0);
- }
-
- if(body && bodylen) {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, bodylen);
- } else {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, 0);
- }
-
- // curl_easy_setopt(HTTP_HANDLE, CURLOPT_VERBOSE, 1);
-
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_URL, http->url);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_HTTPHEADER, http->req_headers);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_READDATA, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKDATA, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEHEADER, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEDATA, &state);
-
- if(curl_easy_perform(HTTP_HANDLE) != 0) {
- JS_ReportError(cx, "Failed to execute HTTP request: %s", ERRBUF);
- goto done;
- }
-
- if(!state.resp_headers) {
- JS_ReportError(cx, "Failed to recieve HTTP headers.");
- goto done;
- }
-
- tmp = OBJECT_TO_JSVAL(state.resp_headers);
- if(!JS_DefineProperty(
- cx, obj,
- "_headers",
- tmp,
- NULL, NULL,
- JSPROP_READONLY
- )) {
- JS_ReportError(cx, "INTERNAL: Failed to set response headers.");
- goto done;
- }
-
- if(state.recvbuf) {
- state.recvbuf[state.read] = '\0';
- jsbody = dec_string(cx, state.recvbuf, state.read+1);
- if(!jsbody) {
- // If we can't decode the body as UTF-8 we forcefully
- // convert it to a string by just forcing each byte
- // to a jschar.
- jsbody = str_from_binary(cx, state.recvbuf, state.read);
- if(!jsbody) {
- if(!JS_IsExceptionPending(cx)) {
- JS_ReportError(cx, "INTERNAL: Failed to decode body.");
- }
- goto done;
- }
- }
- tmp = STRING_TO_JSVAL(jsbody);
- } else {
- tmp = JS_GetEmptyStringValue(cx);
- }
-
- if(!JS_DefineProperty(
- cx, obj,
- "responseText",
- tmp,
- NULL, NULL,
- JSPROP_READONLY
- )) {
- JS_ReportError(cx, "INTERNAL: Failed to set responseText.");
- goto done;
- }
-
- ret = JS_TRUE;
-
-done:
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
-}
-
-static size_t
-send_body(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = (CurlState*) data;
- size_t length = size * nmem;
- size_t towrite = state->sendlen - state->sent;
-
- // Assume this is cURL trying to resend a request that
- // failed.
- if(towrite == 0 && state->sent_once == 0) {
- state->sent_once = 1;
- return 0;
- } else if(towrite == 0) {
- state->sent = 0;
- state->sent_once = 0;
- towrite = state->sendlen;
- }
-
- if(length < towrite) towrite = length;
-
- memcpy(ptr, state->sendbuf + state->sent, towrite);
- state->sent += towrite;
-
- return towrite;
-}
-
-static int
-seek_body(void* ptr, curl_off_t offset, int origin)
-{
- CurlState* state = (CurlState*) ptr;
- if(origin != SEEK_SET) return -1;
-
- state->sent = (size_t) offset;
- return (int) state->sent;
-}
-
-static size_t
-recv_header(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = (CurlState*) data;
- char code[4];
- char* header = (char*) ptr;
- size_t length = size * nmem;
- JSString* hdr = NULL;
- jsuint hdrlen;
- jsval hdrval;
-
- if(length > 7 && strncasecmp(header, "HTTP/1.", 7) == 0) {
- if(length < 12) {
- return CURLE_WRITE_ERROR;
- }
-
- memcpy(code, header+9, 3*sizeof(char));
- code[3] = '\0';
- state->http->last_status = atoi(code);
-
- state->resp_headers = JS_NewArrayObject(state->cx, 0, NULL);
- if(!state->resp_headers) {
- return CURLE_WRITE_ERROR;
- }
-
- return length;
- }
-
- // We get a notice at the \r\n\r\n after headers.
- if(length <= 2) {
- return length;
- }
-
- // Append the new header to our array.
- hdr = dec_string(state->cx, header, length);
- if(!hdr) {
- return CURLE_WRITE_ERROR;
- }
-
- if(!JS_GetArrayLength(state->cx, state->resp_headers, &hdrlen)) {
- return CURLE_WRITE_ERROR;
- }
-
- hdrval = STRING_TO_JSVAL(hdr);
- if(!JS_SetElement(state->cx, state->resp_headers, hdrlen, &hdrval)) {
- return CURLE_WRITE_ERROR;
- }
-
- return length;
-}
-
-static size_t
-recv_body(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = (CurlState*) data;
- size_t length = size * nmem;
- char* tmp = NULL;
-
- if(!state->recvbuf) {
- state->recvlen = 4096;
- state->read = 0;
- state->recvbuf = JS_malloc(state->cx, state->recvlen);
- }
-
- if(!state->recvbuf) {
- return CURLE_WRITE_ERROR;
- }
-
- // +1 so we can add '\0' back up in the go function.
- while(length+1 > state->recvlen - state->read) state->recvlen *= 2;
- tmp = JS_realloc(state->cx, state->recvbuf, state->recvlen);
- if(!tmp) return CURLE_WRITE_ERROR;
- state->recvbuf = tmp;
-
- memcpy(state->recvbuf + state->read, ptr, length);
- state->read += length;
- return length;
-}
-
-JSString*
-str_from_binary(JSContext* cx, char* data, size_t length)
-{
- jschar* conv = (jschar*) JS_malloc(cx, length * sizeof(jschar));
- JSString* ret = NULL;
- size_t i;
-
- if(!conv) return NULL;
-
- for(i = 0; i < length; i++) {
- conv[i] = (jschar) data[i];
- }
-
- ret = JS_NewUCString(cx, conv, length);
- if(!ret) JS_free(cx, conv);
-
- return ret;
-}
-
-#endif /* HAVE_CURL */
diff --git a/src/couch/priv/couch_js/1.8.5/http.h b/src/couch/priv/couch_js/1.8.5/http.h
deleted file mode 100644
index 63d45bd06..000000000
--- a/src/couch/priv/couch_js/1.8.5/http.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#ifndef COUCH_JS_HTTP_H
-#define COUCH_JS_HTTP_H
-
-#include "util.h"
-
-void http_check_enabled();
-JSBool http_ctor(JSContext* cx, JSObject* req);
-void http_dtor(JSContext* cx, JSObject* req);
-JSBool http_open(JSContext* cx, JSObject* req, jsval mth, jsval url, jsval snc);
-JSBool http_set_hdr(JSContext* cx, JSObject* req, jsval name, jsval val);
-JSBool http_send(JSContext* cx, JSObject* req, jsval body);
-int http_status(JSContext* cx, JSObject* req);
-JSBool http_uri(JSContext* cx, JSObject *req, couch_args* args, jsval* uri);
-
-#endif
diff --git a/src/couch/priv/couch_js/1.8.5/main.c b/src/couch/priv/couch_js/1.8.5/main.c
index 986791c90..c8e385cc9 100644
--- a/src/couch/priv/couch_js/1.8.5/main.c
+++ b/src/couch/priv/couch_js/1.8.5/main.c
@@ -22,7 +22,6 @@
#include <jsapi.h>
#include "config.h"
-#include "http.h"
#include "utf8.h"
#include "util.h"
@@ -49,105 +48,6 @@ static JSClass global_class = {
JSCLASS_NO_OPTIONAL_MEMBERS
};
-
-static JSBool
-req_ctor(JSContext* cx, uintN argc, jsval* vp)
-{
- JSBool ret;
- JSObject* obj = JS_NewObjectForConstructor(cx, vp);
- if(!obj) {
- JS_ReportError(cx, "Failed to create CouchHTTP instance.\n");
- return JS_FALSE;
- }
- ret = http_ctor(cx, obj);
- JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj));
- return ret;
-}
-
-
-static void
-req_dtor(JSContext* cx, JSObject* obj)
-{
- http_dtor(cx, obj);
-}
-
-
-static JSBool
-req_open(JSContext* cx, uintN argc, jsval* vp)
-{
- JSObject* obj = JS_THIS_OBJECT(cx, vp);
- jsval* argv = JS_ARGV(cx, vp);
- JSBool ret = JS_FALSE;
-
- if(argc == 2) {
- ret = http_open(cx, obj, argv[0], argv[1], JSVAL_FALSE);
- } else if(argc == 3) {
- ret = http_open(cx, obj, argv[0], argv[1], argv[2]);
- } else {
- JS_ReportError(cx, "Invalid call to CouchHTTP.open");
- }
-
- JS_SET_RVAL(cx, vp, JSVAL_VOID);
- return ret;
-}
-
-
-static JSBool
-req_set_hdr(JSContext* cx, uintN argc, jsval* vp)
-{
- JSObject* obj = JS_THIS_OBJECT(cx, vp);
- jsval* argv = JS_ARGV(cx, vp);
- JSBool ret = JS_FALSE;
-
- if(argc == 2) {
- ret = http_set_hdr(cx, obj, argv[0], argv[1]);
- } else {
- JS_ReportError(cx, "Invalid call to CouchHTTP.set_header");
- }
-
- JS_SET_RVAL(cx, vp, JSVAL_VOID);
- return ret;
-}
-
-
-static JSBool
-req_send(JSContext* cx, uintN argc, jsval* vp)
-{
- JSObject* obj = JS_THIS_OBJECT(cx, vp);
- jsval* argv = JS_ARGV(cx, vp);
- JSBool ret = JS_FALSE;
-
- if(argc == 1) {
- ret = http_send(cx, obj, argv[0]);
- } else {
- JS_ReportError(cx, "Invalid call to CouchHTTP.send");
- }
-
- JS_SET_RVAL(cx, vp, JSVAL_VOID);
- return ret;
-}
-
-
-static JSBool
-req_status(JSContext* cx, JSObject* obj, jsid pid, jsval* vp)
-{
- int status = http_status(cx, obj);
- if(status < 0)
- return JS_FALSE;
-
- JS_SET_RVAL(cx, vp, INT_TO_JSVAL(status));
- return JS_TRUE;
-}
-
-
-static JSBool
-base_url(JSContext *cx, JSObject* obj, jsid pid, jsval* vp)
-{
- couch_args *args = (couch_args*)JS_GetContextPrivate(cx);
- return http_uri(cx, obj, args, &JS_RVAL(cx, vp));
-}
-
-
static JSBool
evalcx(JSContext *cx, uintN argc, jsval* vp)
{
@@ -281,63 +181,6 @@ seal(JSContext* cx, uintN argc, jsval* vp)
}
-static JSBool
-js_sleep(JSContext* cx, uintN argc, jsval* vp)
-{
- jsval* argv = JS_ARGV(cx, vp);
- int duration = 0;
- if(!JS_ConvertArguments(cx, argc, argv, "/i", &duration)) {
- return JS_FALSE;
- }
-
-#ifdef XP_WIN
- Sleep(duration);
-#else
- usleep(duration * 1000);
-#endif
-
- return JS_TRUE;
-}
-
-
-JSClass CouchHTTPClass = {
- "CouchHTTP",
- JSCLASS_HAS_PRIVATE
- | JSCLASS_CONSTRUCT_PROTOTYPE
- | JSCLASS_HAS_RESERVED_SLOTS(2),
- JS_PropertyStub,
- JS_PropertyStub,
- JS_PropertyStub,
- JS_StrictPropertyStub,
- JS_EnumerateStub,
- JS_ResolveStub,
- JS_ConvertStub,
- req_dtor,
- JSCLASS_NO_OPTIONAL_MEMBERS
-};
-
-
-JSPropertySpec CouchHTTPProperties[] = {
- {"status", 0, JSPROP_READONLY, req_status, NULL},
- {"base_url", 0, JSPROP_READONLY | JSPROP_SHARED, base_url, NULL},
- {0, 0, 0, 0, 0}
-};
-
-
-JSFunctionSpec CouchHTTPFunctions[] = {
- JS_FS("_open", req_open, 3, 0),
- JS_FS("_setRequestHeader", req_set_hdr, 2, 0),
- JS_FS("_send", req_send, 1, 0),
- JS_FS_END
-};
-
-
-JSFunctionSpec TestSuiteFunctions[] = {
- JS_FS("sleep", js_sleep, 1, 0),
- JS_FS_END
-};
-
-
static JSFunctionSpec global_functions[] = {
JS_FS("evalcx", evalcx, 0, 0),
JS_FS("gc", gc, 0, 0),
@@ -376,7 +219,6 @@ main(int argc, const char* argv[])
JSContext* cx = NULL;
JSObject* global = NULL;
JSCrossCompartmentCall *call = NULL;
- JSObject* klass = NULL;
JSSCRIPT_TYPE script;
JSString* scriptsrc;
const jschar* schars;
@@ -420,30 +262,6 @@ main(int argc, const char* argv[])
if(couch_load_funcs(cx, global, global_functions) != JS_TRUE)
return 1;
- if(args->use_http) {
- http_check_enabled();
-
- klass = JS_InitClass(
- cx, global,
- NULL,
- &CouchHTTPClass, req_ctor,
- 0,
- CouchHTTPProperties, CouchHTTPFunctions,
- NULL, NULL
- );
-
- if(!klass)
- {
- fprintf(stderr, "Failed to initialize CouchHTTP class.\n");
- exit(2);
- }
- }
-
- if(args->use_test_funs) {
- if(couch_load_funcs(cx, global, TestSuiteFunctions) != JS_TRUE)
- return 1;
- }
-
for(i = 0 ; args->scripts[i] ; i++) {
// Convert script source to jschars.
scriptsrc = couch_readfile(cx, args->scripts[i]);
diff --git a/src/couch/priv/couch_js/1.8.5/util.c b/src/couch/priv/couch_js/1.8.5/util.c
index cf676ea33..5cf94b63a 100644
--- a/src/couch/priv/couch_js/1.8.5/util.c
+++ b/src/couch/priv/couch_js/1.8.5/util.c
@@ -96,8 +96,6 @@ couch_parse_args(int argc, const char* argv[])
fprintf(stderr, "Invalid stack size.\n");
exit(2);
}
- } else if(strcmp("-u", argv[i]) == 0) {
- args->uri_file = argv[++i];
} else if(strcmp("--eval", argv[i]) == 0) {
args->eval = 1;
} else if(strcmp("--", argv[i]) == 0) {
diff --git a/src/couch/priv/couch_js/1.8.5/util.h b/src/couch/priv/couch_js/1.8.5/util.h
index b24d7f76f..9dd290a4c 100644
--- a/src/couch/priv/couch_js/1.8.5/util.h
+++ b/src/couch/priv/couch_js/1.8.5/util.h
@@ -21,8 +21,6 @@ typedef struct {
int use_test_funs;
int stack_size;
const char** scripts;
- const char* uri_file;
- JSString* uri;
} couch_args;
couch_args* couch_parse_args(int argc, const char* argv[]);
diff --git a/src/couch/priv/couch_js/60/help.h b/src/couch/priv/couch_js/60/help.h
index ffb6eb40a..826babbba 100644
--- a/src/couch/priv/couch_js/60/help.h
+++ b/src/couch/priv/couch_js/60/help.h
@@ -46,15 +46,9 @@ static const char USAGE_TEMPLATE[] =
"\n"
" -h display a short help message and exit\n"
" -V display version information and exit\n"
- " -H enable %s cURL bindings (only avaiable\n"
- " if package was built with cURL available)\n"
- " -T enable test suite specific functions (these\n"
- " should not be enabled for production systems)\n"
" -S SIZE specify that the runtime should allow at\n"
" most SIZE bytes of memory to be allocated\n"
" default is 64 MiB\n"
- " -u FILE path to a .uri file containing the address\n"
- " (or addresses) of one or more servers\n"
" --eval Enable runtime code evaluation (dangerous!)\n"
"\n"
"Report bugs at <%s>.\n";
@@ -78,7 +72,6 @@ static const char USAGE_TEMPLATE[] =
basename, \
basename, \
PACKAGE_NAME, \
- basename, \
PACKAGE_BUGREPORT)
#define DISPLAY_USAGE couch_usage(BASENAME)
diff --git a/src/couch/priv/couch_js/60/http.cpp b/src/couch/priv/couch_js/60/http.cpp
deleted file mode 100644
index e1e44d622..000000000
--- a/src/couch/priv/couch_js/60/http.cpp
+++ /dev/null
@@ -1,649 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <jsapi.h>
-#include <js/Initialization.h>
-#include "config.h"
-#include "util.h"
-
-// Soft dependency on cURL bindings because they're
-// only used when running the JS tests from the
-// command line which is rare.
-#ifndef HAVE_CURL
-
-void
-http_check_enabled()
-{
- fprintf(stderr, "HTTP API was disabled at compile time.\n");
- exit(3);
-}
-
-
-bool
-http_ctor(JSContext* cx, JSObject* req)
-{
- return false;
-}
-
-
-void
-http_dtor(JSFreeOp* fop, JSObject* req)
-{
- return;
-}
-
-
-bool
-http_open(JSContext* cx, JSObject* req, JS::Value mth, JS::Value url, JS::Value snc)
-{
- return false;
-}
-
-
-bool
-http_set_hdr(JSContext* cx, JSObject* req, JS::Value name, JS::Value val)
-{
- return false;
-}
-
-
-bool
-http_send(JSContext* cx, JSObject* req, JS::Value body)
-{
- return false;
-}
-
-
-int
-http_status(JSContext* cx, JSObject* req)
-{
- return -1;
-}
-
-bool
-http_uri(JSContext* cx, JSObject* req, couch_args* args, JS::Value* uri_val)
-{
- return false;
-}
-
-
-#else
-#include <curl/curl.h>
-#ifndef XP_WIN
-#include <unistd.h>
-#endif
-
-
-void
-http_check_enabled()
-{
- return;
-}
-
-
-// Map some of the string function names to things which exist on Windows
-#ifdef XP_WIN
-#define strcasecmp _strcmpi
-#define strncasecmp _strnicmp
-#endif
-
-
-typedef struct curl_slist CurlHeaders;
-
-
-typedef struct {
- int method;
- std::string url;
- CurlHeaders* req_headers;
- int16_t last_status;
-} HTTPData;
-
-
-const char* METHODS[] = {"GET", "HEAD", "POST", "PUT", "DELETE", "COPY", "OPTIONS", NULL};
-
-
-#define GET 0
-#define HEAD 1
-#define POST 2
-#define PUT 3
-#define DELETE 4
-#define COPY 5
-#define OPTIONS 6
-
-
-static bool go(JSContext* cx, JSObject* obj, HTTPData* http, std::string& body);
-
-
-bool
-http_ctor(JSContext* cx, JSObject* req)
-{
- HTTPData* http = new HTTPData();
- bool ret = false;
-
- if(!http)
- {
- JS_ReportErrorUTF8(cx, "Failed to create CouchHTTP instance.");
- goto error;
- }
-
- http->method = -1;
- http->req_headers = NULL;
- http->last_status = -1;
-
- JS_SetPrivate(req, http);
-
- ret = true;
- goto success;
-
-error:
- if(http) delete http;
-
-success:
- return ret;
-}
-
-
-void
-http_dtor(JSFreeOp* fop, JSObject* obj)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(obj);
- if(http) {
- if(http->req_headers) curl_slist_free_all(http->req_headers);
- delete http;
- }
-}
-
-
-bool
-http_open(JSContext* cx, JSObject* req, JS::Value mth, JS::Value url, JS::Value snc)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
- int methid;
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- if(!mth.isString()) {
- JS_ReportErrorUTF8(cx, "Method must be a string.");
- return false;
- }
-
- std::string method;
- if(!js_to_string(cx, JS::RootedValue(cx, mth), method)) {
- JS_ReportErrorUTF8(cx, "Failed to encode method.");
- return false;
- }
-
- for(methid = 0; METHODS[methid] != NULL; methid++) {
- if(strcasecmp(METHODS[methid], method.c_str()) == 0) break;
- }
-
- if(methid > OPTIONS) {
- JS_ReportErrorUTF8(cx, "Invalid method specified.");
- return false;
- }
-
- http->method = methid;
-
- if(!url.isString()) {
- JS_ReportErrorUTF8(cx, "URL must be a string");
- return false;
- }
-
- std::string urlstr;
- if(!js_to_string(cx, JS::RootedValue(cx, url), urlstr)) {
- JS_ReportErrorUTF8(cx, "Failed to encode URL.");
- return false;
- }
- http->url = urlstr;
-
- if(snc.isBoolean() && snc.isTrue()) {
- JS_ReportErrorUTF8(cx, "Synchronous flag must be false.");
- return false;
- }
-
- if(http->req_headers) {
- curl_slist_free_all(http->req_headers);
- http->req_headers = NULL;
- }
-
- // Disable Expect: 100-continue
- http->req_headers = curl_slist_append(http->req_headers, "Expect:");
-
- return true;
-}
-
-
-bool
-http_set_hdr(JSContext* cx, JSObject* req, JS::Value name, JS::Value val)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- if(!name.isString())
- {
- JS_ReportErrorUTF8(cx, "Header names must be strings.");
- return false;
- }
-
- std::string keystr;
- if(!js_to_string(cx, JS::RootedValue(cx, name), keystr))
- {
- JS_ReportErrorUTF8(cx, "Failed to encode header name.");
- return false;
- }
-
- if(!val.isString())
- {
- JS_ReportErrorUTF8(cx, "Header values must be strings.");
- return false;
- }
-
- std::string valstr;
- if(!js_to_string(cx, JS::RootedValue(cx, val), valstr)) {
- JS_ReportErrorUTF8(cx, "Failed to encode header value.");
- return false;
- }
-
- std::string header = keystr + ": " + valstr;
- http->req_headers = curl_slist_append(http->req_headers, header.c_str());
-
- return true;
-}
-
-bool
-http_send(JSContext* cx, JSObject* req, JS::Value body)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- std::string bodystr;
- if(!js_to_string(cx, JS::RootedValue(cx, body), bodystr)) {
- JS_ReportErrorUTF8(cx, "Failed to encode body.");
- return false;
- }
-
- return go(cx, req, http, bodystr);
-}
-
-int
-http_status(JSContext* cx, JSObject* req)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- return http->last_status;
-}
-
-bool
-http_uri(JSContext* cx, JSObject* req, couch_args* args, JS::Value* uri_val)
-{
- FILE* uri_fp = NULL;
- JSString* uri_str;
-
- // Default is http://localhost:15986/ when no uri file is specified
- if (!args->uri_file) {
- uri_str = JS_NewStringCopyZ(cx, "http://localhost:15986/");
- *uri_val = JS::StringValue(uri_str);
- JS_SetReservedSlot(req, 0, *uri_val);
- return true;
- }
-
- // Else check to see if the base url is cached in a reserved slot
- *uri_val = JS_GetReservedSlot(req, 0);
- if (!(*uri_val).isUndefined()) {
- return true;
- }
-
- // Read the first line of the couch.uri file.
- if(!((uri_fp = fopen(args->uri_file, "r")) &&
- (uri_str = couch_readline(cx, uri_fp)))) {
- JS_ReportErrorUTF8(cx, "Failed to read couch.uri file.");
- goto error;
- }
-
- fclose(uri_fp);
- *uri_val = JS::StringValue(uri_str);
- JS_SetReservedSlot(req, 0, *uri_val);
- return true;
-
-error:
- if(uri_fp) fclose(uri_fp);
- return false;
-}
-
-
-// Curl Helpers
-
-typedef struct {
- HTTPData* http;
- JSContext* cx;
- JSObject* resp_headers;
- const char* sendbuf;
- size_t sendlen;
- size_t sent;
- int sent_once;
- char* recvbuf;
- size_t recvlen;
- size_t read;
-} CurlState;
-
-/*
- * I really hate doing this but this doesn't have to be
- * uber awesome, it just has to work.
- */
-CURL* HTTP_HANDLE = NULL;
-char ERRBUF[CURL_ERROR_SIZE];
-
-static size_t send_body(void *ptr, size_t size, size_t nmem, void *data);
-static int seek_body(void *ptr, curl_off_t offset, int origin);
-static size_t recv_body(void *ptr, size_t size, size_t nmem, void *data);
-static size_t recv_header(void *ptr, size_t size, size_t nmem, void *data);
-
-static bool
-go(JSContext* cx, JSObject* obj, HTTPData* http, std::string& body)
-{
- CurlState state;
- JSString* jsbody;
- bool ret = false;
- JS::Value tmp;
- JS::RootedObject robj(cx, obj);
- JS::RootedValue vobj(cx);
-
-
- state.cx = cx;
- state.http = http;
-
- state.sendbuf = body.c_str();
- state.sendlen = body.size();
- state.sent = 0;
- state.sent_once = 0;
-
- state.recvbuf = NULL;
- state.recvlen = 0;
- state.read = 0;
-
- if(HTTP_HANDLE == NULL) {
- HTTP_HANDLE = curl_easy_init();
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_READFUNCTION, send_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKFUNCTION,
- (curl_seek_callback) seek_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_HEADERFUNCTION, recv_header);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEFUNCTION, recv_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOPROGRESS, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_ERRORBUFFER, ERRBUF);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_COOKIEFILE, "");
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_USERAGENT,
- "CouchHTTP Client - Relax");
- }
-
- if(!HTTP_HANDLE) {
- JS_ReportErrorUTF8(cx, "Failed to initialize cURL handle.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- tmp = JS_GetReservedSlot(obj, 0);
-
- std::string referer;
- if(!js_to_string(cx, JS::RootedValue(cx, tmp), referer)) {
- JS_ReportErrorUTF8(cx, "Failed to encode referer.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_REFERER, referer.c_str());
-
- if(http->method < 0 || http->method > OPTIONS) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Unknown method.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_CUSTOMREQUEST, METHODS[http->method]);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 0);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 0);
-
- if(http->method == HEAD) {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0);
- } else if(http->method == POST || http->method == PUT) {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0);
- }
-
- if(body.size() > 0) {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, body.size());
- } else {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, 0);
- }
-
- // curl_easy_setopt(HTTP_HANDLE, CURLOPT_VERBOSE, 1);
-
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_URL, http->url.c_str());
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_HTTPHEADER, http->req_headers);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_READDATA, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKDATA, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEHEADER, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEDATA, &state);
-
- if(curl_easy_perform(HTTP_HANDLE) != 0) {
- JS_ReportErrorUTF8(cx, "Failed to execute HTTP request: %s", ERRBUF);
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- if(!state.resp_headers) {
- JS_ReportErrorUTF8(cx, "Failed to recieve HTTP headers.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
- tmp = JS::ObjectValue(*state.resp_headers);
- JS::RootedValue rtmp(cx, tmp);
-
- if(!JS_DefineProperty(
- cx, robj,
- "_headers",
- rtmp,
- JSPROP_READONLY
- )) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Failed to set response headers.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;;
- }
-
- if(state.recvbuf) {
- state.recvbuf[state.read] = '\0';
- std::string bodystr(state.recvbuf, state.read);
- jsbody = string_to_js(cx, bodystr);
- if(!jsbody) {
- // If we can't decode the body as UTF-8 we forcefully
- // convert it to a string by just forcing each byte
- // to a char16_t.
- jsbody = JS_NewStringCopyN(cx, state.recvbuf, state.read);
- if(!jsbody) {
- if(!JS_IsExceptionPending(cx)) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Failed to decode body.");
- }
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
- }
- tmp = JS::StringValue(jsbody);
- } else {
- tmp = JS_GetEmptyStringValue(cx);
- }
-
- JS::RootedValue rtmp2(cx, tmp);
-
- if(!JS_DefineProperty(
- cx, robj,
- "responseText",
- rtmp2,
- JSPROP_READONLY
- )) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Failed to set responseText.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- ret = true;
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
-}
-
-static size_t
-send_body(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = static_cast<CurlState*>(data);
- size_t length = size * nmem;
- size_t towrite = state->sendlen - state->sent;
-
- // Assume this is cURL trying to resend a request that
- // failed.
- if(towrite == 0 && state->sent_once == 0) {
- state->sent_once = 1;
- return 0;
- } else if(towrite == 0) {
- state->sent = 0;
- state->sent_once = 0;
- towrite = state->sendlen;
- }
-
- if(length < towrite) towrite = length;
-
- memcpy(ptr, state->sendbuf + state->sent, towrite);
- state->sent += towrite;
-
- return towrite;
-}
-
-static int
-seek_body(void* ptr, curl_off_t offset, int origin)
-{
- CurlState* state = static_cast<CurlState*>(ptr);
- if(origin != SEEK_SET) return -1;
-
- state->sent = static_cast<size_t>(offset);
- return static_cast<int>(state->sent);
-}
-
-static size_t
-recv_header(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = static_cast<CurlState*>(data);
- char code[4];
- char* header = static_cast<char*>(ptr);
- size_t length = size * nmem;
- JSString* hdr = NULL;
- uint32_t hdrlen;
-
- if(length > 7 && strncasecmp(header, "HTTP/1.", 7) == 0) {
- if(length < 12) {
- return CURLE_WRITE_ERROR;
- }
-
- memcpy(code, header+9, 3*sizeof(char));
- code[3] = '\0';
- state->http->last_status = atoi(code);
-
- state->resp_headers = JS_NewArrayObject(state->cx, 0);
- if(!state->resp_headers) {
- return CURLE_WRITE_ERROR;
- }
-
- return length;
- }
-
- // We get a notice at the \r\n\r\n after headers.
- if(length <= 2) {
- return length;
- }
-
- // Append the new header to our array.
- std::string hdrstr(header, length);
- hdr = string_to_js(state->cx, hdrstr);
- if(!hdr) {
- return CURLE_WRITE_ERROR;
- }
-
- JS::RootedObject obj(state->cx, state->resp_headers);
- if(!JS_GetArrayLength(state->cx, obj, &hdrlen)) {
- return CURLE_WRITE_ERROR;
- }
-
- JS::RootedString hdrval(state->cx, hdr);
- if(!JS_SetElement(state->cx, obj, hdrlen, hdrval)) {
- return CURLE_WRITE_ERROR;
- }
-
- return length;
-}
-
-static size_t
-recv_body(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = static_cast<CurlState*>(data);
- size_t length = size * nmem;
- char* tmp = NULL;
-
- if(!state->recvbuf) {
- state->recvlen = 4096;
- state->read = 0;
- state->recvbuf = static_cast<char*>(JS_malloc(
- state->cx,
- state->recvlen
- ));
- }
-
- if(!state->recvbuf) {
- return CURLE_WRITE_ERROR;
- }
-
- // +1 so we can add '\0' back up in the go function.
- size_t oldlen = state->recvlen;
- while(length+1 > state->recvlen - state->read) state->recvlen *= 2;
- tmp = static_cast<char*>(JS_realloc(
- state->cx,
- state->recvbuf,
- oldlen,
- state->recvlen
- ));
- if(!tmp) return CURLE_WRITE_ERROR;
- state->recvbuf = tmp;
-
- memcpy(state->recvbuf + state->read, ptr, length);
- state->read += length;
- return length;
-}
-
-#endif /* HAVE_CURL */
diff --git a/src/couch/priv/couch_js/60/http.h b/src/couch/priv/couch_js/60/http.h
deleted file mode 100644
index 797b3c060..000000000
--- a/src/couch/priv/couch_js/60/http.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#ifndef COUCH_JS_HTTP_H
-#define COUCH_JS_HTTP_H
-
-#include "util.h"
-
-void http_check_enabled();
-bool http_ctor(JSContext* cx, JSObject* req);
-void http_dtor(JSFreeOp* fop, JSObject* req);
-bool http_open(JSContext* cx, JSObject* req, JS::Value mth, JS::Value url, JS::Value snc);
-bool http_set_hdr(JSContext* cx, JSObject* req, JS::Value name, JS::Value val);
-bool http_send(JSContext* cx, JSObject* req, JS::Value body);
-int http_status(JSContext* cx, JSObject* req);
-bool http_uri(JSContext* cx, JSObject *req, couch_args* args, JS::Value* uri);
-
-#endif
diff --git a/src/couch/priv/couch_js/60/main.cpp b/src/couch/priv/couch_js/60/main.cpp
index 828b9dab5..5169b05d7 100644
--- a/src/couch/priv/couch_js/60/main.cpp
+++ b/src/couch/priv/couch_js/60/main.cpp
@@ -27,7 +27,6 @@
#include <js/Wrapper.h>
#include "config.h"
-#include "http.h"
#include "util.h"
static bool enableSharedMemory = true;
@@ -53,136 +52,6 @@ static JSClass global_class = {
&global_ops
};
-
-static void
-req_dtor(JSFreeOp* fop, JSObject* obj)
-{
- http_dtor(fop, obj);
-}
-
-// With JSClass.construct.
-static const JSClassOps clsOps = {
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- req_dtor,
- nullptr,
- nullptr,
- nullptr
-};
-
-static const JSClass CouchHTTPClass = {
- "CouchHTTP", /* name */
- JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(2), /* flags */
- &clsOps
-};
-
-static bool
-req_ctor(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- bool ret;
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JSObject* obj = JS_NewObjectForConstructor(cx, &CouchHTTPClass, args);
- if(!obj) {
- JS_ReportErrorUTF8(cx, "Failed to create CouchHTTP instance");
- return false;
- }
- ret = http_ctor(cx, obj);
- args.rval().setObject(*obj);
- return ret;
-}
-
-static bool
-req_open(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::Value vobj = args.computeThis(cx);
- JSObject* obj = vobj.toObjectOrNull();
- bool ret = false;
-
- if(argc == 2) {
- ret = http_open(cx, obj, args[0], args[1], JS::BooleanValue(false));
- } else if(argc == 3) {
- ret = http_open(cx, obj, args[0], args[1], args[2]);
- } else {
- JS_ReportErrorUTF8(cx, "Invalid call to CouchHTTP.open");
- }
-
- args.rval().setUndefined();
- return ret;
-}
-
-
-static bool
-req_set_hdr(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::Value vobj = args.computeThis(cx);
- JSObject* obj = vobj.toObjectOrNull();
- bool ret = false;
-
- if(argc == 2) {
- ret = http_set_hdr(cx, obj, args[0], args[1]);
- } else {
- JS_ReportErrorUTF8(cx, "Invalid call to CouchHTTP.set_header");
- }
-
- args.rval().setUndefined();
- return ret;
-}
-
-
-static bool
-req_send(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::Value vobj = args.computeThis(cx);
- JSObject* obj = vobj.toObjectOrNull();
- bool ret = false;
-
- if(argc == 1) {
- ret = http_send(cx, obj, args[0]);
- } else {
- JS_ReportErrorUTF8(cx, "Invalid call to CouchHTTP.send");
- }
-
- args.rval().setUndefined();
- return ret;
-}
-
-static bool
-req_status(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::Value vobj = args.computeThis(cx);
- JSObject* obj = vobj.toObjectOrNull();
-
- int status = http_status(cx, obj);
-
- if(status < 0)
- return false;
-
- args.rval().set(JS::Int32Value(status));
- return true;
-}
-
-static bool
-base_url(JSContext *cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::Value vobj = args.computeThis(cx);
- JSObject* obj = vobj.toObjectOrNull();
-
- couch_args *cargs = static_cast<couch_args*>(JS_GetContextPrivate(cx));
- JS::Value uri_val;
- bool rc = http_uri(cx, obj, cargs, &uri_val);
- args.rval().set(uri_val);
- return rc;
-}
-
static void
SetStandardCompartmentOptions(JS::CompartmentOptions& options)
{
@@ -353,43 +222,6 @@ seal(JSContext* cx, unsigned int argc, JS::Value* vp)
}
-static bool
-js_sleep(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-
- int duration = args[0].toInt32();
-
-#ifdef XP_WIN
- Sleep(duration);
-#else
- usleep(duration * 1000);
-#endif
-
- return true;
-}
-
-JSPropertySpec CouchHTTPProperties[] = {
- JS_PSG("status", req_status, 0),
- JS_PSG("base_url", base_url, 0),
- JS_PS_END
-};
-
-
-JSFunctionSpec CouchHTTPFunctions[] = {
- JS_FN("_open", req_open, 3, 0),
- JS_FN("_setRequestHeader", req_set_hdr, 2, 0),
- JS_FN("_send", req_send, 1, 0),
- JS_FS_END
-};
-
-
-JSFunctionSpec TestSuiteFunctions[] = {
- JS_FN("sleep", js_sleep, 1, 0),
- JS_FS_END
-};
-
-
static JSFunctionSpec global_functions[] = {
JS_FN("evalcx", evalcx, 0, 0),
JS_FN("gc", gc, 0, 0),
@@ -423,7 +255,6 @@ int
main(int argc, const char* argv[])
{
JSContext* cx = NULL;
- JSObject* klass = NULL;
char* scriptsrc;
size_t slen;
int i;
@@ -461,30 +292,6 @@ main(int argc, const char* argv[])
if(couch_load_funcs(cx, global, global_functions) != true)
return 1;
- if(args->use_http) {
- http_check_enabled();
-
- klass = JS_InitClass(
- cx, global,
- NULL,
- &CouchHTTPClass, req_ctor,
- 0,
- CouchHTTPProperties, CouchHTTPFunctions,
- NULL, NULL
- );
-
- if(!klass)
- {
- fprintf(stderr, "Failed to initialize CouchHTTP class.\n");
- exit(2);
- }
- }
-
- if(args->use_test_funs) {
- if(couch_load_funcs(cx, global, TestSuiteFunctions) != true)
- return 1;
- }
-
for(i = 0 ; args->scripts[i] ; i++) {
slen = couch_readfile(args->scripts[i], &scriptsrc);
diff --git a/src/couch/priv/couch_js/60/util.cpp b/src/couch/priv/couch_js/60/util.cpp
index c37c41f2f..3bc58a921 100644
--- a/src/couch/priv/couch_js/60/util.cpp
+++ b/src/couch/priv/couch_js/60/util.cpp
@@ -142,12 +142,8 @@ couch_parse_args(int argc, const char* argv[])
return NULL;
args->eval = 0;
- args->use_http = 0;
- args->use_test_funs = 0;
args->stack_size = 64L * 1024L * 1024L;
args->scripts = nullptr;
- args->uri_file = nullptr;
- args->uri = nullptr;
while(i < argc) {
if(strcmp("-h", argv[i]) == 0) {
@@ -156,18 +152,12 @@ couch_parse_args(int argc, const char* argv[])
} else if(strcmp("-V", argv[i]) == 0) {
DISPLAY_VERSION;
exit(0);
- } else if(strcmp("-H", argv[i]) == 0) {
- args->use_http = 1;
- } else if(strcmp("-T", argv[i]) == 0) {
- args->use_test_funs = 1;
} else if(strcmp("-S", argv[i]) == 0) {
args->stack_size = atoi(argv[++i]);
if(args->stack_size <= 0) {
fprintf(stderr, "Invalid stack size.\n");
exit(2);
}
- } else if(strcmp("-u", argv[i]) == 0) {
- args->uri_file = argv[++i];
} else if(strcmp("--eval", argv[i]) == 0) {
args->eval = 1;
} else if(strcmp("--", argv[i]) == 0) {
diff --git a/src/couch/priv/couch_js/60/util.h b/src/couch/priv/couch_js/60/util.h
index 4c27f0f66..35882a614 100644
--- a/src/couch/priv/couch_js/60/util.h
+++ b/src/couch/priv/couch_js/60/util.h
@@ -17,12 +17,8 @@
typedef struct {
int eval;
- int use_http;
- int use_test_funs;
int stack_size;
const char** scripts;
- const char* uri_file;
- JSString* uri;
} couch_args;
std::string js_to_string(JSContext* cx, JS::HandleValue val);
diff --git a/src/couch/priv/couch_js/68/help.h b/src/couch/priv/couch_js/68/help.h
index c5cb83285..c01c9b8ae 100644
--- a/src/couch/priv/couch_js/68/help.h
+++ b/src/couch/priv/couch_js/68/help.h
@@ -46,10 +46,6 @@ static const char USAGE_TEMPLATE[] =
"\n"
" -h display a short help message and exit\n"
" -V display version information and exit\n"
- " -H enable %s cURL bindings (only avaiable\n"
- " if package was built with cURL available)\n"
- " -T enable test suite specific functions (these\n"
- " should not be enabled for production systems)\n"
" -S SIZE specify that the runtime should allow at\n"
" most SIZE bytes of memory to be allocated\n"
" default is 64 MiB\n"
@@ -78,7 +74,6 @@ static const char USAGE_TEMPLATE[] =
basename, \
basename, \
PACKAGE_NAME, \
- basename, \
PACKAGE_BUGREPORT)
#define DISPLAY_USAGE couch_usage(BASENAME)
diff --git a/src/couch/priv/couch_js/68/http.cpp b/src/couch/priv/couch_js/68/http.cpp
deleted file mode 100644
index 20a609701..000000000
--- a/src/couch/priv/couch_js/68/http.cpp
+++ /dev/null
@@ -1,650 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <jsapi.h>
-#include <js/Initialization.h>
-#include <js/MemoryFunctions.h>
-#include "config.h"
-#include "util.h"
-
-// Soft dependency on cURL bindings because they're
-// only used when running the JS tests from the
-// command line which is rare.
-#ifndef HAVE_CURL
-
-void
-http_check_enabled()
-{
- fprintf(stderr, "HTTP API was disabled at compile time.\n");
- exit(3);
-}
-
-
-bool
-http_ctor(JSContext* cx, JSObject* req)
-{
- return false;
-}
-
-
-void
-http_dtor(JSFreeOp* fop, JSObject* req)
-{
- return;
-}
-
-
-bool
-http_open(JSContext* cx, JSObject* req, JS::Value mth, JS::Value url, JS::Value snc)
-{
- return false;
-}
-
-
-bool
-http_set_hdr(JSContext* cx, JSObject* req, JS::Value name, JS::Value val)
-{
- return false;
-}
-
-
-bool
-http_send(JSContext* cx, JSObject* req, JS::Value body)
-{
- return false;
-}
-
-
-int
-http_status(JSContext* cx, JSObject* req)
-{
- return -1;
-}
-
-bool
-http_uri(JSContext* cx, JSObject* req, couch_args* args, JS::Value* uri_val)
-{
- return false;
-}
-
-
-#else
-#include <curl/curl.h>
-#ifndef XP_WIN
-#include <unistd.h>
-#endif
-
-
-void
-http_check_enabled()
-{
- return;
-}
-
-
-// Map some of the string function names to things which exist on Windows
-#ifdef XP_WIN
-#define strcasecmp _strcmpi
-#define strncasecmp _strnicmp
-#endif
-
-
-typedef struct curl_slist CurlHeaders;
-
-
-typedef struct {
- int method;
- std::string url;
- CurlHeaders* req_headers;
- int16_t last_status;
-} HTTPData;
-
-
-const char* METHODS[] = {"GET", "HEAD", "POST", "PUT", "DELETE", "COPY", "OPTIONS", NULL};
-
-
-#define GET 0
-#define HEAD 1
-#define POST 2
-#define PUT 3
-#define DELETE 4
-#define COPY 5
-#define OPTIONS 6
-
-
-static bool go(JSContext* cx, JSObject* obj, HTTPData* http, std::string& body);
-
-
-bool
-http_ctor(JSContext* cx, JSObject* req)
-{
- HTTPData* http = new HTTPData();
- bool ret = false;
-
- if(!http)
- {
- JS_ReportErrorUTF8(cx, "Failed to create CouchHTTP instance.");
- goto error;
- }
-
- http->method = -1;
- http->req_headers = NULL;
- http->last_status = -1;
-
- JS_SetPrivate(req, http);
-
- ret = true;
- goto success;
-
-error:
- if(http) delete http;
-
-success:
- return ret;
-}
-
-
-void
-http_dtor(JSFreeOp* fop, JSObject* obj)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(obj);
- if(http) {
- if(http->req_headers) curl_slist_free_all(http->req_headers);
- delete http;
- }
-}
-
-
-bool
-http_open(JSContext* cx, JSObject* req, JS::Value mth, JS::Value url, JS::Value snc)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
- int methid;
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- if(!mth.isString()) {
- JS_ReportErrorUTF8(cx, "Method must be a string.");
- return false;
- }
-
- std::string method;
- if(!js_to_string(cx, JS::RootedValue(cx, mth), method)) {
- JS_ReportErrorUTF8(cx, "Failed to encode method.");
- return false;
- }
-
- for(methid = 0; METHODS[methid] != NULL; methid++) {
- if(strcasecmp(METHODS[methid], method.c_str()) == 0) break;
- }
-
- if(methid > OPTIONS) {
- JS_ReportErrorUTF8(cx, "Invalid method specified.");
- return false;
- }
-
- http->method = methid;
-
- if(!url.isString()) {
- JS_ReportErrorUTF8(cx, "URL must be a string");
- return false;
- }
-
- std::string urlstr;
- if(!js_to_string(cx, JS::RootedValue(cx, url), urlstr)) {
- JS_ReportErrorUTF8(cx, "Failed to encode URL.");
- return false;
- }
- http->url = urlstr;
-
- if(snc.isBoolean() && snc.isTrue()) {
- JS_ReportErrorUTF8(cx, "Synchronous flag must be false.");
- return false;
- }
-
- if(http->req_headers) {
- curl_slist_free_all(http->req_headers);
- http->req_headers = NULL;
- }
-
- // Disable Expect: 100-continue
- http->req_headers = curl_slist_append(http->req_headers, "Expect:");
-
- return true;
-}
-
-
-bool
-http_set_hdr(JSContext* cx, JSObject* req, JS::Value name, JS::Value val)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- if(!name.isString())
- {
- JS_ReportErrorUTF8(cx, "Header names must be strings.");
- return false;
- }
-
- std::string keystr;
- if(!js_to_string(cx, JS::RootedValue(cx, name), keystr))
- {
- JS_ReportErrorUTF8(cx, "Failed to encode header name.");
- return false;
- }
-
- if(!val.isString())
- {
- JS_ReportErrorUTF8(cx, "Header values must be strings.");
- return false;
- }
-
- std::string valstr;
- if(!js_to_string(cx, JS::RootedValue(cx, val), valstr)) {
- JS_ReportErrorUTF8(cx, "Failed to encode header value.");
- return false;
- }
-
- std::string header = keystr + ": " + valstr;
- http->req_headers = curl_slist_append(http->req_headers, header.c_str());
-
- return true;
-}
-
-bool
-http_send(JSContext* cx, JSObject* req, JS::Value body)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- std::string bodystr;
- if(!js_to_string(cx, JS::RootedValue(cx, body), bodystr)) {
- JS_ReportErrorUTF8(cx, "Failed to encode body.");
- return false;
- }
-
- return go(cx, req, http, bodystr);
-}
-
-int
-http_status(JSContext* cx, JSObject* req)
-{
- HTTPData* http = (HTTPData*) JS_GetPrivate(req);
-
- if(!http) {
- JS_ReportErrorUTF8(cx, "Invalid CouchHTTP instance.");
- return false;
- }
-
- return http->last_status;
-}
-
-bool
-http_uri(JSContext* cx, JSObject* req, couch_args* args, JS::Value* uri_val)
-{
- FILE* uri_fp = NULL;
- JSString* uri_str;
-
- // Default is http://localhost:15986/ when no uri file is specified
- if (!args->uri_file) {
- uri_str = JS_NewStringCopyZ(cx, "http://localhost:15986/");
- *uri_val = JS::StringValue(uri_str);
- JS_SetReservedSlot(req, 0, *uri_val);
- return true;
- }
-
- // Else check to see if the base url is cached in a reserved slot
- *uri_val = JS_GetReservedSlot(req, 0);
- if (!(*uri_val).isUndefined()) {
- return true;
- }
-
- // Read the first line of the couch.uri file.
- if(!((uri_fp = fopen(args->uri_file, "r")) &&
- (uri_str = couch_readline(cx, uri_fp)))) {
- JS_ReportErrorUTF8(cx, "Failed to read couch.uri file.");
- goto error;
- }
-
- fclose(uri_fp);
- *uri_val = JS::StringValue(uri_str);
- JS_SetReservedSlot(req, 0, *uri_val);
- return true;
-
-error:
- if(uri_fp) fclose(uri_fp);
- return false;
-}
-
-
-// Curl Helpers
-
-typedef struct {
- HTTPData* http;
- JSContext* cx;
- JSObject* resp_headers;
- const char* sendbuf;
- size_t sendlen;
- size_t sent;
- int sent_once;
- char* recvbuf;
- size_t recvlen;
- size_t read;
-} CurlState;
-
-/*
- * I really hate doing this but this doesn't have to be
- * uber awesome, it just has to work.
- */
-CURL* HTTP_HANDLE = NULL;
-char ERRBUF[CURL_ERROR_SIZE];
-
-static size_t send_body(void *ptr, size_t size, size_t nmem, void *data);
-static int seek_body(void *ptr, curl_off_t offset, int origin);
-static size_t recv_body(void *ptr, size_t size, size_t nmem, void *data);
-static size_t recv_header(void *ptr, size_t size, size_t nmem, void *data);
-
-static bool
-go(JSContext* cx, JSObject* obj, HTTPData* http, std::string& body)
-{
- CurlState state;
- JSString* jsbody;
- bool ret = false;
- JS::Value tmp;
- JS::RootedObject robj(cx, obj);
- JS::RootedValue vobj(cx);
-
-
- state.cx = cx;
- state.http = http;
-
- state.sendbuf = body.c_str();;
- state.sendlen = body.size();
- state.sent = 0;
- state.sent_once = 0;
-
- state.recvbuf = NULL;
- state.recvlen = 0;
- state.read = 0;
-
- if(HTTP_HANDLE == NULL) {
- HTTP_HANDLE = curl_easy_init();
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_READFUNCTION, send_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKFUNCTION,
- (curl_seek_callback) seek_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_HEADERFUNCTION, recv_header);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEFUNCTION, recv_body);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOPROGRESS, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_ERRORBUFFER, ERRBUF);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_COOKIEFILE, "");
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_USERAGENT,
- "CouchHTTP Client - Relax");
- }
-
- if(!HTTP_HANDLE) {
- JS_ReportErrorUTF8(cx, "Failed to initialize cURL handle.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- tmp = JS_GetReservedSlot(obj, 0);
-
- std::string referer;
- if(!js_to_string(cx, JS::RootedValue(cx, tmp), referer)) {
- JS_ReportErrorUTF8(cx, "Failed to encode referer.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_REFERER, referer.c_str());
-
- if(http->method < 0 || http->method > OPTIONS) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Unknown method.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_CUSTOMREQUEST, METHODS[http->method]);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 0);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 0);
-
- if(http->method == HEAD) {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_NOBODY, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0);
- } else if(http->method == POST || http->method == PUT) {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_UPLOAD, 1);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_FOLLOWLOCATION, 0);
- }
-
- if(body.size() > 0) {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, body.size());
- } else {
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_INFILESIZE, 0);
- }
-
- // curl_easy_setopt(HTTP_HANDLE, CURLOPT_VERBOSE, 1);
-
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_URL, http->url.c_str());
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_HTTPHEADER, http->req_headers);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_READDATA, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_SEEKDATA, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEHEADER, &state);
- curl_easy_setopt(HTTP_HANDLE, CURLOPT_WRITEDATA, &state);
-
- if(curl_easy_perform(HTTP_HANDLE) != 0) {
- JS_ReportErrorUTF8(cx, "Failed to execute HTTP request: %s", ERRBUF);
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- if(!state.resp_headers) {
- JS_ReportErrorUTF8(cx, "Failed to recieve HTTP headers.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
- tmp = JS::ObjectValue(*state.resp_headers);
- JS::RootedValue rtmp(cx, tmp);
-
- if(!JS_DefineProperty(
- cx, robj,
- "_headers",
- rtmp,
- JSPROP_READONLY
- )) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Failed to set response headers.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;;
- }
-
- if(state.recvbuf) {
- state.recvbuf[state.read] = '\0';
- std::string bodystr(state.recvbuf, state.read);
- jsbody = string_to_js(cx, bodystr);
- if(!jsbody) {
- // If we can't decode the body as UTF-8 we forcefully
- // convert it to a string by just forcing each byte
- // to a char16_t.
- jsbody = JS_NewStringCopyN(cx, state.recvbuf, state.read);
- if(!jsbody) {
- if(!JS_IsExceptionPending(cx)) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Failed to decode body.");
- }
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
- }
- tmp = JS::StringValue(jsbody);
- } else {
- tmp = JS_GetEmptyStringValue(cx);
- }
-
- JS::RootedValue rtmp2(cx, tmp);
-
- if(!JS_DefineProperty(
- cx, robj,
- "responseText",
- rtmp2,
- JSPROP_READONLY
- )) {
- JS_ReportErrorUTF8(cx, "INTERNAL: Failed to set responseText.");
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
- }
-
- ret = true;
- if(state.recvbuf) JS_free(cx, state.recvbuf);
- return ret;
-}
-
-static size_t
-send_body(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = static_cast<CurlState*>(data);
- size_t length = size * nmem;
- size_t towrite = state->sendlen - state->sent;
-
- // Assume this is cURL trying to resend a request that
- // failed.
- if(towrite == 0 && state->sent_once == 0) {
- state->sent_once = 1;
- return 0;
- } else if(towrite == 0) {
- state->sent = 0;
- state->sent_once = 0;
- towrite = state->sendlen;
- }
-
- if(length < towrite) towrite = length;
-
- memcpy(ptr, state->sendbuf + state->sent, towrite);
- state->sent += towrite;
-
- return towrite;
-}
-
-static int
-seek_body(void* ptr, curl_off_t offset, int origin)
-{
- CurlState* state = static_cast<CurlState*>(ptr);
- if(origin != SEEK_SET) return -1;
-
- state->sent = static_cast<size_t>(offset);
- return static_cast<int>(state->sent);
-}
-
-static size_t
-recv_header(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = static_cast<CurlState*>(data);
- char code[4];
- char* header = static_cast<char*>(ptr);
- size_t length = size * nmem;
- JSString* hdr = NULL;
- uint32_t hdrlen;
-
- if(length > 7 && strncasecmp(header, "HTTP/1.", 7) == 0) {
- if(length < 12) {
- return CURLE_WRITE_ERROR;
- }
-
- memcpy(code, header+9, 3*sizeof(char));
- code[3] = '\0';
- state->http->last_status = atoi(code);
-
- state->resp_headers = JS_NewArrayObject(state->cx, 0);
- if(!state->resp_headers) {
- return CURLE_WRITE_ERROR;
- }
-
- return length;
- }
-
- // We get a notice at the \r\n\r\n after headers.
- if(length <= 2) {
- return length;
- }
-
- // Append the new header to our array.
- std::string hdrstr(header, length);
- hdr = string_to_js(state->cx, hdrstr);
- if(!hdr) {
- return CURLE_WRITE_ERROR;
- }
-
- JS::RootedObject obj(state->cx, state->resp_headers);
- if(!JS_GetArrayLength(state->cx, obj, &hdrlen)) {
- return CURLE_WRITE_ERROR;
- }
-
- JS::RootedString hdrval(state->cx, hdr);
- if(!JS_SetElement(state->cx, obj, hdrlen, hdrval)) {
- return CURLE_WRITE_ERROR;
- }
-
- return length;
-}
-
-static size_t
-recv_body(void *ptr, size_t size, size_t nmem, void *data)
-{
- CurlState* state = static_cast<CurlState*>(data);
- size_t length = size * nmem;
- char* tmp = NULL;
-
- if(!state->recvbuf) {
- state->recvlen = 4096;
- state->read = 0;
- state->recvbuf = static_cast<char*>(JS_malloc(
- state->cx,
- state->recvlen
- ));
- }
-
- if(!state->recvbuf) {
- return CURLE_WRITE_ERROR;
- }
-
- // +1 so we can add '\0' back up in the go function.
- size_t oldlen = state->recvlen;
- while(length+1 > state->recvlen - state->read) state->recvlen *= 2;
- tmp = static_cast<char*>(JS_realloc(
- state->cx,
- state->recvbuf,
- oldlen,
- state->recvlen
- ));
- if(!tmp) return CURLE_WRITE_ERROR;
- state->recvbuf = tmp;
-
- memcpy(state->recvbuf + state->read, ptr, length);
- state->read += length;
- return length;
-}
-
-#endif /* HAVE_CURL */
diff --git a/src/couch/priv/couch_js/68/http.h b/src/couch/priv/couch_js/68/http.h
deleted file mode 100644
index 797b3c060..000000000
--- a/src/couch/priv/couch_js/68/http.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-#ifndef COUCH_JS_HTTP_H
-#define COUCH_JS_HTTP_H
-
-#include "util.h"
-
-void http_check_enabled();
-bool http_ctor(JSContext* cx, JSObject* req);
-void http_dtor(JSFreeOp* fop, JSObject* req);
-bool http_open(JSContext* cx, JSObject* req, JS::Value mth, JS::Value url, JS::Value snc);
-bool http_set_hdr(JSContext* cx, JSObject* req, JS::Value name, JS::Value val);
-bool http_send(JSContext* cx, JSObject* req, JS::Value body);
-int http_status(JSContext* cx, JSObject* req);
-bool http_uri(JSContext* cx, JSObject *req, couch_args* args, JS::Value* uri);
-
-#endif
diff --git a/src/couch/priv/couch_js/68/main.cpp b/src/couch/priv/couch_js/68/main.cpp
index 2c95f6129..bb62d16ca 100644
--- a/src/couch/priv/couch_js/68/main.cpp
+++ b/src/couch/priv/couch_js/68/main.cpp
@@ -30,7 +30,6 @@
#include <js/Wrapper.h>
#include "config.h"
-#include "http.h"
#include "util.h"
static bool enableSharedMemory = true;
@@ -56,141 +55,6 @@ static JSClass global_class = {
&global_ops
};
-
-static void
-req_dtor(JSFreeOp* fop, JSObject* obj)
-{
- http_dtor(fop, obj);
-}
-
-// With JSClass.construct.
-static const JSClassOps clsOps = {
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- nullptr,
- req_dtor,
- nullptr,
- nullptr,
- nullptr
-};
-
-static const JSClass CouchHTTPClass = {
- "CouchHTTP", /* name */
- JSCLASS_HAS_PRIVATE | JSCLASS_HAS_RESERVED_SLOTS(2), /* flags */
- &clsOps
-};
-
-static bool
-req_ctor(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- bool ret;
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JSObject* obj = JS_NewObjectForConstructor(cx, &CouchHTTPClass, args);
- if(!obj) {
- JS_ReportErrorUTF8(cx, "Failed to create CouchHTTP instance");
- return false;
- }
- ret = http_ctor(cx, obj);
- args.rval().setObject(*obj);
- return ret;
-}
-
-static bool
-req_open(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::RootedObject obj(cx);
- if (!args.computeThis(cx, &obj))
- return false;
- bool ret = false;
-
- if(argc == 2) {
- ret = http_open(cx, obj, args[0], args[1], JS::BooleanValue(false));
- } else if(argc == 3) {
- ret = http_open(cx, obj, args[0], args[1], args[2]);
- } else {
- JS_ReportErrorUTF8(cx, "Invalid call to CouchHTTP.open");
- }
-
- args.rval().setUndefined();
- return ret;
-}
-
-
-static bool
-req_set_hdr(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::RootedObject obj(cx);
- if (!args.computeThis(cx, &obj))
- return false;
- bool ret = false;
-
- if(argc == 2) {
- ret = http_set_hdr(cx, obj, args[0], args[1]);
- } else {
- JS_ReportErrorUTF8(cx, "Invalid call to CouchHTTP.set_header");
- }
-
- args.rval().setUndefined();
- return ret;
-}
-
-
-static bool
-req_send(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::RootedObject obj(cx);
- if (!args.computeThis(cx, &obj))
- return false;
- bool ret = false;
-
- if(argc == 1) {
- ret = http_send(cx, obj, args[0]);
- } else {
- JS_ReportErrorUTF8(cx, "Invalid call to CouchHTTP.send");
- }
-
- args.rval().setUndefined();
- return ret;
-}
-
-static bool
-req_status(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::RootedObject obj(cx);
- if (!args.computeThis(cx, &obj))
- return false;
-
- int status = http_status(cx, obj);
-
- if(status < 0)
- return false;
-
- args.rval().set(JS::Int32Value(status));
- return true;
-}
-
-static bool
-base_url(JSContext *cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
- JS::RootedObject obj(cx);
- if (!args.computeThis(cx, &obj))
- return false;
-
- couch_args *cargs = static_cast<couch_args*>(JS_GetContextPrivate(cx));
- JS::Value uri_val;
- bool rc = http_uri(cx, obj, cargs, &uri_val);
- args.rval().set(uri_val);
- return rc;
-}
-
static JSObject*
NewSandbox(JSContext* cx, bool lazy)
{
@@ -358,43 +222,6 @@ seal(JSContext* cx, unsigned int argc, JS::Value* vp)
}
-static bool
-js_sleep(JSContext* cx, unsigned int argc, JS::Value* vp)
-{
- JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
-
- int duration = args[0].toInt32();
-
-#ifdef XP_WIN
- Sleep(duration);
-#else
- usleep(duration * 1000);
-#endif
-
- return true;
-}
-
-JSPropertySpec CouchHTTPProperties[] = {
- JS_PSG("status", req_status, 0),
- JS_PSG("base_url", base_url, 0),
- JS_PS_END
-};
-
-
-JSFunctionSpec CouchHTTPFunctions[] = {
- JS_FN("_open", req_open, 3, 0),
- JS_FN("_setRequestHeader", req_set_hdr, 2, 0),
- JS_FN("_send", req_send, 1, 0),
- JS_FS_END
-};
-
-
-JSFunctionSpec TestSuiteFunctions[] = {
- JS_FN("sleep", js_sleep, 1, 0),
- JS_FS_END
-};
-
-
static JSFunctionSpec global_functions[] = {
JS_FN("evalcx", evalcx, 0, 0),
JS_FN("gc", gc, 0, 0),
@@ -428,7 +255,6 @@ int
main(int argc, const char* argv[])
{
JSContext* cx = NULL;
- JSObject* klass = NULL;
int i;
couch_args* args = couch_parse_args(argc, argv);
@@ -463,30 +289,6 @@ main(int argc, const char* argv[])
if(couch_load_funcs(cx, global, global_functions) != true)
return 1;
- if(args->use_http) {
- http_check_enabled();
-
- klass = JS_InitClass(
- cx, global,
- NULL,
- &CouchHTTPClass, req_ctor,
- 0,
- CouchHTTPProperties, CouchHTTPFunctions,
- NULL, NULL
- );
-
- if(!klass)
- {
- fprintf(stderr, "Failed to initialize CouchHTTP class.\n");
- exit(2);
- }
- }
-
- if(args->use_test_funs) {
- if(couch_load_funcs(cx, global, TestSuiteFunctions) != true)
- return 1;
- }
-
for(i = 0 ; args->scripts[i] ; i++) {
const char* filename = args->scripts[i];
diff --git a/src/couch/priv/couch_js/68/util.cpp b/src/couch/priv/couch_js/68/util.cpp
index 7717f1185..6e6105df5 100644
--- a/src/couch/priv/couch_js/68/util.cpp
+++ b/src/couch/priv/couch_js/68/util.cpp
@@ -135,12 +135,8 @@ couch_parse_args(int argc, const char* argv[])
return NULL;
args->eval = 0;
- args->use_http = 0;
- args->use_test_funs = 0;
args->stack_size = 64L * 1024L * 1024L;
args->scripts = nullptr;
- args->uri_file = nullptr;
- args->uri = nullptr;
while(i < argc) {
if(strcmp("-h", argv[i]) == 0) {
@@ -149,18 +145,12 @@ couch_parse_args(int argc, const char* argv[])
} else if(strcmp("-V", argv[i]) == 0) {
DISPLAY_VERSION;
exit(0);
- } else if(strcmp("-H", argv[i]) == 0) {
- args->use_http = 1;
- } else if(strcmp("-T", argv[i]) == 0) {
- args->use_test_funs = 1;
} else if(strcmp("-S", argv[i]) == 0) {
args->stack_size = atoi(argv[++i]);
if(args->stack_size <= 0) {
fprintf(stderr, "Invalid stack size.\n");
exit(2);
}
- } else if(strcmp("-u", argv[i]) == 0) {
- args->uri_file = argv[++i];
} else if(strcmp("--eval", argv[i]) == 0) {
args->eval = 1;
} else if(strcmp("--", argv[i]) == 0) {
diff --git a/src/couch/rebar.config.script b/src/couch/rebar.config.script
index ed5420f0a..59bd40fbb 100644
--- a/src/couch/rebar.config.script
+++ b/src/couch/rebar.config.script
@@ -132,29 +132,6 @@ end.
}
end.
-{CURL_CFLAGS, CURL_LDFLAGS} = case lists:keyfind(with_curl, 1, CouchConfig) of
- {with_curl, true} ->
- case os:type() of
- {win32, _} ->
- {
- "/DHAVE_CURL",
- "/DHAVE_CURL libcurl.lib"
- };
- {unix, freebsd} ->
- {
- "-DHAVE_CURL -I/usr/local/include",
- "-DHAVE_CURL -lcurl"
- };
- _ ->
- {
- "-DHAVE_CURL",
- "-DHAVE_CURL -lcurl"
- }
- end;
- _ ->
- {"", ""}
-end.
-
CouchJSSrc = case SMVsn of
"1.8.5" -> ["priv/couch_js/1.8.5/*.c"];
"60" -> ["priv/couch_js/60/*.cpp"];
@@ -164,13 +141,13 @@ end.
CouchJSEnv = case SMVsn of
"1.8.5" ->
[
- {"CFLAGS", JS_CFLAGS ++ " " ++ CURL_CFLAGS},
- {"LDFLAGS", JS_LDFLAGS ++ " " ++ CURL_LDFLAGS}
+ {"CFLAGS", JS_CFLAGS},
+ {"LDFLAGS", JS_LDFLAGS}
];
_ ->
[
- {"CXXFLAGS", JS_CFLAGS ++ " " ++ CURL_CFLAGS},
- {"LDFLAGS", JS_LDFLAGS ++ " " ++ CURL_LDFLAGS}
+ {"CXXFLAGS", JS_CFLAGS},
+ {"LDFLAGS", JS_LDFLAGS}
]
end.
diff --git a/test/javascript/cli_runner.js b/test/javascript/cli_runner.js
deleted file mode 100644
index a35348f20..000000000
--- a/test/javascript/cli_runner.js
+++ /dev/null
@@ -1,63 +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.
-//
-
-/*
- * Quit current test execution if it is tagged as skipped or ported to elixir
- */
-function quitIfSkippedOrPorted() {
- if(couchTests.skip) {
- quit(2);
- }
-
- if(couchTests.elixir) {
- quit(3);
- }
-}
-
-/*
- * Futon test suite was designed to be able to run all tests populated into
- * couchTests. Here we should only be loading one test, so we'll pop the first
- * test off the list and run the test. If more than one item is loaded in the
- * test object, return an error.
- */
-function runTest() {
- CouchDB.reloadConfig();
- var count = 0;
- var start = new Date().getTime();
-
- for(var name in couchTests) {
- count++;
- }
-
- if (count !== 1) {
- console.log('Only one test per file is allowed.');
- quit(1);
- }
-
- try {
- // Add artificial wait for each test of 1 sec
- while (new Date().getTime() < start + 1200);
- couchTests[name]();
- quit(0);
- } catch(e) {
- console.log("\nError: " + e.message);
- fmtStack(e.stack);
- quit(1)
- }
-}
-
-quitIfSkippedOrPorted();
-
-waitForSuccess(CouchDB.isRunning, 'isRunning');
-
-runTest();
diff --git a/test/javascript/couch.js b/test/javascript/couch.js
deleted file mode 100644
index c325d68be..000000000
--- a/test/javascript/couch.js
+++ /dev/null
@@ -1,557 +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.
-
-// A simple class to represent a database. Uses XMLHttpRequest to interface with
-// the CouchDB server.
-
-function CouchDB(name, httpHeaders, globalRequestOptions) {
- this.globalRequestOptions = globalRequestOptions || {}
- this.name = name;
- this.uri = "/" + encodeURIComponent(name) + "/";
-
- // The XMLHttpRequest object from the most recent request. Callers can
- // use this to check result http status and headers.
- this.last_req = null;
-
- this.request = function(method, uri, requestOptions) {
- requestOptions = requestOptions || {};
- requestOptions.headers = combine(requestOptions.headers, httpHeaders);
- requestOptions.url = globalRequestOptions;
- return CouchDB.request(method, uri, requestOptions);
- };
-
- // Creates the database on the server
- this.createDb = function() {
- this.last_req = this.request("PUT", this.uri);
- CouchDB.maybeThrowError(this.last_req);
- return JSON.parse(this.last_req.responseText);
- };
-
- // Deletes the database on the server
- this.deleteDb = function() {
- this.last_req = this.request("DELETE", this.uri + "?sync=true");
- if (this.last_req.status == 404) {
- return false;
- }
- CouchDB.maybeThrowError(this.last_req);
- return JSON.parse(this.last_req.responseText);
- };
-
- // Save a document to the database
- this.save = function(doc, options, http_headers) {
- if (doc._id == undefined) {
- doc._id = CouchDB.newUuids(1)[0];
- }
- http_headers = http_headers || {};
- this.last_req = this.request("PUT", this.uri +
- encodeURIComponent(doc._id) + encodeOptions(options),
- {body: JSON.stringify(doc), headers: http_headers});
- CouchDB.maybeThrowError(this.last_req);
- var result = JSON.parse(this.last_req.responseText);
- doc._rev = result.rev;
- return result;
- };
-
- // Open a document from the database
- this.open = function(docId, url_params, http_headers) {
- this.last_req = this.request("GET", this.uri + encodeURIComponent(docId)
- + encodeOptions(url_params), {headers:http_headers});
- if (this.last_req.status == 404) {
- return null;
- }
- CouchDB.maybeThrowError(this.last_req);
- return JSON.parse(this.last_req.responseText);
- };
-
- // Deletes a document from the database
- this.deleteDoc = function(doc) {
- this.last_req = this.request("DELETE", this.uri + encodeURIComponent(doc._id)
- + "?rev=" + doc._rev);
- CouchDB.maybeThrowError(this.last_req);
- var result = JSON.parse(this.last_req.responseText);
- doc._rev = result.rev; //record rev in input document
- doc._deleted = true;
- return result;
- };
-
- // Deletes an attachment from a document
- this.deleteDocAttachment = function(doc, attachment_name) {
- this.last_req = this.request("DELETE", this.uri + encodeURIComponent(doc._id)
- + "/" + attachment_name + "?rev=" + doc._rev);
- CouchDB.maybeThrowError(this.last_req);
- var result = JSON.parse(this.last_req.responseText);
- doc._rev = result.rev; //record rev in input document
- return result;
- };
-
- this.bulkSave = function(docs, options) {
- // first prepoulate the UUIDs for new documents
- var newCount = 0;
- for (var i=0; i<docs.length; i++) {
- if (docs[i]._id == undefined) {
- newCount++;
- }
- }
- var newUuids = CouchDB.newUuids(newCount);
- var newCount = 0;
- for (var i=0; i<docs.length; i++) {
- if (docs[i]._id == undefined) {
- docs[i]._id = newUuids.pop();
- }
- }
- var json = {"docs": docs};
- // put any options in the json
- for (var option in options) {
- json[option] = options[option];
- }
- this.last_req = this.request("POST", this.uri + "_bulk_docs", {
- body: JSON.stringify(json)
- });
- if (this.last_req.status == 417) {
- return {errors: JSON.parse(this.last_req.responseText)};
- }
- else {
- CouchDB.maybeThrowError(this.last_req);
- var results = JSON.parse(this.last_req.responseText);
- for (var i = 0; i < docs.length; i++) {
- if(results[i] && results[i].rev && results[i].ok) {
- docs[i]._rev = results[i].rev;
- }
- }
- return results;
- }
- };
-
- this.ensureFullCommit = function() {
- this.last_req = this.request("POST", this.uri + "_ensure_full_commit");
- CouchDB.maybeThrowError(this.last_req);
- return JSON.parse(this.last_req.responseText);
- };
-
- // Applies the map function to the contents of database and returns the results.
- this.query = function(mapFun, reduceFun, options, keys, language) {
- //var body = {language: language || "javascript"};
- var body = {}
- if(keys) {
- options.keys = keys ;
- }
- if (typeof(mapFun) != "string") {
- mapFun = mapFun.toSource ? mapFun.toSource() : "(" + mapFun.toString() + ")";
- }
- if ((!language) || language.toLowerCase() == "javascript") {
- mapFun = mapFun + "/" + "* avoid race cond " + (new Date().getTime()) + " *" + "/";
- }
- body.map = mapFun;
- if (reduceFun != null) {
- if (typeof(reduceFun) != "string") {
- reduceFun = reduceFun.toSource ?
- reduceFun.toSource() : "(" + reduceFun.toString() + ")";
- }
- body.reduce = reduceFun;
- }
- if (options && options.options != undefined) {
- body.options = options.options;
- delete options.options;
- }
- var ddoc = {
- language: language || "javascript",
- views: {
- view: body
- }
- };
- var ddoc_name = "_design/temp_" + get_random_string();
- this.last_req = this.request("PUT", this.uri + ddoc_name, {
- headers: {"Content-Type": "application/json"},
- body: JSON.stringify(ddoc)
- });
- CouchDB.maybeThrowError(this.last_req);
- var ddoc_result = JSON.parse(this.last_req.responseText)
- this.last_req = this.request("GET", this.uri + ddoc_name + "/_view/view"
- + encodeOptions(options));
- CouchDB.maybeThrowError(this.last_req);
- var query_result = JSON.parse(this.last_req.responseText);
- var res = this.request("DELETE", this.uri + ddoc_name + '?rev=' + ddoc_result.rev);
-
- return query_result;
- };
-
- this.view = function(viewname, options, keys) {
- var viewParts = viewname.split('/');
- var viewPath = this.uri + "_design/" + viewParts[0] + "/_view/"
- + viewParts[1] + encodeOptions(options);
- if(!keys) {
- this.last_req = this.request("GET", viewPath);
- } else {
- this.last_req = this.request("POST", viewPath, {
- headers: {"Content-Type": "application/json"},
- body: JSON.stringify({keys:keys})
- });
- }
- if (this.last_req.status == 404) {
- return null;
- }
- CouchDB.maybeThrowError(this.last_req);
- return JSON.parse(this.last_req.responseText);
- };
-
- // gets information about the database
- this.info = function() {
- this.last_req = this.request("GET", this.uri);
- CouchDB.maybeThrowError(this.last_req);
- return JSON.parse(this.last_req.responseText);
- };
-
- // gets information about a design doc
- this.designInfo = function(docid) {
- this.last_req = this.request("GET", this.uri + docid + "/_info");
- CouchDB.maybeThrowError(this.last_req);
- return JSON.parse(this.last_req.responseText);
- };
-
- this.allDocs = function(options,keys) {
- if(!keys) {
- this.last_req = this.request("GET", this.uri + "_all_docs"
- + encodeOptions(options));
- } else {
- this.last_req = this.request("POST", this.uri + "_all_docs"
- + encodeOptions(options), {
- headers: {"Content-Type": "application/json"},
- body: JSON.stringify({keys:keys})
- });
- }
- CouchDB.maybeThrowError(this.last_req);
- return JSON.parse(this.last_req.responseText);
- };
-
- this.designDocs = function() {
- return this.allDocs({startkey:"_design", endkey:"_design0"});
- };
-
- this.changes = function(options) {
- this.last_req = this.request("GET", this.uri + "_changes"
- + encodeOptions(options));
- CouchDB.maybeThrowError(this.last_req);
- return JSON.parse(this.last_req.responseText);
- };
-
- this.compact = function() {
- this.last_req = this.request("POST", this.uri + "_compact");
- CouchDB.maybeThrowError(this.last_req);
- return JSON.parse(this.last_req.responseText);
- };
-
- this.viewCleanup = function() {
- this.last_req = this.request("POST", this.uri + "_view_cleanup");
- CouchDB.maybeThrowError(this.last_req);
- return JSON.parse(this.last_req.responseText);
- };
-
- this.setDbProperty = function(propId, propValue) {
- this.last_req = this.request("PUT", this.uri + propId,{
- body:JSON.stringify(propValue)
- });
- CouchDB.maybeThrowError(this.last_req);
- return JSON.parse(this.last_req.responseText);
- };
-
- this.getDbProperty = function(propId) {
- this.last_req = this.request("GET", this.uri + propId);
- CouchDB.maybeThrowError(this.last_req);
- return JSON.parse(this.last_req.responseText);
- };
-
- this.setSecObj = function(secObj) {
- this.last_req = this.request("PUT", this.uri + "_security",{
- body:JSON.stringify(secObj)
- });
- CouchDB.maybeThrowError(this.last_req);
- return JSON.parse(this.last_req.responseText);
- };
-
- this.getSecObj = function() {
- this.last_req = this.request("GET", this.uri + "_security");
- CouchDB.maybeThrowError(this.last_req);
- return JSON.parse(this.last_req.responseText);
- };
-
- // Convert a options object to an url query string.
- // ex: {key:'value',key2:'value2'} becomes '?key="value"&key2="value2"'
- function encodeOptions(options) {
- var buf = [];
- if (typeof(options) == "object" && options !== null) {
- for (var name in options) {
- if (!options.hasOwnProperty(name)) { continue; };
- var value = options[name];
- if (name == "key" || name == "keys" || name == "startkey" || name == "endkey" || (name == "open_revs" && value !== "all")) {
- value = toJSON(value);
- }
- buf.push(encodeURIComponent(name) + "=" + encodeURIComponent(value));
- }
- }
- if (!buf.length) {
- return "";
- }
- return "?" + buf.join("&");
- }
-
- function toJSON(obj) {
- return obj !== null ? JSON.stringify(obj) : null;
- }
-
- function combine(object1, object2) {
- if (!object2) {
- return object1;
- }
- if (!object1) {
- return object2;
- }
-
- for (var name in object2) {
- object1[name] = object2[name];
- }
- return object1;
- }
-
-}
-
-// this is the XMLHttpRequest object from last request made by the following
-// CouchDB.* functions (except for calls to request itself).
-// Use this from callers to check HTTP status or header values of requests.
-CouchDB.last_req = null;
-CouchDB.urlPrefix = '';
-
-CouchDB.login = function(name, password) {
- CouchDB.last_req = CouchDB.request("POST", "/_session", {
- headers: {"Content-Type": "application/x-www-form-urlencoded",
- "X-CouchDB-WWW-Authenticate": "Cookie"},
- body: "name=" + encodeURIComponent(name) + "&password="
- + encodeURIComponent(password)
- });
- return JSON.parse(CouchDB.last_req.responseText);
-}
-
-CouchDB.logout = function() {
- CouchDB.last_req = CouchDB.request("DELETE", "/_session", {
- headers: {"Content-Type": "application/x-www-form-urlencoded",
- "X-CouchDB-WWW-Authenticate": "Cookie"}
- });
- return JSON.parse(CouchDB.last_req.responseText);
-};
-
-CouchDB.session = function(options) {
- options = options || {};
- CouchDB.last_req = CouchDB.request("GET", "/_session", options);
- CouchDB.maybeThrowError(CouchDB.last_req);
- return JSON.parse(CouchDB.last_req.responseText);
-};
-
-CouchDB.allDbs = function() {
- CouchDB.last_req = CouchDB.request("GET", "/_all_dbs");
- CouchDB.maybeThrowError(CouchDB.last_req);
- return JSON.parse(CouchDB.last_req.responseText);
-};
-
-CouchDB.allDesignDocs = function() {
- var ddocs = {}, dbs = CouchDB.allDbs();
- for (var i=0; i < dbs.length; i++) {
- var db = new CouchDB(dbs[i]);
- ddocs[dbs[i]] = db.designDocs();
- };
- return ddocs;
-};
-
-CouchDB.getVersion = function() {
- CouchDB.last_req = CouchDB.request("GET", "/");
- CouchDB.maybeThrowError(CouchDB.last_req);
- return JSON.parse(CouchDB.last_req.responseText).version;
-};
-
-CouchDB.reloadConfig = function() {
- // diabled until cluser port gets /_config
- return {};
- CouchDB.last_req = CouchDB.request("POST", "/_config/_reload");
- CouchDB.maybeThrowError(CouchDB.last_req);
- return JSON.parse(CouchDB.last_req.responseText);
-};
-
-CouchDB.replicate = function(source, target, rep_options) {
- rep_options = rep_options || {};
- var headers = rep_options.headers || {};
- var body = rep_options.body || {};
- body.source = source;
- body.target = target;
- CouchDB.last_req = CouchDB.request("POST", "/_replicate", {
- headers: headers,
- body: JSON.stringify(body)
- });
- CouchDB.maybeThrowError(CouchDB.last_req);
- return JSON.parse(CouchDB.last_req.responseText);
-};
-
-CouchDB.newXhr = function() {
- if (typeof(XMLHttpRequest) != "undefined") {
- return new XMLHttpRequest();
- } else if (typeof(ActiveXObject) != "undefined") {
- return new ActiveXObject("Microsoft.XMLHTTP");
- } else {
- throw new Error("No XMLHTTPRequest support detected");
- }
-};
-
-CouchDB.xhrbody = function(xhr) {
- if (xhr.responseText) {
- return xhr.responseText;
- } else if (xhr.body) {
- return xhr.body
- } else {
- throw new Error("No XMLHTTPRequest support detected");
- }
-}
-
-CouchDB.xhrheader = function(xhr, header) {
- if(xhr.getResponseHeader) {
- return xhr.getResponseHeader(header);
- } else if(xhr.headers) {
- return xhr.headers[header] || null;
- } else {
- throw new Error("No XMLHTTPRequest support detected");
- }
-}
-
-CouchDB.proxyUrl = function(uri) {
- if(uri.substr(0, CouchDB.protocol.length) != CouchDB.protocol) {
- uri = CouchDB.urlPrefix + uri;
- }
- return uri;
-}
-
-CouchDB.request = function(method, uri, options) {
- options = typeof(options) == 'object' ? options : {};
- options.headers = typeof(options.headers) == 'object' ? options.headers : {};
- options.headers["Content-Type"] = options.headers["Content-Type"] || options.headers["content-type"] || "application/json";
- options.headers["Accept"] = options.headers["Accept"] || options.headers["accept"] || "application/json";
- var req = CouchDB.newXhr();
- uri = CouchDB.proxyUrl(uri);
-
- if (options.url) {
- var params = '';
- for (var key in options.url) {
- var value = options.url[key]
- params += key + '=' + value + '&'
- }
- // if uri already has a ? append with &
- if (uri.indexOf('?') === -1) {
- uri += '?' + params;
- } else {
- uri += '&' + params;
- }
- }
- // console.log(uri);
- // console.log(JSON.stringify(options, null, 2));
- req.open(method, uri, false);
- if (options.headers) {
- var headers = options.headers;
- for (var headerName in headers) {
- if (!headers.hasOwnProperty(headerName)) { continue; }
- req.setRequestHeader(headerName, headers[headerName]);
- }
- }
- req.send(options.body || "");
- return req;
-};
-
-CouchDB.requestStats = function(path, test) {
- var query_arg = "";
- if(test !== null) {
- query_arg = "?flush=true";
- }
-
- var url = "/_node/_local/_stats/" + path.join("/") + query_arg;
- var stat = CouchDB.request("GET", url).responseText;
- return JSON.parse(stat);
-};
-
-CouchDB.uuids_cache = [];
-
-CouchDB.newUuids = function(n, buf) {
- buf = buf || 100;
- if (CouchDB.uuids_cache.length >= n) {
- var uuids = CouchDB.uuids_cache.slice(CouchDB.uuids_cache.length - n);
- if(CouchDB.uuids_cache.length - n == 0) {
- CouchDB.uuids_cache = [];
- } else {
- CouchDB.uuids_cache =
- CouchDB.uuids_cache.slice(0, CouchDB.uuids_cache.length - n);
- }
- return uuids;
- } else {
- CouchDB.last_req = CouchDB.request("GET", "/_uuids?count=" + (buf + n));
- CouchDB.maybeThrowError(CouchDB.last_req);
- var result = JSON.parse(CouchDB.last_req.responseText);
- CouchDB.uuids_cache =
- CouchDB.uuids_cache.concat(result.uuids.slice(0, buf));
- return result.uuids.slice(buf);
- }
-};
-
-CouchDB.maybeThrowError = function(req) {
- if (req.status >= 400) {
- try {
- var result = JSON.parse(req.responseText);
- } catch (ParseError) {
- var result = {error:"unknown", reason:req.responseText};
- }
-
- throw (new CouchError(result));
- }
-}
-
-CouchDB.params = function(options) {
- options = options || {};
- var returnArray = [];
- for(var key in options) {
- var value = options[key];
- returnArray.push(key + "=" + value);
- }
- return returnArray.join("&");
-};
-// Used by replication test
-if (typeof window == 'undefined' || !window) {
- var hostRE = RegExp("https?://([^\/]+)");
- var getter = function () {
- return (new CouchHTTP).base_url.match(hostRE)[1];
- };
- if(Object.defineProperty) {
- Object.defineProperty(CouchDB, "host", {
- get : getter,
- enumerable : true
- });
- } else {
- CouchDB.__defineGetter__("host", getter);
- }
- CouchDB.protocol = "http://";
- CouchDB.inBrowser = false;
-} else {
- CouchDB.host = window.location.host;
- CouchDB.inBrowser = true;
- CouchDB.protocol = window.location.protocol + "//";
-}
-
-// Turns an {error: ..., reason: ...} response into an Error instance
-function CouchError(error) {
- var inst = new Error(error.reason);
- inst.name = 'CouchError';
- inst.error = error.error;
- inst.reason = error.reason;
- return inst;
-}
-CouchError.prototype.constructor = CouchError;
diff --git a/test/javascript/couch_http.js b/test/javascript/couch_http.js
deleted file mode 100644
index c44ce2823..000000000
--- a/test/javascript/couch_http.js
+++ /dev/null
@@ -1,73 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-(function() {
- if(typeof(CouchHTTP) != "undefined") {
- CouchHTTP.prototype.open = function(method, url, async) {
- if(!/^\s*http:\/\//.test(url)) {
- if(/^\//.test(url)) {
- // The couch.uri file (base_url) has a trailing slash
- url = this.base_url + url.slice(1);
- } else {
- url = this.base_url + url;
- }
- }
-
- return this._open(method, url, async);
- };
-
- CouchHTTP.prototype.setRequestHeader = function(name, value) {
- // Drop content-length headers because cURL will set it for us
- // based on body length
- if(name.toLowerCase().replace(/^\s+|\s+$/g, '') != "content-length") {
- this._setRequestHeader(name, value);
- }
- }
-
- CouchHTTP.prototype.send = function(body) {
- this._send(body || "");
- var headers = {};
- this._headers.forEach(function(hdr) {
- var pair = hdr.split(":");
- var name = pair.shift();
- headers[name] = pair.join(":").replace(/^\s+|\s+$/g, "");
- });
- this.headers = headers;
- };
-
- CouchHTTP.prototype.getResponseHeader = function(name) {
- for(var hdr in this.headers) {
- if(hdr.toLowerCase() == name.toLowerCase()) {
- return this.headers[hdr];
- }
- }
- return null;
- };
- }
-})();
-
-CouchDB.urlPrefix = "";
-CouchDB.newXhr = function() {
- return new CouchHTTP();
-};
-
-CouchDB.xhrheader = function(xhr, header) {
- if(typeof(xhr) == "CouchHTTP") {
- return xhr.getResponseHeader(header);
- } else {
- return xhr.headers[header];
- }
-}
-
-CouchDB.xhrbody = function(xhr) {
- return xhr.responseText || xhr.body;
-}
diff --git a/test/javascript/couch_test_runner.js b/test/javascript/couch_test_runner.js
deleted file mode 100644
index 7fe8ed39f..000000000
--- a/test/javascript/couch_test_runner.js
+++ /dev/null
@@ -1,489 +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.
-
-// *********************** Test Framework of Sorts ************************* //
-
-
-function loadScript(url) {
- // disallow loading remote URLs
- var re = /^[a-z0-9_]+(\/[a-z0-9_]+)*\.js#?$/;
- if (!re.test(url)) {
- throw "Not loading remote test scripts";
- }
- if (typeof document != "undefined") document.write('<script src="'+url+'"></script>');
-};
-
-function patchTest(fun) {
- var source = fun.toString();
- var output = "";
- var i = 0;
- var testMarker = "T(";
- while (i < source.length) {
- var testStart = source.indexOf(testMarker, i);
- if (testStart == -1) {
- output = output + source.substring(i, source.length);
- break;
- }
- var testEnd = source.indexOf(");", testStart);
- var testCode = source.substring(testStart + testMarker.length, testEnd);
- output += source.substring(i, testStart) + "T(" + testCode + "," + JSON.stringify(testCode);
- i = testEnd;
- }
- try {
- return eval("(" + output + ")");
- } catch (e) {
- return null;
- }
-}
-
-function runAllTests() {
- var rows = $("#tests tbody.content tr");
- $("td", rows).text("");
- $("td.status", rows).removeClass("error").removeClass("failure").removeClass("success").text("not run");
- var offset = 0;
- function runNext() {
- if (offset < rows.length) {
- var row = rows.get(offset);
- runTest($("th button", row).get(0), function() {
- offset += 1;
- setTimeout(runNext, 100);
- }, false, true);
- } else {
- saveTestReport();
- }
- }
- runNext();
-}
-
-var numFailures = 0;
-var currentRow = null;
-
-function runTest(button, callback, debug, noSave) {
-
- // offer to save admins
- if (currentRow != null) {
- alert("Can not run multiple tests simultaneously.");
- return;
- }
- var row = currentRow = $(button).parents("tr").get(0);
- $("td.status", row).removeClass("error").removeClass("failure").removeClass("success");
- $("td", row).text("");
- $("#toolbar li.current").text("Running: "+row.id);
- var testFun = couchTests[row.id];
- function run() {
- numFailures = 0;
- var start = new Date().getTime();
- try {
- if (debug == undefined || !debug) {
- testFun = patchTest(testFun) || testFun;
- }
- testFun(debug);
- var status = numFailures > 0 ? "failure" : "success";
- } catch (e) {
- var status = "error";
- if ($("td.details ol", row).length == 0) {
- $("<ol></ol>").appendTo($("td.details", row));
- }
- $("<li><b>Exception raised:</b> <code class='error'></code></li>")
- .find("code").text(JSON.stringify(e)).end()
- .appendTo($("td.details ol", row));
- if (debug) {
- currentRow = null;
- throw e;
- }
- }
- if ($("td.details ol", row).length) {
- $("<a href='#'>Run with debugger</a>").click(function() {
- runTest(this, undefined, true);
- }).prependTo($("td.details ol", row));
- }
- var duration = new Date().getTime() - start;
- $("td.status", row).removeClass("running").addClass(status).text(status);
- $("td.duration", row).text(duration + "ms");
- $("#toolbar li.current").text("Finished: "+row.id);
- updateTestsFooter();
- currentRow = null;
- if (callback) callback();
- if (!noSave) saveTestReport();
- }
- $("td.status", row).addClass("running").text("running…");
- setTimeout(run, 100);
-}
-
-function showSource(cell) {
- var name = $(cell).text();
- var win = window.open("", name, "width=700,height=500,resizable=yes,scrollbars=yes");
- win.document.location = "script/test/" + name + ".js";
-}
-
-var readyToRun;
-function setupAdminParty(fun) {
- if (readyToRun) {
- fun();
- } else {
- function removeAdmins(confs, doneFun) {
- // iterate through the config and remove current user last
- // current user is at front of list
- var remove = confs.pop();
- if (remove) {
- $.couch.config({
- success : function() {
- removeAdmins(confs, doneFun);
- }
- }, "admins", remove[0], null);
- } else {
- doneFun();
- }
- };
- $.couch.session({
- success : function(resp) {
- var userCtx = resp.userCtx;
- if (userCtx.name && userCtx.roles.indexOf("_admin") != -1) {
- // admin but not admin party. dialog offering to make admin party
- $.showDialog("dialog/_admin_party.html", {
- submit: function(data, callback) {
- $.couch.config({
- success : function(conf) {
- var meAdmin, adminConfs = [];
- for (var name in conf) {
- if (name == userCtx.name) {
- meAdmin = [name, conf[name]];
- } else {
- adminConfs.push([name, conf[name]]);
- }
- }
- adminConfs.unshift(meAdmin);
- removeAdmins(adminConfs, function() {
- callback();
- $.futon.session.sidebar();
- readyToRun = true;
- setTimeout(fun, 500);
- });
- }
- }, "admins");
- }
- });
- } else if (userCtx.roles.indexOf("_admin") != -1) {
- // admin party!
- readyToRun = true;
- fun();
- } else {
- // not an admin
- alert("Error: You need to be an admin to run the tests.");
- };
- }
- });
- }
-};
-
-function updateTestsListing() {
- for (var name in couchTests) {
- var testFunction = couchTests[name];
- var row = $("<tr><th></th><td></td><td></td><td></td></tr>")
- .find("th").text(name).attr("title", "Show source").click(function() {
- showSource(this);
- }).end()
- .find("td:nth(0)").addClass("status").text("not run").end()
- .find("td:nth(1)").addClass("duration").end()
- .find("td:nth(2)").addClass("details").end();
- $("<button type='button' class='run' title='Run test'></button>").click(function() {
- this.blur();
- var self = this;
- // check for admin party
- setupAdminParty(function() {
- runTest(self);
- });
- return false;
- }).prependTo(row.find("th"));
- row.attr("id", name).appendTo("#tests tbody.content");
- }
- $("#tests tr").removeClass("odd").filter(":odd").addClass("odd");
- updateTestsFooter();
-}
-
-function updateTestsFooter() {
- var tests = $("#tests tbody.content tr td.status");
- var testsRun = tests.filter(".success, .error, .failure");
- var testsFailed = testsRun.not(".success");
- var totalDuration = 0;
- $("#tests tbody.content tr td.duration:contains('ms')").each(function() {
- var text = $(this).text();
- totalDuration += parseInt(text.substr(0, text.length - 2), 10);
- });
- $("#tests tbody.footer td").html("<span>"+testsRun.length + " of " + tests.length +
- " test(s) run, " + testsFailed.length + " failures (" +
- totalDuration + " ms)</span> ");
-}
-
-// make report and save to local db
-// display how many reports need replicating to the mothership
-// have button to replicate them
-
-function saveTestReport(report) {
- var report = makeTestReport();
- if (report) {
- var db = $.couch.db("test_suite_reports");
- var saveReport = function(db_info) {
- report.db = db_info;
- $.couch.info({success : function(node_info) {
- report.node = node_info;
- db.saveDoc(report);
- }});
- };
- var createDb = function() {
- db.create({success: function() {
- db.info({success:saveReport});
- }});
- };
- db.info({error: createDb, success:saveReport});
- }
-};
-
-function makeTestReport() {
- var report = {};
- report.summary = $("#tests tbody.footer td").text();
- report.platform = testPlatform();
- var date = new Date();
- report.timestamp = date.getTime();
- report.timezone = date.getTimezoneOffset();
- report.tests = [];
- $("#tests tbody.content tr").each(function() {
- var status = $("td.status", this).text();
- if (status != "not run") {
- var test = {};
- test.name = this.id;
- test.status = status;
- test.duration = parseInt($("td.duration", this).text());
- test.details = [];
- $("td.details li", this).each(function() {
- test.details.push($(this).text());
- });
- if (test.details.length == 0) {
- delete test.details;
- }
- report.tests.push(test);
- }
- });
- if (report.tests.length > 0) return report;
-};
-
-function testPlatform() {
- var b = $.browser;
- var bs = ["mozilla", "msie", "opera", "safari"];
- for (var i=0; i < bs.length; i++) {
- if (b[bs[i]]) {
- return {"browser" : bs[i], "version" : b.version};
- }
- };
- return {"browser" : "undetected"};
-}
-
-
-function reportTests() {
- // replicate the database to couchdb.couchdb.org
-}
-
-// Use T to perform a test that returns false on failure and if the test fails,
-// display the line that failed.
-// Example:
-// T(MyValue==1);
-function T(arg1, arg2, testName) {
- if (!arg1) {
- if (currentRow) {
- if ($("td.details ol", currentRow).length == 0) {
- $("<ol></ol>").appendTo($("td.details", currentRow));
- }
- var message = (arg2 != null ? arg2 : arg1).toString();
- $("<li><b>Assertion " + (testName ? "'" + testName + "'" : "") + " failed:</b> <code class='failure'></code></li>")
- .find("code").text(message).end()
- .appendTo($("td.details ol", currentRow));
- }
- numFailures += 1;
- }
-}
-
-function TIsnull(actual, testName) {
- T(actual === null, "expected 'null', got '"
- + repr(actual) + "'", testName);
-}
-
-function TEquals(expected, actual, testName) {
- T(equals(expected, actual), "expected '" + repr(expected) +
- "', got '" + repr(actual) + "'", testName);
-}
-
-function TNotEquals(expected, actual, testName) {
- T(notEquals(expected, actual), "expected != '" + repr(expected) +
- "', got '" + repr(actual) + "'", testName);
-}
-
-function TEqualsIgnoreCase(expected, actual, testName) {
- T(equals(expected.toUpperCase(), actual.toUpperCase()), "expected '" + repr(expected) +
- "', got '" + repr(actual) + "'", testName);
-}
-
-function equals(a,b) {
- if (a === b) return true;
- try {
- return repr(a) === repr(b);
- } catch (e) {
- return false;
- }
-}
-
-function notEquals(a,b) {
- if (a != b) return true;
- return false;
-}
-
-function repr(val) {
- if (val === undefined) {
- return null;
- } else if (val === null) {
- return "null";
- } else {
- return JSON.stringify(val);
- }
-}
-
-function makeDocs(start, end, templateDoc) {
- var templateDocSrc = templateDoc ? JSON.stringify(templateDoc) : "{}";
- if (end === undefined) {
- end = start;
- start = 0;
- }
- var docs = [];
- for (var i = start; i < end; i++) {
- var newDoc = eval("(" + templateDocSrc + ")");
- newDoc._id = (i).toString();
- newDoc.integer = i;
- newDoc.string = (i).toString();
- docs.push(newDoc);
- }
- return docs;
-}
-
-function run_on_modified_server(settings, fun) {
- var xhr = CouchDB.request("GET", "/_membership");
- var nodes = JSON.parse(xhr.responseText).all_nodes;
- try {
- // set the settings
- for(var i=0; i < settings.length; i++) {
- var s = settings[i];
- for (var n in nodes) {
- xhr = CouchDB.request("PUT", "/_node/" + nodes[n] + "/_config/" + s.section + "/" + s.key, {
- body: JSON.stringify(s.value),
- headers: {"X-Couch-Persist": "false"}
- });
- CouchDB.maybeThrowError(xhr);
- if (typeof s[nodes[n]] === 'undefined') {
- s[nodes[n]] = {};
- }
- s[nodes[n]] = xhr.responseText;
- }
- }
- // run the thing
- fun();
- } finally {
- // unset the settings
- for(var j=0; j < i; j++) {
- for (var n in nodes) {
- var s = settings[j];
- if(s[nodes[n]] == "\"\"\n") { // unset value
- CouchDB.request("DELETE", "/_node/" + nodes[n] + "/_config/" + s.section + "/" + s.key, {
- headers: {"X-Couch-Persist": "false"}
- });
- } else {
- CouchDB.request("PUT", "/_node/" + nodes[n] + "/_config/" + s.section + "/" + s.key, {
- body: s[nodes[n]],
- headers: {"X-Couch-Persist": "false"}
- });
- }
- }
- }
- }
-}
-
-function stringFun(fun) {
- var string = fun.toSource ? fun.toSource() : "(" + fun.toString() + ")";
- return string;
-}
-
-function waitForSuccess(fun, tag) {
- var start = new Date();
- while(true) {
- if (new Date() - start > 5000) {
- throw("timeout: "+tag);
- } else {
- try {
- fun();
- break;
- } catch (e) {
- log(e)
- }
- // sync http req allow async req to happen
- try {
- CouchDB.request("GET", "/test_suite_db/?tag="+encodeURIComponent(tag));
- } catch (e) {}
- }
- }
-}
-
-// legacy functions for CouchDB < 1.2.0
-// we keep them to make sure we keep BC
-CouchDB.user_prefix = "org.couchdb.user:";
-
-CouchDB.prepareUserDoc = function(user_doc, new_password) {
- user_doc._id = user_doc._id || CouchDB.user_prefix + user_doc.name;
- if (new_password) {
- user_doc.password = new_password;
- }
- user_doc.type = "user";
- if (!user_doc.roles) {
- user_doc.roles = [];
- }
- return user_doc;
-};
-
-function get_random_string() {
- return Math.random()
- .toString(36)
- .replace(/[^a-z]+/g, '')
- .substr(0, 8);
-}
-
-function get_random_db_name() {
- return "test_suite_db_" + get_random_string()
-}
-
-// for Heisenbug-prone spots: retry n times (e.g. quora not met immediately)
-// if the problem still persists afterwards, we need sth else (similar to e.g. webdriver)
-function retry_part(fct, n, duration) {
- n = n || 3;
- duration = (duration == undefined ? 100 : duration);
- for(var i=1; i<=n; i++){
- try {
- return fct();
- }catch(e){
- if(i<n){
- // wait
- sleep(duration);
- }else{
- throw e;
- }
- }
- }
-}
-
-function wait(ms) {
- sleep(ms);
-}
diff --git a/test/javascript/couchdb.uri b/test/javascript/couchdb.uri
deleted file mode 100644
index 99c8819c8..000000000
--- a/test/javascript/couchdb.uri
+++ /dev/null
@@ -1 +0,0 @@
-http://127.0.0.1:15984/
diff --git a/test/javascript/json2.js b/test/javascript/json2.js
deleted file mode 100644
index a1a3b170c..000000000
--- a/test/javascript/json2.js
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- http://www.JSON.org/json2.js
- 2010-03-20
-
- Public Domain.
-
- NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
-
- See http://www.JSON.org/js.html
-
-
- This code should be minified before deployment.
- See http://javascript.crockford.com/jsmin.html
-
- USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
- NOT CONTROL.
-
-
- This file creates a global JSON object containing two methods: stringify
- and parse.
-
- JSON.stringify(value, replacer, space)
- value any JavaScript value, usually an object or array.
-
- replacer an optional parameter that determines how object
- values are stringified for objects. It can be a
- function or an array of strings.
-
- space an optional parameter that specifies the indentation
- of nested structures. If it is omitted, the text will
- be packed without extra whitespace. If it is a number,
- it will specify the number of spaces to indent at each
- level. If it is a string (such as '\t' or '&nbsp;'),
- it contains the characters used to indent at each level.
-
- This method produces a JSON text from a JavaScript value.
-
- When an object value is found, if the object contains a toJSON
- method, its toJSON method will be called and the result will be
- stringified. A toJSON method does not serialize: it returns the
- value represented by the name/value pair that should be serialized,
- or undefined if nothing should be serialized. The toJSON method
- will be passed the key associated with the value, and this will be
- bound to the value
-
- For example, this would serialize Dates as ISO strings.
-
- Date.prototype.toJSON = function (key) {
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- return this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z';
- };
-
- You can provide an optional replacer method. It will be passed the
- key and value of each member, with this bound to the containing
- object. The value that is returned from your method will be
- serialized. If your method returns undefined, then the member will
- be excluded from the serialization.
-
- If the replacer parameter is an array of strings, then it will be
- used to select the members to be serialized. It filters the results
- such that only members with keys listed in the replacer array are
- stringified.
-
- Values that do not have JSON representations, such as undefined or
- functions, will not be serialized. Such values in objects will be
- dropped; in arrays they will be replaced with null. You can use
- a replacer function to replace those with JSON values.
- JSON.stringify(undefined) returns undefined.
-
- The optional space parameter produces a stringification of the
- value that is filled with line breaks and indentation to make it
- easier to read.
-
- If the space parameter is a non-empty string, then that string will
- be used for indentation. If the space parameter is a number, then
- the indentation will be that many spaces.
-
- Example:
-
- text = JSON.stringify(['e', {pluribus: 'unum'}]);
- // text is '["e",{"pluribus":"unum"}]'
-
-
- text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t');
- // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]'
-
- text = JSON.stringify([new Date()], function (key, value) {
- return this[key] instanceof Date ?
- 'Date(' + this[key] + ')' : value;
- });
- // text is '["Date(---current time---)"]'
-
-
- JSON.parse(text, reviver)
- This method parses a JSON text to produce an object or array.
- It can throw a SyntaxError exception.
-
- The optional reviver parameter is a function that can filter and
- transform the results. It receives each of the keys and values,
- and its return value is used instead of the original value.
- If it returns what it received, then the structure is not modified.
- If it returns undefined then the member is deleted.
-
- Example:
-
- // Parse the text. Values that look like ISO date strings will
- // be converted to Date objects.
-
- myData = JSON.parse(text, function (key, value) {
- var a;
- if (typeof value === 'string') {
- a =
-/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
- if (a) {
- return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],
- +a[5], +a[6]));
- }
- }
- return value;
- });
-
- myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) {
- var d;
- if (typeof value === 'string' &&
- value.slice(0, 5) === 'Date(' &&
- value.slice(-1) === ')') {
- d = new Date(value.slice(5, -1));
- if (d) {
- return d;
- }
- }
- return value;
- });
-
-
- This is a reference implementation. You are free to copy, modify, or
- redistribute.
-*/
-
-/*jslint evil: true, strict: false */
-
-/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
- call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
- getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
- lastIndex, length, parse, prototype, push, replace, slice, stringify,
- test, toJSON, toString, valueOf
-*/
-
-
-// Create a JSON object only if one does not already exist. We create the
-// methods in a closure to avoid creating global variables.
-
-if (!this.JSON) {
- this.JSON = {};
-}
-
-(function () {
-
- function f(n) {
- // Format integers to have at least two digits.
- return n < 10 ? '0' + n : n;
- }
-
- if (typeof Date.prototype.toJSON !== 'function') {
-
- Date.prototype.toJSON = function (key) {
-
- return isFinite(this.valueOf()) ?
- this.getUTCFullYear() + '-' +
- f(this.getUTCMonth() + 1) + '-' +
- f(this.getUTCDate()) + 'T' +
- f(this.getUTCHours()) + ':' +
- f(this.getUTCMinutes()) + ':' +
- f(this.getUTCSeconds()) + 'Z' : null;
- };
-
- String.prototype.toJSON =
- Number.prototype.toJSON =
- Boolean.prototype.toJSON = function (key) {
- return this.valueOf();
- };
- }
-
- var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
- gap,
- indent,
- meta = { // table of character substitutions
- '\b': '\\b',
- '\t': '\\t',
- '\n': '\\n',
- '\f': '\\f',
- '\r': '\\r',
- '"' : '\\"',
- '\\': '\\\\'
- },
- rep;
-
-
- function quote(string) {
-
-// If the string contains no control characters, no quote characters, and no
-// backslash characters, then we can safely slap some quotes around it.
-// Otherwise we must also replace the offending characters with safe escape
-// sequences.
-
- escapable.lastIndex = 0;
- return escapable.test(string) ?
- '"' + string.replace(escapable, function (a) {
- var c = meta[a];
- return typeof c === 'string' ? c :
- '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- }) + '"' :
- '"' + string + '"';
- }
-
-
- function str(key, holder) {
-
-// Produce a string from holder[key].
-
- var i, // The loop counter.
- k, // The member key.
- v, // The member value.
- length,
- mind = gap,
- partial,
- value = holder[key];
-
-// If the value has a toJSON method, call it to obtain a replacement value.
-
- if (value && typeof value === 'object' &&
- typeof value.toJSON === 'function') {
- value = value.toJSON(key);
- }
-
-// If we were called with a replacer function, then call the replacer to
-// obtain a replacement value.
-
- if (typeof rep === 'function') {
- value = rep.call(holder, key, value);
- }
-
-// What happens next depends on the value's type.
-
- switch (typeof value) {
- case 'string':
- return quote(value);
-
- case 'number':
-
-// JSON numbers must be finite. Encode non-finite numbers as null.
-
- return isFinite(value) ? String(value) : 'null';
-
- case 'boolean':
- case 'null':
-
-// If the value is a boolean or null, convert it to a string. Note:
-// typeof null does not produce 'null'. The case is included here in
-// the remote chance that this gets fixed someday.
-
- return String(value);
-
-// If the type is 'object', we might be dealing with an object or an array or
-// null.
-
- case 'object':
-
-// Due to a specification blunder in ECMAScript, typeof null is 'object',
-// so watch out for that case.
-
- if (!value) {
- return 'null';
- }
-
-// Make an array to hold the partial results of stringifying this object value.
-
- gap += indent;
- partial = [];
-
-// Is the value an array?
-
- if (Object.prototype.toString.apply(value) === '[object Array]') {
-
-// The value is an array. Stringify every element. Use null as a placeholder
-// for non-JSON values.
-
- length = value.length;
- for (i = 0; i < length; i += 1) {
- partial[i] = str(i, value) || 'null';
- }
-
-// Join all of the elements together, separated with commas, and wrap them in
-// brackets.
-
- v = partial.length === 0 ? '[]' :
- gap ? '[\n' + gap +
- partial.join(',\n' + gap) + '\n' +
- mind + ']' :
- '[' + partial.join(',') + ']';
- gap = mind;
- return v;
- }
-
-// If the replacer is an array, use it to select the members to be stringified.
-
- if (rep && typeof rep === 'object') {
- length = rep.length;
- for (i = 0; i < length; i += 1) {
- k = rep[i];
- if (typeof k === 'string') {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- } else {
-
-// Otherwise, iterate through all of the keys in the object.
-
- for (k in value) {
- if (Object.hasOwnProperty.call(value, k)) {
- v = str(k, value);
- if (v) {
- partial.push(quote(k) + (gap ? ': ' : ':') + v);
- }
- }
- }
- }
-
-// Join all of the member texts together, separated with commas,
-// and wrap them in braces.
-
- v = partial.length === 0 ? '{}' :
- gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' +
- mind + '}' : '{' + partial.join(',') + '}';
- gap = mind;
- return v;
- }
- }
-
-// If the JSON object does not yet have a stringify method, give it one.
-
- if (typeof JSON.stringify !== 'function') {
- JSON.stringify = function (value, replacer, space) {
-
-// The stringify method takes a value and an optional replacer, and an optional
-// space parameter, and returns a JSON text. The replacer can be a function
-// that can replace values, or an array of strings that will select the keys.
-// A default replacer method can be provided. Use of the space parameter can
-// produce text that is more easily readable.
-
- var i;
- gap = '';
- indent = '';
-
-// If the space parameter is a number, make an indent string containing that
-// many spaces.
-
- if (typeof space === 'number') {
- for (i = 0; i < space; i += 1) {
- indent += ' ';
- }
-
-// If the space parameter is a string, it will be used as the indent string.
-
- } else if (typeof space === 'string') {
- indent = space;
- }
-
-// If there is a replacer, it must be a function or an array.
-// Otherwise, throw an error.
-
- rep = replacer;
- if (replacer && typeof replacer !== 'function' &&
- (typeof replacer !== 'object' ||
- typeof replacer.length !== 'number')) {
- throw new Error('JSON.stringify');
- }
-
-// Make a fake root object containing our value under the key of ''.
-// Return the result of stringifying the value.
-
- return str('', {'': value});
- };
- }
-
-
-// If the JSON object does not yet have a parse method, give it one.
-
- if (typeof JSON.parse !== 'function') {
- JSON.parse = function (text, reviver) {
-
-// The parse method takes a text and an optional reviver function, and returns
-// a JavaScript value if the text is a valid JSON text.
-
- var j;
-
- function walk(holder, key) {
-
-// The walk method is used to recursively walk the resulting structure so
-// that modifications can be made.
-
- var k, v, value = holder[key];
- if (value && typeof value === 'object') {
- for (k in value) {
- if (Object.hasOwnProperty.call(value, k)) {
- v = walk(value, k);
- if (v !== undefined) {
- value[k] = v;
- } else {
- delete value[k];
- }
- }
- }
- }
- return reviver.call(holder, key, value);
- }
-
-
-// Parsing happens in four stages. In the first stage, we replace certain
-// Unicode characters with escape sequences. JavaScript handles many characters
-// incorrectly, either silently deleting them, or treating them as line endings.
-
- text = String(text);
- cx.lastIndex = 0;
- if (cx.test(text)) {
- text = text.replace(cx, function (a) {
- return '\\u' +
- ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
- });
- }
-
-// In the second stage, we run the text against regular expressions that look
-// for non-JSON patterns. We are especially concerned with '()' and 'new'
-// because they can cause invocation, and '=' because it can cause mutation.
-// But just to be safe, we want to reject all unexpected forms.
-
-// We split the second stage into 4 regexp operations in order to work around
-// crippling inefficiencies in IE's and Safari's regexp engines. First we
-// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
-// replace all simple value tokens with ']' characters. Third, we delete all
-// open brackets that follow a colon or comma or that begin the text. Finally,
-// we look to see that the remaining characters are only whitespace or ']' or
-// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
-
- if (/^[\],:{}\s]*$/.
-test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
-replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
-replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
-
-// In the third stage we use the eval function to compile the text into a
-// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
-// in JavaScript: it can begin a block or an object literal. We wrap the text
-// in parens to eliminate the ambiguity.
-
- j = eval('(' + text + ')');
-
-// In the optional fourth stage, we recursively walk the new structure, passing
-// each name/value pair to a reviver function for possible transformation.
-
- return typeof reviver === 'function' ?
- walk({'': j}, '') : j;
- }
-
-// If the text is not JSON parseable, then a SyntaxError is thrown.
-
- throw new SyntaxError('JSON.parse');
- };
- }
-}());
diff --git a/test/javascript/replicator_db_inc.js b/test/javascript/replicator_db_inc.js
deleted file mode 100644
index 46dcdd702..000000000
--- a/test/javascript/replicator_db_inc.js
+++ /dev/null
@@ -1,97 +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.
-
-var replicator_db = {};
-replicator_db.wait_rep_doc = 500; // number of millisecs to wait after saving a Rep Doc
-replicator_db.dbA = new CouchDB("test_suite_rep_db_a", {"X-Couch-Full-Commit":"false"});
-replicator_db.dbB = new CouchDB("test_suite_rep_db_b", {"X-Couch-Full-Commit":"false"});
-replicator_db.repDb = new CouchDB("test_suite_rep_db", {"X-Couch-Full-Commit":"false"});
-replicator_db.usersDb = new CouchDB("test_suite_auth", {"X-Couch-Full-Commit":"false"});
-
-replicator_db.docs1 = [
- {
- _id: "foo1",
- value: 11
- },
- {
- _id: "foo2",
- value: 22
- },
- {
- _id: "foo3",
- value: 33
- }
-];
-
-replicator_db.waitForRep = function waitForSeq(repDb, repDoc, state, errorState) {
- var newRep,
- t0 = new Date(),
- t1,
- ms = 3000;
-
- do {
- newRep = repDb.open(repDoc._id);
- t1 = new Date();
- } while (((t1 - t0) <= ms) && newRep._replication_state !== state && (!errorState || newRep._replication_state !== errorState));
- return newRep ? newRep._replication_state : null;
-}
-
-replicator_db.waitForSeq = function waitForSeq(sourceDb, targetDb) {
- var targetSeq,
- sourceSeq = sourceDb.info().update_seq,
- t0 = new Date(),
- t1,
- ms = 3000;
-
- do {
- targetSeq = targetDb.info().update_seq;
- t1 = new Date();
- } while (((t1 - t0) <= ms) && targetSeq < sourceSeq);
-}
-
-replicator_db.waitForDocPos = function waitForDocPos(db, docId, pos) {
- var doc, curPos, t0, t1,
- maxWait = 3000;
-
- doc = db.open(docId);
- curPos = Number(doc._rev.split("-", 1));
- t0 = t1 = new Date();
-
- while ((curPos < pos) && ((t1 - t0) <= maxWait)) {
- doc = db.open(docId);
- curPos = Number(doc._rev.split("-", 1));
- t1 = new Date();
- }
-
- return doc;
-}
-
-replicator_db.wait = function wait(ms) {
- var t0 = new Date(), t1;
- do {
- CouchDB.request("GET", "/");
- t1 = new Date();
- } while ((t1 - t0) <= ms);
-}
-
-
-replicator_db.populate_db = function populate_db(db, docs) {
- if (db.name !== replicator_db.usersDb.name) {
- db.deleteDb();
- db.createDb();
- }
- for (var i = 0; i < docs.length; i++) {
- var d = docs[i];
- delete d._rev;
- T(db.save(d).ok);
- }
-}
diff --git a/test/javascript/run b/test/javascript/run
deleted file mode 100755
index d60179e78..000000000
--- a/test/javascript/run
+++ /dev/null
@@ -1,284 +0,0 @@
-#!/usr/bin/env python3
-#
-# 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.
-
-import glob
-import optparse as op
-import os
-import subprocess as sp
-import sys
-import time
-import re
-import xml.dom.minidom as md
-
-
-USAGE = "%prog [options] [command to run...]"
-TEST_PATH = os.path.dirname(os.path.abspath(__file__))
-ROOT_PATH = os.path.dirname(os.path.dirname(TEST_PATH))
-N = 3
-
-COUCHJS = "src/couch/priv/couchjs"
-
-SCRIPTS = """
- test/javascript/json2.js
- test/javascript/sha1.js
- test/javascript/couch.js
- test/javascript/replicator_db_inc.js
- test/javascript/couch_test_runner.js
- test/javascript/couch_http.js
- test/javascript/test_setup.js
- share/server/util.js
-""".split()
-
-RUNNER = "test/javascript/cli_runner.js"
-
-
-def mkformatter(tests):
- longest = max([len(x) for x in tests])
- green = "\033[32m"
- orange = "\033[33m"
- red = "\033[31m"
- clear = "\033[0m"
- if not sys.stderr.isatty():
- green, orange, red, clear = "", "", "", ""
-
- def _colorized(rval):
- if rval == 0:
- return green + "pass" + clear
- elif rval == 2:
- return orange + "skipped" + clear
- elif rval == 3:
- return green + "ported to elixir" + clear
- else:
- return red + ("fail: %d" % rval) + clear
-
- def _fmt(test):
- if isinstance(test, str):
- padding = (longest - len(test)) * " "
- sys.stderr.write(test + " " + padding)
- sys.stderr.flush()
- elif isinstance(test, int):
- if test:
- sys.stderr.write(_colorized(test) + os.linesep)
- else:
- sys.stderr.write(_colorized(test) + os.linesep)
- sys.stderr.flush()
-
- return _fmt
-
-
-def run_couchjs(test, fmt):
- fmt(test)
- cmd = (
- [COUCHJS, "--eval", "-H", "-T"]
- + ["-u", "test/javascript/couchdb.uri"]
- + SCRIPTS
- + [test, RUNNER]
- )
- p = sp.Popen(cmd, stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.STDOUT)
- output = []
- while True:
- line = p.stdout.readline()
- if not line:
- break
- line = line.decode()
- output.append(line)
- sys.stderr.write(line)
- p.wait()
- fmt(p.returncode)
- return (p.returncode, "".join(output))
-
-
-def write_junit(filename, total_time, results):
- failures = 0
- skipped = 0
- for (_, rc, _, _) in results:
- if rc == 2 or rc == 3:
- skipped += 1
- else:
- failures += 1
-
- doc = md.Document()
- root = doc.createElement("testsuite")
- root.setAttribute("name", "JavaScript tests")
- root.setAttribute("time", "%0.3f" % total_time)
- root.setAttribute("tests", str(len(results)))
- root.setAttribute("failures", str(failures))
- root.setAttribute("errors", "0")
- root.setAttribute("skipped", str(skipped))
- doc.appendChild(root)
-
- for (path, rc, output, test_time) in results:
- name = os.path.split(path)[-1]
- tc = doc.createElement("testcase")
- tc.setAttribute("name", name)
- tc.setAttribute("time", "%0.3f" % test_time)
- if rc == 0:
- pass
- elif rc == 2:
- skipped = doc.createElement("skipped")
- skipped.setAttribute("message", "disabled")
- tc.appendChild(skipped)
- elif rc == 3:
- skipped = doc.createElement("skipped")
- skipped.setAttribute("message", "ported to elixir")
- tc.appendChild(skipped)
- else:
- failure = doc.createElement("failure")
- failure.setAttribute("message", "failed: %d" % rc)
- failure_text = "Exit Code: %d" % rc + "\n\n" + output
- message = doc.createTextNode(failure_text)
- failure.appendChild(message)
- tc.appendChild(failure)
- root.appendChild(tc)
-
- with open(filename, "w") as handle:
- doc.writexml(handle, addindent=" ", newl=os.linesep)
-
-
-def options():
- return [
- op.make_option(
- "-s",
- "--start",
- metavar="FILENAME",
- default=None,
- help="Start from the given filename if multiple files are passed",
- ),
- op.make_option(
- "-a",
- "--all",
- action="store_true",
- dest="all",
- help="Run all tests, even if one or more fail",
- ),
- op.make_option(
- "-i",
- "--ignore",
- type="string",
- action="callback",
- default=None,
- callback=get_delimited_list,
- dest="ignore",
- help="Ignore test suites",
- ),
- op.make_option(
- "-u",
- "--suites",
- type="string",
- action="callback",
- default=None,
- callback=get_delimited_list,
- dest="suites",
- help="Run specific suites",
- ),
- op.make_option(
- "-p",
- "--path",
- type="string",
- default="test/javascript/tests",
- dest="test_path",
- help="Path where the tests are located",
- ),
- op.make_option(
- "-j",
- "--junit-report",
- type="string",
- default="test/javascript/junit.xml",
- dest="junit_report",
- help="Write a JUnit compatible test report",
- ),
- ]
-
-
-def main():
- parser = op.OptionParser(usage=USAGE, option_list=options())
- opts, args = parser.parse_args()
-
- run_list = []
- ignore_list = []
- tests = []
- run_list = [opts.test_path] if not opts.suites else opts.suites
- run_list = build_test_case_paths(opts.test_path, run_list)
- ignore_list = build_test_case_paths(opts.test_path, opts.ignore)
- # sort is needed because certain tests fail if executed out of order
- tests = sorted(list(set(run_list) - set(ignore_list)))
-
- if opts.start is not None:
- tmp = []
- for name in tests:
- if name >= opts.start:
- tmp.append(name)
- tests = tmp
-
- results = []
- begin = time.time()
- passed = 0
- failed = 0
- if len(tests) > 0:
- fmt = mkformatter(tests)
- for test in tests:
- tbefore = time.time()
- (result, output) = run_couchjs(test, fmt)
- results.append((test, result, output, time.time() - tbefore))
- if result == 0 or result == 2 or result == 3:
- passed += 1
- else:
- failed += 1
- if not opts.all:
- break
-
- total_time = time.time() - begin
- if opts.junit_report:
- write_junit(opts.junit_report, total_time, results)
-
- sys.stderr.write(
- "=======================================================" + os.linesep
- )
- sys.stderr.write("JavaScript tests complete." + os.linesep)
- sys.stderr.write(
- " Failed: {0}. Skipped or passed: {1}.".format(failed, passed) + os.linesep
- )
- exit(failed > 0)
-
-
-def build_test_case_paths(path, args=None):
- tests = []
- if args is None:
- args = []
- for name in args:
- if os.path.isdir(name):
- tests.extend(sorted(glob.glob(os.path.join(name, "*.js"))))
- elif os.path.isfile(name):
- check = tests.append(name)
- else:
- pname = os.path.join(path, name)
- if os.path.isfile(pname):
- tests.append(pname)
- elif os.path.isfile(pname + ".js"):
- tests.append(pname + ".js")
- else:
- sys.stderr.write("Waring - Unknown test: " + name + os.linesep)
- return tests
-
-
-def get_delimited_list(option, opt, value, parser):
- delimited = [i for i in re.split(r",|\s", value.strip()) if i]
- setattr(parser.values, option.dest, delimited)
-
-
-if __name__ == "__main__":
- try:
- main()
- except KeyboardInterrupt:
- pass
diff --git a/test/javascript/sha1.js b/test/javascript/sha1.js
deleted file mode 100644
index ee73a6341..000000000
--- a/test/javascript/sha1.js
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
- * in FIPS PUB 180-1
- * Version 2.1a Copyright Paul Johnston 2000 - 2002.
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for details.
- */
-
-/*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
-var b64pad = "="; /* base-64 pad character. "=" for strict RFC compliance */
-var chrsz = 8; /* bits per input character. 8 - ASCII; 16 - Unicode */
-
-/*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
-function hex_sha1(s){return binb2hex(core_sha1(str2binb(s),s.length * chrsz));}
-function b64_sha1(s){return binb2b64(core_sha1(str2binb(s),s.length * chrsz));}
-function str_sha1(s){return binb2str(core_sha1(str2binb(s),s.length * chrsz));}
-function hex_hmac_sha1(key, data){ return binb2hex(core_hmac_sha1(key, data));}
-function b64_hmac_sha1(key, data){ return binb2b64(core_hmac_sha1(key, data));}
-function str_hmac_sha1(key, data){ return binb2str(core_hmac_sha1(key, data));}
-
-/*
- * Perform a simple self-test to see if the VM is working
- */
-function sha1_vm_test()
-{
- return hex_sha1("abc") == "a9993e364706816aba3e25717850c26c9cd0d89d";
-}
-
-/*
- * Calculate the SHA-1 of an array of big-endian words, and a bit length
- */
-function core_sha1(x, len)
-{
- /* append padding */
- x[len >> 5] |= 0x80 << (24 - len % 32);
- x[((len + 64 >> 9) << 4) + 15] = len;
-
- var w = Array(80);
- var a = 1732584193;
- var b = -271733879;
- var c = -1732584194;
- var d = 271733878;
- var e = -1009589776;
-
- for(var i = 0; i < x.length; i += 16)
- {
- var olda = a;
- var oldb = b;
- var oldc = c;
- var oldd = d;
- var olde = e;
-
- for(var j = 0; j < 80; j++)
- {
- if(j < 16) w[j] = x[i + j];
- else w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
- var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
- safe_add(safe_add(e, w[j]), sha1_kt(j)));
- e = d;
- d = c;
- c = rol(b, 30);
- b = a;
- a = t;
- }
-
- a = safe_add(a, olda);
- b = safe_add(b, oldb);
- c = safe_add(c, oldc);
- d = safe_add(d, oldd);
- e = safe_add(e, olde);
- }
- return Array(a, b, c, d, e);
-
-}
-
-/*
- * Perform the appropriate triplet combination function for the current
- * iteration
- */
-function sha1_ft(t, b, c, d)
-{
- if(t < 20) return (b & c) | ((~b) & d);
- if(t < 40) return b ^ c ^ d;
- if(t < 60) return (b & c) | (b & d) | (c & d);
- return b ^ c ^ d;
-}
-
-/*
- * Determine the appropriate additive constant for the current iteration
- */
-function sha1_kt(t)
-{
- return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
- (t < 60) ? -1894007588 : -899497514;
-}
-
-/*
- * Calculate the HMAC-SHA1 of a key and some data
- */
-function core_hmac_sha1(key, data)
-{
- var bkey = str2binb(key);
- if(bkey.length > 16) bkey = core_sha1(bkey, key.length * chrsz);
-
- var ipad = Array(16), opad = Array(16);
- for(var i = 0; i < 16; i++)
- {
- ipad[i] = bkey[i] ^ 0x36363636;
- opad[i] = bkey[i] ^ 0x5C5C5C5C;
- }
-
- var hash = core_sha1(ipad.concat(str2binb(data)), 512 + data.length * chrsz);
- return core_sha1(opad.concat(hash), 512 + 160);
-}
-
-/*
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
-function safe_add(x, y)
-{
- var lsw = (x & 0xFFFF) + (y & 0xFFFF);
- var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
- return (msw << 16) | (lsw & 0xFFFF);
-}
-
-/*
- * Bitwise rotate a 32-bit number to the left.
- */
-function rol(num, cnt)
-{
- return (num << cnt) | (num >>> (32 - cnt));
-}
-
-/*
- * Convert an 8-bit or 16-bit string to an array of big-endian words
- * In 8-bit function, characters >255 have their hi-byte silently ignored.
- */
-function str2binb(str)
-{
- var bin = Array();
- var mask = (1 << chrsz) - 1;
- for(var i = 0; i < str.length * chrsz; i += chrsz)
- bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (32 - chrsz - i%32);
- return bin;
-}
-
-/*
- * Convert an array of big-endian words to a string
- */
-function binb2str(bin)
-{
- var str = "";
- var mask = (1 << chrsz) - 1;
- for(var i = 0; i < bin.length * 32; i += chrsz)
- str += String.fromCharCode((bin[i>>5] >>> (32 - chrsz - i%32)) & mask);
- return str;
-}
-
-/*
- * Convert an array of big-endian words to a hex string.
- */
-function binb2hex(binarray)
-{
- var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
- var str = "";
- for(var i = 0; i < binarray.length * 4; i++)
- {
- str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) +
- hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF);
- }
- return str;
-}
-
-/*
- * Convert an array of big-endian words to a base-64 string
- */
-function binb2b64(binarray)
-{
- var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- var str = "";
- for(var i = 0; i < binarray.length * 4; i += 3)
- {
- var triplet = (((binarray[i >> 2] >> 8 * (3 - i %4)) & 0xFF) << 16)
- | (((binarray[i+1 >> 2] >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 )
- | ((binarray[i+2 >> 2] >> 8 * (3 - (i+2)%4)) & 0xFF);
- for(var j = 0; j < 4; j++)
- {
- if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
- else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
- }
- }
- return str;
-}
diff --git a/test/javascript/test_setup.js b/test/javascript/test_setup.js
deleted file mode 100644
index 6140c0e3f..000000000
--- a/test/javascript/test_setup.js
+++ /dev/null
@@ -1,127 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-/*
- * Add global couchTests object required for existing tests.
- */
-var couchTests = {};
-
-var console = {
- log: function(arg) {
- var msg = (arg.toString()).replace(/\n/g, "\n ");
- print(msg, true);
- }
-};
-
-var fmtStack = function(stack) {
- if(!stack) {
- console.log("No stack information");
- return;
- }
- console.log("Trace back (most recent call first):\n");
- var re = new RegExp("(.*?)@([^:]*):(.*)$");
- var lines = stack.split("\n");
- for(var i = 0; i < lines.length; i++) {
- var line = lines[i];
- if(!line.length) continue;
- var match = re.exec(line);
- if(!match) continue
- var match = re.exec(line);
- if(!match) continue
- var source = match[1].substr(0, 70);
- var file = match[2];
- var lnum = match[3];
- while(lnum.length < 3) lnum = " " + lnum;
- console.log(" " + lnum + ": " + file);
- console.log(" " + source);
- }
-}
-
-function T(arg1, arg2) {
- if(!arg1) {
- var result = (arg2 ? arg2 : arg1);
- throw((result instanceof Error ? result : Error(result)));
- }
-}
-
-function waitForSuccess(fun, tag) {
- var start = new Date().getTime();
- var complete = false;
-
- while (!complete) {
- var now = new Date().getTime();
- if (now > start + 10000) {
- complete = true;
- throw(Error('\nFAIL ' + tag));
- }
- try {
- while (new Date().getTime() < now + 500);
- complete = fun();
- } catch (e) {}
- }
-}
-
-function getUptime() {
- var url = "/_node/node1@127.0.0.1/_system"
- var stats = JSON.parse(CouchDB.request("GET", url).responseText);
- return stats['uptime'];
-}
-
-function restartNodeRequest(node) {
- var url = "/_node/" + node +"/_restart"
- var result = JSON.parse(CouchDB.request("POST", url).responseText);
- if (result.ok != true) {
- throw(Error('FAILED to restart: ' + node));
- }
-}
-
-function restartServer() {
- var olduptime = getUptime();
- if (olduptime < 15) {
- // handle quick-restarts, though this slows things down
- sleep(15000);
- olduptime = getUptime();
- }
-
- restartNodeRequest('node1@127.0.0.1');
-
- /* Wait up to 15s for server to restart */
- var start = new Date().getTime();
- var complete = false;
- while (1) {
- sleep(500);
- try {
- if (getUptime() < olduptime) {
- return;
- }
- } catch (e) {}
-
- var now = new Date().getTime();
- if (now > start + 30000) {
- try {
- uptime = getUptime();
- throw(Error('FAILED to restart: ' + uptime + ' not < ' + olduptime));
- } catch (e) {
- throw(Error('FAILED to restart: server is unresponsive, waited 30s'));
- }
- }
- }
-}
-
-/*
- * If last_req is an object, we got something back. This might be an error, but
- * CouchDB is up and running!
- */
-CouchDB.isRunning = function() {
- CouchDB.last_req = CouchDB.request("GET", "/");
- return typeof CouchDB.last_req == 'object';
-};
diff --git a/test/javascript/tests-cluster/with-quorum/attachments.js b/test/javascript/tests-cluster/with-quorum/attachments.js
deleted file mode 100644
index 8186d7574..000000000
--- a/test/javascript/tests-cluster/with-quorum/attachments.js
+++ /dev/null
@@ -1,37 +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.
-
-couchTests.attachments= function(debug) {
- return console.log('done in test/elixir/test/cluster_with_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var doc = db.save({_id:"dummy"});
- T(doc.ok);
-
- var xhr = CouchDB.request("PUT", "/" + db_name + "/dummy/foo.txt?rev=" + doc.rev, {
- body:"This is no base64 encoded text",
- headers:{"Content-Type": "text/plain;charset=utf-8"}
- });
- T(xhr.status == 201,"Should return 201");
- var rev = JSON.parse(xhr.responseText).rev;
-
- xhr = CouchDB.request("PUT", "/" + db_name + "/dummy/foo.txt?rev=" + rev, {
- body:"This is no base64 encoded text-2",
- headers:{"Content-Type": "text/plain;charset=utf-8"}
- });
- T(xhr.status == 201,"Should return 201");
-
- db.deleteDb();
-}
diff --git a/test/javascript/tests-cluster/with-quorum/attachments_delete.js b/test/javascript/tests-cluster/with-quorum/attachments_delete.js
deleted file mode 100644
index 1980c1124..000000000
--- a/test/javascript/tests-cluster/with-quorum/attachments_delete.js
+++ /dev/null
@@ -1,33 +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.
-
-couchTests.attachments_delete= function(debug) {
- return console.log('done in test/elixir/test/cluster_with_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var doc = db.save({_id:"dummy"});
- T(doc.ok);
- var xhr = CouchDB.request("PUT", "/" + db_name + "/dummy/foo.txt?rev=" + doc.rev, {
- body:"This is no base64 encoded text",
- headers:{"Content-Type": "text/plain;charset=utf-8"}
- });
- T(xhr.status == 201,"Should return 201 Accepted");
- var rev = JSON.parse(xhr.responseText).rev;
-
- xhr = CouchDB.request("DELETE", "/" + db_name + "/dummy/foo.txt?rev=" + rev);
- T(xhr.status == 200,"Should return 200 Ok but returns "+xhr.status);
-
- db.deleteDb();
-}
diff --git a/test/javascript/tests-cluster/with-quorum/attachments_delete_overridden_quorum.js b/test/javascript/tests-cluster/with-quorum/attachments_delete_overridden_quorum.js
deleted file mode 100644
index 48c1f34b9..000000000
--- a/test/javascript/tests-cluster/with-quorum/attachments_delete_overridden_quorum.js
+++ /dev/null
@@ -1,38 +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.
-
-couchTests.skip = true;
-couchTests.attachments_delete_overridden_quorum= function(debug) {
- return console.log('done in test/elixir/test/cluster_with_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"},{"w":3});
- db.createDb();
- if (debug) debugger;
-
- var doc = db.save({_id:"dummy"});
- T(doc.ok);
- var xhr = CouchDB.request("PUT", "/" + db_name + "/dummy/foo.txt?rev=" + doc.rev, {
- body:"This is no base64 encoded text",
- headers:{"Content-Type": "text/plain;charset=utf-8"}
- });
- var rev = JSON.parse(xhr.responseText).rev;
-
- xhr = CouchDB.request("DELETE", "/" + db_name + "/dummy/foo.txt?rev=" + rev);
- console.log("TODO: Clarify correct behaviour. Is not considering overridden quorum. 202->"+xhr.status);
- // TODO: Define correct behaviour
- //T(xhr.status == 202,"Should return 202 but returns "+xhr.status);
-
- //db.deleteDb();
- // cleanup
- // TODO DB deletions fails if the quorum is not met.
- xhr = CouchDB.request("DELETE", "/" + db_name + "/");
-}
diff --git a/test/javascript/tests-cluster/with-quorum/attachments_overridden_quorum.js b/test/javascript/tests-cluster/with-quorum/attachments_overridden_quorum.js
deleted file mode 100644
index cbeb9858d..000000000
--- a/test/javascript/tests-cluster/with-quorum/attachments_overridden_quorum.js
+++ /dev/null
@@ -1,42 +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.
-
-//Test attachments operations with an overridden quorum parameter
-couchTests.skip = true;
-couchTests.attachments_overriden_quorum= function(debug) {
- return console.log('done in test/elixir/test/cluster_with_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"},{"w":3});
- db.createDb();
- if (debug) debugger;
-
- var doc = db.save({_id:"dummy"});
- T(doc.ok);
-
- var xhr = CouchDB.request("PUT", "/" + db_name + "/dummy/foo.txt?rev=" + doc.rev, {
- body:"This is no base64 encoded text",
- headers:{"Content-Type": "text/plain;charset=utf-8"}
- });
- //TODO: Define correct behaviour
- //T(xhr.status == 202,"Should return 202");
- var rev = JSON.parse(xhr.responseText).rev;
-
- xhr = CouchDB.request("PUT", "/" + db_name + "/dummy/foo.txt?rev=" + rev, {
- body:"This is no base64 encoded text-2",
- headers:{"Content-Type": "text/plain;charset=utf-8"}
- });
- console.log("TODO: Clarify correct behaviour. Is not considering overridden quorum. 202->"+xhr.status);
- //TODO: Define correct behaviour
- //T(xhr.status == 202,"Should return 202");
-
- db.deleteDb();
-}
diff --git a/test/javascript/tests-cluster/with-quorum/db_creation.js b/test/javascript/tests-cluster/with-quorum/db_creation.js
deleted file mode 100644
index c8a416d3e..000000000
--- a/test/javascript/tests-cluster/with-quorum/db_creation.js
+++ /dev/null
@@ -1,28 +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.
-
-// Do DB creation under cluster with quorum conditions.
-couchTests.db_creation = function(debug) {
- return console.log('done in test/elixir/test/cluster_with_quorum_test.exs');
-
- if (debug) debugger;
-
- var db_name = get_random_db_name()
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
-
- // DB Creation should return 201 - Created
- xhr = CouchDB.request("PUT", "/" + db_name + "/");
- T(xhr.status == 201);
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests-cluster/with-quorum/db_creation_overridden_quorum.js b/test/javascript/tests-cluster/with-quorum/db_creation_overridden_quorum.js
deleted file mode 100644
index af27f9580..000000000
--- a/test/javascript/tests-cluster/with-quorum/db_creation_overridden_quorum.js
+++ /dev/null
@@ -1,30 +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.
-
-// Do DB creation under cluster with quorum conditions but overriding write quorum.
-couchTests.skip = true;
-couchTests.db_creation_overridden_quorum = function(debug) {
- return console.log('done in test/elixir/test/cluster_with_quorum_test.exs');
-
- if (debug) debugger;
-
- var db_name = get_random_db_name()
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"},{"w":3});
-
- // DB Creation should return 202 - Accepted
- xhr = CouchDB.request("PUT", "/" + db_name + "/");
- console.log("TODO: Clarify correct behaviour. Is not considering overridden quorum. 202->"+xhr.status)
- //T(xhr.status == 202,"Should return 202");
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests-cluster/with-quorum/db_deletion.js b/test/javascript/tests-cluster/with-quorum/db_deletion.js
deleted file mode 100644
index 70e703411..000000000
--- a/test/javascript/tests-cluster/with-quorum/db_deletion.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-// Do DB deletion under cluster with quorum conditions.
-couchTests.db_deletion = function(debug) {
- return console.log('done in test/elixir/test/cluster_with_quorum_test.exs');
-
- if (debug) debugger;
-
- var db_name = get_random_db_name()
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
-
- db.createDb();
-
- // DB Deletion should return 202 - Acceted as the custer is not complete
- xhr = CouchDB.request("DELETE", "/" + db_name + "/");
- T(xhr.status == 202);
-
-// DB Deletion should return 404 - Not found
- xhr = CouchDB.request("DELETE", "/not-existing-db/");
- T(xhr.status == 404);
-};
diff --git a/test/javascript/tests-cluster/with-quorum/db_deletion_overridden_quorum.js b/test/javascript/tests-cluster/with-quorum/db_deletion_overridden_quorum.js
deleted file mode 100644
index 8e9c65e31..000000000
--- a/test/javascript/tests-cluster/with-quorum/db_deletion_overridden_quorum.js
+++ /dev/null
@@ -1,24 +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.
-
-// Do DB deletion in a cluster with quorum conditions.
-couchTests.db_deletion_overridden_quorum = function(debug) {
- return console.log('done in test/elixir/test/cluster_with_quorum_test.exs');
-
- if (debug) debugger;
-
- var db_name = get_random_db_name()
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"},{"w":3});
- db.createDb();
- db.deleteDb();
- T(db.last_req.status="202","Should return 202");
-};
diff --git a/test/javascript/tests-cluster/with-quorum/doc_bulk.js b/test/javascript/tests-cluster/with-quorum/doc_bulk.js
deleted file mode 100644
index 1cb85749f..000000000
--- a/test/javascript/tests-cluster/with-quorum/doc_bulk.js
+++ /dev/null
@@ -1,26 +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.
-
-couchTests.doc_bulk = function(debug) {
- return console.log('done in test/elixir/test/cluster_with_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var docs = makeDocs(5);
- // Create the docs
- var results = db.bulkSave(docs);
- T(db.last_req.status="201","Should return 201")
-
- db.deleteDb();
-}
diff --git a/test/javascript/tests-cluster/with-quorum/doc_bulk_overridden_quorum.js b/test/javascript/tests-cluster/with-quorum/doc_bulk_overridden_quorum.js
deleted file mode 100644
index 2a3be068a..000000000
--- a/test/javascript/tests-cluster/with-quorum/doc_bulk_overridden_quorum.js
+++ /dev/null
@@ -1,26 +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.
-
-couchTests.doc_bulk_overridden_quorum = function(debug) {
- return console.log('done in test/elixir/test/cluster_with_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"},{"w":3});
- db.createDb();
- if (debug) debugger;
-
- var docs = makeDocs(5);
- // Create the docs
- var results = db.bulkSave(docs);
- T(db.last_req.status="202","Should return 202")
-
- db.deleteDb();
-}
diff --git a/test/javascript/tests-cluster/with-quorum/doc_copy.js b/test/javascript/tests-cluster/with-quorum/doc_copy.js
deleted file mode 100644
index e79d38ccd..000000000
--- a/test/javascript/tests-cluster/with-quorum/doc_copy.js
+++ /dev/null
@@ -1,28 +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.
-
-couchTests.doc_copy = function(debug) {
- return console.log('done in test/elixir/test/cluster_with_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- db.save({_id:"dummy"});
-
- var xhr = CouchDB.request("COPY", "/" + db_name + "/dummy", {
- headers: {"Destination":"dummy2"}
- });
- T(xhr.status=="201","Should return 201 ");
-
- db.deleteDb();
-}
diff --git a/test/javascript/tests-cluster/with-quorum/doc_copy_overridden_quorum.js b/test/javascript/tests-cluster/with-quorum/doc_copy_overridden_quorum.js
deleted file mode 100644
index a816817f8..000000000
--- a/test/javascript/tests-cluster/with-quorum/doc_copy_overridden_quorum.js
+++ /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.
-
-couchTests.skip = true;
-couchTests.doc_copy_overriden_quorum = function(debug) {
- return console.log('done in test/elixir/test/cluster_with_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"},{"w":3});
- db.createDb();
- if (debug) debugger;
-
- db.save({_id:"dummy"});
-
- var xhr = CouchDB.request("COPY", "/" + db_name + "/dummy", {
- headers: {"Destination":"dummy2"}
- });
- //TODO: Define correct behaviour
- //T(xhr.status=="202","Should return 202");
- console.log("TODO: Clarify correct behaviour. Is not considering overridden quorum. 202->"+xhr.status);
-
- db.deleteDb();
-
-}
diff --git a/test/javascript/tests-cluster/with-quorum/doc_crud.js b/test/javascript/tests-cluster/with-quorum/doc_crud.js
deleted file mode 100644
index ab90e603e..000000000
--- a/test/javascript/tests-cluster/with-quorum/doc_crud.js
+++ /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.
-
-couchTests.doc_crud = function(debug) {
- return console.log('done in test/elixir/test/cluster_with_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- db.save({_id:"0",a:1});
- T(db.last_req.status=="201");
-
- var doc = db.open("0");
- db.save(doc);
- T(db.last_req.status=="201");
-
- doc = db.open("0");
- db.deleteDoc(doc);
- T(db.last_req.status="200");
- db.deleteDb();
-
-}
diff --git a/test/javascript/tests-cluster/with-quorum/doc_crud_overridden_quorum.js b/test/javascript/tests-cluster/with-quorum/doc_crud_overridden_quorum.js
deleted file mode 100644
index a3513781f..000000000
--- a/test/javascript/tests-cluster/with-quorum/doc_crud_overridden_quorum.js
+++ /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.
-
-couchTests.doc_crud_overridden_quorum = function(debug) {
- return console.log('done in test/elixir/test/cluster_with_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"},{"w":3});
- db.createDb();
- if (debug) debugger;
-
- db.save({_id:"0",a:1});
- T(db.last_req.status=="202","Should return 202 status");
-
- var doc = db.open("0");
- db.save(doc);
- T(db.last_req.status=="202","Should return 202 status");
-
- doc = db.open("0");
- db.deleteDoc(doc);
- T(db.last_req.status="202","Should return 202 status");
-
- db.deleteDb();
-}
diff --git a/test/javascript/tests-cluster/without-quorum/attachments.js b/test/javascript/tests-cluster/without-quorum/attachments.js
deleted file mode 100644
index 349cc88d6..000000000
--- a/test/javascript/tests-cluster/without-quorum/attachments.js
+++ /dev/null
@@ -1,40 +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.
-
-couchTests.attachments= function(debug) {
- return console.log('done in test/elixir/test/cluster_without_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var doc = db.save({_id:"dummy"});
- T(doc.ok);
- var xhr = CouchDB.request("PUT", "/" + db_name + "/dummy/foo.txt?rev=" + doc.rev, {
- body:"This is no base64 encoded text",
- headers:{"Content-Type": "text/plain;charset=utf-8"}
- });
- T(xhr.status == 202,"Should return 202 Accepted");
- var rev = JSON.parse(xhr.responseText).rev;
-
- xhr = CouchDB.request("PUT", "/" + db_name + "/dummy/foo.txt?rev=" + rev, {
- body:"This is no base64 encoded text-2",
- headers:{"Content-Type": "text/plain;charset=utf-8"}
- });
- T(xhr.status == 202,"Should return 202 Accepted");
- rev = JSON.parse(xhr.responseText).rev;
-
- //db.deleteDb();
- // cleanup
- // TODO DB deletions fails if the quorum is not met.
- xhr = CouchDB.request("DELETE", "/" + db_name + "/");
-}
diff --git a/test/javascript/tests-cluster/without-quorum/attachments_delete.js b/test/javascript/tests-cluster/without-quorum/attachments_delete.js
deleted file mode 100644
index 8b8a2dbcf..000000000
--- a/test/javascript/tests-cluster/without-quorum/attachments_delete.js
+++ /dev/null
@@ -1,39 +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.
-
-couchTests.skip = true;
-couchTests.attachments_delete= function(debug) {
- return console.log('done in test/elixir/test/cluster_without_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var doc = db.save({_id:"dummy"});
- T(doc.ok);
- var xhr = CouchDB.request("PUT", "/" + db_name + "/dummy/foo.txt?rev=" + doc.rev, {
- body:"This is no base64 encoded text",
- headers:{"Content-Type": "text/plain;charset=utf-8"}
- });
- T(xhr.status == 202,"Should return 202 Accepted");
- var rev = JSON.parse(xhr.responseText).rev;
-
- xhr = CouchDB.request("DELETE", "/" + db_name + "/dummy/foo.txt?rev=" + rev);
- console.log("TODO: Clarify correct behaviour. Is not considering quorum. 202->"+xhr.status);
- //TODO: Define correct behaviour
- //T(xhr.status == 202,"Should return 202 Accepted but returns "+xhr.status);
-
- //db.deleteDb();
- // cleanup
- // TODO DB deletions fails if the quorum is not met.
- xhr = CouchDB.request("DELETE", "/" + db_name + "/");
-}
diff --git a/test/javascript/tests-cluster/without-quorum/attachments_delete_overridden_quorum.js b/test/javascript/tests-cluster/without-quorum/attachments_delete_overridden_quorum.js
deleted file mode 100644
index 48247e00d..000000000
--- a/test/javascript/tests-cluster/without-quorum/attachments_delete_overridden_quorum.js
+++ /dev/null
@@ -1,38 +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.
-
-couchTests.skip = true;
-couchTests.attachments_delete_overridden_quorum= function(debug) {
- return console.log('done in test/elixir/test/cluster_without_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"},{"w":1});
- db.createDb();
- if (debug) debugger;
-
- var doc = db.save({_id:"dummy"});
- T(doc.ok);
- var xhr = CouchDB.request("PUT", "/" + db_name + "/dummy/foo.txt?rev=" + doc.rev, {
- body:"This is no base64 encoded text",
- headers:{"Content-Type": "text/plain;charset=utf-8"}
- });
- var rev = JSON.parse(xhr.responseText).rev;
-
- xhr = CouchDB.request("DELETE", "/" + db_name + "/dummy/foo.txt?rev=" + rev);
- console.log("TODO: Clarify correct behaviour. Is not considering quorum. 202->"+xhr.status);
- //TODO: Define correct behaviour
- //T(xhr.status == 200,"Should return 200 but returns "+xhr.status);
-
- //db.deleteDb();
- // cleanup
- // TODO DB deletions fails if the quorum is not met.
- xhr = CouchDB.request("DELETE", "/" + db_name + "/");
-}
diff --git a/test/javascript/tests-cluster/without-quorum/attachments_overridden_quorum.js b/test/javascript/tests-cluster/without-quorum/attachments_overridden_quorum.js
deleted file mode 100644
index 2b8e75fd0..000000000
--- a/test/javascript/tests-cluster/without-quorum/attachments_overridden_quorum.js
+++ /dev/null
@@ -1,43 +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.
-
-//Test attachments operations with an overridden quorum parameter
-couchTests.attachments_overriden_quorum= function(debug) {
- return console.log('done in test/elixir/test/cluster_without_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"},{"w":1});
- db.createDb();
- if (debug) debugger;
-
- var doc = db.save({_id:"dummy"});
- T(doc.ok);
-
- var xhr = CouchDB.request("PUT", "/" + db_name + "/dummy/foo.txt?rev=" + doc.rev, {
- body:"This is no base64 encoded text",
- headers:{"Content-Type": "text/plain;charset=utf-8"}
- });
- //TODO: Define correct behaviour
- //T(xhr.status == 201,"Should return 201");
- var rev = JSON.parse(xhr.responseText).rev;
-
- xhr = CouchDB.request("PUT", "/" + db_name + "/dummy/foo.txt?rev=" + rev, {
- body:"This is no base64 encoded text-2",
- headers:{"Content-Type": "text/plain;charset=utf-8"}
- });
- //TODO: Define correct behaviour
- //T(xhr.status == 201,"Should return 201");
-
- //db.deleteDb();
- // cleanup
- // TODO DB deletions fails if the quorum is not met.
- xhr = CouchDB.request("DELETE", "/" + db_name + "/");
-}
diff --git a/test/javascript/tests-cluster/without-quorum/db_creation.js b/test/javascript/tests-cluster/without-quorum/db_creation.js
deleted file mode 100644
index dd9b29497..000000000
--- a/test/javascript/tests-cluster/without-quorum/db_creation.js
+++ /dev/null
@@ -1,28 +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.
-
-// Do DB creation under cluster without quorum conditions.
-couchTests.db_creation = function(debug) {
- return console.log('done in test/elixir/test/cluster_without_quorum_test.exs');
-
- if (debug) debugger;
-
- var db_name = get_random_db_name()
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
-
- // DB Creation should return 202- Accepted
- xhr = CouchDB.request("PUT", "/" + db_name + "/");
- T(xhr.status == 202);
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests-cluster/without-quorum/db_creation_overridden_quorum.js b/test/javascript/tests-cluster/without-quorum/db_creation_overridden_quorum.js
deleted file mode 100644
index 8ed9b4480..000000000
--- a/test/javascript/tests-cluster/without-quorum/db_creation_overridden_quorum.js
+++ /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.
-
-// Do DB creation under cluster with quorum conditions but overriding write quorum.
-couchTests.skip = true;
-couchTests.db_creation_overridden_quorum = function(debug) {
- return console.log('done in test/elixir/test/cluster_without_quorum_test.exs');
-
- if (debug) debugger;
-
- var db_name = get_random_db_name()
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"},{"w":1});
-
- // DB Creation should return 201 - Created
- xhr = CouchDB.request("PUT", "/" + db_name + "/");
- console.log("TODO: Clarify correct behaviour. Is not considering overridden quorum. 201->"+xhr.status)
- //T(xhr.status == 201,"Should return 201");
-
- //db.deleteDb();
- // cleanup
- // TODO DB deletions fails if the quorum is not met.
- xhr = CouchDB.request("DELETE", "/" + db_name + "/");
-};
diff --git a/test/javascript/tests-cluster/without-quorum/db_deletion.js b/test/javascript/tests-cluster/without-quorum/db_deletion.js
deleted file mode 100644
index f156b0e95..000000000
--- a/test/javascript/tests-cluster/without-quorum/db_deletion.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-// Do DB creation under cluster with quorum conditions.
-couchTests.db_deletion = function(debug) {
- return console.log('done in test/elixir/test/cluster_without_quorum_test.exs');
-
- if (debug) debugger;
-
- var db_name = get_random_db_name()
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
-
- db.createDb();
-
- // DB Deletion should return 202 - Acepted
- xhr = CouchDB.request("DELETE", "/" + db_name + "/");
- T(xhr.status == 202);
-
- // DB Deletion should return 404 - Not found
- xhr = CouchDB.request("DELETE", "/not-existing-db/");
- T(xhr.status == 404);
-};
diff --git a/test/javascript/tests-cluster/without-quorum/db_deletion_overridden_quorum.js b/test/javascript/tests-cluster/without-quorum/db_deletion_overridden_quorum.js
deleted file mode 100644
index 86dea83aa..000000000
--- a/test/javascript/tests-cluster/without-quorum/db_deletion_overridden_quorum.js
+++ /dev/null
@@ -1,26 +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.
-
-// Do DB deletion in a cluster with quorum conditions.
-couchTests.db_deletion_overridden_quorum = function(debug) {
- return console.log('done in test/elixir/test/cluster_without_quorum_test.exs');
-
- if (debug) debugger;
-
- var db_name = get_random_db_name()
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"},{"w":1});
- db.createDb();
-
- // DB deletions does not consider overriden quorum param.
- xhr = CouchDB.request("DELETE", "/" + db_name + "/");
- T(db.last_req.status="202","Should return 202");
-};
diff --git a/test/javascript/tests-cluster/without-quorum/doc_bulk.js b/test/javascript/tests-cluster/without-quorum/doc_bulk.js
deleted file mode 100644
index 37f67ec6b..000000000
--- a/test/javascript/tests-cluster/without-quorum/doc_bulk.js
+++ /dev/null
@@ -1,29 +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.
-
-couchTests.doc_bulk = function(debug) {
- return console.log('done in test/elixir/test/cluster_without_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var docs = makeDocs(5);
- // Create the docs
- var results = db.bulkSave(docs);
- T(db.last_req.status="202","Should return 202")
-
- //db.deleteDb();
- // cleanup
- // TODO DB deletions fails if the quorum is not met.
- xhr = CouchDB.request("DELETE", "/" + db_name + "/");
-}
diff --git a/test/javascript/tests-cluster/without-quorum/doc_bulk_overridden_quorum.js b/test/javascript/tests-cluster/without-quorum/doc_bulk_overridden_quorum.js
deleted file mode 100644
index 0f2f36443..000000000
--- a/test/javascript/tests-cluster/without-quorum/doc_bulk_overridden_quorum.js
+++ /dev/null
@@ -1,29 +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.
-
-couchTests.doc_bulk_overridden_quorum = function(debug) {
- return console.log('done in test/elixir/test/cluster_without_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"},{"w":1});
- db.createDb();
- if (debug) debugger;
-
- var docs = makeDocs(5);
- // Create the docs
- var results = db.bulkSave(docs);
- T(db.last_req.status="201","Should return 201")
-
- //db.deleteDb();
- // cleanup
- // TODO DB deletions fails if the quorum is not met.
- xhr = CouchDB.request("DELETE", "/" + db_name + "/");
-}
diff --git a/test/javascript/tests-cluster/without-quorum/doc_copy.js b/test/javascript/tests-cluster/without-quorum/doc_copy.js
deleted file mode 100644
index 6e7ae45b4..000000000
--- a/test/javascript/tests-cluster/without-quorum/doc_copy.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-couchTests.doc_copy = function(debug) {
- return console.log('done in test/elixir/test/cluster_without_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- db.save({_id:"dummy"});
-
- var xhr = CouchDB.request("COPY", "/" + db_name + "/dummy", {
- headers: {"Destination":"dummy2"}
- });
- T(xhr.status=="202","Should return 202 ");
-
- //db.deleteDb();
- // cleanup
- // TODO DB deletions fails if the quorum is not met.
- xhr = CouchDB.request("DELETE", "/" + db_name + "/");
-}
diff --git a/test/javascript/tests-cluster/without-quorum/doc_copy_overridden_quorum.js b/test/javascript/tests-cluster/without-quorum/doc_copy_overridden_quorum.js
deleted file mode 100644
index 301240e22..000000000
--- a/test/javascript/tests-cluster/without-quorum/doc_copy_overridden_quorum.js
+++ /dev/null
@@ -1,35 +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.
-
-couchTests.skip = true;
-couchTests.doc_copy_overriden_quorum = function(debug) {
- return console.log('done in test/elixir/test/cluster_without_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"},{"w":1});
- db.createDb();
- if (debug) debugger;
-
- db.save({_id:"dummy"});
-
- var xhr = CouchDB.request("COPY", "/" + db_name + "/dummy", {
- headers: {"Destination":"dummy2"}
- });
- console.log("TODO: Clarify correct behaviour. Is not considering overridden quorum. 201->"+xhr.status);
- //TODO Defie correct behaviour
- //T(xhr.status=="201","Should return 201");
-
- //db.deleteDb();
- // cleanup
- // TODO DB deletions fails if the quorum is not met.
- xhr = CouchDB.request("DELETE", "/" + db_name + "/");
-
-}
diff --git a/test/javascript/tests-cluster/without-quorum/doc_crud.js b/test/javascript/tests-cluster/without-quorum/doc_crud.js
deleted file mode 100644
index 0a009d58a..000000000
--- a/test/javascript/tests-cluster/without-quorum/doc_crud.js
+++ /dev/null
@@ -1,36 +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.
-
-couchTests.doc_crud = function(debug) {
- return console.log('done in test/elixir/test/cluster_without_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- db.save({_id:"0",a:1});
- T(db.last_req.status=="202","Should return 202 status");
-
- var doc = db.open("0");
- db.save(doc);
- T(db.last_req.status=="202","Should return 202 status");
-
- doc = db.open("0");
- db.deleteDoc(doc);
- T(db.last_req.status="202","Should return 202 status");
-
- //db.deleteDb();
- // cleanup
- // TODO DB deletions fails if the quorum is not met.
- xhr = CouchDB.request("DELETE", "/" + db_name + "/");
-
-}
diff --git a/test/javascript/tests-cluster/without-quorum/doc_crud_overridden_quorum.js b/test/javascript/tests-cluster/without-quorum/doc_crud_overridden_quorum.js
deleted file mode 100644
index 9eb83bd6a..000000000
--- a/test/javascript/tests-cluster/without-quorum/doc_crud_overridden_quorum.js
+++ /dev/null
@@ -1,35 +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.
-
-couchTests.doc_crud_overridden_quorum = function(debug) {
- return console.log('done in test/elixir/test/cluster_without_quorum_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"},{"w":1});
- db.createDb();
- if (debug) debugger;
-
- db.save({_id:"0",a:1});
- T(db.last_req.status=="201","Should return 201 status");
-
- var doc = db.open("0");
- db.save(doc);
- T(db.last_req.status=="201","Should return 201 status");
-
- doc = db.open("0");
- db.deleteDoc(doc);
- T(db.last_req.status="200","Should return 200 status");
-
- //db.deleteDb();
- // cleanup
- // TODO DB deletions fails if the quorum is not met.
- xhr = CouchDB.request("DELETE", "/" + db_name + "/");
-}
diff --git a/test/javascript/tests/all_docs.js b/test/javascript/tests/all_docs.js
deleted file mode 100644
index 0eb382fa9..000000000
--- a/test/javascript/tests/all_docs.js
+++ /dev/null
@@ -1,167 +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.
-
-couchTests.elixir = true;
-couchTests.all_docs = function(debug) {
- return console.log('done in test/elixir/test/all_docs_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}, {w: 3});
- db.createDb();
- if (debug) debugger;
-
- // Create some more documents.
- // Notice the use of the ok member on the return result.
-
- var doc1 = db.save({_id:"0",a:1,b:1});
- var doc2 = db.save({_id:"3",a:4,b:16});
- var doc3 = db.save({_id:"1",a:2,b:4});
- var doc4 = db.save({_id:"2",a:3,b:9});
-
- T(doc1.ok);
- T(doc2.ok);
- T(doc3.ok);
- T(doc4.ok);
-
- var revs = [];
- revs.push(doc1.rev);
- revs.push(doc2.rev);
- revs.push(doc3.rev);
- revs.push(doc4.rev);
-
- // Check the all docs
- var results = db.allDocs();
- var rows = results.rows;
-
- T(results.total_rows == results.rows.length);
-
- for(var i=0; i < rows.length; i++) {
- T(rows[i].id >= "0" && rows[i].id <= "4");
- }
-
- // Check _all_docs with descending=true
- var desc = db.allDocs({descending:true});
- T(desc.total_rows == desc.rows.length);
-
- // Check _all_docs offset
- var all = db.allDocs({startkey:"2"});
- T(all.offset == 2);
-
- // Confirm that queries may assume raw collation.
- var raw = db.allDocs({ startkey: "org.couchdb.user:",
- endkey : "org.couchdb.user;"
- });
- TEquals(0, raw.rows.length);
-
-
- // check that all docs show up in the changes feed
- // the order can vary
- var changes = db.changes();
- changes.results.forEach(function(row, idx) {
- var rev = row.changes[0].rev;
- TEquals(true, revs.indexOf(rev) !== -1, "doc " + i + " should be in changes");
- });
-
- // check that deletions also show up right
- var doc1 = db.open("1");
- var deleted = db.deleteDoc(doc1);
- T(deleted.ok);
- changes = db.changes();
- T(changes.results.length == 4);
- var deleted_doc = changes.results.filter(function(row) {
- return row.deleted == true;
- })[0];
- TEquals("1", deleted_doc.id, "deletes");
-
- // (remember old seq)
- var orig_doc = changes.results.filter(function(row) {
- return row.id == "3"
- })[0];
- // do an update
- var doc3 = db.open("3");
- doc3.updated = "totally";
- doc3 = db.save(doc3);
- changes = db.changes();
-
- // the update should make doc id 3 have another seq num (not nec. higher or the last though)
- T(changes.results.length == 4);
- var updated_doc = changes.results.filter(function(row) {
- return row.id == "3"
- })[0];
- T(orig_doc.seq != updated_doc.seq, "seq num should be different");
-
- // ok now lets see what happens with include docs
- changes = db.changes({include_docs: true});
- T(changes.results.length == 4);
-
- var updated_doc = changes.results.filter(function(row) {
- return row.id == doc3.id
- })[0];
- T(updated_doc.doc.updated == "totally");
-
- var deleted_doc = changes.results.filter(function(row) {
- return row.deleted == true;
- })[0];
- TEquals(true, deleted_doc.doc._deleted, "deletes");
-
- rows = db.allDocs({include_docs: true}, ["1"]).rows;
- TEquals(1, rows.length);
- TEquals("1", rows[0].key);
- TEquals("1", rows[0].id);
- TEquals(true, rows[0].value.deleted);
- TEquals(null, rows[0].doc);
-
- // add conflicts
- var conflictDoc1 = {
- _id: "3", _rev: "2-aa01552213fafa022e6167113ed01087", value: "X"
- };
- var conflictDoc2 = {
- _id: "3", _rev: "2-ff01552213fafa022e6167113ed01087", value: "Z"
- };
- T(db.save(conflictDoc1, {new_edits: false}));
- T(db.save(conflictDoc2, {new_edits: false}));
-
- var winRev = db.open("3");
-
- changes = db.changes({include_docs: true, conflicts: true, style: "all_docs"});
-
- var doc3 = changes.results.filter(function(row) {
- return row.id == "3";
- })[0];
-
- TEquals("3", doc3.id);
- TEquals(3, doc3.changes.length);
- TEquals(winRev._rev, doc3.changes[0].rev);
- TEquals("3", doc3.doc._id);
- TEquals(winRev._rev, doc3.doc._rev);
- TEquals(true, doc3.doc._conflicts instanceof Array);
- TEquals(2, doc3.doc._conflicts.length);
-
- rows = db.allDocs({include_docs: true, conflicts: true}).rows;
- TEquals(3, rows.length);
- TEquals("3", rows[2].key);
- TEquals("3", rows[2].id);
- TEquals(winRev._rev, rows[2].value.rev);
- TEquals(winRev._rev, rows[2].doc._rev);
- TEquals("3", rows[2].doc._id);
- TEquals(true, rows[2].doc._conflicts instanceof Array);
- TEquals(2, rows[2].doc._conflicts.length);
-
- // test the all docs collates sanely
- db.save({_id: "Z", foo: "Z"});
- db.save({_id: "a", foo: "a"});
-
- var rows = db.allDocs({startkey: "Z", endkey: "Z"}).rows;
- T(rows.length == 1);
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/attachment_names.js b/test/javascript/tests/attachment_names.js
deleted file mode 100644
index 16a23ac85..000000000
--- a/test/javascript/tests/attachment_names.js
+++ /dev/null
@@ -1,99 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-couchTests.elixir = true;
-couchTests.attachment_names = function(debug) {
- return console.log('done in test/elixir/test/attachment_names_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}, {w: 3});
- db.createDb();
- if (debug) debugger;
-
- var goodDoc = {
- _id: "good_doc",
- _attachments: {
- "Колян.txt": {
- content_type:"application/octet-stream",
- data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
- }
- }
- };
-
- var save_response = db.save(goodDoc);
- T(save_response.ok);
-
- var xhr = CouchDB.request("GET", "/" + db_name + "/good_doc/Колян.txt");
- T(xhr.responseText == "This is a base64 encoded text");
- T(xhr.getResponseHeader("Content-Type") == "application/octet-stream");
- TEquals("\"aEI7pOYCRBLTRQvvqYrrJQ==\"", xhr.getResponseHeader("Etag"));
-
- var binAttDoc = {
- _id: "bin_doc",
- _attachments:{
- "footxt": {
- content_type:"text/plain",
- data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
- }
- }
- };
-
- // inline attachments
- resp = db.save(binAttDoc);
- TEquals(true, resp.ok, "attachment_name: inline attachment");
-
-
- // standalone docs
- var bin_data = "JHAPDO*AU£PN ){(3u[d 93DQ9¡€])} ææøo'∂ƒæ≤çæππ•¥∫¶®#†π¶®¥π€ª®˙π8np";
-
-
- var xhr = (CouchDB.request("PUT", "/" + db_name + "/bin_doc3/attachmenttxt", {
- headers:{"Content-Type":"text/plain;charset=utf-8"},
- body:bin_data
- }));
-
- var resp = JSON.parse(xhr.responseText);
- TEquals(201, xhr.status, "attachment_name: standalone API");
- TEquals(true, resp.ok, "attachment_name: standalone API");
-
- // bulk docs
- var docs = { docs: [binAttDoc] };
- var xhr = CouchDB.request("POST", "/" + db_name + "/_bulk_docs", {
- body: JSON.stringify(docs)
- });
-
- TEquals(201, xhr.status, "attachment_name: bulk docs");
-
-
- // leading underscores
- var binAttDoc = {
- _id: "bin_doc2",
- _attachments:{
- "_foo.txt": {
- content_type:"text/plain",
- data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
- }
- }
- };
-
- try {
- db.save(binAttDoc);
- TEquals(1, 2, "Attachment name with leading underscore saved. Should never show!");
- } catch (e) {
- TEquals("bad_request", e.error, "attachment_name: leading underscore");
- TEquals("Attachment name '_foo.txt' starts with prohibited character '_'", e.reason, "attachment_name: leading underscore");
- }
-
- // todo: form uploads, waiting for cmlenz' test case for form uploads
- // cleanup
- db.deleteDb();
-
-};
diff --git a/test/javascript/tests/attachment_paths.js b/test/javascript/tests/attachment_paths.js
deleted file mode 100644
index b8c6a794b..000000000
--- a/test/javascript/tests/attachment_paths.js
+++ /dev/null
@@ -1,156 +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.
-
-couchTests.elixir = true;
-couchTests.attachment_paths = function(debug) {
- return console.log('done in test/elixir/test/attachment_paths_test.exs');
- if (debug) debugger;
- var r_db_name = get_random_db_name()
- var dbNames = [r_db_name, r_db_name + "/with_slashes"];
- for (var i=0; i < dbNames.length; i++) {
- var db = new CouchDB(dbNames[i]);
- var dbName = encodeURIComponent(dbNames[i]);
- db.createDb();
-
- // first just save a regular doc with an attachment that has a slash in the url.
- // (also gonna run an encoding check case)
- var binAttDoc = {
- _id: "bin_doc",
- _attachments:{
- "foo/bar.txt": {
- content_type:"text/plain",
- data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
- },
- "foo%2Fbaz.txt": {
- content_type:"text/plain",
- data: "V2UgbGlrZSBwZXJjZW50IHR3byBGLg=="
- }
- }
- };
-
- T(db.save(binAttDoc).ok);
-
- var xhr = CouchDB.request("GET", "/"+dbName+"/bin_doc/foo/bar.txt");
- T(xhr.responseText == "This is a base64 encoded text");
- T(xhr.getResponseHeader("Content-Type") == "text/plain");
-
- // lets try it with an escaped attachment id...
- // weird that it's at two urls
- var xhr = CouchDB.request("GET", "/"+dbName+"/bin_doc/foo%2Fbar.txt");
- T(xhr.status == 200);
- // xhr.responseText == "This is a base64 encoded text"
-
- var xhr = CouchDB.request("GET", "/"+dbName+"/bin_doc/foo/baz.txt");
- T(xhr.status == 404);
-
- var xhr = CouchDB.request("GET", "/"+dbName+"/bin_doc/foo%252Fbaz.txt");
- T(xhr.status == 200);
- T(xhr.responseText == "We like percent two F.");
-
- // require a _rev to PUT
- var xhr = CouchDB.request("PUT", "/"+dbName+"/bin_doc/foo/attachment.txt", {
- headers:{"Content-Type":"text/plain;charset=utf-8"},
- body:"Just some text"
- });
- T(xhr.status == 409);
-
- var xhr = CouchDB.request("PUT", "/"+dbName+"/bin_doc/foo/bar2.txt?rev=" + binAttDoc._rev, {
- body:"This is no base64 encoded text",
- headers:{"Content-Type": "text/plain;charset=utf-8"}
- });
- T(xhr.status == 201);
- var rev = JSON.parse(xhr.responseText).rev;
-
- binAttDoc = db.open("bin_doc");
-
- T(binAttDoc._attachments["foo/bar.txt"] !== undefined);
- T(binAttDoc._attachments["foo%2Fbaz.txt"] !== undefined);
- T(binAttDoc._attachments["foo/bar2.txt"] !== undefined);
- TEquals("text/plain;charset=utf-8", // thank you Safari
- binAttDoc._attachments["foo/bar2.txt"].content_type.toLowerCase(),
- "correct content-type"
- );
- T(binAttDoc._attachments["foo/bar2.txt"].length == 30);
-
- //// now repeat the while thing with a design doc
-
- // first just save a regular doc with an attachment that has a slash in the url.
- // (also gonna run an encoding check case)
- var binAttDoc = {
- _id: "_design/bin_doc",
- _attachments:{
- "foo/bar.txt": {
- content_type:"text/plain",
- data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
- },
- "foo%2Fbaz.txt": {
- content_type:"text/plain",
- data: "V2UgbGlrZSBwZXJjZW50IHR3byBGLg=="
- }
- }
- };
-
- T(db.save(binAttDoc).ok);
-
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design%2Fbin_doc/foo/bar.txt");
- T(xhr.responseText == "This is a base64 encoded text");
- T(xhr.getResponseHeader("Content-Type") == "text/plain");
-
- // lets try it with an escaped attachment id...
- // weird that it's at two urls
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design%2Fbin_doc/foo%2Fbar.txt");
- T(xhr.responseText == "This is a base64 encoded text");
- T(xhr.status == 200);
-
- // err, 3 urls
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design/bin_doc/foo%2Fbar.txt");
- T(xhr.responseText == "This is a base64 encoded text");
- T(xhr.status == 200);
-
- // I mean um, 4 urls
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design/bin_doc/foo/bar.txt");
- T(xhr.responseText == "This is a base64 encoded text");
- T(xhr.status == 200);
-
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design%2Fbin_doc/foo/baz.txt");
- T(xhr.status == 404);
-
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design%2Fbin_doc/foo%252Fbaz.txt");
- T(xhr.status == 200);
- T(xhr.responseText == "We like percent two F.");
-
- // require a _rev to PUT
- var xhr = CouchDB.request("PUT", "/"+dbName+"/_design%2Fbin_doc/foo/attachment.txt", {
- headers:{"Content-Type":"text/plain;charset=utf-8"},
- body:"Just some text"
- });
- T(xhr.status == 409);
-
- var xhr = CouchDB.request("PUT", "/"+dbName+"/_design%2Fbin_doc/foo/bar2.txt?rev=" + binAttDoc._rev, {
- body:"This is no base64 encoded text",
- headers:{"Content-Type": "text/plain;charset=utf-8"}
- });
- T(xhr.status == 201);
- var rev = JSON.parse(xhr.responseText).rev;
-
- binAttDoc = db.open("_design/bin_doc");
-
- T(binAttDoc._attachments["foo/bar.txt"] !== undefined);
- T(binAttDoc._attachments["foo/bar2.txt"] !== undefined);
- TEquals("text/plain;charset=utf-8", // thank you Safari
- binAttDoc._attachments["foo/bar2.txt"].content_type.toLowerCase(),
- "correct content-type"
- );
- T(binAttDoc._attachments["foo/bar2.txt"].length == 30);
- db.deleteDb();
- }
-};
diff --git a/test/javascript/tests/attachment_ranges.js b/test/javascript/tests/attachment_ranges.js
deleted file mode 100644
index 564885cba..000000000
--- a/test/javascript/tests/attachment_ranges.js
+++ /dev/null
@@ -1,164 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-function cacheBust() {
- return "?anti-cache=" + String(Math.round(Math.random() * 1000000));
-};
-
-couchTests.elixir = true;
-couchTests.attachment_ranges = function(debug) {
- return console.log('done in test/elixir/test/attachment_ranges_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {
- "X-Couch-Full-Commit": "false"
- });
- db.createDb();
-
- if (debug) debugger;
-
- if((typeof window != "undefined") && window.navigator.userAgent.match(/Chrome/)) {
- // Chrome is broken.
- return;
- }
-
- var binAttDoc = {
- _id: "bin_doc",
- _attachments: {
- "foo.txt": {
- content_type: "application/octet-stream",
- data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
- }
- }
- };
-
- var save_response = db.save(binAttDoc);
- T(save_response.ok);
-
- // Fetching the whole entity is a 206.
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
- headers: {
- "Range": "bytes=0-28"
- }
- });
- TEquals(206, xhr.status, "fetch 0-28");
- TEquals("This is a base64 encoded text", xhr.responseText);
- TEquals("bytes 0-28/29", xhr.getResponseHeader("Content-Range"));
- TEquals("29", xhr.getResponseHeader("Content-Length"));
-
- // Fetch the whole entity without an end offset is a 200.
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
- headers: {
- "Range": "bytes=0-"
- }
- });
- TEquals(200, xhr.status, "fetch 0-");
- TEquals("This is a base64 encoded text", xhr.responseText);
- TEquals(null, xhr.getResponseHeader("Content-Range"));
- TEquals("29", xhr.getResponseHeader("Content-Length"));
-
- // Even if you ask multiple times.
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
- headers: {
- "Range": "bytes=0-,0-,0-"
- }
- });
- TEquals(200, xhr.status, "multiple 0-'s");
-
- // Badly formed range header is a 200.
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
- headers: {
- "Range": "bytes:0-"
- }
- });
- TEquals(200, xhr.status, "fetch with bad range header");
-
- // Fetch the end of an entity without an end offset is a 206.
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
- headers: {
- "Range": "bytes=2-"
- }
- });
- TEquals(206, xhr.status, "fetch 2-");
- TEquals("is is a base64 encoded text", xhr.responseText);
- TEquals("bytes 2-28/29", xhr.getResponseHeader("Content-Range"));
- TEquals("27", xhr.getResponseHeader("Content-Length"));
-
- // Fetch past the end of the entity is a 206
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
- headers: {
- "Range": "bytes=0-29"
- }
- });
- TEquals(206, xhr.status, "fetch 0-29");
- TEquals("bytes 0-28/29", xhr.getResponseHeader("Content-Range"));
- TEquals("29", xhr.getResponseHeader("Content-Length"));
-
- // Fetch first part of entity is a 206
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
- headers: {
- "Range": "bytes=0-3"
- }
- });
- TEquals(206, xhr.status, "fetch 0-3");
- TEquals("This", xhr.responseText);
- TEquals("4", xhr.getResponseHeader("Content-Length"));
- TEquals("bytes 0-3/29", xhr.getResponseHeader("Content-Range"));
-
- // Fetch middle of entity is also a 206
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
- headers: {
- "Range": "bytes=10-15"
- }
- });
- TEquals(206, xhr.status, "fetch 10-15");
- TEquals("base64", xhr.responseText);
- TEquals("6", xhr.getResponseHeader("Content-Length"));
- TEquals("bytes 10-15/29", xhr.getResponseHeader("Content-Range"));
-
- // Fetch end of entity is also a 206
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
- headers: {
- "Range": "bytes=-3"
- }
- });
- TEquals(206, xhr.status, "fetch -3");
- TEquals("ext", xhr.responseText);
- TEquals("3", xhr.getResponseHeader("Content-Length"));
- TEquals("bytes 26-28/29", xhr.getResponseHeader("Content-Range"));
-
- // backward range is 416
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
- headers: {
- "Range": "bytes=5-3"
- }
- });
- TEquals(416, xhr.status, "fetch 5-3");
-
- // range completely outside of entity is 416
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
- headers: {
- "Range": "bytes=300-310"
- }
- });
- TEquals(416, xhr.status, "fetch 300-310");
-
- // We ignore a Range header with too many ranges
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt" + cacheBust(), {
- headers: {
- "Range": "bytes=0-1,0-1,0-1,0-1,0-1,0-1,0-1,0-1,0-1,0-1"
- }
- });
- TEquals(200, xhr.status, "too many ranges");
- // cleanup
- db.deleteDb();
-
-};
diff --git a/test/javascript/tests/attachment_views.js b/test/javascript/tests/attachment_views.js
deleted file mode 100644
index c6c4b1841..000000000
--- a/test/javascript/tests/attachment_views.js
+++ /dev/null
@@ -1,145 +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.
-
-couchTests.elixir = true;
-couchTests.attachment_views= function(debug) {
- return console.log('done in test/elixir/test/attachment_views_test.exs');
-
- var db_name = get_random_db_name()
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- // count attachments in a view
-
- var attachmentData = "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ=";
-
- db.bulkSave(makeDocs(0, 10));
-
- db.bulkSave(makeDocs(10, 20, {
- _attachments:{
- "foo.txt": {
- content_type:"text/plain",
- data: attachmentData
- }
- }
- }));
-
- db.bulkSave(makeDocs(20, 30, {
- _attachments:{
- "foo.txt": {
- content_type:"text/plain",
- data: attachmentData
- },
- "bar.txt": {
- content_type:"text/plain",
- data: attachmentData
- }
- }
- }));
-
- db.bulkSave(makeDocs(30, 40, {
- _attachments:{
- "foo.txt": {
- content_type:"text/plain",
- data: attachmentData
- },
- "bar.txt": {
- content_type:"text/plain",
- data: attachmentData
- },
- "baz.txt": {
- content_type:"text/plain",
- data: attachmentData
- }
- }
- }));
-
- var mapFunction = function(doc) {
- var count = 0;
-
- for(var idx in doc._attachments) {
- count = count + 1;
- }
-
- emit(parseInt(doc._id), count);
- };
-
- var reduceFunction = function(key, values) {
- return sum(values);
- };
-
- var result = db.query(mapFunction, reduceFunction);
-
- T(result.rows.length == 1);
- T(result.rows[0].value == 60);
-
- var result = db.query(mapFunction, reduceFunction, {
- startkey:10,
- endkey:19
- });
-
- T(result.rows.length == 1);
- T(result.rows[0].value == 10);
-
- var result = db.query(mapFunction, reduceFunction, {
- startkey:20,
- endkey:29
- });
-
- T(result.rows.length == 1);
- T(result.rows[0].value == 20);
-
- var result = db.query(mapFunction, null, {
- startkey: 30,
- endkey: 39,
- include_docs: true
- });
-
- T(result.rows.length == 10);
- T(result.rows[0].value == 3);
- T(result.rows[0].doc._attachments['baz.txt'].stub === true);
- T(result.rows[0].doc._attachments['baz.txt'].data === undefined);
- T(result.rows[0].doc._attachments['baz.txt'].encoding === undefined);
- T(result.rows[0].doc._attachments['baz.txt'].encoded_length === undefined);
-
- var result = db.query(mapFunction, null, {
- startkey: 30,
- endkey: 39,
- include_docs: true,
- attachments: true
- });
-
- T(result.rows.length == 10);
- T(result.rows[0].value == 3);
- T(result.rows[0].doc._attachments['baz.txt'].data === attachmentData);
- T(result.rows[0].doc._attachments['baz.txt'].stub === undefined);
- T(result.rows[0].doc._attachments['baz.txt'].encoding === undefined);
- T(result.rows[0].doc._attachments['baz.txt'].encoded_length === undefined);
-
- var result = db.query(mapFunction, null, {
- startkey: 30,
- endkey: 39,
- include_docs: true,
- att_encoding_info: true
- });
-
- T(result.rows.length == 10);
- T(result.rows[0].value == 3);
- T(result.rows[0].doc._attachments['baz.txt'].data === undefined);
- T(result.rows[0].doc._attachments['baz.txt'].stub === true);
- T(result.rows[0].doc._attachments['baz.txt'].encoding === "gzip");
- T(result.rows[0].doc._attachments['baz.txt'].encoded_length === 47);
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/attachments.js b/test/javascript/tests/attachments.js
deleted file mode 100644
index 61fe8b9b3..000000000
--- a/test/javascript/tests/attachments.js
+++ /dev/null
@@ -1,358 +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.
-
-couchTests.elixir = true;
-couchTests.attachments= function(debug) {
- return console.log('done in test/elixir/test/attachment_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
-
- // MD5 Digests of compressible attachments and therefore Etags
- // will vary depending on platform gzip implementation.
- // These MIME types are defined in [attachments] compressible_types
- var binAttDoc = {
- _id: "bin_doc",
- _attachments:{
- "foo.txt": {
- content_type:"application/octet-stream",
- data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
- }
- }
- };
-
- var save_response = db.save(binAttDoc);
- T(save_response.ok);
-
- var badAttDoc = {
- _id: "bad_doc",
- _attachments: {
- "foo.txt": {
- content_type: "text/plain",
- data: "notBase64Encoded="
- }
- }
- };
-
- try {
- db.save(badAttDoc);
- T(false && "Shouldn't get here!");
- } catch (e) {
- TEquals("bad_request", e.error);
- TEquals("Invalid attachment data for foo.txt", e.message);
- }
-
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt");
- T(xhr.responseText == "This is a base64 encoded text");
- T(xhr.getResponseHeader("Content-Type") == "application/octet-stream");
- TEquals("\"aEI7pOYCRBLTRQvvqYrrJQ==\"", xhr.getResponseHeader("Etag"));
-
- // empty attachment
- var binAttDoc2 = {
- _id: "bin_doc2",
- _attachments:{
- "foo.txt": {
- content_type:"text/plain",
- data: ""
- }
- }
- }
-
- T(db.save(binAttDoc2).ok);
-
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc2/foo.txt");
- T(xhr.responseText.length == 0);
- T(xhr.getResponseHeader("Content-Type") == "text/plain");
-
- // test RESTful doc API
-
- var xhr = CouchDB.request("PUT", "/" + db_name + "/bin_doc2/foo2.txt?rev=" + binAttDoc2._rev, {
- body:"This is no base64 encoded text",
- headers:{"Content-Type": "text/plain;charset=utf-8"}
- });
- T(xhr.status == 201);
- TEquals("/bin_doc2/foo2.txt",
- xhr.getResponseHeader("Location").substr(-18),
- "should return Location header to newly created or updated attachment");
-
- var rev = JSON.parse(xhr.responseText).rev;
-
- binAttDoc2 = db.open("bin_doc2");
-
- T(binAttDoc2._attachments["foo.txt"] !== undefined);
- T(binAttDoc2._attachments["foo2.txt"] !== undefined);
- TEqualsIgnoreCase("text/plain;charset=utf-8", binAttDoc2._attachments["foo2.txt"].content_type);
- T(binAttDoc2._attachments["foo2.txt"].length == 30);
-
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc2/foo2.txt");
- T(xhr.responseText == "This is no base64 encoded text");
- TEqualsIgnoreCase("text/plain;charset=utf-8", xhr.getResponseHeader("Content-Type"));
-
- // test without rev, should fail
- var xhr = CouchDB.request("DELETE", "/" + db_name + "/bin_doc2/foo2.txt");
- T(xhr.status == 409);
-
- // test with rev, should not fail
- var xhr = CouchDB.request("DELETE", "/" + db_name + "/bin_doc2/foo2.txt?rev=" + rev);
- T(xhr.status == 200);
- TEquals(null, xhr.getResponseHeader("Location"),
- "should not return Location header on DELETE request");
-
- // test binary data
- var bin_data = "JHAPDO*AU£PN ){(3u[d 93DQ9¡€])} ææøo'∂ƒæ≤çæππ•¥∫¶®#†π¶®¥π€ª®˙π8np";
- var xhr = CouchDB.request("PUT", "/" + db_name + "/bin_doc3/attachment.txt", {
- headers:{"Content-Type":"text/plain;charset=utf-8"},
- body:bin_data
- });
- T(xhr.status == 201);
- var rev = JSON.parse(xhr.responseText).rev;
-// TODO: revisit Etags (missing on doc write)
-// TEquals('"' + rev + '"', xhr.getResponseHeader("Etag"));
-
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc3/attachment.txt");
- T(xhr.responseText == bin_data);
- TEqualsIgnoreCase("text/plain;charset=utf-8", xhr.getResponseHeader("Content-Type"));
-
- // without rev
- var xhr = CouchDB.request("PUT", "/" + db_name + "/bin_doc3/attachment.txt", {
- headers:{"Content-Type":"text/plain;charset=utf-8"},
- body:bin_data
- });
- T(xhr.status == 409);
-
- // with nonexistent rev
- var xhr = CouchDB.request("PUT", "/" + db_name + "/bin_doc3/attachment.txt" + "?rev=1-adae8575ecea588919bd08eb020c708e", {
- headers:{"Content-Type":"text/plain;charset=utf-8"},
- body:bin_data
- });
- T(xhr.status == 409);
-
- // with current rev
- var xhr = CouchDB.request("PUT", "/" + db_name + "/bin_doc3/attachment.txt?rev=" + rev, {
- headers:{"Content-Type":"text/plain;charset=utf-8"},
- body:bin_data
- });
- T(xhr.status == 201);
- var rev = JSON.parse(xhr.responseText).rev;
-// TODO: revisit Etags (missing on doc write)
-// TEquals('"' + rev + '"', xhr.getResponseHeader("Etag"));
-
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc3/attachment.txt");
- T(xhr.responseText == bin_data);
- TEqualsIgnoreCase("text/plain;charset=utf-8", xhr.getResponseHeader("Content-Type"));
-
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc3/attachment.txt?rev=" + rev);
- T(xhr.responseText == bin_data);
- TEqualsIgnoreCase("text/plain;charset=utf-8", xhr.getResponseHeader("Content-Type"));
-
- var xhr = CouchDB.request("DELETE", "/" + db_name + "/bin_doc3/attachment.txt?rev=" + rev);
- T(xhr.status == 200);
-
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc3/attachment.txt");
- T(xhr.status == 404);
-
- // deleted attachment is still accessible with revision
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc3/attachment.txt?rev=" + rev);
- T(xhr.status == 200);
- T(xhr.responseText == bin_data);
- TEqualsIgnoreCase("text/plain;charset=utf-8", xhr.getResponseHeader("Content-Type"));
-
- // empty attachments
- var xhr = CouchDB.request("PUT", "/" + db_name + "/bin_doc4/attachment.txt", {
- headers:{"Content-Type":"text/plain;charset=utf-8"},
- body:""
- });
- T(xhr.status == 201);
- var rev = JSON.parse(xhr.responseText).rev;
-
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc4/attachment.txt");
- T(xhr.status == 200);
- T(xhr.responseText.length == 0);
-
- // overwrite previsously empty attachment
- var xhr = CouchDB.request("PUT", "/" + db_name + "/bin_doc4/attachment.txt?rev=" + rev, {
- headers:{"Content-Type":"text/plain;charset=utf-8"},
- body:"This is a string"
- });
- T(xhr.status == 201);
-
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc4/attachment.txt");
- T(xhr.status == 200);
- T(xhr.responseText == "This is a string");
-
- // Attachment sparseness COUCHDB-220
-
- var docs = [];
- for (var i = 0; i < 5; i++) {
- var doc = {
- _id: (i).toString(),
- _attachments:{
- "foo.txt": {
- content_type:"text/plain",
- data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
- }
- }
- };
- docs.push(doc);
- }
-
- var saved = db.bulkSave(docs);
- // now delete the docs, and while we are looping over them, remove the
- // '_rev' field so we can re-create after deletion.
- var to_up = [];
- for (i=0;i<saved.length;i++) {
- to_up.push({'_id': saved[i]['id'], '_rev': saved[i]['rev'], '_deleted': true});
- delete docs[i]._rev;
- }
- // delete them.
- var saved2 = db.bulkSave(to_up);
- // re-create them
- var saved3 = db.bulkSave(docs);
-
- var before = db.info().sizes.file;
-
- // Compact it.
- /*T(db.compact().ok);
- T(db.last_req.status == 202);
- // compaction isn't instantaneous, loop until done
- while (db.info().compact_running) {};
-
- var after = db.info().sizes.file;
-
- // Compaction should reduce the database slightly, but not
- // orders of magnitude (unless attachments introduce sparseness)
- T(after > before * 0.1, "before: " + before + " after: " + after);
-*/
-
- // test large attachments - COUCHDB-366
- var lorem = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. '
- for (var i=0; i<10; i++) {
- lorem = lorem + lorem;
- }
- var xhr = CouchDB.request("PUT", "/" + db_name + "/bin_doc5/lorem.txt", {
- headers:{"Content-Type":"text/plain;charset=utf-8"},
- body:lorem
- });
- T(xhr.status == 201);
- var rev = JSON.parse(xhr.responseText).rev;
-
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc5/lorem.txt");
- T(xhr.responseText == lorem);
- TEqualsIgnoreCase("text/plain;charset=utf-8", xhr.getResponseHeader("Content-Type"));
-
- // test large inline attachment too
- var lorem_b64 = 'TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4g'
- for (var i=0; i<10; i++) {
- lorem_b64 = lorem_b64 + lorem_b64;
- }
- var doc = db.open("bin_doc5", {attachments:true});
- TEquals(lorem_b64, doc._attachments["lorem.txt"].data, 'binary attachment data should match');
-
- // test etags for attachments.
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc5/lorem.txt");
- T(xhr.status == 200);
- var etag = xhr.getResponseHeader("etag");
- xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc5/lorem.txt", {
- headers: {"if-none-match": etag}
- });
- T(xhr.status == 304);
-
- // test COUCHDB-497 - empty attachments
- var xhr = CouchDB.request("PUT", "/" + db_name + "/bin_doc5/empty.txt?rev="+rev, {
- headers:{"Content-Type":"text/plain;charset=utf-8", "Content-Length": "0"},
- body:""
- });
- TEquals(201, xhr.status, "should send 201 Accepted");
- var rev = JSON.parse(xhr.responseText).rev;
- var xhr = CouchDB.request("PUT", "/" + db_name + "/bin_doc5/empty.txt?rev="+rev, {
- headers:{"Content-Type":"text/plain;charset=utf-8"}
- });
- TEquals(201, xhr.status, "should send 201 Accepted");
-
- // implicit doc creation allows creating docs with a reserved id. COUCHDB-565
- var xhr = CouchDB.request("PUT", "/" + db_name + "/_nonexistant/attachment.txt", {
- headers: {"Content-Type":"text/plain;charset=utf-8"},
- body: "THIS IS AN ATTACHMENT. BOOYA!"
- });
- TEquals(400, xhr.status, "should return error code 400 Bad Request");
-
- // test COUCHDB-809 - stubs should only require the 'stub' field
- var bin_doc6 = {
- _id: "bin_doc6",
- _attachments:{
- "foo.txt": {
- content_type:"text/plain",
- data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
- }
- }
- };
- T(db.save(bin_doc6).ok);
- // stub out the attachment
- bin_doc6._attachments["foo.txt"] = { stub: true };
- T(db.save(bin_doc6).ok == true);
-
- // wrong rev pos specified
-
- // stub out the attachment with the wrong revpos
- bin_doc6._attachments["foo.txt"] = { stub: true, revpos: 10};
- try {
- T(db.save(bin_doc6).ok == true);
- T(false && "Shouldn't get here!");
- } catch (e) {
- T(e.error == "missing_stub");
- }
-
- // test MD5 header
- var bin_data = "foo bar"
- var xhr = CouchDB.request("PUT", "/" + db_name + "/bin_doc7/attachment.txt", {
- headers:{"Content-Type":"application/octet-stream",
- "Content-MD5":"MntvB0NYESObxH4VRDUycw=="},
- body:bin_data
- });
- TEquals(201, xhr.status);
-
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc7/attachment.txt");
- TEquals('MntvB0NYESObxH4VRDUycw==', xhr.getResponseHeader("Content-MD5"));
-
- // test attachment via multipart/form-data
- var bin_doc8 = {
- _id: "bin_doc8"
- };
- T(db.save(bin_doc8).ok);
- var doc = db.open("bin_doc8");
- var body = "------TF\r\n" +
- "Content-Disposition: form-data; name=\"_rev\"\r\n\r\n" +
- doc._rev + "\r\n" +
- "------TF\r\n" +
- "Content-Disposition: form-data; name=\"_attachments\"; filename=\"file.txt\"\r\n" +
- "Content-Type: text/plain\r\n\r\n" +
- "contents of file.txt\r\n\r\n" +
- "------TF--"
- xhr = CouchDB.request("POST", "/" + db_name + "/bin_doc8", {
- headers: {
- "Content-Type": "multipart/form-data; boundary=----TF",
- "Content-Length": body.length
- },
- body: body
- });
- TEquals(201, xhr.status);
- TEquals(true, JSON.parse(xhr.responseText).ok);
- var doc = db.open("bin_doc8");
- T(doc._attachments);
- T(doc._attachments['file.txt']);
-
- // cleanup
- db.deleteDb();
-
-};
diff --git a/test/javascript/tests/attachments_multipart.js b/test/javascript/tests/attachments_multipart.js
deleted file mode 100644
index 793c8c9ec..000000000
--- a/test/javascript/tests/attachments_multipart.js
+++ /dev/null
@@ -1,426 +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.
-
-couchTests.elixir = true;
-couchTests.attachments_multipart= function(debug) {
- return console.log('done in test/elixir/test/attachment_multipart_test.exs');
- var db_name = get_random_db_name()
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- // mime multipart
-
- var xhr = CouchDB.request("PUT", "/" + db_name + "/multipart", {
- headers: {"Content-Type": "multipart/related;boundary=\"abc123\""},
- body:
- "--abc123\r\n" +
- "content-type: application/json\r\n" +
- "\r\n" +
- JSON.stringify({
- "body":"This is a body.",
- "_attachments":{
- "foo.txt": {
- "follows":true,
- "content_type":"application/test",
- "length":21
- },
- "bar.txt": {
- "follows":true,
- "content_type":"application/test",
- "length":20
- },
- "baz.txt": {
- "follows":true,
- "content_type":"text/plain",
- "length":19
- }
- }
- }) +
- "\r\n--abc123\r\n" +
- "\r\n" +
- "this is 21 chars long" +
- "\r\n--abc123\r\n" +
- "\r\n" +
- "this is 20 chars lon" +
- "\r\n--abc123\r\n" +
- "\r\n" +
- "this is 19 chars lo" +
- "\r\n--abc123--epilogue"
- });
-
- var result = JSON.parse(xhr.responseText);
-
- T(result.ok);
-
-
-
- TEquals(201, xhr.status, "should send 201 Accepted");
-
- xhr = CouchDB.request("GET", "/" + db_name + "/multipart/foo.txt");
-
- T(xhr.responseText == "this is 21 chars long");
-
- xhr = CouchDB.request("GET", "/" + db_name + "/multipart/bar.txt");
-
- T(xhr.responseText == "this is 20 chars lon");
-
- xhr = CouchDB.request("GET", "/" + db_name + "/multipart/baz.txt");
-
- T(xhr.responseText == "this is 19 chars lo");
-
- // now edit an attachment
-
- var doc = db.open("multipart", {att_encoding_info: true});
- var firstrev = doc._rev;
-
- T(doc._attachments["foo.txt"].stub == true);
- T(doc._attachments["bar.txt"].stub == true);
- T(doc._attachments["baz.txt"].stub == true);
- TEquals("undefined", typeof doc._attachments["foo.txt"].encoding);
- TEquals("undefined", typeof doc._attachments["bar.txt"].encoding);
- TEquals("gzip", doc._attachments["baz.txt"].encoding);
-
- //lets change attachment bar
- delete doc._attachments["bar.txt"].stub; // remove stub member (or could set to false)
- delete doc._attachments["bar.txt"].digest; // remove the digest (it's for the gzip form)
- doc._attachments["bar.txt"].length = 18;
- doc._attachments["bar.txt"].follows = true;
- //lets delete attachment baz:
- delete doc._attachments["baz.txt"];
-
- var xhr = CouchDB.request("PUT", "/" + db_name + "/multipart", {
- headers: {"Content-Type": "multipart/related;boundary=\"abc123\""},
- body:
- "--abc123\r\n" +
- "content-type: application/json\r\n" +
- "\r\n" +
- JSON.stringify(doc) +
- "\r\n--abc123\r\n" +
- "\r\n" +
- "this is 18 chars l" +
- "\r\n--abc123--"
- });
- TEquals(201, xhr.status);
-
- xhr = CouchDB.request("GET", "/" + db_name + "/multipart/bar.txt");
-
- T(xhr.responseText == "this is 18 chars l");
-
- xhr = CouchDB.request("GET", "/" + db_name + "/multipart/baz.txt");
- T(xhr.status == 404);
-
- // now test receiving multipart docs
-
- function getBoundary(xhr) {
- var ctype = CouchDB.xhrheader(xhr, "Content-Type");
- var ctypeArgs = ctype.split("; ").slice(1);
- var boundary = null;
- for(var i=0; i<ctypeArgs.length; i++) {
- if (ctypeArgs[i].indexOf("boundary=") == 0) {
- boundary = ctypeArgs[i].split("=")[1];
- if (boundary.charAt(0) == '"') {
- // stringified boundary, parse as json
- // (will maybe not if there are escape quotes)
- boundary = JSON.parse(boundary);
- }
- }
- }
- return boundary;
- }
-
- function parseMultipart(xhr) {
- var boundary = getBoundary(xhr);
- var mimetext = CouchDB.xhrbody(xhr);
- // strip off leading boundary
- var leading = "--" + boundary + "\r\n";
- var last = "\r\n--" + boundary + "--";
-
- // strip off leading and trailing boundary
- var leadingIdx = mimetext.indexOf(leading) + leading.length;
- var trailingIdx = mimetext.indexOf(last);
- mimetext = mimetext.slice(leadingIdx, trailingIdx);
-
- // now split the sections
- var sections = mimetext.split(new RegExp("\\r\\n--" + boundary));
-
- // spilt out the headers for each section
- for(var i=0; i < sections.length; i++) {
- var section = sections[i];
- var headerEndIdx = section.indexOf("\r\n\r\n");
- var headersraw = section.slice(0, headerEndIdx).split(/\r\n/);
- var body = section.slice(headerEndIdx + 4);
- var headers = {};
- for(var j=0; j<headersraw.length; j++) {
- var tmp = headersraw[j].split(": ");
- headers[tmp[0]] = tmp[1];
- }
- sections[i] = {"headers":headers, "body":body};
- }
-
- return sections;
- }
-
-
- xhr = CouchDB.request("GET", "/" + db_name + "/multipart?attachments=true",
- {headers:{"accept": "multipart/related,*/*;"}});
-
- T(xhr.status == 200);
-
- // parse out the multipart
- var sections = parseMultipart(xhr);
- TEquals("790", xhr.getResponseHeader("Content-Length"),
- "Content-Length should be correct");
- T(sections.length == 3);
- // The first section is the json doc. Check it's content-type.
- // Each part carries their own meta data.
- TEquals("application/json", sections[0].headers['Content-Type'],
- "Content-Type should be application/json for section[0]");
- TEquals("application/test", sections[1].headers['Content-Type'],
- "Content-Type should be application/test for section[1]");
- TEquals("application/test", sections[2].headers['Content-Type'],
- "Content-Type should be application/test for section[2]");
-
- TEquals("21", sections[1].headers['Content-Length'],
- "Content-Length should be 21 section[1]");
- TEquals("18", sections[2].headers['Content-Length'],
- "Content-Length should be 18 section[2]");
-
- TEquals('attachment; filename="foo.txt"', sections[1].headers['Content-Disposition'],
- "Content-Disposition should be foo.txt section[1]");
- TEquals('attachment; filename="bar.txt"', sections[2].headers['Content-Disposition'],
- "Content-Disposition should be bar.txt section[2]");
-
- var doc = JSON.parse(sections[0].body);
-
- T(doc._attachments['foo.txt'].follows == true);
- T(doc._attachments['bar.txt'].follows == true);
-
- T(sections[1].body == "this is 21 chars long");
- TEquals("this is 18 chars l", sections[2].body, "should be 18 chars long");
-
- // now get attachments incrementally (only the attachments changes since
- // a certain rev).
-
- xhr = CouchDB.request("GET", "/" + db_name + "/multipart?atts_since=[\"" + firstrev + "\"]",
- {headers:{"accept": "multipart/related, */*"}});
-
- T(xhr.status == 200);
-
- var sections = parseMultipart(xhr);
-
- T(sections.length == 2);
-
- var doc = JSON.parse(sections[0].body);
-
- T(doc._attachments['foo.txt'].stub == true);
- T(doc._attachments['bar.txt'].follows == true);
-
- TEquals("this is 18 chars l", sections[1].body, "should be 18 chars long 2");
-
- // try the atts_since parameter together with the open_revs parameter
- xhr = CouchDB.request(
- "GET",
- "/" + db_name + "/multipart?open_revs=[" +
- '"' + doc._rev + '"]&atts_since=["' + firstrev + '"]',
- {headers: {"accept": "multipart/mixed"}}
- );
-
- T(xhr.status === 200);
-
- sections = parseMultipart(xhr);
- // 1 section, with a multipart/related Content-Type
- T(sections.length === 1);
- T(sections[0].headers['Content-Type'].indexOf('multipart/related;') === 0);
-
- var innerSections = parseMultipart(sections[0]);
- // 2 inner sections: a document body section plus an attachment data section
-// TODO: why does atts_since not work?
-// T(innerSections.length === 2);
- T(innerSections.length === 3);
- T(innerSections[0].headers['Content-Type'] === 'application/json');
-
- doc = JSON.parse(innerSections[0].body);
-
-// TODO: why does atts_since not work?
-// T(doc._attachments['foo.txt'].stub === true);
- T(doc._attachments['foo.txt'].follows === true);
- T(doc._attachments['bar.txt'].follows === true);
-
-// TODO: why does atts_since not work?
- T(innerSections[1].body === "this is 21 chars long");
- T(innerSections[2].body === "this is 18 chars l");
-
- // try it with a rev that doesn't exist (should get all attachments)
-
- xhr = CouchDB.request("GET", "/" + db_name + "/multipart?atts_since=[\"1-2897589\"]",
- {headers:{"accept": "multipart/related,*/*;"}});
-
- T(xhr.status == 200);
-
- var sections = parseMultipart(xhr);
-
- T(sections.length == 3);
-
- var doc = JSON.parse(sections[0].body);
-
- T(doc._attachments['foo.txt'].follows == true);
- T(doc._attachments['bar.txt'].follows == true);
-
- T(sections[1].body == "this is 21 chars long");
- TEquals("this is 18 chars l", sections[2].body, "should be 18 chars long 3");
- // try it with a rev that doesn't exist, and one that does
-
- xhr = CouchDB.request("GET", "/" + db_name + "/multipart?atts_since=[\"1-2897589\",\"" + firstrev + "\"]",
- {headers:{"accept": "multipart/related,*/*;"}});
-
- T(xhr.status == 200);
-
- var sections = parseMultipart(xhr);
-
- T(sections.length == 2);
-
- var doc = JSON.parse(sections[0].body);
-
- T(doc._attachments['foo.txt'].stub == true);
- T(doc._attachments['bar.txt'].follows == true);
-
- TEquals("this is 18 chars l", sections[1].body, "should be 18 chars long 4");
-
- // check that with the document multipart/mixed API it's possible to receive
- // attachments in compressed form (if they're stored in compressed form)
-
- var server_config = [
- {
- section: "attachments",
- key: "compression_level",
- value: "8"
- },
- {
- section: "attachments",
- key: "compressible_types",
- value: "text/plain"
- }
- ];
-
- function testMultipartAttCompression() {
- var doc = { _id: "foobar" };
- var lorem =
- CouchDB.request("GET", "/_utils/script/test/lorem.txt").responseText;
- var helloData = "hello world";
-
- TEquals(true, db.save(doc).ok);
-
- var firstRev = doc._rev;
- var xhr = CouchDB.request(
- "PUT",
- "/" + db.name + "/" + doc._id + "/data.bin?rev=" + firstRev,
- {
- body: helloData,
- headers: {"Content-Type": "application/binary"}
- }
- );
- TEquals(201, xhr.status);
-
- var secondRev = db.open(doc._id)._rev;
- xhr = CouchDB.request(
- "PUT",
- "/" + db.name + "/" + doc._id + "/lorem.txt?rev=" + secondRev,
- {
- body: lorem,
- headers: {"Content-Type": "text/plain"}
- }
- );
- TEquals(201, xhr.status);
-
- var thirdRev = db.open(doc._id)._rev;
-
- xhr = CouchDB.request(
- "GET",
- '/' + db.name + '/' + doc._id + '?open_revs=["' + thirdRev + '"]',
- {
- headers: {
- "Accept": "multipart/mixed",
- "X-CouchDB-Send-Encoded-Atts": "true"
- }
- }
- );
- TEquals(200, xhr.status);
-
- var sections = parseMultipart(xhr);
- // 1 section, with a multipart/related Content-Type
- TEquals(1, sections.length);
- TEquals(0,
- sections[0].headers['Content-Type'].indexOf('multipart/related;'));
-
- var innerSections = parseMultipart(sections[0]);
- // 3 inner sections: a document body section plus 2 attachment data sections
- TEquals(3, innerSections.length);
- TEquals('application/json', innerSections[0].headers['Content-Type']);
-
- doc = JSON.parse(innerSections[0].body);
-
- TEquals(true, doc._attachments['lorem.txt'].follows);
- TEquals("gzip", doc._attachments['lorem.txt'].encoding);
- TEquals(true, doc._attachments['data.bin'].follows);
- T(doc._attachments['data.bin'] !== "gzip");
-
- if (innerSections[1].body === helloData) {
- T(innerSections[2].body !== lorem);
- } else if (innerSections[2].body === helloData) {
- T(innerSections[1].body !== lorem);
- } else {
- T(false, "Could not found data.bin attachment data");
- }
-
- // now test that it works together with the atts_since parameter
-
- xhr = CouchDB.request(
- "GET",
- '/' + db.name + '/' + doc._id + '?open_revs=["' + thirdRev + '"]' +
- '&atts_since=["' + secondRev + '"]',
- {
- headers: {
- "Accept": "multipart/mixed",
- "X-CouchDB-Send-Encoded-Atts": "true"
- }
- }
- );
- TEquals(200, xhr.status);
-
- sections = parseMultipart(xhr);
- // 1 section, with a multipart/related Content-Type
- TEquals(1, sections.length);
- TEquals(0,
- sections[0].headers['Content-Type'].indexOf('multipart/related;'));
-
- innerSections = parseMultipart(sections[0]);
- // 2 inner sections: a document body section plus 1 attachment data section
-// TODO: why does atts_since not work?
-// TEquals(2, innerSections.length);
- TEquals('application/json', innerSections[0].headers['Content-Type']);
-
- doc = JSON.parse(innerSections[0].body);
-
- TEquals(true, doc._attachments['lorem.txt'].follows);
- TEquals("gzip", doc._attachments['lorem.txt'].encoding);
-// TODO: why does atts_since not work?
-// TEquals("undefined", typeof doc._attachments['data.bin'].follows);
-// TEquals(true, doc._attachments['data.bin'].stub);
- T(innerSections[1].body !== lorem);
- }
-
- run_on_modified_server(server_config, testMultipartAttCompression);
-
-// // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/auth_cache.js b/test/javascript/tests/auth_cache.js
deleted file mode 100644
index 73fec3532..000000000
--- a/test/javascript/tests/auth_cache.js
+++ /dev/null
@@ -1,274 +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.
-
-couchTests.elixir = true;
-couchTests.auth_cache = function(debug) {
- if (debug) debugger;
-
- // Simple secret key generator
- function generateSecret(length) {
- var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" +
- "0123456789+/";
- var secret = '';
- for (var i = 0; i < length; i++) {
- secret += tab.charAt(Math.floor(Math.random() * 64));
- }
- return secret;
- }
-
- var db_name = get_random_db_name();
- var authDb = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}, {w: 3});
- authDb.createDb();
- var server_config = [
- {
- section: "chttpd_auth",
- key: "authentication_db",
- value: authDb.name
- },
- {
- section: "chttpd_auth",
- key: "auth_cache_size",
- value: "3"
- },
- {
- section: "httpd",
- key: "authentication_handlers",
- value: "{couch_httpd_auth, default_authentication_handler}"
- },
- {
- section: "chttpd_auth",
- key: "secret",
- value: generateSecret(64)
- }
- ];
-
-
- function hits() {
- var hits = CouchDB.requestStats(["couchdb", "auth_cache_hits"], true);
- return hits.value || 0;
- }
-
-
- function misses() {
- var misses = CouchDB.requestStats(["couchdb", "auth_cache_misses"], true);
- return misses.value || 0;
- }
-
-
- function testFun() {
- var hits_before,
- misses_before,
- hits_after,
- misses_after;
-
- var fdmanana = CouchDB.prepareUserDoc({
- name: "fdmanana",
- roles: ["dev"]
- }, "qwerty");
-
- T(authDb.save(fdmanana).ok);
-
- var chris = CouchDB.prepareUserDoc({
- name: "chris",
- roles: ["dev", "mafia", "white_costume"]
- }, "the_god_father");
-
- T(authDb.save(chris).ok);
-
- var joe = CouchDB.prepareUserDoc({
- name: "joe",
- roles: ["erlnager"]
- }, "functional");
-
- T(authDb.save(joe).ok);
-
- var johndoe = CouchDB.prepareUserDoc({
- name: "johndoe",
- roles: ["user"]
- }, "123456");
-
- T(authDb.save(johndoe).ok);
-
- hits_before = hits();
- misses_before = misses();
-
- T(CouchDB.login("fdmanana", "qwerty").ok);
- T(CouchDB.logout().ok);
-
- hits_after = hits();
- misses_after = misses();
-
- T(misses_after === (misses_before + 1));
- // XXX BUGGED T(hits_after === hits_before);
-
- hits_before = hits_after;
- misses_before = misses_after;
-
- T(CouchDB.login("fdmanana", "qwerty").ok);
- T(CouchDB.logout().ok);
-
- hits_after = hits();
- misses_after = misses();
-
- T(misses_after === misses_before);
- // XXX BUGGED T(hits_after === (hits_before + 1));
-
- hits_before = hits_after;
- misses_before = misses_after;
-
- T(CouchDB.login("chris", "the_god_father").ok);
- T(CouchDB.logout().ok);
-
- hits_after = hits();
- misses_after = misses();
-
- T(misses_after === (misses_before + 1));
- // XXX BUGGED T(hits_after === hits_before);
-
- hits_before = hits_after;
- misses_before = misses_after;
-
- T(CouchDB.login("joe", "functional").ok);
- T(CouchDB.logout().ok);
-
- hits_after = hits();
- misses_after = misses();
-
- T(misses_after === (misses_before + 1));
- // XXX BUGGED T(hits_after === hits_before);
-
- hits_before = hits_after;
- misses_before = misses_after;
-
- T(CouchDB.login("johndoe", "123456").ok);
- T(CouchDB.logout().ok);
-
- hits_after = hits();
- misses_after = misses();
-
- T(misses_after === (misses_before + 1));
- // XXX BUGGED T(hits_after === hits_before);
-
- hits_before = hits_after;
- misses_before = misses_after;
-
- T(CouchDB.login("joe", "functional").ok);
- T(CouchDB.logout().ok);
-
- hits_after = hits();
- misses_after = misses();
-
- // it's an MRU cache, joe was removed from cache to add johndoe
- // XXX BUGGED T(misses_after === (misses_before + 1));
- // XXX BUGGED T(hits_after === hits_before);
-
- hits_before = hits_after;
- misses_before = misses_after;
-
- T(CouchDB.login("fdmanana", "qwerty").ok);
- T(CouchDB.logout().ok);
-
- hits_after = hits();
- misses_after = misses();
-
- T(misses_after === misses_before);
- // XXX BUGGED T(hits_after === (hits_before + 1));
-
- hits_before = hits_after;
- misses_before = misses_after;
-
- fdmanana.password = "foobar";
- T(authDb.save(fdmanana).ok);
-
- // cache was refreshed
-/* // XXX BUGGED
- T(CouchDB.login("fdmanana", "qwerty").error === "unauthorized");
- T(CouchDB.login("fdmanana", "foobar").ok);
- T(CouchDB.logout().ok);
-*/
-
- hits_after = hits();
- misses_after = misses();
-
- T(misses_after === misses_before);
- // XXX BUGGED T(hits_after === (hits_before + 2));
-
- hits_before = hits_after;
- misses_before = misses_after;
-
- // and yet another update
- fdmanana.password = "javascript";
- T(authDb.save(fdmanana).ok);
-
- // cache was refreshed
-/* // XXX BUGGED
- T(CouchDB.login("fdmanana", "foobar").error === "unauthorized");
- T(CouchDB.login("fdmanana", "javascript").ok);
- T(CouchDB.logout().ok);
-*/
-
- hits_after = hits();
- misses_after = misses();
-
- T(misses_after === misses_before);
- // XXX BUGGED T(hits_after === (hits_before + 2));
-
- T(authDb.deleteDoc(fdmanana).ok);
-
- hits_before = hits_after;
- misses_before = misses_after;
-
- T(CouchDB.login("fdmanana", "javascript").error === "unauthorized");
-
- hits_after = hits();
- misses_after = misses();
-
- T(misses_after === misses_before);
- T(hits_after === (hits_before + 1));
-
- // login, compact authentication DB, login again and verify that
- // there was a cache hit
- hits_before = hits_after;
- misses_before = misses_after;
-
- T(CouchDB.login("johndoe", "123456").ok);
- T(CouchDB.logout().ok);
-
- hits_after = hits();
- misses_after = misses();
-
- // XXX BUGGED T(misses_after === (misses_before + 1));
- // XXX BUGGED T(hits_after === hits_before);
-
- T(authDb.compact().ok);
-
- while (authDb.info().compact_running);
-
- hits_before = hits_after;
- misses_before = misses_after;
-
- T(CouchDB.login("johndoe", "123456").ok);
- T(CouchDB.logout().ok);
-
- hits_after = hits();
- misses_after = misses();
-
- // XXX BUGGED T(misses_after === misses_before);
- // XXX BUGGED T(hits_after === (hits_before + 1));
- }
-
-
- run_on_modified_server(server_config, testFun);
-
- // cleanup
- authDb.deleteDb();
-}
diff --git a/test/javascript/tests/basics.js b/test/javascript/tests/basics.js
deleted file mode 100644
index 51abb4090..000000000
--- a/test/javascript/tests/basics.js
+++ /dev/null
@@ -1,302 +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.
-
-// Do some basic tests.
-couchTests.elixir = true;
-couchTests.basics = function(debug) {
- return console.log('done in test/elixir/test/basics_test.exs');
- if (debug) debugger;
-
- var result = JSON.parse(CouchDB.request("GET", "/").responseText);
- T(result.couchdb == "Welcome");
-
- var db_name = get_random_db_name()
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
-
- //TODO bug COUCHDB-100: DELETE on non-existent DB returns 500 instead of 404
- //TODO db.deleteDb();
-
- db.createDb();
-
- // PUT on existing DB should return 412 instead of 500
- xhr = CouchDB.request("PUT", "/" + db_name + "/");
- T(xhr.status == 412);
-
- // creating a new DB should return Location header
- // and it should work for dbs with slashes (COUCHDB-411)
- var db_name2 = get_random_db_name();
- var dbnames = [db_name2, db_name2 + "%2Fwith_slashes"];
- dbnames.forEach(function(dbname) {
- xhr = CouchDB.request("DELETE", "/" + dbname);
- xhr = CouchDB.request("PUT", "/" + dbname);
- TEquals(dbname,
- xhr.getResponseHeader("Location").substr(-dbname.length),
- "should return Location header to newly created document");
- TEquals(CouchDB.protocol,
- xhr.getResponseHeader("Location").substr(0, CouchDB.protocol.length),
- "should return absolute Location header to newly created document");
- CouchDB.request("DELETE", "/" + dbname);
- });
-
- // Get the database info, check the db_name
- TEquals(db.info().db_name, db_name, "get correct database name");
- T(CouchDB.allDbs().indexOf("" + db_name + "") != -1);
-
- // Get the database info, check the doc_count
- T(db.info().doc_count == 0);
-
- // create a document and save it to the database
- var doc = {_id:"0",a:1,b:1};
- var result = db.save(doc);
-
- T(result.ok==true); // return object has an ok member with a value true
- T(result.id); // the _id of the document is set.
- T(result.rev); // the revision id of the document is set.
-
- // Verify the input doc is now set with the doc id and rev
- // (for caller convenience).
- T(doc._id == result.id && doc._rev == result.rev);
-
- var id = result.id; // save off the id for later
-
- // make sure the revs_info status is good
- var doc = db.open(id, {revs_info:true});
- T(doc._revs_info[0].status == "available");
-
- // make sure you can do a seq=true option
- var doc = db.open(id, {local_seq:true});
- T(doc._local_seq == 1);
-
-
- // Create some more documents.
- // Notice the use of the ok member on the return result.
- T(db.save({_id:"1",a:2,b:4}).ok);
- T(db.save({_id:"2",a:3,b:9}).ok);
- T(db.save({_id:"3",a:4,b:16}).ok);
-
- // with n=3 and w=r=2, it SHOULD be reliable in clusters - execute often 2 see...
-
- // Check the database doc count
- T(db.info().doc_count == 4);
-
- // COUCHDB-954
- var oldRev = db.save({_id:"COUCHDB-954", a:1}).rev;
- var newRev = db.save({_id:"COUCHDB-954", _rev:oldRev}).rev;
-
- // test behavior of open_revs with explicit revision list
- var result = db.open("COUCHDB-954", {open_revs:[oldRev,newRev]});
- T(result.length == 2, "should get two revisions back");
- T(result[0].ok);
- T(result[1].ok);
-
- // latest=true suppresses non-leaf revisions
-// TODO: does no more work on cluster - function_clause error fabric_doc_open_revs:handle_message/3
-// var result = db.open("COUCHDB-954", {open_revs:[oldRev,newRev], latest:true});
-// T(result.length == 1, "should only get the child revision with latest=true");
-// T(result[0].ok._rev == newRev, "should get the child and not the parent");
-
- // latest=true returns a child when you ask for a parent
- var result = db.open("COUCHDB-954", {open_revs:[oldRev], latest:true});
- T(result[0].ok._rev == newRev, "should get child when we requested parent");
-
- // clean up after ourselves
- db.save({_id:"COUCHDB-954", _rev:newRev, _deleted:true});
-
- // Test a simple map functions
-
- // create a map function that selects all documents whose "a" member
- // has a value of 4, and then returns the document's b value.
- var mapFunction = function(doc){
- if (doc.a==4)
- emit(null, doc.b);
- };
-
- var results = db.query(mapFunction);
-
- // verify only one document found and the result value (doc.b).
- T(results.total_rows == 1 && results.rows[0].value == 16);
-
- // reopen document we saved earlier
- var existingDoc = db.open(id);
-
- T(existingDoc.a==1);
-
- //modify and save
- existingDoc.a=4;
- db.save(existingDoc);
-
- // redo the map query
- results = db.query(mapFunction);
-
- // the modified document should now be in the results.
- T(results.total_rows == 2);
-
- // write 2 more documents
- T(db.save({a:3,b:9}).ok);
- T(db.save({a:4,b:16}).ok);
-
- results = db.query(mapFunction);
-
- // 1 more document should now be in the result.
- T(results.total_rows == 3);
- TEquals(6, db.info().doc_count, 'number of docs in db');
-
- var reduceFunction = function(keys, values){
- return sum(values);
- };
-
- results = db.query(mapFunction, reduceFunction);
-
- T(results.rows[0].value == 33);
-
- // delete a document
- T(db.deleteDoc(existingDoc).ok);
-
- // make sure we can't open the doc
- T(db.open(existingDoc._id) == null);
-
- results = db.query(mapFunction);
-
- // 1 less document should now be in the results.
- T(results.total_rows == 2);
- T(db.info().doc_count == (5));
-
- // make sure we can still open the old rev of the deleted doc
- T(db.open(existingDoc._id, {rev: existingDoc._rev}) != null);
- // make sure restart works
-// TODO: investigate why it won't work
-// T(db.ensureFullCommit().ok);
-// restartServer();
-
- // make sure we can still open
- T(db.open(existingDoc._id, {rev: existingDoc._rev}) != null);
-
- // test that the POST response has a Location header
- var xhr = CouchDB.request("POST", "/" + db_name + "", {
- body: JSON.stringify({"foo":"bar"}),
- headers: {"Content-Type": "application/json"}
- });
- var resp = JSON.parse(xhr.responseText);
- T(resp.ok);
- var loc = xhr.getResponseHeader("Location");
- T(loc, "should have a Location header");
- var locs = loc.split('/');
- T(locs[locs.length-1] == resp.id);
- T(locs[locs.length-2] == "" + db_name + "");
-
- // test that that POST's with an _id aren't overriden with a UUID.
- var xhr = CouchDB.request("POST", "/" + db_name + "", {
- headers: {"Content-Type": "application/json"},
- body: JSON.stringify({"_id": "oppossum", "yar": "matey"})
- });
- var resp = JSON.parse(xhr.responseText);
- T(resp.ok);
- T(resp.id == "oppossum");
- var doc = db.open("oppossum");
- T(doc.yar == "matey");
-
- // document put's should return a Location header
- var xhr = CouchDB.request("PUT", "/" + db_name + "/newdoc", {
- body: JSON.stringify({"a":1})
- });
- TEquals("/" + db_name + "/newdoc",
- xhr.getResponseHeader("Location").substr(-(db_name.length + 1 + 7)),
- "should return Location header to newly created document");
- TEquals(CouchDB.protocol,
- xhr.getResponseHeader("Location").substr(0, CouchDB.protocol.length),
- "should return absolute Location header to newly created document");
-
- // deleting a non-existent doc should be 404
- xhr = CouchDB.request("DELETE", "/" + db_name + "/doc-does-not-exist");
- T(xhr.status == 404);
-
- // Check for invalid document members
- var bad_docs = [
- ["goldfish", {"_zing": 4}],
- ["zebrafish", {"_zoom": "hello"}],
- ["mudfish", {"zane": "goldfish", "_fan": "something smells delicious"}],
- ["tastyfish", {"_bing": {"wha?": "soda can"}}]
- ];
- var test_doc = function(info) {
- var data = JSON.stringify(info[1]);
- xhr = CouchDB.request("PUT", "/" + db_name + "/" + info[0], {body: data});
- T(xhr.status == 400);
- result = JSON.parse(xhr.responseText);
- T(result.error == "doc_validation");
-
- xhr = CouchDB.request("POST", "/" + db_name + "/", {
- headers: {"Content-Type": "application/json"},
- body: data
- });
- T(xhr.status == 400);
- result = JSON.parse(xhr.responseText);
- T(result.error == "doc_validation");
- };
- bad_docs.forEach(test_doc);
-
- // Check some common error responses.
- // PUT body not an object
- xhr = CouchDB.request("PUT", "/" + db_name + "/bar", {body: "[]"});
- T(xhr.status == 400);
- result = JSON.parse(xhr.responseText);
- T(result.error == "bad_request");
- T(result.reason == "Document must be a JSON object");
-
- // Body of a _bulk_docs is not an object
- xhr = CouchDB.request("POST", "/" + db_name + "/_bulk_docs", {body: "[]"});
- T(xhr.status == 400);
- result = JSON.parse(xhr.responseText);
- T(result.error == "bad_request");
- T(result.reason == "Request body must be a JSON object");
-
- // Body of an _all_docs multi-get is not a {"key": [...]} structure.
- xhr = CouchDB.request("POST", "/" + db_name + "/_all_docs", {body: "[]"});
- T(xhr.status == 400);
- result = JSON.parse(xhr.responseText);
- T(result.error == "bad_request");
- T(result.reason == "Request body must be a JSON object");
- var data = "{\"keys\": 1}";
- xhr = CouchDB.request("POST", "/" + db_name + "/_all_docs", {body:data});
- T(xhr.status == 400);
- result = JSON.parse(xhr.responseText);
- T(result.error == "bad_request");
- T(result.reason == "`keys` body member must be an array.");
-
- // oops, the doc id got lost in code nirwana
- xhr = CouchDB.request("DELETE", "/" + db_name + "/?rev=foobarbaz");
- TEquals(400, xhr.status, "should return a bad request");
- result = JSON.parse(xhr.responseText);
- TEquals("bad_request", result.error);
- TEquals("You tried to DELETE a database with a ?=rev parameter. Did you mean to DELETE a document instead?", result.reason);
-
- // On restart, a request for creating a database that already exists can
- // not override the existing database file
- // TODO
- // db = new CouchDB(db_name);
- // xhr = CouchDB.request("PUT", "/" + db.name);
- // TEquals(201, xhr.status);
- //
- // TEquals(true, db.save({"_id": "doc1"}).ok);
- // TEquals(true, db.ensureFullCommit().ok);
- //
- // TEquals(1, db.info().doc_count);
- //
- // restartServer();
- //
- // xhr = CouchDB.request("PUT", "/" + db.name);
- // TEquals(412, xhr.status);
- //
- // TEquals(1, db.info().doc_count);
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/batch_save.js b/test/javascript/tests/batch_save.js
deleted file mode 100644
index bbfb2ed9c..000000000
--- a/test/javascript/tests/batch_save.js
+++ /dev/null
@@ -1,52 +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.
-
-couchTests.elixir = true;
-couchTests.batch_save = function(debug) {
- return console.log('done in test/elixir/test/batch_save_test.exs');
- var db_name = get_random_db_name()
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var i
- for(i=0; i < 100; i++) {
- T(db.save({_id:i.toString(),a:i,b:i}, {batch : "ok"}).ok);
-
- // test that response is 202 Accepted
- T(db.last_req.status == 202);
- }
-
- for(i=0; i < 100; i++) {
- // attempt to save the same document a bunch of times
- T(db.save({_id:"foo",a:i,b:i}, {batch : "ok"}).ok);
-
- // test that response is 202 Accepted
- T(db.last_req.status == 202);
- }
-
- while(db.allDocs().total_rows != 101){};
-
- // repeat the tests for POST
- for(i=0; i < 100; i++) {
- var resp = db.request("POST", db.uri + "?batch=ok", {
- headers: {"Content-Type": "application/json"},
- body: JSON.stringify({a:1})
- });
- T(JSON.parse(resp.responseText).ok);
- }
-
- while(db.allDocs().total_rows != 201){};
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/bulk_docs.js b/test/javascript/tests/bulk_docs.js
deleted file mode 100644
index 767a54367..000000000
--- a/test/javascript/tests/bulk_docs.js
+++ /dev/null
@@ -1,153 +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.
-
-couchTests.elixir = true;
-couchTests.bulk_docs = function(debug) {
- return console.log('done in test/elixir/test/basics_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var docs = makeDocs(5);
-
- // Create the docs
- var results = db.bulkSave(docs);
-
- T(results.length == 5);
- for (var i = 0; i < 5; i++) {
- T(results[i].id == docs[i]._id);
- T(results[i].rev);
- // Update the doc
- docs[i].string = docs[i].string + ".00";
- }
-
- // Save the docs
- results = db.bulkSave(docs);
- T(results.length == 5);
- for (i = 0; i < 5; i++) {
- T(results[i].id == i.toString());
-
- // set the delete flag to delete the docs in the next step
- docs[i]._deleted = true;
- }
-
- // now test a bulk update with a conflict
- // open and save
- var doc = db.open("0");
- db.save(doc);
-
- // Now bulk delete the docs
- results = db.bulkSave(docs);
-
- // doc "0" should be a conflict
- T(results.length == 5);
- T(results[0].id == "0");
- T(results[0].error == "conflict");
- T(typeof results[0].rev === "undefined"); // no rev member when a conflict
-
- // but the rest are not
- for (i = 1; i < 5; i++) {
- T(results[i].id == i.toString());
- T(results[i].rev);
- T(db.open(docs[i]._id) == null);
- }
-
- // now force a conflict to to save
-
- // save doc 0, this will cause a conflict when we save docs[0]
- var doc = db.open("0");
- docs[0] = db.open("0");
- db.save(doc);
-
- docs[0].shooby = "dooby";
-
- // Now save the bulk docs, When we use all_or_nothing, we don't get conflict
- // checking, all docs are saved regardless of conflict status, or none are
- // saved.
-// TODO: all_or_nothing is not yet supported on clusters
-// results = db.bulkSave(docs,{all_or_nothing:true});
-// T(results.error === undefined);
-//
-// var doc = db.open("0", {conflicts:true});
-// var docConflict = db.open("0", {rev:doc._conflicts[0]});
-//
-// T(doc.shooby == "dooby" || docConflict.shooby == "dooby");
-
- // verify creating a document with no id returns a new id
- var req = CouchDB.request("POST", "/" + db_name + "/_bulk_docs", {
- body: JSON.stringify({"docs": [{"foo":"bar"}]})
- });
- results = JSON.parse(req.responseText);
-
- T(results[0].id != "");
- T(results[0].rev != "");
-
-
- // Regression test for failure on update/delete
- var newdoc = {"_id": "foobar", "body": "baz"};
- T(db.save(newdoc).ok);
- var update = {"_id": newdoc._id, "_rev": newdoc._rev, "body": "blam"};
- var torem = {"_id": newdoc._id, "_rev": newdoc._rev, "_deleted": true};
- results = db.bulkSave([update, torem]);
- T(results[0].error == "conflict" || results[1].error == "conflict");
-
-
- // verify that sending a request with no docs causes error thrown
- var req = CouchDB.request("POST", "/" + db_name + "/_bulk_docs", {
- body: JSON.stringify({"doc": [{"foo":"bar"}]})
- });
-
- T(req.status == 400 );
- result = JSON.parse(req.responseText);
- T(result.error == "bad_request");
- T(result.reason == "POST body must include `docs` parameter.");
-
- // verify that sending a request with invalid `docs` causes error
- var req = CouchDB.request("POST", "/" + db_name + "/_bulk_docs", {
- body: JSON.stringify({"docs": "foo"})
- });
-
- T(req.status == 400);
- result = JSON.parse(req.responseText);
- T(result.error == "bad_request");
- T(result.reason == "`docs` parameter must be an array.");
-
- // verify that sending a request with invalid `new_edits` causes error
- var req = CouchDB.request("POST", "/" + db_name + "/_bulk_docs", {
- body: JSON.stringify({"docs": [], "new_edits": 0})
- });
-
- T(req.status == 400);
- result = JSON.parse(req.responseText);
- T(result.error == "bad_request");
- T(result.reason == "`new_edits` parameter must be a boolean.");
-
- // jira-911
- db.deleteDb();
- // avoid Heisenbugs w/ files remaining - create a new name
- db_name = get_random_db_name();
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- docs = [];
- docs.push({"_id":"0", "a" : 0});
- docs.push({"_id":"1", "a" : 1});
- docs.push({"_id":"1", "a" : 2});
- docs.push({"_id":"3", "a" : 3});
- results = db.bulkSave(docs);
- T(results[1].id == "1");
- T(results[1].error == undefined);
- T(results[2].error == "conflict");
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/changes.js b/test/javascript/tests/changes.js
deleted file mode 100644
index 338c1571c..000000000
--- a/test/javascript/tests/changes.js
+++ /dev/null
@@ -1,812 +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.
-couchTests.elixir = true;
-
-function jsonp(obj) {
- T(jsonp_flag == 0);
- T(obj.results.length == 1 && obj.last_seq == 1, "jsonp");
- jsonp_flag = 1;
-}
-
-couchTests.changes = function(debug) {
- return console.log('done in test/elixir/test/changes_test.exs and changes_async_test.exs');
-
- var db;
- if (debug) debugger;
-
- // poor man's browser detection
- var is_safari = false;
- if (typeof (navigator) == "undefined") {
- is_safari = true; // For CouchHTTP based runners
- } else if (navigator.userAgent.match(/AppleWebKit/)) {
- is_safari = true;
- }
-
- testChanges("live");
- testChanges("continuous");
- function testChanges(feed) {
- var db_name = get_random_db_name();
- // (write-quorums help keep a consistent feed)
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"true"}, {"w": 3});
- db.createDb();
-
- var req = CouchDB.request("GET", "/" + db_name + "/_changes");
- var resp = JSON.parse(req.responseText);
-
- TEquals(0, resp.results.length, "db must be empty")
- TEquals("0", resp.last_seq.substr(0, 1), "seq must start with 0")
- var docFoo = {_id:"foo", bar:1};
- T(db.save(docFoo).ok);
- T(db.ensureFullCommit().ok);
- T(db.open(docFoo._id)._id == docFoo._id);
-
- retry_part(function(){ // avoid Heisenbugs
- req = CouchDB.request("GET", "/" + db_name + "/_changes");
- var resp = JSON.parse(req.responseText);
- TEquals("1", resp.last_seq.substr(0, 1), "seq must start with 1");
- T(resp.results.length == 1, "one doc db");
- T(resp.results[0].changes[0].rev == docFoo._rev);
- });
-
- // test with callback
-// TODO: either allow jsonp in the default global config or implement a config chg mechanism analogouts 2 sebastianrothbucher:clustertest - or leave out
-// run_on_modified_server(
-// [{section: "httpd",
-// key: "allow_jsonp",
-// value: "true"}],
-// function() {
-// var xhr = CouchDB.request("GET", "/" + db_name + "/_changes?callback=jsonp");
-// T(xhr.status == 200);
-// jsonp_flag = 0;
-// eval(xhr.responseText);
-// T(jsonp_flag == 1);
-// });
-
- // increase timeout to 100 to have enough time 2 assemble (seems like too little timeouts kill
- req = CouchDB.request("GET", "/" + db_name + "/_changes?feed=" + feed + "&timeout=100");
- var lines = req.responseText.split("\n");
- T(JSON.parse(lines[0]).changes[0].rev == docFoo._rev);
- // the sequence is not fully ordered and a complex structure now
- T(JSON.parse(lines[1]).last_seq[0] == 1);
-
- var xhr;
-
- try {
- xhr = CouchDB.newXhr();
- } catch (err) {
- }
-
- // these will NEVER run as we're always in navigator == undefined
- if (!is_safari && xhr) {
- // Only test the continuous stuff if we have a real XHR object
- // with real async support.
-
- // WebKit (last checked on nightly #47686) does fail on processing
- // the async-request properly while javascript is executed.
-
- xhr.open("GET", CouchDB.proxyUrl("/" + db_name + "/_changes?feed=" + feed + "&timeout=500"), true);
- xhr.send("");
-
- var docBar = {_id:"bar", bar:1};
- db.save(docBar);
-
- var lines, change1, change2;
- waitForSuccess(function() {
- lines = xhr.responseText.split("\n");
- change1 = JSON.parse(lines[0]);
- change2 = JSON.parse(lines[1]);
- if (change2.seq != 2) {
- throw "bad seq, try again";
- }
- return true;
- }, "bar-only");
-
- T(change1.seq == 1);
- T(change1.id == "foo");
-
- T(change2.seq == 2);
- T(change2.id == "bar");
- T(change2.changes[0].rev == docBar._rev);
-
-
- var docBaz = {_id:"baz", baz:1};
- db.save(docBaz);
-
- var change3;
- waitForSuccess(function() {
- lines = xhr.responseText.split("\n");
- change3 = JSON.parse(lines[2]);
- if (change3.seq != 3) {
- throw "bad seq, try again";
- }
- return true;
- });
-
- T(change3.seq == 3);
- T(change3.id == "baz");
- T(change3.changes[0].rev == docBaz._rev);
-
-
- xhr = CouchDB.newXhr();
-
- //verify the heartbeat newlines are sent
- xhr.open("GET", CouchDB.proxyUrl("/" + db_name + "/_changes?feed=" + feed + "&heartbeat=10&timeout=500"), true);
- xhr.send("");
-
- var str;
- waitForSuccess(function() {
- str = xhr.responseText;
- if (str.charAt(str.length - 1) != "\n" || str.charAt(str.length - 2) != "\n") {
- throw("keep waiting");
- }
- return true;
- }, "heartbeat");
-
- T(str.charAt(str.length - 1) == "\n");
- T(str.charAt(str.length - 2) == "\n");
-
- // otherwise we'll continue to receive heartbeats forever
- xhr.abort();
- }
- db.deleteDb();
- }
-
- // these will NEVER run as we're always in navigator == undefined
- if (!is_safari && xhr) {
- // test Server Sent Event (eventsource)
- if (!!window.EventSource) {
- var source = new EventSource(
- "/" + db_name + "/_changes?feed=eventsource");
- var results = [];
- var sourceListener = function(e) {
- var data = JSON.parse(e.data);
- results.push(data);
- };
-
- source.addEventListener('message', sourceListener , false);
-
- waitForSuccess(function() {
- if (results.length != 3) {
- throw "bad seq, try again";
- }
- return true;
- });
-
- source.removeEventListener('message', sourceListener, false);
-
- T(results[0].seq == 1);
- T(results[0].id == "foo");
-
- T(results[1].seq == 2);
- T(results[1].id == "bar");
- T(results[1].changes[0].rev == docBar._rev);
- }
-
- // test that we receive EventSource heartbeat events
- if (!!window.EventSource) {
- var source = new EventSource(
- "/" + db_name + "/_changes?feed=eventsource&heartbeat=10");
-
- var count_heartbeats = 0;
- source.addEventListener('heartbeat', function () { count_heartbeats = count_heartbeats + 1; } , false);
-
- waitForSuccess(function() {
- if (count_heartbeats < 3) {
- throw "keep waiting";
- }
- return true;
- }, "eventsource-heartbeat");
-
- T(count_heartbeats >= 3);
- source.close();
- }
-
- // test longpolling
- xhr = CouchDB.newXhr();
-
- xhr.open("GET", CouchDB.proxyUrl("/" + db_name + "/_changes?feed=longpoll"), true);
- xhr.send("");
-
- waitForSuccess(function() {
- lines = xhr.responseText.split("\n");
- if (lines[5] != '"last_seq":3}') {
- throw("still waiting");
- }
- return true;
- }, "last_seq");
-
- xhr = CouchDB.newXhr();
-
- xhr.open("GET", CouchDB.proxyUrl("/" + db_name + "/_changes?feed=longpoll&since=3"), true);
- xhr.send("");
-
- var docBarz = {_id:"barz", bar:1};
- db.save(docBarz);
-
- var parse_changes_line = function(line) {
- if (line.charAt(line.length-1) == ",") {
- var linetrimmed = line.substring(0, line.length-1);
- } else {
- var linetrimmed = line;
- }
- return JSON.parse(linetrimmed);
- };
-
- waitForSuccess(function() {
- lines = xhr.responseText.split("\n");
- if (lines[3] != '"last_seq":4}') {
- throw("still waiting");
- }
- return true;
- }, "change_lines");
-
- var change = parse_changes_line(lines[1]);
- T(change.seq == 4);
- T(change.id == "barz");
- T(change.changes[0].rev == docBarz._rev);
- T(lines[3]=='"last_seq":4}');
-
-
- // test since=now
- xhr = CouchDB.newXhr();
-
- xhr.open("GET", "/" + db_name + "/_changes?feed=longpoll&since=now", true);
- xhr.send("");
-
- var docBarz = {_id:"barzzzz", bar:1};
- db.save(docBarz);
-
- var parse_changes_line = function(line) {
- if (line.charAt(line.length-1) == ",") {
- var linetrimmed = line.substring(0, line.length-1);
- } else {
- var linetrimmed = line;
- }
- return JSON.parse(linetrimmed);
- };
-
- waitForSuccess(function() {
- lines = xhr.responseText.split("\n");
- if (lines[3] != '"last_seq":5}') {
- throw("still waiting");
- }
- return true;
- }, "change_lines");
-
- var change = parse_changes_line(lines[1]);
- T(change.seq == 5);
- T(change.id == "barzzzz");
- T(change.changes[0].rev == docBarz._rev);
- T(lines[3]=='"last_seq":5}');
- }
-
- db.deleteDb();
- // test on a new DB
- var db_name = get_random_db_name();
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"true"}, {"w": 3});
- db.createDb();
-
- // test the filtered changes
- var ddoc = {
- _id : "_design/changes_filter",
- "filters" : {
- "bop" : "function(doc, req) { return (doc.bop);}",
- "dynamic" : stringFun(function(doc, req) {
- var field = req.query.field;
- return doc[field];
- }),
- "userCtx" : stringFun(function(doc, req) {
- return doc.user && (doc.user == req.userCtx.name);
- }),
- "conflicted" : "function(doc, req) { return (doc._conflicts);}"
- },
- options : {
- local_seq : true
- },
- views : {
- local_seq : {
- map : "function(doc) {emit(doc._local_seq, null)}"
- },
- blah: {
- map : 'function(doc) {' +
- ' if (doc._id == "blah") {' +
- ' emit(null, null);' +
- ' }' +
- '}'
- }
- }
- };
-
- db.save(ddoc);
-
- var req = CouchDB.request("GET", "/" + db_name + "/_changes?filter=changes_filter/bop");
- var resp = JSON.parse(req.responseText);
- T(resp.results.length == 0);
-
- var docres1 = db.save({"bop" : "foom"});
- T(docres1.ok);
- var docres2 = db.save({"bop" : false});
- T(docres2.ok);
-
- var req = CouchDB.request("GET", "/" + db_name + "/_changes?filter=changes_filter/bop");
- var resp = JSON.parse(req.responseText);
- var seqold = resp.results[0].seq;
- T(resp.results.length == 1, "filtered/bop");
- T(resp.results[0].changes[0].rev == docres1.rev, "filtered/bop rev");
- // save and reload (substitute for all those parts that never run)
- var chgdoc1 = db.open(docres1.id);
- chgdoc1.newattr = "s/th new";
- docres1 = db.save(chgdoc1);
- T(docres1.ok);
- req = CouchDB.request("GET", "/" + db_name + "/_changes?filter=changes_filter/bop");
- resp = JSON.parse(req.responseText);
- var seqchg = resp.results[0].seq;
- T(resp.results.length == 1, "filtered/bop new");
- T(resp.results[0].changes[0].rev == docres1.rev, "filtered/bop rev new");
- T(seqold != seqchg, "filtered/bop new seq number");
-
- req = CouchDB.request("GET", "/" + db_name + "/_changes?filter=changes_filter/dynamic&field=woox");
- resp = JSON.parse(req.responseText);
- T(resp.results.length == 0);
-
- req = CouchDB.request("GET", "/" + db_name + "/_changes?filter=changes_filter/dynamic&field=bop");
- resp = JSON.parse(req.responseText);
- T(resp.results.length == 1, "changes_filter/dynamic&field=bop");
- T(resp.results[0].changes[0].rev == docres1.rev, "filtered/dynamic&field=bop rev");
-
- // these will NEVER run as we're always in navigator == undefined
- if (!is_safari && xhr) { // full test requires parallel connections
- // filter with longpoll
- // longpoll filters full history when run without a since seq
- xhr = CouchDB.newXhr();
- xhr.open("GET", CouchDB.proxyUrl("/" + db_name + "/_changes?feed=longpoll&filter=changes_filter/bop"), false);
- xhr.send("");
- var resp = JSON.parse(xhr.responseText);
- T(resp.last_seq == 8);
- // longpoll waits until a matching change before returning
- xhr = CouchDB.newXhr();
- xhr.open("GET", CouchDB.proxyUrl("/" + db_name + "/_changes?feed=longpoll&since=7&filter=changes_filter/bop"), true);
- xhr.send("");
- db.save({"_id":"falsy", "bop" : ""}); // empty string is falsy
- db.save({"_id":"bingo","bop" : "bingo"});
-
- waitForSuccess(function() {
- resp = JSON.parse(xhr.responseText);
- return true;
- }, "longpoll-since");
-
- T(resp.last_seq == 10);
- T(resp.results && resp.results.length > 0 && resp.results[0]["id"] == "bingo", "filter the correct update");
- xhr.abort();
-
- var timeout = 500;
- var last_seq = 11;
- while (true) {
-
- // filter with continuous
- xhr = CouchDB.newXhr();
- xhr.open("GET", CouchDB.proxyUrl("/" + db_name + "/_changes?feed=continuous&filter=changes_filter/bop&timeout="+timeout), true);
- xhr.send("");
-
- db.save({"_id":"rusty", "bop" : "plankton"});
- T(xhr.readyState != 4, "test client too slow");
- var rusty = db.open("rusty", {cache_bust : new Date()});
- T(rusty._id == "rusty");
-
- waitForSuccess(function() { // throws an error after 5 seconds
- if (xhr.readyState != 4) {
- throw("still waiting");
- }
- return true;
- }, "continuous-rusty");
- lines = xhr.responseText.split("\n");
- var good = false;
- try {
- JSON.parse(lines[3]);
- good = true;
- } catch(e) {
- }
- if (good) {
- T(JSON.parse(lines[1]).id == "bingo", lines[1]);
- T(JSON.parse(lines[2]).id == "rusty", lines[2]);
- T(JSON.parse(lines[3]).last_seq == last_seq, lines[3]);
- break;
- } else {
- xhr.abort();
- db.deleteDoc(rusty);
- timeout = timeout * 2;
- last_seq = last_seq + 2;
- }
- }
- }
- // error conditions
-
- // non-existing design doc
- var req = CouchDB.request("GET",
- "/" + db_name + "/_changes?filter=nothingtosee/bop");
- TEquals(404, req.status, "should return 404 for non existant design doc");
-
- // non-existing filter
- var req = CouchDB.request("GET",
- "/" + db_name + "/_changes?filter=changes_filter/movealong");
- TEquals(404, req.status, "should return 404 for non existant filter fun");
-
- // both
- var req = CouchDB.request("GET",
- "/" + db_name + "/_changes?filter=nothingtosee/movealong");
- TEquals(404, req.status,
- "should return 404 for non existant design doc and filter fun");
-
- // changes get all_docs style with deleted docs
- var doc = {a:1};
- db.save(doc);
- db.deleteDoc(doc);
- var req = CouchDB.request("GET",
- "/" + db_name + "/_changes?filter=changes_filter/bop&style=all_docs");
- var resp = JSON.parse(req.responseText);
- var expect = (!is_safari && xhr) ? 3: 1;
- TEquals(expect, resp.results.length, "should return matching rows");
-
- // test filter on view function (map)
- //
- T(db.save({"_id":"blah", "bop" : "plankton"}).ok);
- var req = CouchDB.request("GET", "/" + db_name + "/_changes?filter=_view&view=changes_filter/blah");
- var resp = JSON.parse(req.responseText);
- T(resp.results.length === 1);
- T(resp.results[0].id === "blah");
-
-
- // test for userCtx
-// TODO: either make part of global config, or allow 4 config changes - or leave out
-/*
- run_on_modified_server(
- [{section: "httpd",
- key: "authentication_handlers",
- value: "{couch_httpd_auth, special_test_authentication_handler}"},
- {section:"httpd",
- key: "WWW-Authenticate",
- value: "X-Couch-Test-Auth"}],
-
- function() {
- var authOpts = {"headers":{"WWW-Authenticate": "X-Couch-Test-Auth Chris Anderson:mp3"}};
-
- var req = CouchDB.request("GET", "/_session", authOpts);
- var resp = JSON.parse(req.responseText);
-
- T(db.save({"user" : "Noah Slater"}).ok);
- var req = CouchDB.request("GET", "/" + db_name + "/_changes?filter=changes_filter/userCtx", authOpts);
- var resp = JSON.parse(req.responseText);
- T(resp.results.length == 0);
-
- var docResp = db.save({"user" : "Chris Anderson"});
- T(docResp.ok);
- T(db.ensureFullCommit().ok);
- req = CouchDB.request("GET", "/" + db_name + "/_changes?filter=changes_filter/userCtx", authOpts);
- resp = JSON.parse(req.responseText);
- T(resp.results.length == 1, "userCtx");
- T(resp.results[0].id == docResp.id);
- }
- );
-*/
-
- req = CouchDB.request("GET", "/" + db_name + "/_changes?limit=1");
- resp = JSON.parse(req.responseText);
- TEquals(1, resp.results.length);
-
- //filter includes _conflicts
-// TODO: all_or_nothing not yet in place
-// var id = db.save({'food' : 'pizza'}).id;
-// db.bulkSave([{_id: id, 'food' : 'pasta'}], {all_or_nothing:true});
-//
-// req = CouchDB.request("GET", "/" + db_name + "/_changes?filter=changes_filter/conflicted");
-// resp = JSON.parse(req.responseText);
-// T(resp.results.length == 1, "filter=changes_filter/conflicted");
-
- // test with erlang filter function
-// TODO: either make part of global config, or allow 4 config changes - or leave out
-/*
- run_on_modified_server([{
- section: "native_query_servers",
- key: "erlang",
- value: "{couch_native_process, start_link, []}"
- }], function() {
- var erl_ddoc = {
- _id: "_design/erlang",
- language: "erlang",
- filters: {
- foo:
- 'fun({Doc}, Req) -> ' +
- ' case couch_util:get_value(<<"value">>, Doc) of' +
- ' undefined -> false;' +
- ' Value -> (Value rem 2) =:= 0;' +
- ' _ -> false' +
- ' end ' +
- 'end.'
- }
- };
-
- db.deleteDb();
- db.createDb();
- T(db.save(erl_ddoc).ok);
-
- var req = CouchDB.request("GET", "/" + db_name + "/_changes?filter=erlang/foo");
- var resp = JSON.parse(req.responseText);
- T(resp.results.length === 0);
-
- T(db.save({_id: "doc1", value : 1}).ok);
- T(db.save({_id: "doc2", value : 2}).ok);
- T(db.save({_id: "doc3", value : 3}).ok);
- T(db.save({_id: "doc4", value : 4}).ok);
-
- var req = CouchDB.request("GET", "/" + db_name + "/_changes?filter=erlang/foo");
- var resp = JSON.parse(req.responseText);
- T(resp.results.length === 2);
- T(resp.results[0].id === "doc2");
- T(resp.results[1].id === "doc4");
-
- // test filtering on docids
- //
-
- var options = {
- headers: {"Content-Type": "application/json"},
- body: JSON.stringify({"doc_ids": ["something", "anotherthing", "andmore"]})
- };
-
- var req = CouchDB.request("POST", "/" + db_name + "/_changes?filter=_doc_ids", options);
- var resp = JSON.parse(req.responseText);
- T(resp.results.length === 0);
-
- T(db.save({"_id":"something", "bop" : "plankton"}).ok);
- var req = CouchDB.request("POST", "/" + db_name + "/_changes?filter=_doc_ids", options);
- var resp = JSON.parse(req.responseText);
- T(resp.results.length === 1);
- T(resp.results[0].id === "something");
-
- T(db.save({"_id":"anotherthing", "bop" : "plankton"}).ok);
- var req = CouchDB.request("POST", "/" + db_name + "/_changes?filter=_doc_ids", options);
- var resp = JSON.parse(req.responseText);
- T(resp.results.length === 2);
- T(resp.results[0].id === "something");
- T(resp.results[1].id === "anotherthing");
-
- var docids = JSON.stringify(["something", "anotherthing", "andmore"]),
- req = CouchDB.request("GET", "/" + db_name + "/_changes?filter=_doc_ids&doc_ids="+docids, options);
- var resp = JSON.parse(req.responseText);
- T(resp.results.length === 2);
- T(resp.results[0].id === "something");
- T(resp.results[1].id === "anotherthing");
-
- var req = CouchDB.request("GET", "/" + db_name + "/_changes?filter=_design");
- var resp = JSON.parse(req.responseText);
- T(resp.results.length === 1);
- T(resp.results[0].id === "_design/erlang");
-
-
- if (!is_safari && xhr) {
- // filter docids with continuous
- xhr = CouchDB.newXhr();
- xhr.open("POST", CouchDB.proxyUrl("/" + db_name + "/_changes?feed=continuous&timeout=500&since=7&filter=_doc_ids"), true);
- xhr.setRequestHeader("Content-Type", "application/json");
-
- xhr.send(options.body);
-
- T(db.save({"_id":"andmore", "bop" : "plankton"}).ok);
-
- waitForSuccess(function() {
- if (xhr.readyState != 4) {
- throw("still waiting");
- }
- return true;
- }, "andmore-only");
-
- var line = JSON.parse(xhr.responseText.split("\n")[0]);
- T(line.seq == 8);
- T(line.id == "andmore");
- }
- });
-*/
-
- db.deleteDb();
- // COUCHDB-1037 - empty result for ?limit=1&filter=foo/bar in some cases
- // test w/ new temp DB
- db_name = get_random_db_name();
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"true"}, {"w": 3});
- T(db.createDb());
-
- ddoc = {
- _id: "_design/testdocs",
- filters: {
- testdocsonly: (function(doc, req) {
- return (typeof doc.integer === "number");
- }).toString()
- }
- };
- T(db.save(ddoc));
-
- ddoc = {
- _id: "_design/foobar",
- foo: "bar"
- };
- T(db.save(ddoc));
-
- db.bulkSave(makeDocs(0, 5));
-
-// for n>1 you can't be sure all docs are there immediately - so either stick w/ -n 1 or implement check-wait-check or use the quorum (for now, the latter seems 2 suffice)
-
- req = CouchDB.request("GET", "/" + db.name + "/_changes");
- resp = JSON.parse(req.responseText);
- // you can't know wether 7 is the last seq as you don't know how many collapse into one number
- //TEquals(7, resp.last_seq);
- TEquals(7, resp.results.length);
-
- req = CouchDB.request(
- "GET", "/"+ db.name + "/_changes?limit=1&filter=testdocs/testdocsonly");
- resp = JSON.parse(req.responseText);
- // (seq as before)
- //TEquals(3, resp.last_seq);
- TEquals(1, resp.results.length);
- // also, we can't guarantee ordering
- T(resp.results[0].id.match("[0-5]"));
-
- req = CouchDB.request(
- "GET", "/" + db.name + "/_changes?limit=2&filter=testdocs/testdocsonly");
- resp = JSON.parse(req.responseText);
- // (seq as before)
- //TEquals(4, resp.last_seq);
- TEquals(2, resp.results.length);
- // also, we can't guarantee ordering
- T(resp.results[0].id.match("[0-5]"));
- T(resp.results[1].id.match("[0-5]"));
-
-// TODO: either use local port for stats (and aggregate when n>1) or leave out
-// TEquals(0, CouchDB.requestStats(['couchdb', 'httpd', 'clients_requesting_changes'], true).value);
-// CouchDB.request("GET", "/" + db.name + "/_changes");
-// TEquals(0, CouchDB.requestStats(['couchdb', 'httpd', 'clients_requesting_changes'], true).value);
-
- db.deleteDb();
- // COUCHDB-1256
- // test w/ new temp DB
- db_name = get_random_db_name();
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"true"}, {"w": 3});
- T(db.createDb());
-
- T(db.save({"_id":"foo", "a" : 123}).ok);
- T(db.save({"_id":"bar", "a" : 456}).ok);
-
- options = {
- headers: {"Content-Type": "application/json"},
- body: JSON.stringify({"_rev":"1-cc609831f0ca66e8cd3d4c1e0d98108a", "a":456})
- };
- req = CouchDB.request("PUT", "/" + db.name + "/foo?new_edits=false", options);
-
- req = CouchDB.request("GET", "/" + db.name + "/_changes?style=all_docs");
- resp = JSON.parse(req.responseText);
-
- // (seq as before)
- //TEquals(3, resp.last_seq);
- TEquals(2, resp.results.length);
-
- // we can no longer pass a number into 'since' - but we have the 2nd last above - so we can use it (puh!)
- req = CouchDB.request("GET", "/" + db.name + "/_changes?style=all_docs&since=" + encodeURIComponent(resp.results[0].seq));
- resp = JSON.parse(req.responseText);
-
- // (seq as before)
- //TEquals(3, resp.last_seq);
- TEquals(1, resp.results.length);
- // TEquals(2, resp.results[0].changes.length);
-
- db.deleteDb();
- // COUCHDB-1852
- // test w/ new temp DB
- db_name = get_random_db_name();
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"true"}, {"w": 3});
- T(db.createDb());
-
- // create 4 documents... this assumes the update sequnce will start from 0 and then do sth in the cluster
- db.save({"bop" : "foom"});
- db.save({"bop" : "foom"});
- db.save({"bop" : "foom"});
- db.save({"bop" : "foom"});
- // because of clustering, we need the 2nd entry as since value
- req = CouchDB.request("GET", "/" + db_name + "/_changes");
-
- // simulate an EventSource request with a Last-Event-ID header
- // increase timeout to 100 to have enough time 2 assemble (seems like too little timeouts kill
- req = CouchDB.request("GET", "/" + db_name + "/_changes?feed=eventsource&timeout=100&since=0",
- {"headers": {"Accept": "text/event-stream", "Last-Event-ID": JSON.parse(req.responseText).results[1].seq}});
-
- // "parse" the eventsource response and collect only the "id: ..." lines
- var changes = req.responseText.split('\n')
- .map(function (el) {
- return el.split(":").map(function (el) { return el.trim()});
- })
- .filter(function (el) { return (el[0] === "id"); })
-
- // make sure we only got 2 changes, and they are update_seq=3 and update_seq=4
- T(changes.length === 2);
- // seq is different now
- //T(changes[0][1] === "3");
- //T(changes[1][1] === "4");
-
- db.deleteDb();
- // COUCHDB-1923
- // test w/ new temp DB
- db_name = get_random_db_name();
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"true"}, {"w": 3});
- T(db.createDb());
-
- var attachmentData = "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ=";
-
- db.bulkSave(makeDocs(20, 30, {
- _attachments:{
- "foo.txt": {
- content_type:"text/plain",
- data: attachmentData
- },
- "bar.txt": {
- content_type:"text/plain",
- data: attachmentData
- }
- }
- }));
-
- var mapFunction = function(doc) {
- var count = 0;
-
- for(var idx in doc._attachments) {
- count = count + 1;
- }
-
- emit(parseInt(doc._id), count);
- };
-
- var req = CouchDB.request("GET", "/" + db_name + "/_changes?include_docs=true");
- var resp = JSON.parse(req.responseText);
-
- T(resp.results.length == 10);
- T(resp.results[0].doc._attachments['foo.txt'].stub === true);
- T(resp.results[0].doc._attachments['foo.txt'].data === undefined);
- T(resp.results[0].doc._attachments['foo.txt'].encoding === undefined);
- T(resp.results[0].doc._attachments['foo.txt'].encoded_length === undefined);
- T(resp.results[0].doc._attachments['bar.txt'].stub === true);
- T(resp.results[0].doc._attachments['bar.txt'].data === undefined);
- T(resp.results[0].doc._attachments['bar.txt'].encoding === undefined);
- T(resp.results[0].doc._attachments['bar.txt'].encoded_length === undefined);
-
- var req = CouchDB.request("GET", "/" + db_name + "/_changes?include_docs=true&attachments=true");
- var resp = JSON.parse(req.responseText);
-
- T(resp.results.length == 10);
- T(resp.results[0].doc._attachments['foo.txt'].stub === undefined);
- T(resp.results[0].doc._attachments['foo.txt'].data === attachmentData);
- T(resp.results[0].doc._attachments['foo.txt'].encoding === undefined);
- T(resp.results[0].doc._attachments['foo.txt'].encoded_length === undefined);
- T(resp.results[0].doc._attachments['bar.txt'].stub === undefined);
- T(resp.results[0].doc._attachments['bar.txt'].data == attachmentData);
- T(resp.results[0].doc._attachments['bar.txt'].encoding === undefined);
- T(resp.results[0].doc._attachments['bar.txt'].encoded_length === undefined);
-
- var req = CouchDB.request("GET", "/" + db_name + "/_changes?include_docs=true&att_encoding_info=true");
- var resp = JSON.parse(req.responseText);
-
- T(resp.results.length == 10);
- T(resp.results[0].doc._attachments['foo.txt'].stub === true);
- T(resp.results[0].doc._attachments['foo.txt'].data === undefined);
- T(resp.results[0].doc._attachments['foo.txt'].encoding === "gzip");
- T(resp.results[0].doc._attachments['foo.txt'].encoded_length === 47);
- T(resp.results[0].doc._attachments['bar.txt'].stub === true);
- T(resp.results[0].doc._attachments['bar.txt'].data === undefined);
- T(resp.results[0].doc._attachments['bar.txt'].encoding === "gzip");
- T(resp.results[0].doc._attachments['bar.txt'].encoded_length === 47);
-
- db.deleteDb();
-};
diff --git a/test/javascript/tests/coffee.js b/test/javascript/tests/coffee.js
deleted file mode 100644
index 42a1a68ec..000000000
--- a/test/javascript/tests/coffee.js
+++ /dev/null
@@ -1,72 +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.
-
-// test basic coffeescript functionality
-couchTests.elixir = true;
-couchTests.coffee = function(debug) {
- return console.log('done in test/elixir/test/coffee_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var ddoc = {
- _id: "_design/coffee",
- language: "coffeescript",
- views: {
- myview: {
- map: '(doc) -> if doc.foo\n emit(doc.foo, 1)',
- reduce: '(keys, values, rereduce) ->\n sum = 0\n for x in values\n sum = sum + x\n sum'
- }
- },
- shows: {
- myshow: '(doc) ->\n "Foo #{doc.foo}"'
- },
- lists: {
- mylist: '(head, req) ->\n while row = getRow()\n send("Foo #{row.value}")\n return "Foo"'
- },
- filters: {
- filter: "(doc) ->\n doc.foo"
- }
- };
-
- db.save(ddoc);
-
- var docs = [
- {_id:"a", foo: 100},
- {foo:1},
- {foo:1},
- {foo:2},
- {foo:2},
- {bar:1},
- {bar:1},
- {bar:2},
- {bar:2}
- ];
-
- db.bulkSave(docs);
-
- var res = db.view("coffee/myview");
- TEquals(5, res.rows[0].value, "should sum up values");
-
- var res = CouchDB.request("GET", "/" + db.name + "/_design/coffee/_show/myshow/a");
- TEquals("Foo 100", res.responseText, "should show 100");
-
- var res = CouchDB.request("GET", "/" + db.name + "/_design/coffee/_list/mylist/myview");
- TEquals("Foo 5Foo", res.responseText, "should list");
-
- var changes = db.changes({filter: "coffee/filter"});
- TEquals(5, changes.results.length, "should have changes");
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/compact.js b/test/javascript/tests/compact.js
deleted file mode 100644
index fa05e3008..000000000
--- a/test/javascript/tests/compact.js
+++ /dev/null
@@ -1,71 +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.
-
-couchTests.elixir = true;
-couchTests.compact = function(debug) {
- return console.log('done in test/elixir/test/coffee_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
- var docs = makeDocs(0, 20);
- db.bulkSave(docs);
-
- var binAttDoc = {
- _id: "bin_doc",
- _attachments:{
- "foo.txt": {
- content_type:"text/plain",
- data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
- }
- }
- };
-
- T(db.save(binAttDoc).ok);
-
- var originalsize = db.info().sizes.file;
- var originaldatasize = db.info().sizes.active;
- var start_time = db.info().instance_start_time;
-
- TEquals("number", typeof originaldatasize, "data size is a number");
- T(originaldatasize < originalsize, "data size is < then db file size");
-
- for(var i in docs) {
- db.deleteDoc(docs[i]);
- }
- T(db.ensureFullCommit().ok);
- var deletesize = db.info().sizes.file;
- var deletedatasize = db.info().sizes.active;
- T(deletesize > originalsize);
- T(db.setDbProperty("_revs_limit", 666).ok);
-
- T(db.compact().ok);
- T(db.last_req.status == 202);
- // compaction isn't instantaneous, loop until done
- while (db.info().compact_running) {};
- T(db.info().instance_start_time == start_time);
- T(db.getDbProperty("_revs_limit") === 666);
-
- T(db.ensureFullCommit().ok);
- restartServer();
- var xhr = CouchDB.request("GET", "/" + db_name + "/bin_doc/foo.txt");
- T(xhr.responseText == "This is a base64 encoded text");
- T(xhr.getResponseHeader("Content-Type") == "text/plain");
- T(db.info().doc_count == 1);
- // XXX BUGGED! T(db.info().sizes.active < deletedatasize);
- TEquals("number", typeof db.info().sizes.active, "data size is a number");
- T(db.info().sizes.active < db.info().sizes.file, "data size is < then db file size");
-
- // cleanup
- db.deleteDb();
-
-};
diff --git a/test/javascript/tests/config.js b/test/javascript/tests/config.js
deleted file mode 100644
index e3cacc291..000000000
--- a/test/javascript/tests/config.js
+++ /dev/null
@@ -1,222 +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.
-
-couchTests.elixir = true;
-couchTests.config = function(debug) {
- return console.log('done in test/elixir/test/config_test.exs');
- if (debug) debugger;
-
- // test that /_config returns all the settings
- var xhr = CouchDB.request("GET", "/_node/node1@127.0.0.1/_config");
- var config = JSON.parse(xhr.responseText);
-
- config_port = config.chttpd.port;
-
- /*
- if we run on standard ports, we can't extract
- the number from the URL. Instead we try to guess
- from the protocol what port we are running on.
- If we can't guess, we don't test for the port.
- Overengineering FTW.
- */
- var server_port = CouchDB.host.split(':');
- if(server_port.length == 1 && CouchDB.inBrowser) {
- if(CouchDB.protocol == "http://") {
- port = "80";
- }
- if(CouchDB.protocol == "https://") {
- port = "443";
- }
- } else {
- port = server_port.pop();
- }
-
- if(CouchDB.protocol == "http://") {
- config_port = config.chttpd.port;
- }
- if(CouchDB.protocol == "https://") {
- config_port = config.ssl.port;
- }
-
- if(port && config_port != "0") {
- TEquals(config_port, port, "ports should match");
- }
-
- T(config.couchdb.database_dir);
- T(config.log.level);
-
- // test that settings can be altered, and that an undefined whitelist allows any change
- TEquals(undefined, config.httpd.config_whitelist, "Default whitelist is empty");
- xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/test/foo",{
- body : JSON.stringify("bar"),
- headers: {"X-Couch-Persist": "false"}
- });
- T(xhr.status == 200);
- xhr = CouchDB.request("GET", "/_node/node1@127.0.0.1/_config/test");
- config = JSON.parse(xhr.responseText);
- T(config.foo == "bar");
-
- // you can get a single key
- xhr = CouchDB.request("GET", "/_node/node1@127.0.0.1/_config/test/foo");
- config = JSON.parse(xhr.responseText);
- T(config == "bar");
-
- // Server-side password hashing, and raw updates disabling that.
- var password_plain = 's3cret';
- var password_hashed = null;
-
- xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/admins/administrator",{
- body : JSON.stringify(password_plain),
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status, "Create an admin in the config");
-
- T(CouchDB.login("administrator", password_plain).ok);
-
- xhr = CouchDB.request("GET", "/_node/node1@127.0.0.1/_config/admins/administrator");
- password_hashed = JSON.parse(xhr.responseText);
- T(password_hashed.match(/^-pbkdf2-/) || password_hashed.match(/^-hashed-/),
- "Admin password is hashed");
-
-/* // XXX: BUGGED
- xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/admins/administrator?raw=nothanks",{
- body : JSON.stringify(password_hashed),
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(400, xhr.status, "CouchDB rejects an invalid 'raw' option");
-
- xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/admins/administrator?raw=true",{
- body : JSON.stringify(password_hashed),
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status, "Set an raw, pre-hashed admin password");
-
- xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/admins/administrator?raw=false",{
- body : JSON.stringify(password_hashed),
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status, "Set an admin password with raw=false");
-
- // The password is literally the string "-pbkdf2-abcd...".
- T(CouchDB.login("administrator", password_hashed).ok);
-
- xhr = CouchDB.request("GET", "/_node/node1@127.0.0.1/_config/admins/administrator");
- T(password_hashed != JSON.parse(xhr.responseText),
- "Hashed password was not stored as a raw string");
-*/
-
- xhr = CouchDB.request("DELETE", "/_node/node1@127.0.0.1/_config/admins/administrator",{
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status, "Delete an admin from the config");
- T(CouchDB.logout().ok);
-
- // Non-term whitelist values allow further modification of the whitelist.
- xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/httpd/config_whitelist",{
- body : JSON.stringify("!This is an invalid Erlang term!"),
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status, "Set config whitelist to an invalid Erlang term");
- xhr = CouchDB.request("DELETE", "/_node/node1@127.0.0.1/_config/httpd/config_whitelist",{
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status, "Modify whitelist despite it being invalid syntax");
-
- // Non-list whitelist values allow further modification of the whitelist.
- xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/httpd/config_whitelist",{
- body : JSON.stringify("{[yes, a_valid_erlang_term, but_unfortunately, not_a_list]}"),
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status, "Set config whitelist to an non-list term");
- xhr = CouchDB.request("DELETE", "/_node/node1@127.0.0.1/_config/httpd/config_whitelist",{
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status, "Modify whitelist despite it not being a list");
-
- // Keys not in the whitelist may not be modified.
- xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/httpd/config_whitelist",{
- body : JSON.stringify("[{httpd,config_whitelist}, {test,foo}]"),
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status, "Set config whitelist to something valid");
-
-/* // XXX BUGGED!
- ["PUT", "DELETE"].forEach(function(method) {
- ["test/not_foo", "not_test/foo", "neither_test/nor_foo"].forEach(function(pair) {
- var path = "/_node/node1@127.0.0.1/_config/" + pair;
- var test_name = method + " to " + path + " disallowed: not whitelisted";
-
- xhr = CouchDB.request(method, path, {
- body : JSON.stringify("Bummer! " + test_name),
- headers: {"X-Couch-Persist": "false"}
- });
- console.log(test_name);
- TEquals(400, xhr.status, test_name);
- });
- });
-*/
-
- // Keys in the whitelist may be modified.
- ["PUT", "DELETE"].forEach(function(method) {
- xhr = CouchDB.request(method, "/_node/node1@127.0.0.1/_config/test/foo",{
- body : JSON.stringify(method + " to whitelisted config variable"),
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status, "Keys in the whitelist may be modified");
- });
-
- // Non-2-tuples in the whitelist are ignored
- xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/httpd/config_whitelist",{
- body : JSON.stringify("[{httpd,config_whitelist}, these, {are}, {nOt, 2, tuples}," +
- " [so], [they, will], [all, become, noops], {test,foo}]"),
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status, "Set config whitelist with some inert values");
- ["PUT", "DELETE"].forEach(function(method) {
- xhr = CouchDB.request(method, "/_node/node1@127.0.0.1/_config/test/foo",{
- body : JSON.stringify(method + " to whitelisted config variable"),
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status, "Update whitelisted variable despite invalid entries");
- });
-
- // Atoms, binaries, and strings suffice as whitelist sections and keys.
- ["{test,foo}", '{"test","foo"}', '{<<"test">>,<<"foo">>}'].forEach(function(pair) {
- xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/httpd/config_whitelist",{
- body : JSON.stringify("[{httpd,config_whitelist}, " + pair + "]"),
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status, "Set config whitelist to include " + pair);
-
- var pair_format = {"t":"tuple", '"':"string", "<":"binary"}[pair[1]];
- ["PUT", "DELETE"].forEach(function(method) {
- xhr = CouchDB.request(method, "/_node/node1@127.0.0.1/_config/test/foo",{
- body : JSON.stringify(method + " with " + pair_format),
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status, "Whitelist works with " + pair_format);
- });
- });
-
- xhr = CouchDB.request("DELETE", "/_node/node1@127.0.0.1/_config/httpd/config_whitelist",{
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status, "Reset config whitelist to undefined");
-
- // Confirm that the blacklist is functional
- ["daemons", "external", "httpd_design_handlers", "httpd_db_handlers", "native_query_servers", "os_daemons", "query_servers"].forEach(function(section) {
- xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/" + section + "/wohali",{
- body: "\"rules\""
- });
- TEquals(403, xhr.status, "Blacklisted config section " + section);
- });
-};
diff --git a/test/javascript/tests/conflicts.js b/test/javascript/tests/conflicts.js
deleted file mode 100644
index ab25e626f..000000000
--- a/test/javascript/tests/conflicts.js
+++ /dev/null
@@ -1,123 +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.
-
-// Do some edit conflict detection tests
-couchTests.elixir = true;
-couchTests.conflicts = function(debug) {
- return console.log('done in test/elixir/test/conflicts_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- // create a doc and save
- var doc = {_id:"foo",a:1,b:1};
- T(db.save(doc).ok);
-
- // reopen
- var doc2 = db.open(doc._id);
-
- // ensure the revisions are the same
- T(doc._id == doc2._id && doc._rev == doc2._rev);
-
- // edit the documents.
- doc.a = 2;
- doc2.a = 3;
-
- // save one document
- T(db.save(doc).ok);
-
- // save the other document
- try {
- db.save(doc2); // this should generate a conflict exception
- T("no save conflict 1" && false); // we shouldn't hit here
- } catch (e) {
- T(e.error == "conflict");
- }
-
- var changes = db.changes();
-
- T(changes.results.length == 1);
-
- // Now clear out the _rev member and save. This indicates this document is
- // new, not based on an existing revision.
- doc2._rev = undefined;
- try {
- db.save(doc2); // this should generate a conflict exception
- T("no save conflict 2" && false); // we shouldn't hit here
- } catch (e) {
- T(e.error == "conflict");
- }
-
- // Make a few bad requests, specifying conflicting revs
- // ?rev doesn't match body
- var xhr = CouchDB.request("PUT", "/" + db_name + "/foo?rev=1-foobar", {
- body : JSON.stringify(doc)
- });
- T(xhr.status == 400);
-
- // If-Match doesn't match body
- xhr = CouchDB.request("PUT", "/" + db_name + "/foo", {
- headers: {"If-Match": "1-foobar"},
- body: JSON.stringify(doc)
- });
- T(xhr.status == 400);
-
- // ?rev= doesn't match If-Match
- xhr = CouchDB.request("PUT", "/" + db_name + "/foo?rev=1-boobaz", {
- headers: {"If-Match": "1-foobar"},
- body: JSON.stringify(doc2)
- });
- T(xhr.status == 400);
-
- // Now update the document using ?rev=
- xhr = CouchDB.request("PUT", "/" + db_name + "/foo?rev=" + doc._rev, {
- body: JSON.stringify(doc)
- });
- T(xhr.status == 201);
-
- // reopen
- var doc = db.open(doc._id);
-
- // Now delete the document from the database
- T(db.deleteDoc(doc).ok);
-
- T(db.save(doc2).ok); // we can save a new document over a deletion without
- // knowing the deletion rev.
-
- // Verify COUCHDB-1178
- var r1 = {"_id":"doc","foo":"bar"};
- var r2 = {"_id":"doc","foo":"baz","_rev":"1-4c6114c65e295552ab1019e2b046b10e"};
- var r3 = {"_id":"doc","foo":"bam","_rev":"2-cfcd6781f13994bde69a1c3320bfdadb"};
- var r4 = {"_id":"doc","foo":"bat","_rev":"3-cc2f3210d779aef595cd4738be0ef8ff"};
-
- T(db.save({"_id":"_design/couchdb-1178","validate_doc_update":"function(){}"}).ok);
- T(db.save(r1).ok);
- T(db.save(r2).ok);
- T(db.save(r3).ok);
-
- // we can't compact clustered DBs, but the tests will be meaningful still w/out
- //T(db.compact().ok);
- //while (db.info().compact_running) {};
-
- TEquals({"_id":"doc",
- "_rev":"3-cc2f3210d779aef595cd4738be0ef8ff",
- "foo":"bam",
- "_revisions":{"start":3,
- "ids":["cc2f3210d779aef595cd4738be0ef8ff",
- "cfcd6781f13994bde69a1c3320bfdadb",
- "4c6114c65e295552ab1019e2b046b10e"]}},
- db.open("doc", {"revs": true}));
- TEquals([], db.bulkSave([r4, r3, r2], {"new_edits":false}), "no failures");
-
- db.deleteDb();
-};
diff --git a/test/javascript/tests/cookie_auth.js b/test/javascript/tests/cookie_auth.js
deleted file mode 100644
index 2d49ebe1c..000000000
--- a/test/javascript/tests/cookie_auth.js
+++ /dev/null
@@ -1,303 +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.
-
-couchTests.elixir = true;
-couchTests.cookie_auth = function(debug) {
- // This tests cookie-based authentication.
-
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
-
- // used later, needs to be global here
- var users_db_name = '_users';
- var usersDb = new CouchDB(users_db_name, {"X-Couch-Full-Commit":"false"});
- try { usersDb.createDb(); } catch (e) { /* ignore if exists*/ }
-
- if (debug) debugger;
-
- var password = "3.141592653589";
-
- var loginUser = function(username) {
- var pws = {
- jan: "apple",
- "Jason Davies": password,
- jchris: "funnybone"
- };
- var username1 = username.replace(/[0-9]$/, "");
- var password = pws[username];
- //console.log("Logging in '" + username1 + "' with password '" + password + "'");
- T(CouchDB.login(username1, pws[username]).ok);
- };
-
- var open_as = function(db, docId, username) {
- loginUser(username);
- try {
- return db.open(docId, {"anti-cache": Math.round(Math.random() * 100000)});
- } finally {
- CouchDB.logout();
- }
- };
-
- var save_as = function(db, doc, username)
- {
- loginUser(username);
- try {
- return db.save(doc);
- } catch (ex) {
- return ex;
- } finally {
- CouchDB.logout();
- }
- };
-
- // Simple secret key generator
- function generateSecret(length) {
- var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- var secret = '';
- for (var i=0; i<length; i++) {
- secret += tab.charAt(Math.floor(Math.random() * 64));
- }
- return secret;
- }
-
- // this function will be called on the modified server
- var testFun = function () {
- try {
-
- // test that the users db is born with the auth ddoc
- var ddoc = open_as(usersDb, "_design/_auth", "jan");
- T(ddoc && ddoc.validate_doc_update);
-
- // TODO test that changing the config so an existing db becomes the users db installs the ddoc also
-
- // Create a user
- var jasonUserDoc = CouchDB.prepareUserDoc({
- name: "Jason Davies"
- }, password);
- T(usersDb.save(jasonUserDoc).ok);
-
- var checkDoc = open_as(usersDb, jasonUserDoc._id, "jan");
- TEquals("Jason Davies", checkDoc.name);
-
- var jchrisUserDoc = CouchDB.prepareUserDoc({
- name: "jchris"
- }, "funnybone");
- T(usersDb.save(jchrisUserDoc).ok);
-
- // make sure we cant create duplicate users
- var duplicateJchrisDoc = CouchDB.prepareUserDoc({
- name: "jchris"
- }, "eh, Boo-Boo?");
-
- try {
- usersDb.save(duplicateJchrisDoc);
- T(false && "Can't create duplicate user names. Should have thrown an error.");
- } catch (e) {
- TEquals("conflict", e.error);
- TEquals(409, usersDb.last_req.status);
- }
-
- // we can't create _names
- var underscoreUserDoc = CouchDB.prepareUserDoc({
- name: "_why"
- }, "copperfield");
-
- try {
- usersDb.save(underscoreUserDoc);
- T(false && "Can't create underscore user names. Should have thrown an error.");
- } catch (e) {
- TEquals("forbidden", e.error);
- TEquals(403, usersDb.last_req.status);
- }
-
- // we can't create docs with malformed ids
- var badIdDoc = CouchDB.prepareUserDoc({
- name: "w00x"
- }, "bar");
-
- badIdDoc._id = "org.apache.couchdb:w00x";
-
- try {
- usersDb.save(badIdDoc);
- T(false && "Can't create malformed docids. Should have thrown an error.");
- } catch (e) {
- TEquals("forbidden", e.error);
- TEquals(403, usersDb.last_req.status);
- }
-
- // login works
- T(CouchDB.login('Jason Davies', password).ok);
- TEquals('Jason Davies', CouchDB.session().userCtx.name);
-
- // JSON login works
- var xhr = CouchDB.request("POST", "/_session", {
- headers: {"Content-Type": "application/json"},
- body: JSON.stringify({
- name: 'Jason Davies',
- password: password
- })
- });
-
- T(JSON.parse(xhr.responseText).ok);
- TEquals('Jason Davies', CouchDB.session().userCtx.name);
-
- // update one's own credentials document
- jasonUserDoc.foo=2;
- T(usersDb.save(jasonUserDoc).ok);
- T(CouchDB.session().userCtx.roles.indexOf("_admin") == -1);
- // can't delete another users doc unless you are admin
- try {
- usersDb.deleteDoc(jchrisUserDoc);
- T(false && "Can't delete other users docs. Should have thrown an error.");
- } catch (e) {
- TEquals("not_found", e.error);
- TEquals(404, usersDb.last_req.status);
- }
-
- // TODO should login() throw an exception here?
- T(!CouchDB.login('Jason Davies', "2.71828").ok);
- T(!CouchDB.login('Robert Allen Zimmerman', 'd00d').ok);
-
- // a failed login attempt should log you out
- T(CouchDB.session().userCtx.name != 'Jason Davies');
-
- // test redirect on success
- xhr = CouchDB.request("POST", "/_session?next=/", {
- headers: {"Content-Type": "application/x-www-form-urlencoded"},
- body: "name=Jason%20Davies&password="+encodeURIComponent(password)
- });
- // the browser should transparently follow the redirect and GET the server root (/)
- // see http://dev.w3.org/2006/webapi/XMLHttpRequest/#infrastructure-for-the-send-method
- if (xhr.status == 200) {
- T(/Welcome/.test(xhr.responseText))
- }
-
- // test redirect on fail
- xhr = CouchDB.request("POST", "/_session?fail=/", {
- headers: {"Content-Type": "application/x-www-form-urlencoded"},
- body: "name=Jason%20Davies&password=foobar"
- });
- if (xhr.status == 200) {
- T(/Welcome/.test(xhr.responseText));
- }
-
- // test users db validations
- //
- // test that you can't update docs unless you are logged in as the user (or are admin)
- T(CouchDB.login("jchris", "funnybone").ok);
- T(CouchDB.session().userCtx.name == "jchris");
- T(CouchDB.session().userCtx.roles.length == 0);
-
- jasonUserDoc.foo=3;
-
- try {
- usersDb.save(jasonUserDoc);
- T(false && "Can't update someone else's user doc. Should have thrown an error.");
- } catch (e) {
- T(e.error == "not_found");
- T(usersDb.last_req.status == 404);
- }
-
- // test that you can't edit roles unless you are admin
- jchrisUserDoc.roles = ["foo"];
-
- try {
- usersDb.save(jchrisUserDoc);
- T(false && "Can't set roles unless you are admin. Should have thrown an error.");
- } catch (e) {
- T(e.error == "forbidden");
- T(usersDb.last_req.status == 403);
- }
-
- T(CouchDB.logout().ok);
-
- jchrisUserDoc.foo = ["foo"];
- T(save_as(usersDb, jchrisUserDoc, "jan"));
- wait(5000) // wait for auth cache invalidation
-
- // test that you can't save system (underscore) roles even if you are admin
- jchrisUserDoc.roles = ["_bar"];
-
- var res = save_as(usersDb, jchrisUserDoc, "jan");
- T(res.error == "forbidden");
- T(usersDb.last_req.status == 403);
-
- // make sure the foo role has been applied
- T(CouchDB.login("jchris", "funnybone").ok);
- T(CouchDB.session().userCtx.name == "jchris");
- T(CouchDB.session().userCtx.roles.indexOf("_admin") == -1);
- T(CouchDB.session().userCtx.roles.indexOf("foo") != -1);
-
- // now let's make jchris a server admin
- T(CouchDB.logout().ok);
-
- // set the -hashed- password so the salt matches
- // todo ask on the ML about this
-
- TEquals(true, CouchDB.login("jan", "apple").ok);
- run_on_modified_server([{section: "admins",
- key: "jchris", value: "funnybone"}], function() {
- T(CouchDB.login("jchris", "funnybone").ok);
- T(CouchDB.session().userCtx.name == "jchris");
- T(CouchDB.session().userCtx.roles.indexOf("_admin") != -1);
- // test that jchris still has the foo role
- T(CouchDB.session().userCtx.roles.indexOf("foo") != -1);
-
- // should work even when user doc has no password
- jchrisUserDoc = usersDb.open(jchrisUserDoc._id);
- delete jchrisUserDoc.salt;
- delete jchrisUserDoc.password_sha;
- T(usersDb.save(jchrisUserDoc).ok);
- T(CouchDB.logout().ok);
- T(CouchDB.login("jchris", "funnybone").ok);
- var s = CouchDB.session();
- T(s.userCtx.name == "jchris");
- T(s.userCtx.roles.indexOf("_admin") != -1);
- // test session info
- T(s.info.authenticated == "cookie");
- T(s.info.authentication_db == users_db_name);
- // test that jchris still has the foo role
- T(CouchDB.session().userCtx.roles.indexOf("foo") != -1);
- });
-
- } finally {
- // Make sure we erase any auth cookies so we don't affect other tests
- T(CouchDB.logout().ok);
- }
- // log in one last time so run_on_modified_server can clean up the admin account
- TEquals(true, CouchDB.login("jan", "apple").ok);
- };
-
- // per se, _users is born with a ddoc
- // problem is: the birth seems async and it takes some time till it is there. We do know, however, that it WILL. So: use _changes 2 our advantage
- var users_db_chg = CouchDB.request("GET", users_db_name + "/_changes?feed=longpoll&timeout=5000&filter=_design");
- T(users_db_chg.responseText);
- // now we should be safe
- run_on_modified_server(
- [
- {section: "couch_httpd_auth",
- key: "authentication_db", value: users_db_name},
- {section: "chttpd_auth",
- key: "authentication_db", value: users_db_name},
- {section: "couch_httpd_auth",
- key: "iterations", value: "1"},
- {section: "admins",
- key: "jan", value: "apple"}
- ],
- testFun
- );
-
- // cleanup
- db.deleteDb();
- usersDb.deleteDb();
-};
diff --git a/test/javascript/tests/copy_doc.js b/test/javascript/tests/copy_doc.js
deleted file mode 100644
index 107732c0b..000000000
--- a/test/javascript/tests/copy_doc.js
+++ /dev/null
@@ -1,70 +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.
-
-couchTests.elixir = true;
-couchTests.copy_doc = function(debug) {
- return console.log('done in test/elixir/test/copy_doc_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- // copy a doc
- var ok = db.save({_id:"doc_to_be_copied",v:1}).ok;
- TEquals(true, ok, "Should return ok:true");
- var xhr = CouchDB.request("COPY", "/" + db_name + "/doc_to_be_copied", {
- headers: {"Destination":"doc_that_was_copied"}
- });
-
- TEquals(true, JSON.parse(xhr.responseText).ok, "Should return ok:true");
-
- TEquals(201, xhr.status, "Should return 201 status");
- TEquals(1, db.open("doc_that_was_copied").v, "Should have value 1");
-
- // COPY with existing target
- var ok = db.save({_id:"doc_to_be_copied2",v:1}).ok;
- TEquals(true, ok, "Should return ok:true");
- var doc = db.save({_id:"doc_to_be_overwritten",v:2});
- TEquals(true, doc.ok, "Should return ok:true");
-
- // error condition
- var xhr = CouchDB.request("COPY", "/" + db_name + "/doc_to_be_copied2", {
- headers: {"Destination":"doc_to_be_overwritten"}
- });
- TEquals(409, xhr.status, "Should return 409 status"); // conflict
-
- var xhr = CouchDB.request("COPY", "/" + db_name + "/doc_to_be_copied2");
- TEquals(400, xhr.status, "Should return 400 status");
- TEquals("Destination header is mandatory for COPY.", JSON.parse(xhr.responseText).reason,
- "Should report missing destination header");
-
- var xhr = CouchDB.request("COPY", "/" + db_name + "/doc_to_be_copied2", {
- headers: {
- "Destination": "http://localhost:5984/" + db_name + "/doc_to_be_written"
- }});
- TEquals(400, xhr.status, "Should return 400 status");
- TEquals("Destination URL must be relative.", JSON.parse(xhr.responseText).reason,
- "Should report invalid destination header");
-
- var rev = db.open("doc_to_be_overwritten")._rev;
- var xhr = CouchDB.request("COPY", "/" + db_name + "/doc_to_be_copied2", {
- headers: {"Destination":"doc_to_be_overwritten?rev=" + rev}
- });
- TEquals(201, xhr.status, "Should return 201 status");
-
- var over = db.open("doc_to_be_overwritten");
- T(rev != over._rev);
- TEquals(1, over.v, "Should be value 1");
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/design_docs.js b/test/javascript/tests/design_docs.js
deleted file mode 100644
index dd2d0e307..000000000
--- a/test/javascript/tests/design_docs.js
+++ /dev/null
@@ -1,447 +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.
-
-couchTests.elixir = true;
-couchTests.design_docs = function(debug) {
- return console.log('done in test/elixir/test/design_docs.exs');
- var db_name = get_random_db_name();
- var db_name_a = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- var db2 = new CouchDB(db_name_a, {"X-Couch-Full-Commit":"false"});
-
- if (debug) debugger;
-
- db.createDb();
- db2.createDb();
-
-/*
- var server_config = [
- {
- section: "query_server_config",
- key: "reduce_limit",
- value: "false"
- }
- ];
-*/
-
- // var testFun = function() {
- var numDocs = 500;
-
- function makebigstring(power) {
- var str = "a";
- while(power-- > 0) {
- str = str + str;
- }
- return str;
- }
-
- var designDoc = {
- _id: "_design/test",
- language: "javascript",
- autoupdate: false,
- whatever : {
- stringzone : "exports.string = 'plankton';",
- commonjs : {
- whynot : "exports.test = require('../stringzone'); " +
- "exports.foo = require('whatever/stringzone');",
- upper : "exports.testing = require('./whynot').test.string.toUpperCase()+" +
- "module.id+require('./whynot').foo.string",
- circular_one: "require('./circular_two'); exports.name = 'One';",
- circular_two: "require('./circular_one'); exports.name = 'Two';"
- },
- // paths relative to parent
- idtest1: {
- a: {
- b: {d: "module.exports = require('../c/e').id;"},
- c: {e: "exports.id = module.id;"}
- }
- },
- // multiple paths relative to parent
- idtest2: {
- a: {
- b: {d: "module.exports = require('../../a/c/e').id;"},
- c: {e: "exports.id = module.id;"}
- }
- },
- // paths relative to module
- idtest3: {
- a: {
- b: "module.exports = require('./c/d').id;",
- c: {
- d: "module.exports = require('./e');",
- e: "exports.id = module.id;"
- }
- }
- },
- // paths relative to module and parent
- idtest4: {
- a: {
- b: "module.exports = require('../a/./c/d').id;",
- c: {
- d: "module.exports = require('./e');",
- e: "exports.id = module.id;"
- }
- }
- },
- // paths relative to root
- idtest5: {
- a: "module.exports = require('whatever/idtest5/b').id;",
- b: "exports.id = module.id;"
- }
- },
- views: {
- all_docs_twice: {
- map:
- (function(doc) {
- emit(doc.integer, null);
- emit(doc.integer, null);
- }).toString()
- },
- no_docs: {
- map:
- (function(doc) {
- }).toString()
- },
- single_doc: {
- map:
- (function(doc) {
- if (doc._id === "1") {
- emit(1, null);
- }
- }).toString()
- },
- summate: {
- map:
- (function(doc) {
- emit(doc.integer, doc.integer);
- }).toString(),
- reduce:
- (function(keys, values) {
- return sum(values);
- }).toString()
- },
- summate2: {
- map:
- (function(doc) {
- emit(doc.integer, doc.integer);
- }).toString(),
- reduce:
- (function(keys, values) {
- return sum(values);
- }).toString()
- },
- huge_src_and_results: {
- map:
- (function(doc) {
- if (doc._id === "1") {
- emit(makebigstring(16), null);
- }
- }).toString(),
- reduce:
- (function(keys, values) {
- return makebigstring(16);
- }).toString()
- },
- lib : {
- baz : "exports.baz = 'bam';",
- foo : {
- foo : "exports.foo = 'bar';",
- boom : "exports.boom = 'ok';",
- zoom : "exports.zoom = 'yeah';"
- }
- },
- commonjs : {
- map :
- (function(doc) {
- emit(null, require('views/lib/foo/boom').boom);
- }).toString()
- }
- },
- shows: {
- simple:
- (function() {
- return 'ok';
- }).toString(),
- requirey:
- (function() {
- var lib = require('whatever/commonjs/upper');
- return lib.testing;
- }).toString(),
- circular:
- (function() {
- var lib = require('whatever/commonjs/upper');
- return JSON.stringify(this);
- }).toString(),
- circular_require:
- (function() {
- return require('whatever/commonjs/circular_one').name;
- }).toString(),
- idtest1: (function() {
- return require('whatever/idtest1/a/b/d');
- }).toString(),
- idtest2: (function() {
- return require('whatever/idtest2/a/b/d');
- }).toString(),
- idtest3: (function() {
- return require('whatever/idtest3/a/b');
- }).toString(),
- idtest4: (function() {
- return require('whatever/idtest4/a/b');
- }).toString(),
- idtest5: (function() {
- return require('whatever/idtest5/a');
- }).toString()
- }
- }; // designDoc
-
- var xhr = CouchDB.request(
- "PUT", "/" + db_name_a + "/_design/test", {body: JSON.stringify(designDoc)}
- );
- var resp = JSON.parse(xhr.responseText);
-
- TEquals(resp.rev, db.save(designDoc).rev);
-
- // test commonjs require
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/requirey");
- T(xhr.status == 200);
- TEquals("PLANKTONwhatever/commonjs/upperplankton", xhr.responseText);
-
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/circular");
- T(xhr.status == 200);
- TEquals("javascript", JSON.parse(xhr.responseText).language);
-
- // test circular commonjs dependencies
- xhr = CouchDB.request(
- "GET",
- "/" + db_name + "/_design/test/_show/circular_require"
- );
- TEquals(200, xhr.status);
- TEquals("One", xhr.responseText);
-
- // test module id values are as expected:
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/idtest1");
- TEquals(200, xhr.status);
- TEquals("whatever/idtest1/a/c/e", xhr.responseText);
-
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/idtest2");
- TEquals(200, xhr.status);
- TEquals("whatever/idtest2/a/c/e", xhr.responseText);
-
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/idtest3");
- TEquals(200, xhr.status);
- TEquals("whatever/idtest3/a/c/e", xhr.responseText);
-
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/idtest4");
- TEquals(200, xhr.status);
- TEquals("whatever/idtest4/a/c/e", xhr.responseText);
-
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/idtest5");
- TEquals(200, xhr.status);
- TEquals("whatever/idtest5/b", xhr.responseText);
-
-
- var prev_view_sig = db.designInfo("_design/test").view_index.signature;
- var prev_view_size = db.designInfo("_design/test").view_index.sizes.file;
-
- db.bulkSave(makeDocs(1, numDocs + 1));
- T(db.ensureFullCommit().ok);
-
- // test that we get correct design doc info back,
- // and also that GET /db/_design/test/_info
- // hasn't triggered an update of the views
- db.view("test/summate", {stale: "ok"}); // make sure view group's open
- for (var i = 0; i < 2; i++) {
- var dinfo = db.designInfo("_design/test");
- TEquals("test", dinfo.name);
- var vinfo = dinfo.view_index;
- TEquals(prev_view_size, vinfo.sizes.file, "view group disk size didn't change");
- TEquals(false, vinfo.compact_running);
- TEquals(prev_view_sig, vinfo.signature, 'ddoc sig');
- // wait some time (there were issues where an update
- // of the views had been triggered in the background)
- var start = new Date().getTime();
- while (new Date().getTime() < start + 2000);
- TEquals(0, db.view("test/all_docs_twice", {stale: "ok"}).total_rows, 'view info');
- TEquals(0, db.view("test/single_doc", {stale: "ok"}).total_rows, 'view info');
- TEquals(0, db.view("test/summate", {stale: "ok"}).rows.length, 'view info');
- T(db.ensureFullCommit().ok);
- // restartServer();
- };
-
- db.bulkSave(makeDocs(numDocs + 1, numDocs * 2 + 1));
- T(db.ensureFullCommit().ok);
-
- // open view group
- db.view("test/summate", {stale: "ok"});
- // wait so the views can get initialized
- var start = new Date().getTime();
- while (new Date().getTime() < start + 2000);
-
- // test that POST /db/_view_cleanup
- // doesn't trigger an update of the views
- var len1 = db.view("test/all_docs_twice", {stale: "ok"}).total_rows;
- var len2 = db.view("test/single_doc", {stale: "ok"}).total_rows;
- var len3 = db.view("test/summate", {stale: "ok"}).rows.length;
- for (i = 0; i < 2; i++) {
- T(db.viewCleanup().ok);
- // wait some time (there were issues where an update
- // of the views had been triggered in the background)
- start = new Date().getTime();
- while (new Date().getTime() < start + 2000);
- TEquals(len1, db.view("test/all_docs_twice", {stale: "ok"}).total_rows, 'view cleanup');
- TEquals(len2, db.view("test/single_doc", {stale: "ok"}).total_rows, 'view cleanup');
- TEquals(len3, db.view("test/summate", {stale: "ok"}).rows.length, 'view cleanup');
- T(db.ensureFullCommit().ok);
- // restartServer();
- // we'll test whether the view group stays closed
- // and the views stay uninitialized (they should!)
- len1 = len2 = len3 = 0;
- };
-
- // test commonjs in map functions
- resp = db.view("test/commonjs", {limit:1});
- T(resp.rows[0].value == 'ok');
-
- // test that the _all_docs view returns correctly with keys
- var results = db.allDocs({startkey:"_design", endkey:"_design0"});
- T(results.rows.length == 1);
-
- for (i = 0; i < 2; i++) {
- var rows = db.view("test/all_docs_twice").rows;
- for (var j = 0; j < numDocs; j++) {
- T(rows[2 * j].key == (j + 1));
- T(rows[(2 * j) + 1].key == (j + 1));
- };
- T(db.view("test/no_docs").total_rows == 0);
- T(db.view("test/single_doc").total_rows == 1);
- T(db.ensureFullCommit().ok);
- // restartServer();
- };
-
- // test when language not specified, Javascript is implied
- var designDoc2 = {
- _id: "_design/test2",
- // language: "javascript",
- views: {
- single_doc: {
- map:
- (function(doc) {
- if (doc._id === "1") {
- emit(1, null);
- }
- }).toString()
- }
- }
- };
-
- T(db.save(designDoc2).ok);
- T(db.view("test2/single_doc").total_rows == 1);
-
- var summate = function(N) {
- return (N + 1) * (N / 2);
- };
- var result = db.view("test/summate");
- T(result.rows[0].value == summate(numDocs * 2));
-
- result = db.view("test/summate", {startkey: 4, endkey: 4});
- T(result.rows[0].value == 4);
-
- result = db.view("test/summate", {startkey: 4, endkey: 5});
- T(result.rows[0].value == 9);
-
- result = db.view("test/summate", {startkey: 4, endkey: 6});
- T(result.rows[0].value == 15);
-
- // test start_key and end_key aliases
- result = db.view("test/summate", {start_key: 4, end_key: 6});
- T(result.rows[0].value == 15);
-
- // Verify that a shared index (view def is an exact copy of "summate")
- // does not confuse the reduce stage
- result = db.view("test/summate2", {startkey: 4, endkey: 6});
- T(result.rows[0].value == 15);
-
- for(i = 1; i < (numDocs / 2); i += 30) {
- result = db.view("test/summate", {startkey: i, endkey: (numDocs - i)});
- T(result.rows[0].value == summate(numDocs - i) - summate(i - 1));
- }
-
- T(db.deleteDoc(designDoc).ok);
- waitForSuccess(function() {
- var ddoc = db.open(designDoc._id)
- if (ddoc != null) {
- throw({});
- }
- return true;
- }, 'db.open(designDoc._id)');
- T(db.view("test/no_docs") == null);
-
- T(db.ensureFullCommit().ok);
- // restartServer();
- T(db.open(designDoc._id) == null);
- T(db.view("test/no_docs") == null);
-
- // trigger ddoc cleanup
- T(db.viewCleanup().ok);
- //}; // enf of testFun
-
- // not used now as we don't have modifications so far (would have to put them in)
- //run_on_modified_server(server_config, testFun);
-
- // COUCHDB-1227 - if a design document is deleted, by adding a "_deleted"
- // field with the boolean value true, its validate_doc_update functions
- // should no longer have effect.
- db.deleteDb();
- // avoid Heisenbugs w/ files remaining - create a new name
- db_name = get_random_db_name();
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- var ddoc = {
- _id: "_design/test",
- language: "javascript",
- validate_doc_update: (function(newDoc, oldDoc, userCtx, secObj) {
- if (newDoc.value % 2 == 0) {
- throw({forbidden: "dont like even numbers"});
- }
- return true;
- }).toString()
- };
-
- TEquals(true, db.save(ddoc).ok);
- try {
- db.save({_id: "doc1", value: 4});
- T(false, "doc insertion should have failed");
- } catch (x) {
- TEquals("forbidden", x.error);
- }
-
- var doc = db.open("doc1");
- TEquals(null, doc);
- ddoc._deleted = true;
- TEquals(true, db.save(ddoc).ok);
-
- var resp = db.save({_id: "doc1", value: 4})
- try {
- TEquals(true, resp.ok);
- } catch (x) {
- resp = JSON.stringify(resp)
- T(false, "doc insertion should have succeeded: " + resp);
- }
-
- doc = db.open("doc1");
- TEquals(true, doc !== null, "doc was not persisted");
- TEquals(4, doc.value);
-
- // cleanup
- db.deleteDb();
- db2.deleteDb();
-};
diff --git a/test/javascript/tests/design_docs_query.js b/test/javascript/tests/design_docs_query.js
deleted file mode 100644
index 7b4b612c0..000000000
--- a/test/javascript/tests/design_docs_query.js
+++ /dev/null
@@ -1,156 +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.
-couchTests.elixir = true;
-couchTests.design_docs_query = function(debug) {
- return console.log('done in test/elixir/test/design_docs_query_test.exs');
-
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var docs = makeDocs(5);
-
- // create the docs
- var results = db.bulkSave(docs);
- T(results.length == 5);
- for (var i = 0; i < 5; i++) {
- T(results[i].id == docs[i]._id);
- }
-
- // create the ddocs
- for (var i = 0; i < 5; i++) {
- T(db.save({
- _id : "_design/ddoc0" + (i+1).toString(),
- views : {
- "testing" : {
- "map" : "function(){emit(1,1)}"
- }
- }
- }).ok);
- }
-
- // test design_docs
- var path = "/" + db_name + "/_design_docs?";
- var xhr_AllDDocs = CouchDB.request("GET", path);
- T(xhr_AllDDocs.status == 200, "standard get should be 200");
- var allDDocs = JSON.parse(xhr_AllDDocs.responseText);
- TEquals(5, allDDocs.total_rows, "total_rows mismatch");
- TEquals(5, allDDocs.rows.length, "amount of rows mismatch");
-
- // test key="_design/ddoc03"
- var xhr = CouchDB.request("GET", path + "key=\"_design/ddoc03\"");
- T(xhr.status = 200, "standard get should be 200");
- var result = JSON.parse(xhr.responseText);
- TEquals(1, result.rows.length, "amount of rows mismatch");
- TEquals("_design/ddoc03", result.rows[0].key, "key test");
-
- // test descending=true
- var xhr = CouchDB.request("GET", path + "descending=true");
- T(xhr.status == 200, "standard get should be 200");
- var result = JSON.parse(xhr.responseText);
- TEquals(5, result.rows.length, "amount of rows mismatch");
- TEquals("_design/ddoc05", result.rows[0].key, "descending test");
-
- // test descending=false
- var xhr = CouchDB.request("GET", path + "descending=false");
- T(xhr.status == 200, "standard get should be 200");
- var result = JSON.parse(xhr.responseText);
- TEquals(5, result.rows.length, "amount of rows mismatch");
- TEquals("_design/ddoc01", result.rows[0].key, "descending test");
-
- // test end_key="_design/ddoc03"
- var xhr = CouchDB.request("GET", path + "end_key=\"_design/ddoc03\"");
- T(xhr.status = 200, "standard get should be 200");
- var result = JSON.parse(xhr.responseText);
- TEquals(3, result.rows.length, "amount of rows mismatch");
- TEquals("_design/ddoc03", result.rows[2].key, "end_key test");
-
- // test endkey="_design/ddoc03"
- var xhr = CouchDB.request("GET", path + "endkey=\"_design/ddoc03\"");
- T(xhr.status = 200, "standard get should be 200");
- var result = JSON.parse(xhr.responseText);
- TEquals(3, result.rows.length, "amount of rows mismatch");
- TEquals("_design/ddoc03", result.rows[2].key, "endkey test");
-
- // test start_key="_design/ddoc03"
- var xhr = CouchDB.request("GET", path + "start_key=\"_design/ddoc03\"");
- T(xhr.status = 200, "standard get should be 200");
- var result = JSON.parse(xhr.responseText);
- TEquals(3, result.rows.length, "amount of rows mismatch");
- TEquals("_design/ddoc03", result.rows[0].key, "start_key test");
-
- // test startkey="_design/ddoc03"
- var xhr = CouchDB.request("GET", path + "startkey=\"_design/ddoc03\"");
- T(xhr.status = 200, "standard get should be 200");
- var result = JSON.parse(xhr.responseText);
- TEquals(3, result.rows.length, "amount of rows mismatch");
- TEquals("_design/ddoc03", result.rows[0].key, "startkey test");
-
- // test end_key="_design/ddoc03"&inclusive_end=true
- var xhr = CouchDB.request("GET", path + "end_key=\"_design/ddoc03\"&inclusive_end=true");
- T(xhr.status = 200, "standard get should be 200");
- var result = JSON.parse(xhr.responseText);
- TEquals(3, result.rows.length, "amount of rows mismatch");
- TEquals("_design/ddoc03", result.rows[2].key, "end_key and inclusive_end test");
-
- // test end_key="_design/ddoc03"&inclusive_end=false
- var xhr = CouchDB.request("GET", path + "end_key=\"_design/ddoc03\"&inclusive_end=false");
- T(xhr.status = 200, "standard get should be 200");
- var result = JSON.parse(xhr.responseText);
- TEquals(2, result.rows.length, "amount of rows mismatch");
- TEquals("_design/ddoc02", result.rows[1].key, "end_key and inclusive_end test");
-
- // test end_key="_design/ddoc03"&inclusive_end=false&descending=true
- var xhr = CouchDB.request("GET", path +
- "end_key=\"_design/ddoc03\"&inclusive_end=false&descending=true");
- T(xhr.status = 200, "standard get should be 200");
- var result = JSON.parse(xhr.responseText);
- TEquals(2, result.rows.length, "amount of rows mismatch");
- TEquals("_design/ddoc04", result.rows[1].key, "end_key, inclusive_end and descending test");
-
- // test end_key="_design/ddoc05"&limit=2
- var xhr = CouchDB.request("GET", path +
- "end_key=\"_design/ddoc05\"&limit=2");
- T(xhr.status = 200, "standard get should be 200");
- var result = JSON.parse(xhr.responseText);
- TEquals(2, result.rows.length, "amount of rows mismatch");
- TEquals("_design/ddoc02", result.rows[1].key, "end_key and limit test");
-
- // test end_key="_design/ddoc05"&skip=2
- var xhr = CouchDB.request("GET", path +
- "end_key=\"_design/ddoc05\"&skip=2");
- T(xhr.status = 200, "standard get should be 200");
- var result = JSON.parse(xhr.responseText);
- TEquals(3, result.rows.length, "amount of rows mismatch");
- TEquals("_design/ddoc03", result.rows[0].key, "end_key and skip test");
- TEquals("_design/ddoc05", result.rows[2].key, "end_key and skip test");
-
- // test end_key="_design/ddoc05"&update_seq=true
- var xhr = CouchDB.request("GET", path +
- "end_key=\"_design/ddoc05\"&update_seq=true");
- T(xhr.status = 200, "standard get should be 200");
- var result = JSON.parse(xhr.responseText);
- T(result.update_seq);
-
- // test POST with keys
- var xhr = CouchDB.request("POST", path, {
- headers: {"Content-Type": "application/json"},
- body: JSON.stringify({"keys" : ["_design/ddoc02", "_design/ddoc03"]})
- });
- T(xhr.status = 200, "standard get should be 200");
- var result = JSON.parse(xhr.responseText);
- TEquals(2, result.rows.length, "amount of rows mismatch");
- TEquals("_design/ddoc03", result.rows[1].key, "POST test");
-
- db.deleteDb();
-};
diff --git a/test/javascript/tests/design_options.js b/test/javascript/tests/design_options.js
deleted file mode 100644
index aaab39e5b..000000000
--- a/test/javascript/tests/design_options.js
+++ /dev/null
@@ -1,78 +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.
-couchTests.elixir = true;
-couchTests.design_options = function(debug) {
- return console.log('done in test/elixir/test/design_options.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- //// test the includes_design option
- var map = "function (doc) {emit(null, doc._id);}";
- var withseq = "function(doc) {emit(doc._local_seq, null)}"
-
- // we need a design doc even to test temp views with it
- var designDoc = {
- _id:"_design/fu",
- language: "javascript",
- options: {
- include_design: true,
- local_seq: true
- },
- views: {
- data: {"map": map},
- with_seq : {"map" : withseq}
- }
- };
- T(db.save(designDoc).ok);
-
- // should work for temp views
- // no more there on cluster - pointless test
- //var rows = db.query(map, null, {options:{include_design: true}}).rows;
- //T(rows.length == 1);
- //T(rows[0].value == "_design/fu");
- //
- //rows = db.query(map).rows;
- //T(rows.length == 0);
-
- // when true, should include design docs in views
- rows = db.view("fu/data").rows;
- T(rows.length == 1);
- T(rows[0].value == "_design/fu");
-
- // when false, should not
- designDoc.options.include_design = false;
- delete designDoc._rev;
- designDoc._id = "_design/bingo";
- T(db.save(designDoc).ok);
- rows = db.view("bingo/data").rows;
- T(rows.length == 0);
-
- // should default to false
- delete designDoc.options;
- delete designDoc._rev;
- designDoc._id = "_design/bango";
- T(db.save(designDoc).ok);
- rows = db.view("bango/data").rows;
- T(rows.length == 0);
-
- // should also have local_seq in the view
- var resp = db.save({});
- rows = db.view("fu/with_seq").rows;
- // format is more complex on cluster now
- T(!!rows[0].key)
- T(!!rows[1].key)
- var doc = db.open(resp.id);
- db.deleteDoc(doc);
- db.deleteDb();
-};
diff --git a/test/javascript/tests/design_paths.js b/test/javascript/tests/design_paths.js
deleted file mode 100644
index e1d64ea77..000000000
--- a/test/javascript/tests/design_paths.js
+++ /dev/null
@@ -1,74 +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.
-couchTests.elixir = true;
-couchTests.design_paths = function(debug) {
- return console.log('done in test/elixir/test/design_paths.exs');
- if (debug) debugger;
- var db_name = get_random_db_name()
- var dbNames = [db_name, db_name + "/with_slashes"];
- for (var i=0; i < dbNames.length; i++) {
- var db = new CouchDB(dbNames[i]);
- var dbName = encodeURIComponent(dbNames[i]);
- db.createDb();
-
- // create a ddoc w bulk_docs
- db.bulkSave([{
- _id : "_design/test",
- views : {
- "testing" : {
- "map" : "function(){emit(1,1)}"
- }
- }
- }]);
-
- // ddoc is getable
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design/test");
- var resp = JSON.parse(xhr.responseText);
- T(resp._id == "_design/test");
-
- // it's at 2 urls...
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design%2Ftest");
- var resp = JSON.parse(xhr.responseText);
- T(resp._id == "_design/test");
-
- // ensure that views are addressable
- resp = db.view("test/testing")
- T(resp.total_rows == 0)
-
- // create a ddoc by putting to url with raw slash
- var xhr = CouchDB.request("PUT", "/"+dbName+"/_design/test2",{
- body : JSON.stringify({
- _id : "_design/test2",
- views : {
- "testing" : {
- "map" : "function(){emit(1,1)}"
- }
- }
- })
- });
-
- // ddoc is getable
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design/test2");
- var resp = JSON.parse(xhr.responseText);
- T(resp._id == "_design/test2");
-
- // it's at 2 urls...
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design%2Ftest2");
- var resp = JSON.parse(xhr.responseText);
- T(resp._id == "_design/test2");
-
- // ensure that views are addressable
- resp = db.view("test2/testing");
- T(resp.total_rows == 0);
- db.deleteDb();
- };
-};
diff --git a/test/javascript/tests/erlang_views.js b/test/javascript/tests/erlang_views.js
deleted file mode 100644
index 140925f58..000000000
--- a/test/javascript/tests/erlang_views.js
+++ /dev/null
@@ -1,137 +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.
-couchTests.elixir = true;
-couchTests.erlang_views = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- run_on_modified_server(
- [],
- function() {
- // Note we just do some basic 'smoke tests' here - the
- // test/query_server_spec.rb tests have more comprehensive tests
- var doc = {_id: "1", integer: 1, string: "str1", array: [1, 2, 3]};
- T(db.save(doc).ok);
-
- var mfun = 'fun({Doc}) -> ' +
- ' K = couch_util:get_value(<<"integer">>, Doc, null), ' +
- ' V = couch_util:get_value(<<"string">>, Doc, null), ' +
- ' Emit(K, V) ' +
- 'end.';
-
- // emitting a key value that is undefined should result in that row not
- // being included in the view results
- var results = db.query(mfun, null, null, null, "erlang");
- T(results.total_rows == 1);
- T(results.rows[0].key == 1);
- T(results.rows[0].value == "str1");
- // check simple reduction - another doc with same key.
- var doc = {_id: "2", integer: 1, string: "str2"};
- T(db.save(doc).ok);
- rfun = 'fun' +
- ' (_, Values, false) -> length(Values); ' +
- ' (_, Values, true) -> lists:sum(Values) ' +
- ' end.';
- results = db.query(mfun, rfun, null, null, "erlang");
- T(results.rows[0].value == 2);
-
- // simple 'list' tests
- var designDoc = {
- _id:"_design/erlview",
- language: "erlang",
- shows: {
- simple:
- 'fun(Doc, {Req}) -> ' +
- ' {Info} = couch_util:get_value(<<"info">>, Req, {[]}), ' +
- ' Purged = couch_util:get_value(<<"purge_seq">>, Info, -1), ' +
- ' Verb = couch_util:get_value(<<"method">>, Req, <<"not_get">>), ' +
- ' R = list_to_binary(io_lib:format("~s - ~s", [Purged, Verb])), ' +
- ' {[{<<"code">>, 200}, {<<"headers">>, {[]}}, {<<"body">>, R}]} ' +
- 'end.'
- },
- lists: {
- simple_list :
- 'fun(Head, {Req}) -> ' +
- ' Send(<<"head">>), ' +
- ' Fun = fun({Row}, _) -> ' +
- ' Val = couch_util:get_value(<<"value">>, Row, -1), ' +
- ' Send(list_to_binary(integer_to_list(Val))), ' +
- ' {ok, nil} ' +
- ' end, ' +
- ' {ok, _} = FoldRows(Fun, nil), ' +
- ' <<"tail">> ' +
- 'end. '
- },
- views: {
- simple_view : {
- map: mfun,
- reduce: rfun
- }
- }
- };
- T(db.save(designDoc).ok);
-
- var url = "/" + db_name + "/_design/erlview/_show/simple/1";
- var xhr = CouchDB.request("GET", url);
- T(xhr.status == 200, "standard get should be 200");
- T(/0-/.test(xhr.responseText));
- T(/- GET/.test(xhr.responseText));
-
- var url = "/" + db_name + "/_design/erlview/_list/simple_list/simple_view";
- var xhr = CouchDB.request("GET", url);
- T(xhr.status == 200, "standard get should be 200");
- T(xhr.responseText == "head2tail");
-
- // Larger dataset
-
- db.deleteDb();
- // avoid Heisenbugs when files are not cleared entirely
- db_name = get_random_db_name();
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- var words = "foo bar abc def baz xxyz".split(/\s+/);
-
- var docs = [];
- for(var i = 0; i < 250; i++) {
- var body = [];
- for(var j = 0; j < 100; j++) {
- body.push({
- word: words[j%words.length],
- count: j
- });
- }
- docs.push({
- "_id": "test-" + i,
- "words": body
- });
- }
- T(db.bulkSave(docs).length, 250, "Saved big doc set.");
- var mfun = 'fun({Doc}) -> ' +
- 'Words = couch_util:get_value(<<"words">>, Doc), ' +
- 'lists:foreach(fun({Word}) -> ' +
- 'WordString = couch_util:get_value(<<"word">>, Word), ' +
- 'Count = couch_util:get_value(<<"count">>, Word), ' +
- 'Emit(WordString , Count) ' +
- 'end, Words) ' +
- 'end.';
-
- var rfun = 'fun(Keys, Values, RR) -> length(Values) end.';
- var results = db.query(mfun, rfun, null, null, "erlang");
- T(results.rows[0].key === null, "Returned a reduced value.");
- T(results.rows[0].value > 0, "Reduce value exists.");
- });
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/etags_head.js b/test/javascript/tests/etags_head.js
deleted file mode 100644
index 678479004..000000000
--- a/test/javascript/tests/etags_head.js
+++ /dev/null
@@ -1,87 +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.
-
-couchTests.elixir = true;
-couchTests.etags_head = function(debug) {
- return console.log('done in test/elixir/test/etags_head_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var xhr;
-
- // create a new doc
- xhr = CouchDB.request("PUT", "/" + db_name + "/1", {
- body: "{}"
- });
- T(xhr.status == 201);
-
- // extract the ETag header values
- var etag = xhr.getResponseHeader("etag");
-
- // get the doc and verify the headers match
- xhr = CouchDB.request("GET", "/" + db_name + "/1");
- T(etag == xhr.getResponseHeader("etag"));
-
- // 'head' the doc and verify the headers match
- xhr = CouchDB.request("HEAD", "/" + db_name + "/1", {
- headers: {"if-none-match": "s"}
- });
- T(etag == xhr.getResponseHeader("etag"));
-
- // replace a doc
- xhr = CouchDB.request("PUT", "/" + db_name + "/1", {
- body: "{}",
- headers: {"if-match": etag}
- });
- T(xhr.status == 201);
-
- // extract the new ETag value
- var etagOld= etag;
- etag = xhr.getResponseHeader("etag");
-
- // fail to replace a doc
- xhr = CouchDB.request("PUT", "/" + db_name + "/1", {
- body: "{}"
- });
- T(xhr.status == 409);
-
- // verify get w/Etag
- xhr = CouchDB.request("GET", "/" + db_name + "/1", {
- headers: {"if-none-match": etagOld}
- });
- T(xhr.status == 200);
- xhr = CouchDB.request("GET", "/" + db_name + "/1", {
- headers: {"if-none-match": etag}
- });
- T(xhr.status == 304);
- xhr = CouchDB.request("GET", "/" + db_name + "/1", {
- headers: {"if-none-match": "W/" + etag}
- });
- T(xhr.status == 304);
-
- // fail to delete a doc
- xhr = CouchDB.request("DELETE", "/" + db_name + "/1", {
- headers: {"if-match": etagOld}
- });
- T(xhr.status == 409);
-
- //now do it for real
- xhr = CouchDB.request("DELETE", "/" + db_name + "/1", {
- headers: {"if-match": etag}
- });
- T(xhr.status == 200);
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/etags_views.js b/test/javascript/tests/etags_views.js
deleted file mode 100644
index 555fe663d..000000000
--- a/test/javascript/tests/etags_views.js
+++ /dev/null
@@ -1,224 +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.
-
-// TODO: https://issues.apache.org/jira/browse/COUCHDB-2859
-couchTests.skip = true;
-couchTests.etags_views = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"true"});
- db.createDb();
- if (debug) debugger;
-
- var designDoc = {
- _id: "_design/etags",
- language: "javascript",
- views : {
- fooView: {
- map: stringFun(function(doc) {
- if (doc.foo) {
- emit("bar", 1);
- }
- }),
- },
- basicView : {
- map : stringFun(function(doc) {
- if(doc.integer && doc.string) {
- emit(doc.integer, doc.string);
- }
- })
- },
- withReduce : {
- map : stringFun(function(doc) {
- if(doc.integer && doc.string) {
- emit(doc.integer, doc.string);
- }
- }),
- reduce : stringFun(function(keys, values, rereduce) {
- if (rereduce) {
- return sum(values);
- } else {
- return values.length;
- }
- })
- }
- }
- };
- T(db.save(designDoc).ok);
- db.bulkSave(makeDocs(0, 10));
-
- var xhr;
-
- // verify get w/Etag on map view
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/basicView");
- T(xhr.status == 200);
- var etag = xhr.getResponseHeader("etag");
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/basicView", {
- headers: {"if-none-match": etag}
- });
- T(xhr.status == 304);
-
- // verify ETag doesn't change when an update
- // doesn't change the view group's index
- T(db.save({"_id":"doc1", "foo":"bar"}).ok);
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/basicView");
- var etag1 = xhr.getResponseHeader("etag");
- T(etag1 == etag);
-
- // verify ETag always changes for include_docs=true on update
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/basicView?include_docs=true");
- var etag1 = xhr.getResponseHeader("etag");
- T(db.save({"_id":"doc2", "foo":"bar"}).ok);
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/basicView?include_docs=true");
- var etag2 = xhr.getResponseHeader("etag");
- T(etag1 != etag2);
-
- // Verify that purges affect etags
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/fooView");
- var foo_etag = xhr.getResponseHeader("etag");
- var doc1 = db.open("doc1");
- xhr = CouchDB.request("POST", "/" + db_name + "/_purge", {
- body: JSON.stringify({"doc1":[doc1._rev]})
- });
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/fooView");
- var etag1 = xhr.getResponseHeader("etag");
- T(etag1 != foo_etag);
-
- // Test that _purge didn't affect the other view etags.
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/basicView");
- var etag1 = xhr.getResponseHeader("etag");
- T(etag1 == etag);
-
- // verify different views in the same view group may have different ETags
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/fooView");
- var etag1 = xhr.getResponseHeader("etag");
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/basicView");
- var etag2 = xhr.getResponseHeader("etag");
- T(etag1 != etag2);
-
- // verify ETag changes when an update changes the view group's index.
- db.bulkSave(makeDocs(10, 20));
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/basicView");
- var etag1 = xhr.getResponseHeader("etag");
- T(etag1 != etag);
-
- // verify ETag is the same after a restart
- restartServer();
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/basicView");
- var etag2 = xhr.getResponseHeader("etag");
- T(etag1 == etag2);
-
- // reduce view
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/withReduce");
- T(xhr.status == 200);
- var etag = xhr.getResponseHeader("etag");
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/withReduce",{
- headers: {"if-none-match": etag}
- });
- T(xhr.status == 304);
-
- // verify ETag doesn't change when an update
- // doesn't change the view group's index
- T(db.save({"_id":"doc3", "foo":"bar"}).ok);
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/withReduce");
- var etag1 = xhr.getResponseHeader("etag");
- T(etag1 == etag);
- // purge
- var doc3 = db.open("doc3");
- xhr = CouchDB.request("POST", "/" + db_name + "/_purge", {
- body: JSON.stringify({"doc3":[doc3._rev]})
- });
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/withReduce");
- var etag1 = xhr.getResponseHeader("etag");
- T(etag1 == etag);
-
- // verify different views in the same view group may have different ETags
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/fooView");
- var etag1 = xhr.getResponseHeader("etag");
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/withReduce");
- var etag2 = xhr.getResponseHeader("etag");
- T(etag1 != etag2);
-
- // verify ETag changes when an update changes the view group's index
- db.bulkSave(makeDocs(20, 30));
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/withReduce");
- var etag1 = xhr.getResponseHeader("etag");
- T(etag1 != etag);
-
- // verify ETag is the same after a restart
- restartServer();
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/etags/_view/withReduce");
- var etag2 = xhr.getResponseHeader("etag");
- T(etag1 == etag2);
-
- // confirm ETag changes with different POST bodies
- xhr = CouchDB.request("POST", "/" + db_name + "/_design/etags/_view/basicView",
- {body: JSON.stringify({keys:[1]})}
- );
- var etag1 = xhr.getResponseHeader("etag");
- xhr = CouchDB.request("POST", "/" + db_name + "/_design/etags/_view/basicView",
- {body: JSON.stringify({keys:[2]})}
- );
- var etag2 = xhr.getResponseHeader("etag");
- T(etag1 != etag2, "POST to map view generates key-depdendent ETags");
-
- xhr = CouchDB.request("POST",
- "/" + db_name + "/_design/etags/_view/withReduce?group=true",
- {body: JSON.stringify({keys:[1]})}
- );
- etag1 = xhr.getResponseHeader("etag");
- xhr = CouchDB.request("POST",
- "/" + db_name + "/_design/etags/_view/withReduce?group=true",
- {body: JSON.stringify({keys:[2]})}
- );
- etag2 = xhr.getResponseHeader("etag");
- T(etag1 != etag2, "POST to reduce view generates key-depdendent ETags");
-
- // all docs
- xhr = CouchDB.request("GET", "/" + db_name + "/_all_docs");
- T(xhr.status == 200);
- var etag = xhr.getResponseHeader("etag");
- xhr = CouchDB.request("GET", "/" + db_name + "/_all_docs", {
- headers: {"if-none-match": etag}
- });
- T(xhr.status == 304);
-
- // _changes
- xhr = CouchDB.request("GET", "/" + db_name + "/_changes");
- T(xhr.status == 200);
- var etag = xhr.getResponseHeader("etag");
- xhr = CouchDB.request("GET", "/" + db_name + "/_changes", {
- headers: {"if-none-match": etag}
- });
- T(xhr.status == 304);
-
- // list etag
- // in the list test for now
-
- // A new database should have unique _all_docs etags.
- db.deleteDb();
- db.createDb(); // TODO: when re-activating try having a new DB name
- db.save({a: 1});
- xhr = CouchDB.request("GET", "/" + db_name + "/_all_docs");
- var etag = xhr.getResponseHeader("etag");
- db.deleteDb();
- db.createDb(); // TODO: when re-activating try having a new DB name
- db.save({a: 2});
- xhr = CouchDB.request("GET", "/" + db_name + "/_all_docs");
- var new_etag = xhr.getResponseHeader("etag");
- T(etag != new_etag);
- // but still be cacheable
- xhr = CouchDB.request("GET", "/" + db_name + "/_all_docs");
- T(new_etag == xhr.getResponseHeader("etag"));
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/form_submit.js b/test/javascript/tests/form_submit.js
deleted file mode 100644
index f8dd2baf0..000000000
--- a/test/javascript/tests/form_submit.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-// Do some basic tests.
-couchTests.elixir = true;
-couchTests.form_submit = function(debug) {
- return console.log('done in test/elixir/test/form_summit_test.exs');
-
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
-
- var json = "{}";
- var xhr = CouchDB.request("POST", "/" + db_name + "/baz", {body: json});
- T(xhr.status == 415);
- result = JSON.parse(xhr.responseText);
- T(result.error, "bad_content_type");
- T(result.reason, "Invalid Content-Type header for form upload");
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/http.js b/test/javascript/tests/http.js
deleted file mode 100644
index bc35921e1..000000000
--- a/test/javascript/tests/http.js
+++ /dev/null
@@ -1,82 +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.
-couchTests.elixir = true;
-couchTests.http = function(debug) {
- return console.log('done in test/elixir/test/http_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
-
- // bug COUCHDB-100: DELETE on non-existent DB returns 500 instead of 404
-
- db.createDb();
-
- // PUT on existing DB should return 412 instead of 500
- if (debug) debugger;
-
- var xhr = CouchDB.request("PUT", "/" + db_name + "/test", {body: "{}"});
- var host = CouchDB.host;
-
- TEquals(CouchDB.protocol + host + "/" + db_name + "/test",
- xhr.getResponseHeader("Location"),
- "should include ip address");
-
- xhr = CouchDB.request("PUT", "/" + db_name + "/test2", {
- body: "{}",
- headers: {"X-Forwarded-Host": "mysite.com"}
- });
-
- TEquals(CouchDB.protocol + "mysite.com/" + db_name + "/test2",
- xhr.getResponseHeader("Location"),
- "should include X-Forwarded-Host");
-
- run_on_modified_server([{
- section:"httpd",
- key:"x_forwarded_host",
- value:"X-Host"}],
- function() {
- xhr = CouchDB.request("PUT", "/" + db_name + "/test3", {
- body: "{}",
- headers: {"X-Host": "mysite2.com"}
- });
- TEquals(CouchDB.protocol + "mysite2.com/" + db_name + "/test3",
- xhr.getResponseHeader("Location"),
- "should include X-Host");
- });
-
- // COUCHDB-708: newlines document names
- xhr = CouchDB.request("PUT", "/" + db_name + "/docid%0A/attachment.txt", {
- headers: {"Content-Type": "text/plain;charset=utf-8"},
- body: ""
- });
- TEquals(CouchDB.protocol + host + "/" + db_name + "/docid%0A/attachment.txt",
- xhr.getResponseHeader("Location"),
- "should work with newlines in document names for attachments");
-
- xhr = CouchDB.request("PUT", "/" + db_name + "/docidtest%0A", {
- body: JSON.stringify({"foo": "bar"}),
- headers: {"Content-Type": "application/json"}
- });
- TEquals(CouchDB.protocol + host + "/" + db_name + "/docidtest%0A",
- xhr.getResponseHeader("Location"),
- "should work with newlines in document names");
-
- xhr = CouchDB.request("POST", "/" + db_name + "/", {
- body: JSON.stringify({"_id": "docidtestpost%0A"}),
- headers: {"Content-Type": "application/json"}
- });
- TEquals(CouchDB.protocol + host + "/" + db_name + "/docidtestpost%250A",
- xhr.getResponseHeader("Location"),
- "should work with newlines in document names");
-
- // cleanup
- db.deleteDb();
-}
diff --git a/test/javascript/tests/invalid_docids.js b/test/javascript/tests/invalid_docids.js
deleted file mode 100644
index 31c9d6cea..000000000
--- a/test/javascript/tests/invalid_docids.js
+++ /dev/null
@@ -1,82 +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.
-
-couchTests.elixir = true;
-couchTests.invalid_docids = function(debug) {
- return console.log('done in test/elixir/test/invalid_docids_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- // Test _local explicitly first.
- T(db.save({"_id": "_local/foo"}).ok);
- T(db.open("_local/foo")._id == "_local/foo");
-
- var urls = [
- "/" + db_name + "/_local",
- "/" + db_name + "/_local/",
- "/" + db_name + "/_local%2F",
- "/" + db_name + "/_local/foo/bar",
- ];
-
- urls.forEach(function(u) {
- var res = db.request("PUT", u, {"body": "{}"});
- T(res.status == 400);
- T(JSON.parse(res.responseText).error == "bad_request");
- });
-
- //Test non-string
- try {
- db.save({"_id": 1});
- T(1 == 0, "doc id must be string");
- } catch(e) {
- T(db.last_req.status == 400);
- T(e.error == "illegal_docid");
- }
-
- // Via PUT with _id not in body.
- var res = res = db.request("PUT", "/" + db_name + "/_other", {"body": "{}"});
- T(res.status == 400);
- T(JSON.parse(res.responseText).error == "illegal_docid");
-
- // Accidental POST to form handling code.
- res = db.request("POST", "/" + db_name + "/_tmp_view", {"body": "{}"});
- T(res.status == 400);
- T(JSON.parse(res.responseText).error == "illegal_docid");
-
- // Test invalid _prefix
- try {
- db.save({"_id": "_invalid"});
- T(1 == 0, "doc id may not start with underscore");
- } catch(e) {
- T(db.last_req.status == 400);
- T(e.error == "illegal_docid");
- }
-
- // Test _bulk_docs explicitly.
- var docs = [{"_id": "_design/foo"}, {"_id": "_local/bar"}];
- db.bulkSave(docs);
- docs.forEach(function(d) {T(db.open(d._id)._id == d._id);});
-
- docs = [{"_id": "_invalid"}];
- try {
- db.bulkSave(docs);
- T(1 == 0, "doc id may not start with underscore, even in bulk docs");
- } catch(e) {
- T(db.last_req.status == 400);
- T(e.error == "illegal_docid");
- }
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/jsonp.js b/test/javascript/tests/jsonp.js
deleted file mode 100644
index f34fdc9c5..000000000
--- a/test/javascript/tests/jsonp.js
+++ /dev/null
@@ -1,87 +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.
-couchTests.elixir = true;
-
-// Verify callbacks ran
-var jsonp_flag = 0;
-
-// Callbacks
-function jsonp_no_chunk(doc) {
- T(jsonp_flag == 0);
- T(doc._id == "0");
- jsonp_flag = 1;
-}
-
-function jsonp_chunk(doc) {
- T(jsonp_flag == 0);
- T(doc.total_rows == 1);
- jsonp_flag = 1;
-}
-
-// Do some jsonp tests.
-couchTests.jsonp = function(debug) {
- return console.log('done in test/elixir/test/jsonp_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var doc = {_id:"0",a:0,b:0};
- T(db.save(doc).ok);
-
- // callback param is ignored unless jsonp is configured
- var xhr = CouchDB.request("GET", "/" + db_name + "/0?callback=jsonp_not_configured");
- JSON.parse(xhr.responseText);
-
- run_on_modified_server(
- [{section: "httpd",
- key: "allow_jsonp",
- value: "true"}],
- function() {
-
- // Test unchunked callbacks.
- var xhr = CouchDB.request("GET", "/" + db_name + "/0?callback=jsonp_no_chunk");
- TEquals("application/javascript", xhr.getResponseHeader("Content-Type"));
- T(xhr.status == 200);
- jsonp_flag = 0;
- eval(xhr.responseText);
- T(jsonp_flag == 1);
- xhr = CouchDB.request("GET", "/" + db_name + "/0?callback=foo\"");
- T(xhr.status == 400);
-
- // Test chunked responses
- var doc = {_id:"1",a:1,b:1};
- T(db.save(doc).ok);
-
- var designDoc = {
- _id:"_design/test",
- language: "javascript",
- views: {
- all_docs: {map: "function(doc) {if(doc.a) emit(null, doc.a);}"}
- }
- };
- T(db.save(designDoc).ok);
-
- var url = "/" + db_name + "/_design/test/_view/all_docs?callback=jsonp_chunk";
- xhr = CouchDB.request("GET", url);
- TEquals("application/javascript", xhr.getResponseHeader("Content-Type"));
- T(xhr.status == 200);
- jsonp_flag = 0;
- eval(xhr.responseText);
- T(jsonp_flag == 1);
- xhr = CouchDB.request("GET", url + "\'");
- T(xhr.status == 400);
- });
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/large_docs.js b/test/javascript/tests/large_docs.js
deleted file mode 100644
index aa36b6cc3..000000000
--- a/test/javascript/tests/large_docs.js
+++ /dev/null
@@ -1,38 +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.
-
-couchTests.elixir = true;
-couchTests.large_docs = function(debug) {
- return console.log('done in test/elixir/test/large_docs_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var longtext = "0123456789\n";
-
- for (var i=0; i<10; i++) {
- longtext = longtext + longtext
- }
- T(db.save({"longtest":longtext}).ok);
- T(db.save({"longtest":longtext}).ok);
- T(db.save({"longtest":longtext}).ok);
- T(db.save({"longtest":longtext}).ok);
-
- // query all documents, and return the doc.foo member as a key.
- results = db.query(function(doc){
- emit(null, doc.longtest);
- });
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/list_views.js b/test/javascript/tests/list_views.js
deleted file mode 100644
index e255e1546..000000000
--- a/test/javascript/tests/list_views.js
+++ /dev/null
@@ -1,502 +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.
-
-couchTests.list_views = function(debug) {
-
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var designDoc = {
- _id:"_design/lists",
- language: "javascript",
- views : {
- basicView : {
- map : stringFun(function(doc) {
- emit(doc.integer, doc.string);
- })
- },
- withReduce : {
- map : stringFun(function(doc) {
- emit(doc.integer, doc.string);
- }),
- reduce : stringFun(function(keys, values, rereduce) {
- if (rereduce) {
- return sum(values);
- } else {
- return values.length;
- }
- })
- }
- },
- lists: {
- basicBasic : stringFun(function(head, req) {
- send("head");
- var row;
- while(row = getRow()) {
- log("row: "+toJSON(row));
- send(row.key);
- };
- return "tail";
- }),
- basicJSON : stringFun(function(head, req) {
- start({"headers":{"Content-Type" : "application/json"}});
- send('{"head":'+toJSON(head)+', ');
- send('"req":'+toJSON(req)+', ');
- send('"rows":[');
- var row, sep = '';
- while (row = getRow()) {
- send(sep + toJSON(row));
- sep = ', ';
- }
- return "]}";
- }),
- simpleForm: stringFun(function(head, req) {
- log("simpleForm");
- send('<ul>');
- var row, row_number = 0, prevKey, firstKey = null;
- while (row = getRow()) {
- row_number += 1;
- if (!firstKey) firstKey = row.key;
- prevKey = row.key;
- send('\n<li>Key: '+row.key
- +' Value: '+row.value
- +' LineNo: '+row_number+'</li>');
- }
- return '</ul><p>FirstKey: '+ firstKey + ' LastKey: '+ prevKey+'</p>';
- }),
- acceptSwitch: stringFun(function(head, req) {
- // respondWith takes care of setting the proper headers
- provides("html", function() {
- send("HTML <ul>");
-
- var row, num = 0;
- while (row = getRow()) {
- num ++;
- send('\n<li>Key: '
- +row.key+' Value: '+row.value
- +' LineNo: '+num+'</li>');
- }
-
- // tail
- return '</ul>';
- });
- }),
- qsParams: stringFun(function(head, req) {
- return toJSON(req.query) + "\n";
- }),
- stopIter: stringFun(function(req) {
- send("head");
- var row, row_number = 0;
- while(row = getRow()) {
- if(row_number > 2) break;
- send(" " + row_number);
- row_number += 1;
- };
- return " tail";
- }),
- stopIter2: stringFun(function(head, req) {
- provides("html", function() {
- send("head");
- var row, row_number = 0;
- while(row = getRow()) {
- if(row_number > 2) break;
- send(" " + row_number);
- row_number += 1;
- };
- return " tail";
- });
- }),
- tooManyGetRows : stringFun(function() {
- send("head");
- var row;
- while(row = getRow()) {
- send(row.key);
- };
- getRow();
- getRow();
- getRow();
- row = getRow();
- return "after row: "+toJSON(row);
- }),
- emptyList: stringFun(function() {
- return " ";
- }),
- rowError : stringFun(function(head, req) {
- send("head");
- var row = getRow();
- send(fooBarBam); // intentional error
- return "tail";
- }),
- docReference : stringFun(function(head, req) {
- send("head");
- var row = getRow();
- send(row.doc.integer);
- return "tail";
- }),
- secObj: stringFun(function(head, req) {
- return toJSON(req.secObj);
- }),
- setHeaderAfterGotRow: stringFun(function(head, req) {
- getRow();
- start({
- code: 400,
- headers: {
- "X-My-Header": "MyHeader"
- }
- });
- send("bad request");
- }),
- allDocs: stringFun(function(head, req){
- start({'headers': {'Content-Type': 'application/json'}});
- var resp = head;
- var rows = [];
- while(row=getRow()){
- rows.push(row);
- }
- resp.rows = rows;
- return toJSON(resp);
- })
- }
- };
- var viewOnlyDesignDoc = {
- _id:"_design/views",
- language: "javascript",
- views : {
- basicView : {
- map : stringFun(function(doc) {
- emit(-doc.integer, doc.string);
- })
- }
- }
- };
- var erlListDoc = {
- _id: "_design/erlang",
- language: "erlang",
- lists: {
- simple:
- 'fun(Head, {Req}) -> ' +
- ' Send(<<"[">>), ' +
- ' Fun = fun({Row}, Sep) -> ' +
- ' Val = couch_util:get_value(<<"key">>, Row, 23), ' +
- ' Send(list_to_binary(Sep ++ integer_to_list(Val))), ' +
- ' {ok, ","} ' +
- ' end, ' +
- ' {ok, _} = FoldRows(Fun, ""), ' +
- ' Send(<<"]">>) ' +
- 'end.'
- }
- };
-
- T(db.save(designDoc).ok);
-
- var docs = makeDocs(0, 10);
- db.bulkSave(docs);
-
- var view = db.view('lists/basicView');
- T(view.total_rows == 10);
-
- // standard get
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/basicBasic/basicView");
- T(xhr.status == 200, "standard get should be 200");
- T(/head0123456789tail/.test(xhr.responseText));
-
- // standard options - works though it does not make lots of sense
- var xhr = CouchDB.request("OPTIONS", "/" + db_name + "/_design/lists/_list/basicBasic/basicView");
- T(xhr.status == 200, "standard get should be 200");
- T(/head0123456789tail/.test(xhr.responseText));
-
- // TODO: test that etags are available - actually they're not (yet): https://issues.apache.org/jira/browse/COUCHDB-2859
- //var etag = xhr.getResponseHeader("etag");
- //xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/basicBasic/basicView", {
- // headers: {"if-none-match": etag}
- //});
- //T(xhr.status == 304);
-
- // confirm ETag changes with different POST bodies
- // (not yet - see above)
- //xhr = CouchDB.request("POST", "/" + db_name + "/_design/lists/_list/basicBasic/basicView",
- // {body: JSON.stringify({keys:[1]})}
- //);
- //var etag1 = xhr.getResponseHeader("etag");
- //xhr = CouchDB.request("POST", "/" + db_name + "/_design/lists/_list/basicBasic/basicView",
- // {body: JSON.stringify({keys:[2]})}
- //);
- //var etag2 = xhr.getResponseHeader("etag");
- //T(etag1 != etag2, "POST to map _list generates key-depdendent ETags");
-
- // test the richness of the arguments
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/basicJSON/basicView?update_seq=true");
- T(xhr.status == 200, "standard get should be 200");
- var resp = JSON.parse(xhr.responseText);
- TEquals(10, resp.head.total_rows);
- TEquals(0, resp.head.offset);
- // we don't have a (meaningful) update seq in a clustered env
- //TEquals(11, resp.head.update_seq);
-
- T(resp.rows.length == 10);
- TEquals(resp.rows[0], {"id": "0","key": 0,"value": "0"});
-
- TEquals(resp.req.info.db_name, "" + db_name + "");
- TEquals(resp.req.method, "GET");
- TEquals(resp.req.path, [
- "" + db_name + "",
- "_design",
- "lists",
- "_list",
- "basicJSON",
- "basicView"
- ]);
- T(resp.req.headers.Accept);
- T(resp.req.headers.Host);
- T(resp.req.headers["User-Agent"]);
- T(resp.req.cookie);
- TEquals("/" + db_name + "/_design/lists/_list/basicJSON/basicView?update_seq=true",
- resp.req.raw_path, "should include raw path");
-
- // get with query params
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/simpleForm/basicView?startkey=3&endkey=8");
- T(xhr.status == 200, "with query params");
- T(!(/Key: 1/.test(xhr.responseText)));
- T(/FirstKey: 3/.test(xhr.responseText));
- T(/LastKey: 8/.test(xhr.responseText));
-
- // with 0 rows
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/simpleForm/basicView?startkey=30");
- T(xhr.status == 200, "0 rows");
- T(/<\/ul>/.test(xhr.responseText));
-
- //too many Get Rows
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/tooManyGetRows/basicView");
- T(xhr.status == 200, "tooManyGetRows");
- T(/9after row: null/.test(xhr.responseText));
-
-
- // reduce with 0 rows
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/simpleForm/withReduce?startkey=30");
- T(xhr.status == 200, "reduce 0 rows");
- T(/LastKey: undefined/.test(xhr.responseText));
-
- // when there is a reduce present, but not used
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/simpleForm/withReduce?reduce=false");
- T(xhr.status == 200, "reduce false");
- T(/Key: 1/.test(xhr.responseText));
-
-
- // when there is a reduce present, and used
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/simpleForm/withReduce?group=true");
- T(xhr.status == 200, "group reduce");
- T(/Key: 1/.test(xhr.responseText));
-
- // there should be etags on reduce as well
- // (see above 4 etags)
- //var etag = xhr.getResponseHeader("etag");
- //T(etag, "Etags should be served with reduce lists");
- //xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/simpleForm/withReduce?group=true", {
- // headers: {"if-none-match": etag}
- //});
- //T(xhr.status == 304);
-
- // confirm ETag changes with different POST bodies
- // (see above)
- //xhr = CouchDB.request("POST", "/" + db_name + "/_design/lists/_list/simpleForm/withReduce?group=true",
- // {body: JSON.stringify({keys:[1]})}
- //);
- //var etag1 = xhr.getResponseHeader("etag");
- //xhr = CouchDB.request("POST", "/" + db_name + "/_design/lists/_list/simpleForm/withReduce?group=true",
- // {body: JSON.stringify({keys:[2]})}
- //);
- //var etag2 = xhr.getResponseHeader("etag");
- //T(etag1 != etag2, "POST to reduce _list generates key-depdendent ETags");
-
- // verify the etags expire correctly
- var docs = makeDocs(11, 12);
- db.bulkSave(docs);
-
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/simpleForm/withReduce?group=true", {
- // will always be 200 as etags don't make sense (see above)
- //headers: {"if-none-match": etag}
- });
- T(xhr.status == 200, "reduce etag");
-
- // empty list
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/emptyList/basicView");
- T(xhr.responseText.match(/^ $/));
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/emptyList/withReduce?group=true");
- T(xhr.responseText.match(/^ $/));
-
- // multi-key fetch
- var xhr = CouchDB.request("POST", "/" + db_name + "/_design/lists/_list/simpleForm/basicView", {
- body: '{"keys":[2,4,5,7]}'
- });
- T(xhr.status == 200, "multi key");
- T(!(/Key: 1 /.test(xhr.responseText)));
- T(/Key: 2/.test(xhr.responseText));
- T(/FirstKey: 2/.test(xhr.responseText));
- T(/LastKey: 7/.test(xhr.responseText));
-
- // multi-key fetch with GET
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/simpleForm/basicView" +
- "?keys=[2,4,5,7]");
-
- T(xhr.status == 200, "multi key");
- T(!(/Key: 1 /.test(xhr.responseText)));
- T(/Key: 2/.test(xhr.responseText));
- T(/FirstKey: 2/.test(xhr.responseText));
- T(/LastKey: 7/.test(xhr.responseText));
-
- // no multi-key fetch allowed when group=false
- xhr = CouchDB.request("POST", "/" + db_name + "/_design/lists/_list/simpleForm/withReduce?group=false", {
- body: '{"keys":[2,4,5,7]}'
- });
- T(xhr.status == 400);
- T(/query_parse_error/.test(xhr.responseText));
-
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/rowError/basicView");
- T(/ReferenceError/.test(xhr.responseText));
-
-
- // with include_docs and a reference to the doc.
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/docReference/basicView?include_docs=true");
- T(xhr.responseText.match(/head0tail/));
-
- // now with extra qs params
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/qsParams/basicView?foo=blam");
- T(xhr.responseText.match(/blam/));
-
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/stopIter/basicView");
- // T(xhr.getResponseHeader("Content-Type") == "text/plain");
- T(xhr.responseText.match(/^head 0 1 2 tail$/) && "basic stop");
-
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/stopIter2/basicView", {
- headers : {
- "Accept" : "text/html"
- }
- });
- T(xhr.responseText.match(/^head 0 1 2 tail$/) && "stop 2");
-
- // aborting iteration with reduce
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/stopIter/withReduce?group=true");
- T(xhr.responseText.match(/^head 0 1 2 tail$/) && "reduce stop");
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/stopIter2/withReduce?group=true", {
- headers : {
- "Accept" : "text/html"
- }
- });
- T(xhr.responseText.match(/^head 0 1 2 tail$/) && "reduce stop 2");
-
- // with accept headers for HTML
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/acceptSwitch/basicView", {
- headers: {
- "Accept": 'text/html'
- }
- });
- T(xhr.getResponseHeader("Content-Type") == "text/html; charset=utf-8");
- T(xhr.responseText.match(/HTML/));
- T(xhr.responseText.match(/Value/));
-
- // Test we can run lists and views from separate docs.
- T(db.save(viewOnlyDesignDoc).ok);
- var url = "/" + db_name + "/_design/lists/_list/simpleForm/views/basicView" +
- "?startkey=-3";
- xhr = CouchDB.request("GET", url);
- T(xhr.status == 200, "multiple design docs.");
- T(!(/Key: -4/.test(xhr.responseText)));
- T(/FirstKey: -3/.test(xhr.responseText));
- T(/LastKey: 0/.test(xhr.responseText));
-
- // Test we do multi-key requests on lists and views in separate docs.
- var url = "/" + db_name + "/_design/lists/_list/simpleForm/views/basicView";
- xhr = CouchDB.request("POST", url, {
- body: '{"keys":[-2,-4,-5,-7]}'
- });
-
- T(xhr.status == 200, "multi key separate docs");
- T(!(/Key: -3/.test(xhr.responseText)));
- T(/Key: -7/.test(xhr.responseText));
- T(/FirstKey: -2/.test(xhr.responseText));
- T(/LastKey: -7/.test(xhr.responseText));
-
- // Test if secObj is available
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/secObj/basicView");
- T(xhr.status == 200, "standard get should be 200");
- var resp = JSON.parse(xhr.responseText);
- T(typeof(resp) == "object");
-
- var erlViewTest = function() {
- T(db.save(erlListDoc).ok);
- var url = "/" + db_name + "/_design/erlang/_list/simple/views/basicView" +
- "?startkey=-3";
- xhr = CouchDB.request("GET", url);
- T(xhr.status == 200, "multiple languages in design docs.");
- var list = JSON.parse(xhr.responseText);
- T(list.length == 4);
- for(var i = 0; i < list.length; i++)
- {
- T(list[i] + 3 == i);
- }
- };
-
- // make _config available 4 tests or leave commented out
- //run_on_modified_server([{
- // section: "native_query_servers",
- // key: "erlang",
- // value: "{couch_native_process, start_link, []}"
- //}], erlViewTest);
-
- // COUCHDB-1113
- var ddoc = {
- _id: "_design/test",
- views: {
- me: {
- map: (function(doc) { emit(null,null)}).toString()
- }
- },
- lists: {
- you: (function(head, req) {
- var row;
- while(row = getRow()) {
- send(row);
- }
- }).toString()
- }
- };
- db.save(ddoc);
-
- var resp = CouchDB.request("GET", "/" + db.name + "/_design/test/_list/you/me", {
- headers: {
- "Content-Type": "application/x-www-form-urlencoded"
- }
- });
- TEquals(200, resp.status, "should return a 200 response");
-
- // TEST HTTP header response set after getRow() called in _list function.
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/setHeaderAfterGotRow/basicView");
- T(xhr.status == 400);
- T(xhr.getResponseHeader("X-My-Header") == "MyHeader");
- T(xhr.responseText.match(/^bad request$/));
-
- // test handling _all_docs by _list functions. the result should be equal
- var xhr_lAllDocs = CouchDB.request("GET", "/" + db_name + "/_design/lists/_list/allDocs/_all_docs");
- T(xhr_lAllDocs.status == 200, "standard get should be 200");
- var xhr_allDocs = CouchDB.request("GET", "/" + db_name + "/_all_docs");
- var allDocs = JSON.parse(xhr_allDocs.responseText);
- var lAllDocs = JSON.parse(xhr_lAllDocs.responseText);
- TEquals(allDocs.total_rows, lAllDocs.total_rows, "total_rows mismatch");
- TEquals(allDocs.offset, lAllDocs.offset, "offset mismatch");
- TEquals(allDocs.rows.length, lAllDocs.rows.length, "amount of rows mismatch");
- TEquals(allDocs.rows, lAllDocs.rows, "rows mismatch");
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/lorem.txt b/test/javascript/tests/lorem.txt
deleted file mode 100644
index 0ef85bab8..000000000
--- a/test/javascript/tests/lorem.txt
+++ /dev/null
@@ -1,103 +0,0 @@
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus nunc sapien, porta id pellentesque at, elementum et felis. Curabitur condimentum ante in metus iaculis quis congue diam commodo. Donec eleifend ante sed nulla dapibus convallis. Ut cursus aliquam neque, vel porttitor tellus interdum ut. Sed pharetra lacinia adipiscing. In tristique tristique felis non tincidunt. Nulla auctor mauris a velit cursus ultricies. In at libero quis justo consectetur laoreet. Nullam id ultrices nunc. Donec non turpis nulla, eu lacinia ante. Nunc eu orci et turpis pretium venenatis. Nam molestie, lacus at dignissim elementum, ante libero consectetur libero, ut lacinia lacus urna et purus. Nullam lorem ipsum, dapibus vel ullamcorper a, malesuada a metus. Sed porta adipiscing magna, quis pulvinar purus mattis fringilla. Integer pellentesque sapien in neque tristique ac iaculis libero ultricies. Ut eget pharetra purus.
-
-Nulla in convallis tellus. Proin tincidunt suscipit vulputate. Suspendisse potenti. Nullam tristique justo mi, a tristique ligula. Duis convallis aliquam iaculis. Nulla dictum fringilla congue. Suspendisse ac leo lectus, ac aliquam justo. Ut porttitor commodo mi sed luctus. Nulla at enim lorem. Nunc eu justo sapien, a blandit odio. Curabitur faucibus sollicitudin dolor, id lacinia sem auctor in. Donec varius nunc at lectus sagittis nec luctus arcu pharetra. Nunc sed metus justo. Cras vel mauris diam. Ut feugiat felis eget neque pharetra vestibulum consectetur massa facilisis. Quisque consectetur luctus nisi quis tincidunt. Vivamus cursus cursus quam non blandit. Pellentesque et velit lacus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
-
-In et dolor vitae orci adipiscing congue. Aliquam gravida nibh at nisl gravida molestie. Curabitur a bibendum sapien. Aliquam tincidunt, nulla nec pretium lobortis, odio augue tincidunt arcu, a lobortis odio sem ut purus. Donec accumsan mattis nunc vitae lacinia. Suspendisse potenti. Integer commodo nisl quis nibh interdum non fringilla dui sodales. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In hac habitasse platea dictumst. Etiam ullamcorper, mi id feugiat bibendum, purus neque cursus mauris, id sodales quam nisi id velit. Sed lectus leo, tincidunt vel rhoncus imperdiet, blandit in leo. Integer quis magna nulla. Donec vel nisl magna, ut rhoncus dui. Aliquam gravida, nulla nec eleifend luctus, neque nibh pharetra ante, quis egestas elit metus a mi. Nunc nec augue quam. Morbi tincidunt tristique varius. Suspendisse iaculis elit feugiat magna pellentesque ultricies. Vestibulum aliquam tortor non ante ullamcorper fringilla. Donec iaculis mi quis mauris ornare vestibulum.
-
-In a magna nisi, a ultricies massa. Donec elit neque, viverra non tempor quis, fringilla in metus. Integer odio odio, euismod vitae mollis sed, sodales eget libero. Donec nec massa in felis ornare pharetra at nec tellus. Nunc lorem dolor, pretium vel auctor in, volutpat vitae felis. Maecenas rhoncus, orci vel blandit euismod, turpis erat tincidunt ante, elementum adipiscing nisl urna in nisi. Phasellus sagittis, enim sed accumsan consequat, urna augue lobortis erat, non malesuada quam metus sollicitudin ante. In leo purus, dignissim quis varius vel, pellentesque et nibh. In sed tortor iaculis libero mollis pellentesque id vitae lectus. In hac habitasse platea dictumst. Phasellus mauris enim, posuere eget luctus ac, iaculis et quam. Vivamus et nibh diam, elementum egestas tellus. Aenean vulputate malesuada est. Sed posuere porta diam a sodales. Proin eu sem non velit facilisis venenatis sed a turpis.
-
-Pellentesque sed risus a ante vulputate lobortis sit amet eu nisl. Suspendisse ut eros mi, a rhoncus lacus. Curabitur fermentum vehicula tellus, a ornare mi condimentum vel. Integer molestie volutpat viverra. Integer posuere euismod venenatis. Proin ac mauris sed nulla pharetra porttitor. Duis vel dui in risus sodales auctor sit amet non enim. Maecenas mollis lacus at ligula faucibus sodales. Cras vel neque arcu. Sed tincidunt tortor pretium nisi interdum quis dictum arcu laoreet. Morbi pretium ultrices feugiat. Maecenas convallis augue nec felis malesuada malesuada scelerisque mauris placerat. Sed at magna enim, at fringilla dolor. Quisque ut mattis dui. Praesent consectetur ante viverra nisi blandit pharetra. Quisque metus elit, dignissim vitae fermentum sit amet, fringilla imperdiet odio. Cras eget purus eget tellus feugiat luctus a ac purus. Cras vitae nisl vel augue rhoncus porttitor sit amet quis lorem. Donec interdum pellentesque adipiscing. Phasellus neque libero, aliquam in mattis vitae, consectetur adipiscing nibh.
-
-Donec nec nulla urna, ac sagittis lectus. Suspendisse non elit sed mi auctor facilisis vitae et lectus. Fusce ac vulputate mauris. Morbi condimentum ultrices metus, et accumsan purus malesuada at. Maecenas lobortis ante sed massa dictum vitae venenatis elit commodo. Proin tellus eros, adipiscing sed dignissim vitae, tempor eget ante. Aenean id tellus nec magna cursus pharetra vitae vel enim. Morbi vestibulum pharetra est in vulputate. Aliquam vitae metus arcu, id aliquet nulla. Phasellus ligula est, hendrerit nec iaculis ut, volutpat vel eros. Suspendisse vitae urna turpis, placerat adipiscing diam. Phasellus feugiat vestibulum neque eu dapibus. Nulla facilisi. Duis tortor felis, euismod sit amet aliquet in, volutpat nec turpis. Mauris rhoncus ipsum ut purus eleifend ut lobortis lectus dapibus. Quisque non erat lorem. Vivamus posuere imperdiet iaculis. Ut ligula lacus, eleifend at tempor id, auctor eu leo.
-
-Donec mi enim, laoreet pulvinar mollis eu, malesuada viverra nunc. In vitae metus vitae neque tempor dapibus. Maecenas tincidunt purus a felis aliquam placerat. Nulla facilisi. Suspendisse placerat pharetra mattis. Integer tempor malesuada justo at tempus. Maecenas vehicula lorem a sapien bibendum vel iaculis risus feugiat. Pellentesque diam erat, dapibus et pellentesque quis, molestie ut massa. Vivamus iaculis interdum massa id bibendum. Quisque ut mauris dui, sit amet varius elit. Vestibulum elit lorem, rutrum non consectetur ut, laoreet nec nunc. Donec nec mauris ante. Curabitur ut est sed odio pharetra laoreet. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur purus risus, laoreet sed porta id, sagittis vel ipsum. Maecenas nibh diam, cursus et varius sit amet, fringilla sed magna. Nullam id neque eu leo faucibus mollis. Duis nec adipiscing mauris. Suspendisse sollicitudin, enim eu pulvinar commodo, erat augue ultrices mi, a tristique magna sem non libero.
-
-Sed in metus nulla. Praesent nec adipiscing sapien. Donec laoreet, velit non rutrum vestibulum, ligula neque adipiscing turpis, at auctor sapien elit ut massa. Nullam aliquam, enim vel posuere rutrum, justo erat laoreet est, vel fringilla lacus nisi non lectus. Etiam lectus nunc, laoreet et placerat at, venenatis quis libero. Praesent in placerat elit. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque fringilla augue eu nibh placerat dictum. Nunc porttitor tristique diam, eu aliquam enim aliquet vel. Aliquam lacinia interdum ipsum, in posuere metus luctus vel. Vivamus et nisl a eros semper elementum. Donec venenatis orci at diam tristique sollicitudin. In eu eros sed odio rutrum luctus non nec tellus.
-
-Nulla nec felis elit. Nullam in ipsum in ipsum consequat fringilla quis vel tortor. Phasellus non massa nisi, sit amet aliquam urna. Sed fermentum nibh vitae lacus tincidunt nec tincidunt massa bibendum. Etiam elit dui, facilisis sit amet vehicula nec, iaculis at sapien. Ut at massa id dui ultrices volutpat ut ac libero. Fusce ipsum mi, bibendum a lacinia et, pulvinar eget mauris. Proin faucibus urna ut lorem elementum vulputate. Duis quam leo, malesuada non euismod ut, blandit facilisis mauris. Suspendisse sit amet magna id velit tincidunt aliquet nec eu dolor. Curabitur bibendum lorem vel felis tempus dapibus. Aliquam erat volutpat. Aenean cursus tortor nec dui aliquet porta. Aenean commodo iaculis suscipit. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Quisque sit amet ornare elit. Nam ligula risus, vestibulum nec mattis in, condimentum ac ante. Donec fringilla, justo et ultrices faucibus, tellus est volutpat massa, vitae commodo sapien diam non risus. Vivamus at arcu gravida purus mollis feugiat.
-
-Nulla a turpis quis sapien commodo dignissim eu quis justo. Maecenas eu lorem odio, ut hendrerit velit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin facilisis porttitor ullamcorper. Praesent mollis dignissim massa, laoreet aliquet velit pellentesque non. Nunc facilisis convallis tristique. Mauris porttitor ante at tellus convallis placerat. Morbi aliquet nisi ac nisl pulvinar id dictum nisl mollis. Sed ornare sem et risus placerat lobortis id eget elit. Integer consequat, magna id suscipit pharetra, nulla velit suscipit orci, ut interdum augue augue quis quam. Fusce pretium aliquet vulputate. Mauris blandit dictum molestie. Proin nulla nibh, bibendum eu placerat at, tincidunt ac nisl. Nullam vulputate metus ut libero rutrum ultricies. Nunc sit amet dui mauris. Suspendisse adipiscing lacus in augue eleifend mollis.
-
-Duis pretium ultrices mattis. Nam euismod risus a erat lacinia bibendum. Morbi massa tortor, consectetur id eleifend id, pellentesque vel tortor. Praesent urna lorem, porttitor at condimentum vitae, luctus eget elit. Maecenas fringilla quam convallis est hendrerit viverra. Etiam vehicula, sapien non pulvinar adipiscing, nisi massa vestibulum est, id interdum mauris velit eu est. Vestibulum est arcu, facilisis at ultricies non, vulputate id sapien. Vestibulum ipsum metus, pharetra nec pellentesque id, facilisis id sapien. Donec rutrum odio et lacus ultricies ullamcorper. Integer sed est ut mi posuere tincidunt quis non leo. Morbi tellus justo, ultricies sit amet ultrices quis, facilisis vitae magna. Donec ligula metus, pellentesque non tristique ac, vestibulum sed erat. Aliquam erat volutpat.
-
-Nam dignissim, nisl eget consequat euismod, sem lectus auctor orci, ut porttitor lacus dui ac neque. In hac habitasse platea dictumst. Fusce egestas porta facilisis. In hac habitasse platea dictumst. Mauris cursus rhoncus risus ac euismod. Quisque vitae risus a tellus venenatis convallis. Curabitur laoreet sapien eu quam luctus lobortis. Vivamus sollicitudin sodales dolor vitae sodales. Suspendisse pharetra laoreet aliquet. Maecenas ullamcorper orci vel tortor luctus iaculis ut vitae metus. Vestibulum ut arcu ac tellus mattis eleifend eget vehicula elit.
-
-In sed feugiat eros. Donec bibendum ullamcorper diam, eu faucibus mauris dictum sed. Duis tincidunt justo in neque accumsan dictum. Maecenas in rutrum sapien. Ut id feugiat lacus. Nulla facilisi. Nunc ac lorem id quam varius cursus a et elit. Aenean posuere libero eu tortor vehicula ut ullamcorper odio consequat. Sed in dignissim dui. Curabitur iaculis tempor quam nec placerat. Aliquam venenatis nibh et justo iaculis lacinia. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque tempus magna sed mi aliquet eget varius odio congue.
-
-Integer sem sem, semper in vestibulum vitae, lobortis quis erat. Duis ante lectus, fermentum sed tempor sit amet, placerat sit amet sem. Mauris congue tincidunt ipsum. Ut viverra, lacus vel varius pharetra, purus enim pulvinar ipsum, non pellentesque enim justo non erat. Fusce ipsum orci, ultrices sed pellentesque at, hendrerit laoreet enim. Nunc blandit mollis pretium. Ut mollis, nulla aliquam sodales vestibulum, libero lorem tempus tortor, a pellentesque nibh elit a ipsum. Phasellus fermentum ligula at neque adipiscing sollicitudin. Suspendisse id ipsum arcu. Sed tincidunt placerat viverra. Donec libero augue, porttitor sit amet varius eget, rutrum nec lacus. Proin blandit orci sit amet diam dictum id porttitor risus iaculis. Integer lacinia feugiat leo, vitae auctor turpis eleifend vel. Suspendisse lorem quam, pretium id bibendum sed, viverra vitae tortor. Nullam ultricies libero eu risus convallis eget ullamcorper nisi elementum. Mauris nulla elit, bibendum id vulputate vitae, imperdiet rutrum lorem. Curabitur eget dignissim orci. Sed semper tellus ipsum, at blandit dui. Integer dapibus facilisis sodales. Vivamus sollicitudin varius est, quis ornare justo cursus id.
-
-Nunc vel ullamcorper mi. Suspendisse potenti. Nunc et urna a augue scelerisque ultrices non quis mi. In quis porttitor elit. Aenean quis erat nulla, a venenatis tellus. Fusce vestibulum nisi sed leo adipiscing dignissim. Nunc interdum, lorem et lacinia vestibulum, quam est mattis magna, sit amet volutpat elit augue at libero. Cras gravida dui quis velit lobortis condimentum et eleifend ligula. Phasellus ac metus quam, id venenatis mi. Aliquam ut turpis ac tellus dapibus dapibus eu in mi. Quisque eget nibh eros. Fusce consectetur leo velit.
-
-Vestibulum semper egestas mauris. Morbi vestibulum sem sem. Aliquam venenatis, felis sed eleifend porta, mauris diam semper arcu, sit amet ultricies est sapien sit amet libero. Vestibulum dui orci, ornare condimentum mollis nec, molestie ac eros. Proin vitae mollis velit. Praesent eget felis mi. Maecenas eu vulputate nisi. Vestibulum varius, arcu in ultricies vestibulum, nibh leo sagittis odio, ut bibendum nisl mi nec diam. Integer at enim feugiat nulla semper bibendum ut a velit. Proin at nisi ut lorem aliquam varius eget quis elit. Nullam nec odio vel lectus congue consequat adipiscing ac mi. Fusce vitae laoreet libero. Curabitur sit amet sem neque, nec posuere enim. Curabitur at massa a sem gravida iaculis nec et nibh. Sed vitae dui vitae leo tincidunt pretium a aliquam erat. Suspendisse ultricies odio at metus tempor in pellentesque arcu ultricies.
-
-Sed aliquam mattis quam, in vulputate sapien ultrices in. Pellentesque quis velit sed dui hendrerit cursus. Pellentesque non nunc lacus, a semper metus. Fusce euismod velit quis diam suscipit consequat. Praesent commodo accumsan neque. Proin viverra, ipsum non tristique ultrices, velit velit facilisis lorem, vel rutrum neque eros ac nisi. Suspendisse felis massa, faucibus in volutpat ac, dapibus et odio. Pellentesque id tellus sit amet risus ultricies ullamcorper non nec sapien. Nam placerat viverra ullamcorper. Nam placerat porttitor sapien nec pulvinar. Curabitur vel odio sit amet odio accumsan aliquet vitae a lectus. Pellentesque lobortis viverra consequat. Mauris elementum cursus nulla, sit amet hendrerit justo dictum sed. Maecenas diam odio, fringilla ac congue quis, adipiscing ut elit.
-
-Aliquam lorem eros, pharetra nec egestas vitae, mattis nec risus. Mauris arcu massa, sodales eget gravida sed, viverra vitae turpis. Ut ligula urna, euismod ac tincidunt eu, faucibus sed felis. Praesent mollis, ipsum quis rhoncus dignissim, odio sem venenatis nulla, at consequat felis augue vel erat. Nam fermentum feugiat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Etiam vitae dui in nisi adipiscing ultricies non eu justo. Donec tristique ultricies adipiscing. Nulla sodales, nunc a tristique elementum, erat neque egestas nisl, at hendrerit orci sapien sed libero. Vivamus a mauris turpis, quis laoreet ipsum. Nunc nec mi et nisl pellentesque scelerisque. Vivamus volutpat, justo tristique lacinia condimentum, erat justo ultrices urna, elementum viverra eros augue non libero. Sed mollis mollis arcu, at fermentum diam suscipit quis.
-
-Etiam sit amet nibh justo, posuere volutpat nunc. Morbi pellentesque neque in orci volutpat eu scelerisque lorem dictum. Mauris mollis iaculis est, nec sagittis sapien consequat id. Nunc nec malesuada odio. Duis quis suscipit odio. Mauris purus dui, sodales id mattis sit amet, posuere in arcu. Phasellus porta elementum convallis. Maecenas at orci et mi vulputate sollicitudin in in turpis. Pellentesque cursus adipiscing neque sit amet commodo. Fusce ut mi eu lectus porttitor volutpat et nec felis.
-
-Curabitur scelerisque eros quis nisl viverra vel ultrices velit vestibulum. Sed lobortis pulvinar sapien ac venenatis. Sed ante nibh, rhoncus eget dictum in, mollis ut nisi. Phasellus facilisis mi non lorem tristique non eleifend sem fringilla. Integer ut augue est. In venenatis tincidunt scelerisque. Etiam ante dui, posuere quis malesuada vitae, malesuada a arcu. Aenean faucibus venenatis sapien, ut facilisis nisi blandit vel. Aenean ac lorem eu sem fermentum placerat. Proin neque purus, aliquet ut tincidunt ut, convallis sit amet eros. Phasellus vehicula ullamcorper enim non vehicula. Etiam porta odio ut ipsum adipiscing egestas id a odio. Pellentesque blandit, sapien ut pulvinar interdum, mi nulla hendrerit elit, in tempor diam enim a urna. In tellus odio, ornare sed condimentum a, mattis eu augue.
-
-Fusce hendrerit porttitor euismod. Donec malesuada egestas turpis, et ultricies felis elementum vitae. Nullam in sem nibh. Nullam ultricies hendrerit justo sit amet lobortis. Sed tincidunt, mauris at ornare laoreet, sapien purus elementum elit, nec porttitor nisl purus et erat. Donec felis nisi, rutrum ullamcorper gravida ac, tincidunt sit amet urna. Proin vel justo vitae eros sagittis bibendum a ut nibh. Phasellus sodales laoreet tincidunt. Maecenas odio massa, condimentum id aliquet ut, rhoncus vel lectus. Duis pharetra consectetur sapien. Phasellus posuere ultricies massa, non rhoncus risus aliquam tempus.
-
-Praesent venenatis magna id sem dictum eu vehicula ipsum vulputate. Sed a convallis sapien. Sed justo dolor, rhoncus vel rutrum mattis, sollicitudin ut risus. Nullam sit amet convallis est. Etiam non tincidunt ligula. Fusce suscipit pretium elit at ullamcorper. Quisque sollicitudin, diam id interdum porta, metus ipsum volutpat libero, id venenatis felis orci non velit. Suspendisse potenti. Mauris rutrum, tortor sit amet pellentesque tincidunt, erat quam ultricies odio, id aliquam elit leo nec leo. Pellentesque justo eros, rutrum at feugiat nec, porta et tellus. Aenean eget metus lectus.
-
-Praesent euismod, turpis quis laoreet consequat, neque ante imperdiet quam, ac semper tortor nibh in nulla. Integer scelerisque eros vehicula urna lacinia ac facilisis mauris accumsan. Phasellus at mauris nibh. Curabitur enim ante, rutrum sed adipiscing hendrerit, pellentesque non augue. In hac habitasse platea dictumst. Nam tempus euismod massa a dictum. Donec sit amet justo ac diam ultricies ultricies. Sed tincidunt erat quis quam tempus vel interdum erat rhoncus. In hac habitasse platea dictumst. Vestibulum vehicula varius sem eget interdum. Cras bibendum leo nec felis venenatis sed pharetra sem feugiat. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Sed quam orci, mollis eget sagittis accumsan, vulputate sit amet dui. Praesent eu elementum arcu.
-
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum nisl metus, hendrerit ut laoreet sed, consectetur at purus. Duis interdum congue lobortis. Nullam sed massa porta felis eleifend consequat sit amet nec metus. Aliquam placerat dictum erat at eleifend. Vestibulum libero ante, ullamcorper a porttitor suscipit, accumsan vel nisi. Donec et magna neque. Nam elementum ultrices justo, eget sollicitudin sapien imperdiet eget. Nullam auctor dictum nunc, at feugiat odio vestibulum a. Sed erat nulla, viverra hendrerit commodo id, ullamcorper ac orci. Phasellus pellentesque feugiat suscipit. Etiam egestas fermentum enim. Etiam gravida interdum tellus ac laoreet. Morbi mattis aliquet eros, non tempor erat ullamcorper in. Etiam pulvinar interdum turpis ac vehicula. Sed quam justo, accumsan id consectetur a, aliquet sed leo. Aenean vitae blandit mauris.
-
-In sed eros augue, non rutrum odio. Etiam vitae dui neque, in tristique massa. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Maecenas dictum elit at lectus tempor non pharetra nisl hendrerit. Sed sed quam eu lectus ultrices malesuada tincidunt a est. Nam vel eros risus. Maecenas eros elit, blandit fermentum tempor eget, lobortis id diam. Vestibulum lacinia lacus vitae magna volutpat eu dignissim eros convallis. Vivamus ac velit tellus, a congue neque. Integer mi nulla, varius non luctus in, dictum sit amet sem. Ut laoreet, sapien sit amet scelerisque porta, purus sapien vestibulum nibh, sed luctus libero massa ac elit. Donec iaculis odio eget odio sagittis nec venenatis lorem blandit.
-
-Aliquam imperdiet tellus posuere justo vehicula sed vestibulum ante tristique. Fusce feugiat faucibus purus nec molestie. Nulla tempor neque id magna iaculis quis sollicitudin eros semper. Praesent viverra sagittis luctus. Morbi sit amet magna sed odio gravida varius. Ut nisi libero, vulputate feugiat pretium tempus, egestas sit amet justo. Pellentesque consequat tempor nisi in lobortis. Sed fermentum convallis dui ac sollicitudin. Integer auctor augue eget tellus tempus fringilla. Proin nec dolor sapien, nec tristique nibh. Aliquam a velit at mi mattis aliquet.
-
-Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Aliquam ultrices erat non turpis auctor id ornare mauris sagittis. Quisque porttitor, tellus ut convallis sagittis, mi libero feugiat tellus, rhoncus placerat ipsum tortor id risus. Donec tincidunt feugiat leo. Cras id mi neque, eu malesuada eros. Ut molestie magna quis libero placerat malesuada. Aliquam erat volutpat. Aliquam non mauris lorem, in adipiscing metus. Donec eget ipsum in elit commodo ornare bibendum a nibh. Vivamus odio erat, placerat ac vestibulum eget, malesuada ut nisi. Etiam suscipit sollicitudin leo semper sollicitudin. Sed rhoncus risus sit amet sem eleifend dictum pretium sapien egestas. Nulla at urna nunc, vel aliquet leo. Praesent ultricies, mi eu pretium lobortis, erat nibh euismod leo, sit amet gravida sapien eros et turpis. Donec lacinia venenatis lectus, non lacinia mi hendrerit sit amet. Integer sed felis vel orci aliquam pulvinar. Phasellus et risus id erat euismod tincidunt. Sed luctus tempor nisi, nec tempor ipsum elementum eget. Integer nisl tortor, viverra in dapibus at, mattis ac erat. Curabitur nec dui lectus.
-
-Phasellus suscipit, tortor eu varius fringilla, sapien magna egestas risus, ut suscipit dui mauris quis velit. Cras a sapien quis sapien hendrerit tristique a sit amet elit. Pellentesque dui arcu, malesuada et sodales sit amet, dapibus vel quam. Sed non adipiscing ligula. Ut vulputate purus at nisl posuere sodales. Maecenas diam velit, tincidunt id mattis eu, aliquam ac nisi. Maecenas pretium, augue a sagittis suscipit, leo ligula eleifend dolor, mollis feugiat odio augue non eros. Pellentesque scelerisque orci pretium quam mollis at lobortis dui facilisis. Morbi congue metus id tortor porta fringilla. Sed lorem mi, molestie fermentum sagittis at, gravida a nisi. Donec eu vestibulum velit. In viverra, enim eu elementum sodales, enim odio dapibus urna, eget commodo nisl mauris ut odio. Curabitur nec enim nulla. In nec elit ipsum. Nunc in massa suscipit magna elementum faucibus in nec ipsum. Nullam suscipit malesuada elementum. Etiam sed mi in nibh ultricies venenatis nec pharetra magna. In purus ante, rhoncus vel placerat sed, fermentum sit amet dui. Sed at sodales velit.
-
-Duis suscipit pellentesque pellentesque. Praesent porta lobortis cursus. Quisque sagittis velit non tellus bibendum at sollicitudin lacus aliquet. Sed nibh risus, blandit a aliquet eget, vehicula et est. Suspendisse facilisis bibendum aliquam. Fusce consectetur convallis erat, eget mollis diam fermentum sollicitudin. Quisque tincidunt porttitor pretium. Nullam id nisl et urna vulputate dapibus. Donec quis lorem urna. Quisque id justo nec nunc blandit convallis. Nunc volutpat, massa sollicitudin adipiscing vestibulum, massa urna congue lectus, sit amet ultricies augue orci convallis turpis. Nulla at lorem elit. Nunc tristique, quam facilisis commodo porttitor, lacus ligula accumsan nisi, et laoreet justo ante vitae eros. Curabitur sed augue arcu. Phasellus porttitor vestibulum felis, ut consectetur arcu tempor non. In justo risus, semper et suscipit id, ullamcorper at urna. Quisque tincidunt, urna nec aliquam tristique, nibh odio faucibus augue, in ornare enim turpis accumsan dolor. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse sodales varius turpis eu fermentum.
-
-Morbi ultricies diam eget massa posuere lobortis. Aliquam volutpat pellentesque enim eu porttitor. Donec lacus felis, consectetur a pretium vitae, bibendum non enim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam ut nibh a quam pellentesque auctor ut id velit. Duis lacinia justo eget mi placerat bibendum. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec velit tortor, tempus nec tristique id, aliquet sit amet turpis. Praesent et neque nec magna porta fringilla. Morbi id egestas eros. Donec semper tincidunt ullamcorper. Phasellus tempus lacinia hendrerit. Quisque faucibus pretium neque non convallis. Nunc malesuada accumsan rhoncus. Cras lobortis, sem sed fringilla convallis, augue velit semper nisl, commodo varius nisi diam ac leo.
-
-Quisque interdum tellus ac ante posuere ut cursus lorem egestas. Nulla facilisi. Aenean sed massa nec nisi scelerisque vulputate. Etiam convallis consectetur iaculis. Maecenas ac purus ut ante dignissim auctor ac quis lorem. Pellentesque suscipit tincidunt orci. Fusce aliquam dapibus orci, at bibendum ipsum adipiscing eget. Morbi pellentesque hendrerit quam, nec placerat urna vulputate sed. Quisque vel diam lorem. Praesent id diam quis enim elementum rhoncus sagittis eget purus. Quisque fringilla bibendum leo in laoreet. Vestibulum id nibh risus, non elementum metus. Ut a felis diam, non mollis nisl. Cras elit ante, ullamcorper quis iaculis eu, sodales vel est. Curabitur quis lobortis dolor. Aliquam mattis gravida metus pellentesque vulputate.
-
-Ut id augue id dolor luctus euismod et quis velit. Maecenas enim dolor, tempus sit amet hendrerit eu, faucibus vitae neque. Proin sit amet varius elit. Proin varius felis ullamcorper purus dignissim consequat. Cras cursus tempus eros. Nunc ultrices venenatis ullamcorper. Aliquam et feugiat tellus. Phasellus sit amet vestibulum elit. Phasellus ac purus lacus, et accumsan eros. Morbi ultrices, purus a porta sodales, odio metus posuere neque, nec elementum risus turpis sit amet magna. Sed est quam, ultricies at congue adipiscing, lobortis in justo. Proin iaculis dictum nunc, eu laoreet quam varius vitae. Donec sit amet feugiat turpis. Mauris sit amet magna quam, ac consectetur dui. Curabitur eget magna tellus, eu pharetra felis. Donec sit amet tortor nisl. Aliquam et tortor facilisis lacus tincidunt commodo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur nunc magna, ultricies id convallis at, ullamcorper vitae massa.
-
-Phasellus viverra iaculis placerat. Nulla consequat dolor sit amet erat dignissim posuere. Nulla lacinia augue vitae mi tempor gravida. Phasellus non tempor tellus. Quisque non enim semper tortor sagittis facilisis. Aliquam urna felis, egestas at posuere nec, aliquet eu nibh. Praesent sed vestibulum enim. Mauris iaculis velit dui, et fringilla enim. Nulla nec nisi orci. Sed volutpat, justo eget fringilla adipiscing, nisl nulla condimentum libero, sed sodales est est et odio. Cras ipsum dui, varius eu elementum consequat, faucibus in leo. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
-
-Ut malesuada molestie eleifend. Curabitur id enim dui, eu tincidunt nibh. Mauris sit amet ante leo. Duis turpis ipsum, bibendum sed mattis sit amet, accumsan quis dolor. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aenean a imperdiet metus. Quisque sollicitudin felis id neque tempor scelerisque. Donec at orci felis. Vivamus tempus convallis auctor. Donec interdum euismod lobortis. Sed at lacus nec odio dignissim mollis. Sed sapien orci, porttitor tempus accumsan vel, tincidunt nec ante. Nunc rhoncus egestas dapibus. Suspendisse fermentum dictum fringilla. Nullam nisi justo, eleifend a consectetur convallis, porttitor et tortor. Proin vitae lorem non dolor suscipit lacinia eu eget nulla.
-
-Suspendisse egestas, sapien sit amet blandit scelerisque, nulla arcu tristique dui, a porta justo quam vitae arcu. In metus libero, bibendum non volutpat ut, laoreet vel turpis. Nunc faucibus velit eu ipsum commodo nec iaculis eros volutpat. Vivamus congue auctor elit sed suscipit. Duis commodo, libero eu vestibulum feugiat, leo mi dapibus tellus, in placerat nisl dui at est. Vestibulum viverra tristique lorem, ornare egestas erat rutrum a. Nullam at augue massa, ut consectetur ipsum. Pellentesque malesuada, velit ut lobortis sagittis, nisi massa semper odio, malesuada semper purus nisl vel lectus. Nunc dui sem, mattis vitae laoreet vitae, sollicitudin ac leo. Nulla vel fermentum est.
-
-Vivamus in odio a nisi dignissim rhoncus in in lacus. Donec et nisl tortor. Donec sagittis consequat mi, vel placerat tellus convallis id. Aliquam facilisis rutrum nisl sed pretium. Donec et lacinia nisl. Aliquam erat volutpat. Curabitur ac pulvinar tellus. Nullam varius lobortis porta. Cras dapibus, ligula ut porta ultricies, leo lacus viverra purus, quis mollis urna risus eu leo. Nunc malesuada consectetur purus, vel auctor lectus scelerisque posuere. Maecenas dui massa, vestibulum bibendum blandit non, interdum eget mauris. Phasellus est ante, pulvinar at imperdiet quis, imperdiet vel urna. Quisque eget volutpat orci. Quisque et arcu purus, ut faucibus velit.
-
-Praesent sed ipsum urna. Praesent sagittis varius magna, id commodo dolor malesuada ac. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Quisque sit amet nunc eu sem ornare tempor. Mauris id dolor nec erat convallis porta in lobortis nisi. Curabitur hendrerit rhoncus tortor eu hendrerit. Pellentesque eu ante vel elit luctus eleifend quis viverra nulla. Suspendisse odio diam, euismod eu porttitor molestie, sollicitudin sit amet nulla. Sed ante urna, dictum bibendum rhoncus et, blandit nec ante. Suspendisse tortor augue, accumsan quis suscipit id, accumsan sit amet erat. Donec pharetra varius lobortis. Maecenas ipsum diam, faucibus eu tempus id, convallis nec enim. Duis arcu turpis, fringilla nec egestas ut, dignissim tristique nulla. Curabitur suscipit dui non justo ultrices pharetra. Aliquam erat volutpat. Nulla facilisi. Quisque id felis eu sem aliquam fringilla.
-
-Etiam quis augue in tellus consequat eleifend. Aenean dignissim congue felis id elementum. Duis fringilla varius ipsum, nec suscipit leo semper vel. Ut sollicitudin, orci a tincidunt accumsan, diam lectus laoreet lacus, vel fermentum quam est vel eros. Aliquam fringilla sapien ac sapien faucibus convallis. Aliquam id nunc eu justo consequat tincidunt. Quisque nec nisl dui. Phasellus augue lectus, varius vitae auctor vel, rutrum at risus. Vivamus lacinia leo quis neque ultrices nec elementum felis fringilla. Proin vel porttitor lectus.
-
-Curabitur sapien lorem, mollis ut accumsan non, ultricies et metus. Curabitur vel lorem quis sapien fringilla laoreet. Morbi id urna ac orci elementum blandit eget volutpat neque. Pellentesque sem odio, iaculis eu pharetra vitae, cursus in quam. Nulla molestie ligula id massa luctus et pulvinar nisi pulvinar. Nunc fermentum augue a lacus fringilla rhoncus porttitor erat dictum. Nunc sit amet tellus et dui viverra auctor euismod at nisl. In sed congue magna. Proin et tortor ut augue placerat dignissim a eu justo. Morbi porttitor porta lobortis. Pellentesque nibh lacus, adipiscing ut tristique quis, consequat vitae velit. Maecenas ut luctus libero. Vivamus auctor odio et erat semper sagittis. Vivamus interdum velit in risus mattis quis dictum ante rhoncus. In sagittis porttitor eros, at lobortis metus ultrices vel. Curabitur non aliquam nisl. Vestibulum luctus feugiat suscipit. Etiam non lacus vel nulla egestas iaculis id quis risus.
-
-Etiam in auctor urna. Fusce ultricies molestie convallis. In hac habitasse platea dictumst. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Mauris iaculis lorem faucibus purus gravida at convallis turpis sollicitudin. Suspendisse at velit lorem, a fermentum ipsum. Etiam condimentum, dui vel condimentum elementum, sapien sem blandit sapien, et pharetra leo neque et lectus. Nunc viverra urna iaculis augue ultrices ac porttitor lacus dignissim. Aliquam ut turpis dui. Sed eget aliquet felis. In bibendum nibh sit amet sapien accumsan accumsan pharetra magna molestie.
-
-Mauris aliquet urna eget lectus adipiscing at congue turpis consequat. Vivamus tincidunt fermentum risus et feugiat. Nulla molestie ullamcorper nibh sed facilisis. Phasellus et cursus purus. Nam cursus, dui dictum ultrices viverra, erat risus varius elit, eu molestie dui eros quis quam. Aliquam et ante neque, ac consectetur dui. Donec condimentum erat id elit dictum sed accumsan leo sagittis. Proin consequat congue risus, vel tincidunt leo imperdiet eu. Vestibulum malesuada turpis eu metus imperdiet pretium. Aliquam condimentum ultrices nibh, eu semper enim eleifend a. Etiam condimentum nisl quam.
-
-Pellentesque id molestie nisl. Maecenas et lectus at justo molestie viverra sit amet sit amet ligula. Nullam non porttitor magna. Quisque elementum arcu cursus tortor rutrum lobortis. Morbi sit amet lectus vitae enim euismod dignissim eget at neque. Vivamus consequat vehicula dui, vitae auctor augue dignissim in. In tempus sem quis justo tincidunt sit amet auctor turpis lobortis. Pellentesque non est nunc. Vestibulum mollis fringilla interdum. Maecenas ipsum dolor, pharetra id tristique mattis, luctus vitae urna. Ut ullamcorper arcu eget elit convallis mollis. Pellentesque condimentum, massa ac hendrerit tempor, mauris purus blandit justo, et pharetra leo justo a est. Duis arcu augue, facilisis vel dignissim sed, aliquam quis magna. Quisque non consequat dolor. Suspendisse a ultrices leo.
-
-Donec vitae pretium nibh. Maecenas bibendum bibendum diam in placerat. Ut accumsan, mi vitae vestibulum euismod, nunc justo vulputate nisi, non placerat mi urna et diam. Maecenas malesuada lorem ut arcu mattis mollis. Nulla facilisi. Donec est leo, bibendum eu pulvinar in, cursus vel metus. Aliquam erat volutpat. Nullam feugiat porttitor neque in vulputate. Quisque nec mi eu magna consequat cursus non at arcu. Etiam risus metus, sollicitudin et ultrices at, tincidunt sed nunc. Sed eget scelerisque augue. Ut fringilla venenatis sem non eleifend. Nunc mattis, risus sit amet vulputate varius, risus justo egestas mauris, id interdum odio ipsum et nisl. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi id erat odio, nec pulvinar enim.
-
-Curabitur ac fermentum quam. Morbi eu eros sapien, vitae tempus dolor. Mauris vestibulum blandit enim ut venenatis. Aliquam egestas, eros at consectetur tincidunt, lorem augue iaculis est, nec mollis felis arcu in nunc. Sed in odio sed libero pellentesque volutpat vitae a ante. Morbi commodo volutpat tellus, ut viverra purus placerat fermentum. Integer iaculis facilisis arcu, at gravida lorem bibendum at. Aenean id eros eget est sagittis convallis sed et dui. Donec eu pulvinar tellus. Nunc dignissim rhoncus tellus, at pellentesque metus luctus at. Sed ornare aliquam diam, a porttitor leo sollicitudin sed. Nam vitae lectus lacus. Integer adipiscing quam neque, blandit posuere libero. Sed libero nunc, egestas sodales tempus sed, cursus blandit tellus. Vestibulum mi purus, ultricies quis placerat vel, molestie at dui.
-
-Nulla commodo odio justo. Pellentesque non ornare diam. In consectetur sapien ac nunc sagittis malesuada. Morbi ullamcorper tempor erat nec rutrum. Duis ut commodo justo. Cras est orci, consectetur sed interdum sed, scelerisque sit amet nulla. Vestibulum justo nulla, pellentesque a tempus et, dapibus et arcu. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi tristique, eros nec congue adipiscing, ligula sem rhoncus felis, at ornare tellus mauris ac risus. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Proin mauris dui, tempor fermentum dictum et, cursus a leo. Maecenas nec nisl a tellus pellentesque rhoncus. Nullam ultrices euismod dui eu congue.
-
-In nec tempor risus. In faucibus nisi eget diam dignissim consequat. Donec pulvinar ante nec enim mattis rutrum. Vestibulum leo augue, molestie nec dapibus in, dictum at enim. Integer aliquam, lorem eu vulputate lacinia, mi orci tempor enim, eget mattis ligula magna a magna. Praesent sed erat ut tortor interdum viverra. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla facilisi. Maecenas sit amet lectus lacus. Nunc vitae purus id ligula laoreet condimentum. Duis auctor tortor vel dui pulvinar a facilisis arcu dignissim. In hac habitasse platea dictumst. Donec sollicitudin pellentesque egestas. Sed sed sem justo. Maecenas laoreet hendrerit mauris, ut porttitor lorem iaculis ac. Quisque molestie sem quis lorem tempor rutrum. Phasellus nibh mauris, rhoncus in consectetur non, aliquet eu massa.
-
-Curabitur velit arcu, pretium porta placerat quis, varius ut metus. Vestibulum vulputate tincidunt justo, vitae porttitor lectus imperdiet sit amet. Vivamus enim dolor, sollicitudin ut semper non, ornare ornare dui. Aliquam tempor fermentum sapien eget condimentum. Curabitur laoreet bibendum ante, in euismod lacus lacinia eu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Suspendisse potenti. Sed at libero eu tortor tempus scelerisque. Nulla facilisi. Nullam vitae neque id justo viverra rhoncus pretium at libero. Etiam est urna, aliquam vel pulvinar non, ornare vel purus.
-
-Nulla varius, nisi eget condimentum semper, metus est dictum odio, vel mattis risus est sed velit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc non est nec tellus ultricies mattis ut eget velit. Integer condimentum ante id lorem blandit lacinia. Donec vel tortor augue, in condimentum nisi. Pellentesque pellentesque nulla ut nulla porttitor quis sodales enim rutrum. Sed augue risus, euismod a aliquet at, vulputate non libero. Nullam nibh odio, dignissim fermentum pulvinar ac, congue eu mi. Duis tincidunt, nibh id venenatis placerat, diam turpis gravida leo, sit amet mollis massa dolor quis mauris. Vivamus scelerisque sodales arcu et dapibus. Suspendisse potenti. Cras quis tellus arcu, quis laoreet sem. Fusce porttitor, sapien vel tristique sodales, velit leo porta arcu, quis pellentesque nunc metus non odio. Nam arcu libero, ullamcorper ut pharetra non, dignissim et velit. Quisque dolor lorem, vehicula sit amet scelerisque in, varius at nulla. Pellentesque vitae sem eget tortor iaculis pulvinar. Sed nunc justo, euismod gravida pulvinar eget, gravida eget turpis. Cras vel dictum nisi. Nullam nulla libero, gravida sit amet aliquam quis, commodo vitae odio. Cras vitae nibh nec dui placerat semper.
-
-Vivamus at fringilla eros. Vivamus at nisl id massa commodo feugiat quis non massa. Morbi tellus urna, auctor sit amet elementum sed, rutrum non lectus. Nulla feugiat dui in sapien ornare et imperdiet est ornare. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum semper rutrum tempor. Sed in felis nibh, sed aliquam enim. Curabitur ut quam scelerisque velit placerat dictum. Donec eleifend vehicula purus, eu vestibulum sapien rutrum eu. Vivamus in odio vel est vulputate iaculis. Nunc rutrum feugiat pretium.
-
-Maecenas ipsum neque, auctor quis lacinia vitae, euismod ac orci. Donec molestie massa consequat est porta ac porta purus tincidunt. Nam bibendum leo nec lacus mollis non condimentum dolor rhoncus. Nulla ac volutpat lorem. Nullam erat purus, convallis eget commodo id, varius quis augue. Nullam aliquam egestas mi, vel suscipit nisl mattis consequat. Quisque vel egestas sapien. Nunc lorem velit, convallis nec laoreet et, aliquet eget massa. Nam et nibh ac dui vehicula aliquam quis eu augue. Cras vel magna ut elit rhoncus interdum iaculis volutpat nisl. Suspendisse arcu lorem, varius rhoncus tempor id, pulvinar sed tortor. Pellentesque ultricies laoreet odio ac dignissim. Aliquam diam arcu, placerat quis egestas eget, facilisis eu nunc. Mauris vulputate, nisl sit amet mollis interdum, risus tortor ornare orci, sed egestas orci eros non diam. Vestibulum hendrerit, metus quis placerat pellentesque, enim purus faucibus dui, sit amet ultricies lectus ipsum id lorem. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Praesent eget diam odio, eu bibendum elit. In vestibulum orci eu erat tincidunt tristique.
-
-Cras consectetur ante eu turpis placerat sollicitudin. Mauris et lacus tortor, eget pharetra velit. Donec accumsan ultrices tempor. Donec at nibh a elit condimentum dapibus. Integer sit amet vulputate ante. Suspendisse potenti. In sodales laoreet massa vitae lacinia. Morbi vel lacus feugiat arcu vulputate molestie. Aliquam massa magna, ullamcorper accumsan gravida quis, rhoncus pulvinar nulla. Praesent sit amet ipsum diam, sit amet lacinia neque. In et sapien augue. Etiam enim elit, ultrices vel rutrum id, scelerisque non enim.
-
-Proin et egestas neque. Praesent et ipsum dolor. Nunc non varius nisl. Fusce in tortor nisi. Maecenas convallis neque in ligula blandit quis vehicula leo mollis. Pellentesque sagittis blandit leo, dapibus pellentesque leo ultrices ac. Curabitur ac egestas libero. Donec pretium pharetra pretium. Fusce imperdiet, turpis eu aliquam porta, ante elit eleifend risus, luctus auctor arcu ante ut nunc. Vivamus in leo felis, vitae eleifend lacus. Donec tempus aliquam purus porttitor tristique. Suspendisse diam neque, suscipit feugiat fringilla non, eleifend sit nullam.
diff --git a/test/javascript/tests/lorem_b64.txt b/test/javascript/tests/lorem_b64.txt
deleted file mode 100644
index 8a21d79e6..000000000
--- a/test/javascript/tests/lorem_b64.txt
+++ /dev/null
@@ -1 +0,0 @@
-TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gUGhhc2VsbHVzIG51bmMgc2FwaWVuLCBwb3J0YSBpZCBwZWxsZW50ZXNxdWUgYXQsIGVsZW1lbnR1bSBldCBmZWxpcy4gQ3VyYWJpdHVyIGNvbmRpbWVudHVtIGFudGUgaW4gbWV0dXMgaWFjdWxpcyBxdWlzIGNvbmd1ZSBkaWFtIGNvbW1vZG8uIERvbmVjIGVsZWlmZW5kIGFudGUgc2VkIG51bGxhIGRhcGlidXMgY29udmFsbGlzLiBVdCBjdXJzdXMgYWxpcXVhbSBuZXF1ZSwgdmVsIHBvcnR0aXRvciB0ZWxsdXMgaW50ZXJkdW0gdXQuIFNlZCBwaGFyZXRyYSBsYWNpbmlhIGFkaXBpc2NpbmcuIEluIHRyaXN0aXF1ZSB0cmlzdGlxdWUgZmVsaXMgbm9uIHRpbmNpZHVudC4gTnVsbGEgYXVjdG9yIG1hdXJpcyBhIHZlbGl0IGN1cnN1cyB1bHRyaWNpZXMuIEluIGF0IGxpYmVybyBxdWlzIGp1c3RvIGNvbnNlY3RldHVyIGxhb3JlZXQuIE51bGxhbSBpZCB1bHRyaWNlcyBudW5jLiBEb25lYyBub24gdHVycGlzIG51bGxhLCBldSBsYWNpbmlhIGFudGUuIE51bmMgZXUgb3JjaSBldCB0dXJwaXMgcHJldGl1bSB2ZW5lbmF0aXMuIE5hbSBtb2xlc3RpZSwgbGFjdXMgYXQgZGlnbmlzc2ltIGVsZW1lbnR1bSwgYW50ZSBsaWJlcm8gY29uc2VjdGV0dXIgbGliZXJvLCB1dCBsYWNpbmlhIGxhY3VzIHVybmEgZXQgcHVydXMuIE51bGxhbSBsb3JlbSBpcHN1bSwgZGFwaWJ1cyB2ZWwgdWxsYW1jb3JwZXIgYSwgbWFsZXN1YWRhIGEgbWV0dXMuIFNlZCBwb3J0YSBhZGlwaXNjaW5nIG1hZ25hLCBxdWlzIHB1bHZpbmFyIHB1cnVzIG1hdHRpcyBmcmluZ2lsbGEuIEludGVnZXIgcGVsbGVudGVzcXVlIHNhcGllbiBpbiBuZXF1ZSB0cmlzdGlxdWUgYWMgaWFjdWxpcyBsaWJlcm8gdWx0cmljaWVzLiBVdCBlZ2V0IHBoYXJldHJhIHB1cnVzLgoKTnVsbGEgaW4gY29udmFsbGlzIHRlbGx1cy4gUHJvaW4gdGluY2lkdW50IHN1c2NpcGl0IHZ1bHB1dGF0ZS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gTnVsbGFtIHRyaXN0aXF1ZSBqdXN0byBtaSwgYSB0cmlzdGlxdWUgbGlndWxhLiBEdWlzIGNvbnZhbGxpcyBhbGlxdWFtIGlhY3VsaXMuIE51bGxhIGRpY3R1bSBmcmluZ2lsbGEgY29uZ3VlLiBTdXNwZW5kaXNzZSBhYyBsZW8gbGVjdHVzLCBhYyBhbGlxdWFtIGp1c3RvLiBVdCBwb3J0dGl0b3IgY29tbW9kbyBtaSBzZWQgbHVjdHVzLiBOdWxsYSBhdCBlbmltIGxvcmVtLiBOdW5jIGV1IGp1c3RvIHNhcGllbiwgYSBibGFuZGl0IG9kaW8uIEN1cmFiaXR1ciBmYXVjaWJ1cyBzb2xsaWNpdHVkaW4gZG9sb3IsIGlkIGxhY2luaWEgc2VtIGF1Y3RvciBpbi4gRG9uZWMgdmFyaXVzIG51bmMgYXQgbGVjdHVzIHNhZ2l0dGlzIG5lYyBsdWN0dXMgYXJjdSBwaGFyZXRyYS4gTnVuYyBzZWQgbWV0dXMganVzdG8uIENyYXMgdmVsIG1hdXJpcyBkaWFtLiBVdCBmZXVnaWF0IGZlbGlzIGVnZXQgbmVxdWUgcGhhcmV0cmEgdmVzdGlidWx1bSBjb25zZWN0ZXR1ciBtYXNzYSBmYWNpbGlzaXMuIFF1aXNxdWUgY29uc2VjdGV0dXIgbHVjdHVzIG5pc2kgcXVpcyB0aW5jaWR1bnQuIFZpdmFtdXMgY3Vyc3VzIGN1cnN1cyBxdWFtIG5vbiBibGFuZGl0LiBQZWxsZW50ZXNxdWUgZXQgdmVsaXQgbGFjdXMuIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLgoKSW4gZXQgZG9sb3Igdml0YWUgb3JjaSBhZGlwaXNjaW5nIGNvbmd1ZS4gQWxpcXVhbSBncmF2aWRhIG5pYmggYXQgbmlzbCBncmF2aWRhIG1vbGVzdGllLiBDdXJhYml0dXIgYSBiaWJlbmR1bSBzYXBpZW4uIEFsaXF1YW0gdGluY2lkdW50LCBudWxsYSBuZWMgcHJldGl1bSBsb2JvcnRpcywgb2RpbyBhdWd1ZSB0aW5jaWR1bnQgYXJjdSwgYSBsb2JvcnRpcyBvZGlvIHNlbSB1dCBwdXJ1cy4gRG9uZWMgYWNjdW1zYW4gbWF0dGlzIG51bmMgdml0YWUgbGFjaW5pYS4gU3VzcGVuZGlzc2UgcG90ZW50aS4gSW50ZWdlciBjb21tb2RvIG5pc2wgcXVpcyBuaWJoIGludGVyZHVtIG5vbiBmcmluZ2lsbGEgZHVpIHNvZGFsZXMuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIEV0aWFtIHVsbGFtY29ycGVyLCBtaSBpZCBmZXVnaWF0IGJpYmVuZHVtLCBwdXJ1cyBuZXF1ZSBjdXJzdXMgbWF1cmlzLCBpZCBzb2RhbGVzIHF1YW0gbmlzaSBpZCB2ZWxpdC4gU2VkIGxlY3R1cyBsZW8sIHRpbmNpZHVudCB2ZWwgcmhvbmN1cyBpbXBlcmRpZXQsIGJsYW5kaXQgaW4gbGVvLiBJbnRlZ2VyIHF1aXMgbWFnbmEgbnVsbGEuIERvbmVjIHZlbCBuaXNsIG1hZ25hLCB1dCByaG9uY3VzIGR1aS4gQWxpcXVhbSBncmF2aWRhLCBudWxsYSBuZWMgZWxlaWZlbmQgbHVjdHVzLCBuZXF1ZSBuaWJoIHBoYXJldHJhIGFudGUsIHF1aXMgZWdlc3RhcyBlbGl0IG1ldHVzIGEgbWkuIE51bmMgbmVjIGF1Z3VlIHF1YW0uIE1vcmJpIHRpbmNpZHVudCB0cmlzdGlxdWUgdmFyaXVzLiBTdXNwZW5kaXNzZSBpYWN1bGlzIGVsaXQgZmV1Z2lhdCBtYWduYSBwZWxsZW50ZXNxdWUgdWx0cmljaWVzLiBWZXN0aWJ1bHVtIGFsaXF1YW0gdG9ydG9yIG5vbiBhbnRlIHVsbGFtY29ycGVyIGZyaW5naWxsYS4gRG9uZWMgaWFjdWxpcyBtaSBxdWlzIG1hdXJpcyBvcm5hcmUgdmVzdGlidWx1bS4KCkluIGEgbWFnbmEgbmlzaSwgYSB1bHRyaWNpZXMgbWFzc2EuIERvbmVjIGVsaXQgbmVxdWUsIHZpdmVycmEgbm9uIHRlbXBvciBxdWlzLCBmcmluZ2lsbGEgaW4gbWV0dXMuIEludGVnZXIgb2RpbyBvZGlvLCBldWlzbW9kIHZpdGFlIG1vbGxpcyBzZWQsIHNvZGFsZXMgZWdldCBsaWJlcm8uIERvbmVjIG5lYyBtYXNzYSBpbiBmZWxpcyBvcm5hcmUgcGhhcmV0cmEgYXQgbmVjIHRlbGx1cy4gTnVuYyBsb3JlbSBkb2xvciwgcHJldGl1bSB2ZWwgYXVjdG9yIGluLCB2b2x1dHBhdCB2aXRhZSBmZWxpcy4gTWFlY2VuYXMgcmhvbmN1cywgb3JjaSB2ZWwgYmxhbmRpdCBldWlzbW9kLCB0dXJwaXMgZXJhdCB0aW5jaWR1bnQgYW50ZSwgZWxlbWVudHVtIGFkaXBpc2NpbmcgbmlzbCB1cm5hIGluIG5pc2kuIFBoYXNlbGx1cyBzYWdpdHRpcywgZW5pbSBzZWQgYWNjdW1zYW4gY29uc2VxdWF0LCB1cm5hIGF1Z3VlIGxvYm9ydGlzIGVyYXQsIG5vbiBtYWxlc3VhZGEgcXVhbSBtZXR1cyBzb2xsaWNpdHVkaW4gYW50ZS4gSW4gbGVvIHB1cnVzLCBkaWduaXNzaW0gcXVpcyB2YXJpdXMgdmVsLCBwZWxsZW50ZXNxdWUgZXQgbmliaC4gSW4gc2VkIHRvcnRvciBpYWN1bGlzIGxpYmVybyBtb2xsaXMgcGVsbGVudGVzcXVlIGlkIHZpdGFlIGxlY3R1cy4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIFBoYXNlbGx1cyBtYXVyaXMgZW5pbSwgcG9zdWVyZSBlZ2V0IGx1Y3R1cyBhYywgaWFjdWxpcyBldCBxdWFtLiBWaXZhbXVzIGV0IG5pYmggZGlhbSwgZWxlbWVudHVtIGVnZXN0YXMgdGVsbHVzLiBBZW5lYW4gdnVscHV0YXRlIG1hbGVzdWFkYSBlc3QuIFNlZCBwb3N1ZXJlIHBvcnRhIGRpYW0gYSBzb2RhbGVzLiBQcm9pbiBldSBzZW0gbm9uIHZlbGl0IGZhY2lsaXNpcyB2ZW5lbmF0aXMgc2VkIGEgdHVycGlzLgoKUGVsbGVudGVzcXVlIHNlZCByaXN1cyBhIGFudGUgdnVscHV0YXRlIGxvYm9ydGlzIHNpdCBhbWV0IGV1IG5pc2wuIFN1c3BlbmRpc3NlIHV0IGVyb3MgbWksIGEgcmhvbmN1cyBsYWN1cy4gQ3VyYWJpdHVyIGZlcm1lbnR1bSB2ZWhpY3VsYSB0ZWxsdXMsIGEgb3JuYXJlIG1pIGNvbmRpbWVudHVtIHZlbC4gSW50ZWdlciBtb2xlc3RpZSB2b2x1dHBhdCB2aXZlcnJhLiBJbnRlZ2VyIHBvc3VlcmUgZXVpc21vZCB2ZW5lbmF0aXMuIFByb2luIGFjIG1hdXJpcyBzZWQgbnVsbGEgcGhhcmV0cmEgcG9ydHRpdG9yLiBEdWlzIHZlbCBkdWkgaW4gcmlzdXMgc29kYWxlcyBhdWN0b3Igc2l0IGFtZXQgbm9uIGVuaW0uIE1hZWNlbmFzIG1vbGxpcyBsYWN1cyBhdCBsaWd1bGEgZmF1Y2lidXMgc29kYWxlcy4gQ3JhcyB2ZWwgbmVxdWUgYXJjdS4gU2VkIHRpbmNpZHVudCB0b3J0b3IgcHJldGl1bSBuaXNpIGludGVyZHVtIHF1aXMgZGljdHVtIGFyY3UgbGFvcmVldC4gTW9yYmkgcHJldGl1bSB1bHRyaWNlcyBmZXVnaWF0LiBNYWVjZW5hcyBjb252YWxsaXMgYXVndWUgbmVjIGZlbGlzIG1hbGVzdWFkYSBtYWxlc3VhZGEgc2NlbGVyaXNxdWUgbWF1cmlzIHBsYWNlcmF0LiBTZWQgYXQgbWFnbmEgZW5pbSwgYXQgZnJpbmdpbGxhIGRvbG9yLiBRdWlzcXVlIHV0IG1hdHRpcyBkdWkuIFByYWVzZW50IGNvbnNlY3RldHVyIGFudGUgdml2ZXJyYSBuaXNpIGJsYW5kaXQgcGhhcmV0cmEuIFF1aXNxdWUgbWV0dXMgZWxpdCwgZGlnbmlzc2ltIHZpdGFlIGZlcm1lbnR1bSBzaXQgYW1ldCwgZnJpbmdpbGxhIGltcGVyZGlldCBvZGlvLiBDcmFzIGVnZXQgcHVydXMgZWdldCB0ZWxsdXMgZmV1Z2lhdCBsdWN0dXMgYSBhYyBwdXJ1cy4gQ3JhcyB2aXRhZSBuaXNsIHZlbCBhdWd1ZSByaG9uY3VzIHBvcnR0aXRvciBzaXQgYW1ldCBxdWlzIGxvcmVtLiBEb25lYyBpbnRlcmR1bSBwZWxsZW50ZXNxdWUgYWRpcGlzY2luZy4gUGhhc2VsbHVzIG5lcXVlIGxpYmVybywgYWxpcXVhbSBpbiBtYXR0aXMgdml0YWUsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgbmliaC4KCkRvbmVjIG5lYyBudWxsYSB1cm5hLCBhYyBzYWdpdHRpcyBsZWN0dXMuIFN1c3BlbmRpc3NlIG5vbiBlbGl0IHNlZCBtaSBhdWN0b3IgZmFjaWxpc2lzIHZpdGFlIGV0IGxlY3R1cy4gRnVzY2UgYWMgdnVscHV0YXRlIG1hdXJpcy4gTW9yYmkgY29uZGltZW50dW0gdWx0cmljZXMgbWV0dXMsIGV0IGFjY3Vtc2FuIHB1cnVzIG1hbGVzdWFkYSBhdC4gTWFlY2VuYXMgbG9ib3J0aXMgYW50ZSBzZWQgbWFzc2EgZGljdHVtIHZpdGFlIHZlbmVuYXRpcyBlbGl0IGNvbW1vZG8uIFByb2luIHRlbGx1cyBlcm9zLCBhZGlwaXNjaW5nIHNlZCBkaWduaXNzaW0gdml0YWUsIHRlbXBvciBlZ2V0IGFudGUuIEFlbmVhbiBpZCB0ZWxsdXMgbmVjIG1hZ25hIGN1cnN1cyBwaGFyZXRyYSB2aXRhZSB2ZWwgZW5pbS4gTW9yYmkgdmVzdGlidWx1bSBwaGFyZXRyYSBlc3QgaW4gdnVscHV0YXRlLiBBbGlxdWFtIHZpdGFlIG1ldHVzIGFyY3UsIGlkIGFsaXF1ZXQgbnVsbGEuIFBoYXNlbGx1cyBsaWd1bGEgZXN0LCBoZW5kcmVyaXQgbmVjIGlhY3VsaXMgdXQsIHZvbHV0cGF0IHZlbCBlcm9zLiBTdXNwZW5kaXNzZSB2aXRhZSB1cm5hIHR1cnBpcywgcGxhY2VyYXQgYWRpcGlzY2luZyBkaWFtLiBQaGFzZWxsdXMgZmV1Z2lhdCB2ZXN0aWJ1bHVtIG5lcXVlIGV1IGRhcGlidXMuIE51bGxhIGZhY2lsaXNpLiBEdWlzIHRvcnRvciBmZWxpcywgZXVpc21vZCBzaXQgYW1ldCBhbGlxdWV0IGluLCB2b2x1dHBhdCBuZWMgdHVycGlzLiBNYXVyaXMgcmhvbmN1cyBpcHN1bSB1dCBwdXJ1cyBlbGVpZmVuZCB1dCBsb2JvcnRpcyBsZWN0dXMgZGFwaWJ1cy4gUXVpc3F1ZSBub24gZXJhdCBsb3JlbS4gVml2YW11cyBwb3N1ZXJlIGltcGVyZGlldCBpYWN1bGlzLiBVdCBsaWd1bGEgbGFjdXMsIGVsZWlmZW5kIGF0IHRlbXBvciBpZCwgYXVjdG9yIGV1IGxlby4KCkRvbmVjIG1pIGVuaW0sIGxhb3JlZXQgcHVsdmluYXIgbW9sbGlzIGV1LCBtYWxlc3VhZGEgdml2ZXJyYSBudW5jLiBJbiB2aXRhZSBtZXR1cyB2aXRhZSBuZXF1ZSB0ZW1wb3IgZGFwaWJ1cy4gTWFlY2VuYXMgdGluY2lkdW50IHB1cnVzIGEgZmVsaXMgYWxpcXVhbSBwbGFjZXJhdC4gTnVsbGEgZmFjaWxpc2kuIFN1c3BlbmRpc3NlIHBsYWNlcmF0IHBoYXJldHJhIG1hdHRpcy4gSW50ZWdlciB0ZW1wb3IgbWFsZXN1YWRhIGp1c3RvIGF0IHRlbXB1cy4gTWFlY2VuYXMgdmVoaWN1bGEgbG9yZW0gYSBzYXBpZW4gYmliZW5kdW0gdmVsIGlhY3VsaXMgcmlzdXMgZmV1Z2lhdC4gUGVsbGVudGVzcXVlIGRpYW0gZXJhdCwgZGFwaWJ1cyBldCBwZWxsZW50ZXNxdWUgcXVpcywgbW9sZXN0aWUgdXQgbWFzc2EuIFZpdmFtdXMgaWFjdWxpcyBpbnRlcmR1bSBtYXNzYSBpZCBiaWJlbmR1bS4gUXVpc3F1ZSB1dCBtYXVyaXMgZHVpLCBzaXQgYW1ldCB2YXJpdXMgZWxpdC4gVmVzdGlidWx1bSBlbGl0IGxvcmVtLCBydXRydW0gbm9uIGNvbnNlY3RldHVyIHV0LCBsYW9yZWV0IG5lYyBudW5jLiBEb25lYyBuZWMgbWF1cmlzIGFudGUuIEN1cmFiaXR1ciB1dCBlc3Qgc2VkIG9kaW8gcGhhcmV0cmEgbGFvcmVldC4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gQ3VyYWJpdHVyIHB1cnVzIHJpc3VzLCBsYW9yZWV0IHNlZCBwb3J0YSBpZCwgc2FnaXR0aXMgdmVsIGlwc3VtLiBNYWVjZW5hcyBuaWJoIGRpYW0sIGN1cnN1cyBldCB2YXJpdXMgc2l0IGFtZXQsIGZyaW5naWxsYSBzZWQgbWFnbmEuIE51bGxhbSBpZCBuZXF1ZSBldSBsZW8gZmF1Y2lidXMgbW9sbGlzLiBEdWlzIG5lYyBhZGlwaXNjaW5nIG1hdXJpcy4gU3VzcGVuZGlzc2Ugc29sbGljaXR1ZGluLCBlbmltIGV1IHB1bHZpbmFyIGNvbW1vZG8sIGVyYXQgYXVndWUgdWx0cmljZXMgbWksIGEgdHJpc3RpcXVlIG1hZ25hIHNlbSBub24gbGliZXJvLgoKU2VkIGluIG1ldHVzIG51bGxhLiBQcmFlc2VudCBuZWMgYWRpcGlzY2luZyBzYXBpZW4uIERvbmVjIGxhb3JlZXQsIHZlbGl0IG5vbiBydXRydW0gdmVzdGlidWx1bSwgbGlndWxhIG5lcXVlIGFkaXBpc2NpbmcgdHVycGlzLCBhdCBhdWN0b3Igc2FwaWVuIGVsaXQgdXQgbWFzc2EuIE51bGxhbSBhbGlxdWFtLCBlbmltIHZlbCBwb3N1ZXJlIHJ1dHJ1bSwganVzdG8gZXJhdCBsYW9yZWV0IGVzdCwgdmVsIGZyaW5naWxsYSBsYWN1cyBuaXNpIG5vbiBsZWN0dXMuIEV0aWFtIGxlY3R1cyBudW5jLCBsYW9yZWV0IGV0IHBsYWNlcmF0IGF0LCB2ZW5lbmF0aXMgcXVpcyBsaWJlcm8uIFByYWVzZW50IGluIHBsYWNlcmF0IGVsaXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gUGVsbGVudGVzcXVlIGZyaW5naWxsYSBhdWd1ZSBldSBuaWJoIHBsYWNlcmF0IGRpY3R1bS4gTnVuYyBwb3J0dGl0b3IgdHJpc3RpcXVlIGRpYW0sIGV1IGFsaXF1YW0gZW5pbSBhbGlxdWV0IHZlbC4gQWxpcXVhbSBsYWNpbmlhIGludGVyZHVtIGlwc3VtLCBpbiBwb3N1ZXJlIG1ldHVzIGx1Y3R1cyB2ZWwuIFZpdmFtdXMgZXQgbmlzbCBhIGVyb3Mgc2VtcGVyIGVsZW1lbnR1bS4gRG9uZWMgdmVuZW5hdGlzIG9yY2kgYXQgZGlhbSB0cmlzdGlxdWUgc29sbGljaXR1ZGluLiBJbiBldSBlcm9zIHNlZCBvZGlvIHJ1dHJ1bSBsdWN0dXMgbm9uIG5lYyB0ZWxsdXMuCgpOdWxsYSBuZWMgZmVsaXMgZWxpdC4gTnVsbGFtIGluIGlwc3VtIGluIGlwc3VtIGNvbnNlcXVhdCBmcmluZ2lsbGEgcXVpcyB2ZWwgdG9ydG9yLiBQaGFzZWxsdXMgbm9uIG1hc3NhIG5pc2ksIHNpdCBhbWV0IGFsaXF1YW0gdXJuYS4gU2VkIGZlcm1lbnR1bSBuaWJoIHZpdGFlIGxhY3VzIHRpbmNpZHVudCBuZWMgdGluY2lkdW50IG1hc3NhIGJpYmVuZHVtLiBFdGlhbSBlbGl0IGR1aSwgZmFjaWxpc2lzIHNpdCBhbWV0IHZlaGljdWxhIG5lYywgaWFjdWxpcyBhdCBzYXBpZW4uIFV0IGF0IG1hc3NhIGlkIGR1aSB1bHRyaWNlcyB2b2x1dHBhdCB1dCBhYyBsaWJlcm8uIEZ1c2NlIGlwc3VtIG1pLCBiaWJlbmR1bSBhIGxhY2luaWEgZXQsIHB1bHZpbmFyIGVnZXQgbWF1cmlzLiBQcm9pbiBmYXVjaWJ1cyB1cm5hIHV0IGxvcmVtIGVsZW1lbnR1bSB2dWxwdXRhdGUuIER1aXMgcXVhbSBsZW8sIG1hbGVzdWFkYSBub24gZXVpc21vZCB1dCwgYmxhbmRpdCBmYWNpbGlzaXMgbWF1cmlzLiBTdXNwZW5kaXNzZSBzaXQgYW1ldCBtYWduYSBpZCB2ZWxpdCB0aW5jaWR1bnQgYWxpcXVldCBuZWMgZXUgZG9sb3IuIEN1cmFiaXR1ciBiaWJlbmR1bSBsb3JlbSB2ZWwgZmVsaXMgdGVtcHVzIGRhcGlidXMuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gQWVuZWFuIGN1cnN1cyB0b3J0b3IgbmVjIGR1aSBhbGlxdWV0IHBvcnRhLiBBZW5lYW4gY29tbW9kbyBpYWN1bGlzIHN1c2NpcGl0LiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUXVpc3F1ZSBzaXQgYW1ldCBvcm5hcmUgZWxpdC4gTmFtIGxpZ3VsYSByaXN1cywgdmVzdGlidWx1bSBuZWMgbWF0dGlzIGluLCBjb25kaW1lbnR1bSBhYyBhbnRlLiBEb25lYyBmcmluZ2lsbGEsIGp1c3RvIGV0IHVsdHJpY2VzIGZhdWNpYnVzLCB0ZWxsdXMgZXN0IHZvbHV0cGF0IG1hc3NhLCB2aXRhZSBjb21tb2RvIHNhcGllbiBkaWFtIG5vbiByaXN1cy4gVml2YW11cyBhdCBhcmN1IGdyYXZpZGEgcHVydXMgbW9sbGlzIGZldWdpYXQuCgpOdWxsYSBhIHR1cnBpcyBxdWlzIHNhcGllbiBjb21tb2RvIGRpZ25pc3NpbSBldSBxdWlzIGp1c3RvLiBNYWVjZW5hcyBldSBsb3JlbSBvZGlvLCB1dCBoZW5kcmVyaXQgdmVsaXQuIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gUHJvaW4gZmFjaWxpc2lzIHBvcnR0aXRvciB1bGxhbWNvcnBlci4gUHJhZXNlbnQgbW9sbGlzIGRpZ25pc3NpbSBtYXNzYSwgbGFvcmVldCBhbGlxdWV0IHZlbGl0IHBlbGxlbnRlc3F1ZSBub24uIE51bmMgZmFjaWxpc2lzIGNvbnZhbGxpcyB0cmlzdGlxdWUuIE1hdXJpcyBwb3J0dGl0b3IgYW50ZSBhdCB0ZWxsdXMgY29udmFsbGlzIHBsYWNlcmF0LiBNb3JiaSBhbGlxdWV0IG5pc2kgYWMgbmlzbCBwdWx2aW5hciBpZCBkaWN0dW0gbmlzbCBtb2xsaXMuIFNlZCBvcm5hcmUgc2VtIGV0IHJpc3VzIHBsYWNlcmF0IGxvYm9ydGlzIGlkIGVnZXQgZWxpdC4gSW50ZWdlciBjb25zZXF1YXQsIG1hZ25hIGlkIHN1c2NpcGl0IHBoYXJldHJhLCBudWxsYSB2ZWxpdCBzdXNjaXBpdCBvcmNpLCB1dCBpbnRlcmR1bSBhdWd1ZSBhdWd1ZSBxdWlzIHF1YW0uIEZ1c2NlIHByZXRpdW0gYWxpcXVldCB2dWxwdXRhdGUuIE1hdXJpcyBibGFuZGl0IGRpY3R1bSBtb2xlc3RpZS4gUHJvaW4gbnVsbGEgbmliaCwgYmliZW5kdW0gZXUgcGxhY2VyYXQgYXQsIHRpbmNpZHVudCBhYyBuaXNsLiBOdWxsYW0gdnVscHV0YXRlIG1ldHVzIHV0IGxpYmVybyBydXRydW0gdWx0cmljaWVzLiBOdW5jIHNpdCBhbWV0IGR1aSBtYXVyaXMuIFN1c3BlbmRpc3NlIGFkaXBpc2NpbmcgbGFjdXMgaW4gYXVndWUgZWxlaWZlbmQgbW9sbGlzLgoKRHVpcyBwcmV0aXVtIHVsdHJpY2VzIG1hdHRpcy4gTmFtIGV1aXNtb2QgcmlzdXMgYSBlcmF0IGxhY2luaWEgYmliZW5kdW0uIE1vcmJpIG1hc3NhIHRvcnRvciwgY29uc2VjdGV0dXIgaWQgZWxlaWZlbmQgaWQsIHBlbGxlbnRlc3F1ZSB2ZWwgdG9ydG9yLiBQcmFlc2VudCB1cm5hIGxvcmVtLCBwb3J0dGl0b3IgYXQgY29uZGltZW50dW0gdml0YWUsIGx1Y3R1cyBlZ2V0IGVsaXQuIE1hZWNlbmFzIGZyaW5naWxsYSBxdWFtIGNvbnZhbGxpcyBlc3QgaGVuZHJlcml0IHZpdmVycmEuIEV0aWFtIHZlaGljdWxhLCBzYXBpZW4gbm9uIHB1bHZpbmFyIGFkaXBpc2NpbmcsIG5pc2kgbWFzc2EgdmVzdGlidWx1bSBlc3QsIGlkIGludGVyZHVtIG1hdXJpcyB2ZWxpdCBldSBlc3QuIFZlc3RpYnVsdW0gZXN0IGFyY3UsIGZhY2lsaXNpcyBhdCB1bHRyaWNpZXMgbm9uLCB2dWxwdXRhdGUgaWQgc2FwaWVuLiBWZXN0aWJ1bHVtIGlwc3VtIG1ldHVzLCBwaGFyZXRyYSBuZWMgcGVsbGVudGVzcXVlIGlkLCBmYWNpbGlzaXMgaWQgc2FwaWVuLiBEb25lYyBydXRydW0gb2RpbyBldCBsYWN1cyB1bHRyaWNpZXMgdWxsYW1jb3JwZXIuIEludGVnZXIgc2VkIGVzdCB1dCBtaSBwb3N1ZXJlIHRpbmNpZHVudCBxdWlzIG5vbiBsZW8uIE1vcmJpIHRlbGx1cyBqdXN0bywgdWx0cmljaWVzIHNpdCBhbWV0IHVsdHJpY2VzIHF1aXMsIGZhY2lsaXNpcyB2aXRhZSBtYWduYS4gRG9uZWMgbGlndWxhIG1ldHVzLCBwZWxsZW50ZXNxdWUgbm9uIHRyaXN0aXF1ZSBhYywgdmVzdGlidWx1bSBzZWQgZXJhdC4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LgoKTmFtIGRpZ25pc3NpbSwgbmlzbCBlZ2V0IGNvbnNlcXVhdCBldWlzbW9kLCBzZW0gbGVjdHVzIGF1Y3RvciBvcmNpLCB1dCBwb3J0dGl0b3IgbGFjdXMgZHVpIGFjIG5lcXVlLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gRnVzY2UgZWdlc3RhcyBwb3J0YSBmYWNpbGlzaXMuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBNYXVyaXMgY3Vyc3VzIHJob25jdXMgcmlzdXMgYWMgZXVpc21vZC4gUXVpc3F1ZSB2aXRhZSByaXN1cyBhIHRlbGx1cyB2ZW5lbmF0aXMgY29udmFsbGlzLiBDdXJhYml0dXIgbGFvcmVldCBzYXBpZW4gZXUgcXVhbSBsdWN0dXMgbG9ib3J0aXMuIFZpdmFtdXMgc29sbGljaXR1ZGluIHNvZGFsZXMgZG9sb3Igdml0YWUgc29kYWxlcy4gU3VzcGVuZGlzc2UgcGhhcmV0cmEgbGFvcmVldCBhbGlxdWV0LiBNYWVjZW5hcyB1bGxhbWNvcnBlciBvcmNpIHZlbCB0b3J0b3IgbHVjdHVzIGlhY3VsaXMgdXQgdml0YWUgbWV0dXMuIFZlc3RpYnVsdW0gdXQgYXJjdSBhYyB0ZWxsdXMgbWF0dGlzIGVsZWlmZW5kIGVnZXQgdmVoaWN1bGEgZWxpdC4KCkluIHNlZCBmZXVnaWF0IGVyb3MuIERvbmVjIGJpYmVuZHVtIHVsbGFtY29ycGVyIGRpYW0sIGV1IGZhdWNpYnVzIG1hdXJpcyBkaWN0dW0gc2VkLiBEdWlzIHRpbmNpZHVudCBqdXN0byBpbiBuZXF1ZSBhY2N1bXNhbiBkaWN0dW0uIE1hZWNlbmFzIGluIHJ1dHJ1bSBzYXBpZW4uIFV0IGlkIGZldWdpYXQgbGFjdXMuIE51bGxhIGZhY2lsaXNpLiBOdW5jIGFjIGxvcmVtIGlkIHF1YW0gdmFyaXVzIGN1cnN1cyBhIGV0IGVsaXQuIEFlbmVhbiBwb3N1ZXJlIGxpYmVybyBldSB0b3J0b3IgdmVoaWN1bGEgdXQgdWxsYW1jb3JwZXIgb2RpbyBjb25zZXF1YXQuIFNlZCBpbiBkaWduaXNzaW0gZHVpLiBDdXJhYml0dXIgaWFjdWxpcyB0ZW1wb3IgcXVhbSBuZWMgcGxhY2VyYXQuIEFsaXF1YW0gdmVuZW5hdGlzIG5pYmggZXQganVzdG8gaWFjdWxpcyBsYWNpbmlhLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gUGVsbGVudGVzcXVlIHRlbXB1cyBtYWduYSBzZWQgbWkgYWxpcXVldCBlZ2V0IHZhcml1cyBvZGlvIGNvbmd1ZS4KCkludGVnZXIgc2VtIHNlbSwgc2VtcGVyIGluIHZlc3RpYnVsdW0gdml0YWUsIGxvYm9ydGlzIHF1aXMgZXJhdC4gRHVpcyBhbnRlIGxlY3R1cywgZmVybWVudHVtIHNlZCB0ZW1wb3Igc2l0IGFtZXQsIHBsYWNlcmF0IHNpdCBhbWV0IHNlbS4gTWF1cmlzIGNvbmd1ZSB0aW5jaWR1bnQgaXBzdW0uIFV0IHZpdmVycmEsIGxhY3VzIHZlbCB2YXJpdXMgcGhhcmV0cmEsIHB1cnVzIGVuaW0gcHVsdmluYXIgaXBzdW0sIG5vbiBwZWxsZW50ZXNxdWUgZW5pbSBqdXN0byBub24gZXJhdC4gRnVzY2UgaXBzdW0gb3JjaSwgdWx0cmljZXMgc2VkIHBlbGxlbnRlc3F1ZSBhdCwgaGVuZHJlcml0IGxhb3JlZXQgZW5pbS4gTnVuYyBibGFuZGl0IG1vbGxpcyBwcmV0aXVtLiBVdCBtb2xsaXMsIG51bGxhIGFsaXF1YW0gc29kYWxlcyB2ZXN0aWJ1bHVtLCBsaWJlcm8gbG9yZW0gdGVtcHVzIHRvcnRvciwgYSBwZWxsZW50ZXNxdWUgbmliaCBlbGl0IGEgaXBzdW0uIFBoYXNlbGx1cyBmZXJtZW50dW0gbGlndWxhIGF0IG5lcXVlIGFkaXBpc2Npbmcgc29sbGljaXR1ZGluLiBTdXNwZW5kaXNzZSBpZCBpcHN1bSBhcmN1LiBTZWQgdGluY2lkdW50IHBsYWNlcmF0IHZpdmVycmEuIERvbmVjIGxpYmVybyBhdWd1ZSwgcG9ydHRpdG9yIHNpdCBhbWV0IHZhcml1cyBlZ2V0LCBydXRydW0gbmVjIGxhY3VzLiBQcm9pbiBibGFuZGl0IG9yY2kgc2l0IGFtZXQgZGlhbSBkaWN0dW0gaWQgcG9ydHRpdG9yIHJpc3VzIGlhY3VsaXMuIEludGVnZXIgbGFjaW5pYSBmZXVnaWF0IGxlbywgdml0YWUgYXVjdG9yIHR1cnBpcyBlbGVpZmVuZCB2ZWwuIFN1c3BlbmRpc3NlIGxvcmVtIHF1YW0sIHByZXRpdW0gaWQgYmliZW5kdW0gc2VkLCB2aXZlcnJhIHZpdGFlIHRvcnRvci4gTnVsbGFtIHVsdHJpY2llcyBsaWJlcm8gZXUgcmlzdXMgY29udmFsbGlzIGVnZXQgdWxsYW1jb3JwZXIgbmlzaSBlbGVtZW50dW0uIE1hdXJpcyBudWxsYSBlbGl0LCBiaWJlbmR1bSBpZCB2dWxwdXRhdGUgdml0YWUsIGltcGVyZGlldCBydXRydW0gbG9yZW0uIEN1cmFiaXR1ciBlZ2V0IGRpZ25pc3NpbSBvcmNpLiBTZWQgc2VtcGVyIHRlbGx1cyBpcHN1bSwgYXQgYmxhbmRpdCBkdWkuIEludGVnZXIgZGFwaWJ1cyBmYWNpbGlzaXMgc29kYWxlcy4gVml2YW11cyBzb2xsaWNpdHVkaW4gdmFyaXVzIGVzdCwgcXVpcyBvcm5hcmUganVzdG8gY3Vyc3VzIGlkLgoKTnVuYyB2ZWwgdWxsYW1jb3JwZXIgbWkuIFN1c3BlbmRpc3NlIHBvdGVudGkuIE51bmMgZXQgdXJuYSBhIGF1Z3VlIHNjZWxlcmlzcXVlIHVsdHJpY2VzIG5vbiBxdWlzIG1pLiBJbiBxdWlzIHBvcnR0aXRvciBlbGl0LiBBZW5lYW4gcXVpcyBlcmF0IG51bGxhLCBhIHZlbmVuYXRpcyB0ZWxsdXMuIEZ1c2NlIHZlc3RpYnVsdW0gbmlzaSBzZWQgbGVvIGFkaXBpc2NpbmcgZGlnbmlzc2ltLiBOdW5jIGludGVyZHVtLCBsb3JlbSBldCBsYWNpbmlhIHZlc3RpYnVsdW0sIHF1YW0gZXN0IG1hdHRpcyBtYWduYSwgc2l0IGFtZXQgdm9sdXRwYXQgZWxpdCBhdWd1ZSBhdCBsaWJlcm8uIENyYXMgZ3JhdmlkYSBkdWkgcXVpcyB2ZWxpdCBsb2JvcnRpcyBjb25kaW1lbnR1bSBldCBlbGVpZmVuZCBsaWd1bGEuIFBoYXNlbGx1cyBhYyBtZXR1cyBxdWFtLCBpZCB2ZW5lbmF0aXMgbWkuIEFsaXF1YW0gdXQgdHVycGlzIGFjIHRlbGx1cyBkYXBpYnVzIGRhcGlidXMgZXUgaW4gbWkuIFF1aXNxdWUgZWdldCBuaWJoIGVyb3MuIEZ1c2NlIGNvbnNlY3RldHVyIGxlbyB2ZWxpdC4KClZlc3RpYnVsdW0gc2VtcGVyIGVnZXN0YXMgbWF1cmlzLiBNb3JiaSB2ZXN0aWJ1bHVtIHNlbSBzZW0uIEFsaXF1YW0gdmVuZW5hdGlzLCBmZWxpcyBzZWQgZWxlaWZlbmQgcG9ydGEsIG1hdXJpcyBkaWFtIHNlbXBlciBhcmN1LCBzaXQgYW1ldCB1bHRyaWNpZXMgZXN0IHNhcGllbiBzaXQgYW1ldCBsaWJlcm8uIFZlc3RpYnVsdW0gZHVpIG9yY2ksIG9ybmFyZSBjb25kaW1lbnR1bSBtb2xsaXMgbmVjLCBtb2xlc3RpZSBhYyBlcm9zLiBQcm9pbiB2aXRhZSBtb2xsaXMgdmVsaXQuIFByYWVzZW50IGVnZXQgZmVsaXMgbWkuIE1hZWNlbmFzIGV1IHZ1bHB1dGF0ZSBuaXNpLiBWZXN0aWJ1bHVtIHZhcml1cywgYXJjdSBpbiB1bHRyaWNpZXMgdmVzdGlidWx1bSwgbmliaCBsZW8gc2FnaXR0aXMgb2RpbywgdXQgYmliZW5kdW0gbmlzbCBtaSBuZWMgZGlhbS4gSW50ZWdlciBhdCBlbmltIGZldWdpYXQgbnVsbGEgc2VtcGVyIGJpYmVuZHVtIHV0IGEgdmVsaXQuIFByb2luIGF0IG5pc2kgdXQgbG9yZW0gYWxpcXVhbSB2YXJpdXMgZWdldCBxdWlzIGVsaXQuIE51bGxhbSBuZWMgb2RpbyB2ZWwgbGVjdHVzIGNvbmd1ZSBjb25zZXF1YXQgYWRpcGlzY2luZyBhYyBtaS4gRnVzY2Ugdml0YWUgbGFvcmVldCBsaWJlcm8uIEN1cmFiaXR1ciBzaXQgYW1ldCBzZW0gbmVxdWUsIG5lYyBwb3N1ZXJlIGVuaW0uIEN1cmFiaXR1ciBhdCBtYXNzYSBhIHNlbSBncmF2aWRhIGlhY3VsaXMgbmVjIGV0IG5pYmguIFNlZCB2aXRhZSBkdWkgdml0YWUgbGVvIHRpbmNpZHVudCBwcmV0aXVtIGEgYWxpcXVhbSBlcmF0LiBTdXNwZW5kaXNzZSB1bHRyaWNpZXMgb2RpbyBhdCBtZXR1cyB0ZW1wb3IgaW4gcGVsbGVudGVzcXVlIGFyY3UgdWx0cmljaWVzLgoKU2VkIGFsaXF1YW0gbWF0dGlzIHF1YW0sIGluIHZ1bHB1dGF0ZSBzYXBpZW4gdWx0cmljZXMgaW4uIFBlbGxlbnRlc3F1ZSBxdWlzIHZlbGl0IHNlZCBkdWkgaGVuZHJlcml0IGN1cnN1cy4gUGVsbGVudGVzcXVlIG5vbiBudW5jIGxhY3VzLCBhIHNlbXBlciBtZXR1cy4gRnVzY2UgZXVpc21vZCB2ZWxpdCBxdWlzIGRpYW0gc3VzY2lwaXQgY29uc2VxdWF0LiBQcmFlc2VudCBjb21tb2RvIGFjY3Vtc2FuIG5lcXVlLiBQcm9pbiB2aXZlcnJhLCBpcHN1bSBub24gdHJpc3RpcXVlIHVsdHJpY2VzLCB2ZWxpdCB2ZWxpdCBmYWNpbGlzaXMgbG9yZW0sIHZlbCBydXRydW0gbmVxdWUgZXJvcyBhYyBuaXNpLiBTdXNwZW5kaXNzZSBmZWxpcyBtYXNzYSwgZmF1Y2lidXMgaW4gdm9sdXRwYXQgYWMsIGRhcGlidXMgZXQgb2Rpby4gUGVsbGVudGVzcXVlIGlkIHRlbGx1cyBzaXQgYW1ldCByaXN1cyB1bHRyaWNpZXMgdWxsYW1jb3JwZXIgbm9uIG5lYyBzYXBpZW4uIE5hbSBwbGFjZXJhdCB2aXZlcnJhIHVsbGFtY29ycGVyLiBOYW0gcGxhY2VyYXQgcG9ydHRpdG9yIHNhcGllbiBuZWMgcHVsdmluYXIuIEN1cmFiaXR1ciB2ZWwgb2RpbyBzaXQgYW1ldCBvZGlvIGFjY3Vtc2FuIGFsaXF1ZXQgdml0YWUgYSBsZWN0dXMuIFBlbGxlbnRlc3F1ZSBsb2JvcnRpcyB2aXZlcnJhIGNvbnNlcXVhdC4gTWF1cmlzIGVsZW1lbnR1bSBjdXJzdXMgbnVsbGEsIHNpdCBhbWV0IGhlbmRyZXJpdCBqdXN0byBkaWN0dW0gc2VkLiBNYWVjZW5hcyBkaWFtIG9kaW8sIGZyaW5naWxsYSBhYyBjb25ndWUgcXVpcywgYWRpcGlzY2luZyB1dCBlbGl0LgoKQWxpcXVhbSBsb3JlbSBlcm9zLCBwaGFyZXRyYSBuZWMgZWdlc3RhcyB2aXRhZSwgbWF0dGlzIG5lYyByaXN1cy4gTWF1cmlzIGFyY3UgbWFzc2EsIHNvZGFsZXMgZWdldCBncmF2aWRhIHNlZCwgdml2ZXJyYSB2aXRhZSB0dXJwaXMuIFV0IGxpZ3VsYSB1cm5hLCBldWlzbW9kIGFjIHRpbmNpZHVudCBldSwgZmF1Y2lidXMgc2VkIGZlbGlzLiBQcmFlc2VudCBtb2xsaXMsIGlwc3VtIHF1aXMgcmhvbmN1cyBkaWduaXNzaW0sIG9kaW8gc2VtIHZlbmVuYXRpcyBudWxsYSwgYXQgY29uc2VxdWF0IGZlbGlzIGF1Z3VlIHZlbCBlcmF0LiBOYW0gZmVybWVudHVtIGZldWdpYXQgdm9sdXRwYXQuIENsYXNzIGFwdGVudCB0YWNpdGkgc29jaW9zcXUgYWQgbGl0b3JhIHRvcnF1ZW50IHBlciBjb251YmlhIG5vc3RyYSwgcGVyIGluY2VwdG9zIGhpbWVuYWVvcy4gRXRpYW0gdml0YWUgZHVpIGluIG5pc2kgYWRpcGlzY2luZyB1bHRyaWNpZXMgbm9uIGV1IGp1c3RvLiBEb25lYyB0cmlzdGlxdWUgdWx0cmljaWVzIGFkaXBpc2NpbmcuIE51bGxhIHNvZGFsZXMsIG51bmMgYSB0cmlzdGlxdWUgZWxlbWVudHVtLCBlcmF0IG5lcXVlIGVnZXN0YXMgbmlzbCwgYXQgaGVuZHJlcml0IG9yY2kgc2FwaWVuIHNlZCBsaWJlcm8uIFZpdmFtdXMgYSBtYXVyaXMgdHVycGlzLCBxdWlzIGxhb3JlZXQgaXBzdW0uIE51bmMgbmVjIG1pIGV0IG5pc2wgcGVsbGVudGVzcXVlIHNjZWxlcmlzcXVlLiBWaXZhbXVzIHZvbHV0cGF0LCBqdXN0byB0cmlzdGlxdWUgbGFjaW5pYSBjb25kaW1lbnR1bSwgZXJhdCBqdXN0byB1bHRyaWNlcyB1cm5hLCBlbGVtZW50dW0gdml2ZXJyYSBlcm9zIGF1Z3VlIG5vbiBsaWJlcm8uIFNlZCBtb2xsaXMgbW9sbGlzIGFyY3UsIGF0IGZlcm1lbnR1bSBkaWFtIHN1c2NpcGl0IHF1aXMuCgpFdGlhbSBzaXQgYW1ldCBuaWJoIGp1c3RvLCBwb3N1ZXJlIHZvbHV0cGF0IG51bmMuIE1vcmJpIHBlbGxlbnRlc3F1ZSBuZXF1ZSBpbiBvcmNpIHZvbHV0cGF0IGV1IHNjZWxlcmlzcXVlIGxvcmVtIGRpY3R1bS4gTWF1cmlzIG1vbGxpcyBpYWN1bGlzIGVzdCwgbmVjIHNhZ2l0dGlzIHNhcGllbiBjb25zZXF1YXQgaWQuIE51bmMgbmVjIG1hbGVzdWFkYSBvZGlvLiBEdWlzIHF1aXMgc3VzY2lwaXQgb2Rpby4gTWF1cmlzIHB1cnVzIGR1aSwgc29kYWxlcyBpZCBtYXR0aXMgc2l0IGFtZXQsIHBvc3VlcmUgaW4gYXJjdS4gUGhhc2VsbHVzIHBvcnRhIGVsZW1lbnR1bSBjb252YWxsaXMuIE1hZWNlbmFzIGF0IG9yY2kgZXQgbWkgdnVscHV0YXRlIHNvbGxpY2l0dWRpbiBpbiBpbiB0dXJwaXMuIFBlbGxlbnRlc3F1ZSBjdXJzdXMgYWRpcGlzY2luZyBuZXF1ZSBzaXQgYW1ldCBjb21tb2RvLiBGdXNjZSB1dCBtaSBldSBsZWN0dXMgcG9ydHRpdG9yIHZvbHV0cGF0IGV0IG5lYyBmZWxpcy4KCkN1cmFiaXR1ciBzY2VsZXJpc3F1ZSBlcm9zIHF1aXMgbmlzbCB2aXZlcnJhIHZlbCB1bHRyaWNlcyB2ZWxpdCB2ZXN0aWJ1bHVtLiBTZWQgbG9ib3J0aXMgcHVsdmluYXIgc2FwaWVuIGFjIHZlbmVuYXRpcy4gU2VkIGFudGUgbmliaCwgcmhvbmN1cyBlZ2V0IGRpY3R1bSBpbiwgbW9sbGlzIHV0IG5pc2kuIFBoYXNlbGx1cyBmYWNpbGlzaXMgbWkgbm9uIGxvcmVtIHRyaXN0aXF1ZSBub24gZWxlaWZlbmQgc2VtIGZyaW5naWxsYS4gSW50ZWdlciB1dCBhdWd1ZSBlc3QuIEluIHZlbmVuYXRpcyB0aW5jaWR1bnQgc2NlbGVyaXNxdWUuIEV0aWFtIGFudGUgZHVpLCBwb3N1ZXJlIHF1aXMgbWFsZXN1YWRhIHZpdGFlLCBtYWxlc3VhZGEgYSBhcmN1LiBBZW5lYW4gZmF1Y2lidXMgdmVuZW5hdGlzIHNhcGllbiwgdXQgZmFjaWxpc2lzIG5pc2kgYmxhbmRpdCB2ZWwuIEFlbmVhbiBhYyBsb3JlbSBldSBzZW0gZmVybWVudHVtIHBsYWNlcmF0LiBQcm9pbiBuZXF1ZSBwdXJ1cywgYWxpcXVldCB1dCB0aW5jaWR1bnQgdXQsIGNvbnZhbGxpcyBzaXQgYW1ldCBlcm9zLiBQaGFzZWxsdXMgdmVoaWN1bGEgdWxsYW1jb3JwZXIgZW5pbSBub24gdmVoaWN1bGEuIEV0aWFtIHBvcnRhIG9kaW8gdXQgaXBzdW0gYWRpcGlzY2luZyBlZ2VzdGFzIGlkIGEgb2Rpby4gUGVsbGVudGVzcXVlIGJsYW5kaXQsIHNhcGllbiB1dCBwdWx2aW5hciBpbnRlcmR1bSwgbWkgbnVsbGEgaGVuZHJlcml0IGVsaXQsIGluIHRlbXBvciBkaWFtIGVuaW0gYSB1cm5hLiBJbiB0ZWxsdXMgb2Rpbywgb3JuYXJlIHNlZCBjb25kaW1lbnR1bSBhLCBtYXR0aXMgZXUgYXVndWUuCgpGdXNjZSBoZW5kcmVyaXQgcG9ydHRpdG9yIGV1aXNtb2QuIERvbmVjIG1hbGVzdWFkYSBlZ2VzdGFzIHR1cnBpcywgZXQgdWx0cmljaWVzIGZlbGlzIGVsZW1lbnR1bSB2aXRhZS4gTnVsbGFtIGluIHNlbSBuaWJoLiBOdWxsYW0gdWx0cmljaWVzIGhlbmRyZXJpdCBqdXN0byBzaXQgYW1ldCBsb2JvcnRpcy4gU2VkIHRpbmNpZHVudCwgbWF1cmlzIGF0IG9ybmFyZSBsYW9yZWV0LCBzYXBpZW4gcHVydXMgZWxlbWVudHVtIGVsaXQsIG5lYyBwb3J0dGl0b3IgbmlzbCBwdXJ1cyBldCBlcmF0LiBEb25lYyBmZWxpcyBuaXNpLCBydXRydW0gdWxsYW1jb3JwZXIgZ3JhdmlkYSBhYywgdGluY2lkdW50IHNpdCBhbWV0IHVybmEuIFByb2luIHZlbCBqdXN0byB2aXRhZSBlcm9zIHNhZ2l0dGlzIGJpYmVuZHVtIGEgdXQgbmliaC4gUGhhc2VsbHVzIHNvZGFsZXMgbGFvcmVldCB0aW5jaWR1bnQuIE1hZWNlbmFzIG9kaW8gbWFzc2EsIGNvbmRpbWVudHVtIGlkIGFsaXF1ZXQgdXQsIHJob25jdXMgdmVsIGxlY3R1cy4gRHVpcyBwaGFyZXRyYSBjb25zZWN0ZXR1ciBzYXBpZW4uIFBoYXNlbGx1cyBwb3N1ZXJlIHVsdHJpY2llcyBtYXNzYSwgbm9uIHJob25jdXMgcmlzdXMgYWxpcXVhbSB0ZW1wdXMuCgpQcmFlc2VudCB2ZW5lbmF0aXMgbWFnbmEgaWQgc2VtIGRpY3R1bSBldSB2ZWhpY3VsYSBpcHN1bSB2dWxwdXRhdGUuIFNlZCBhIGNvbnZhbGxpcyBzYXBpZW4uIFNlZCBqdXN0byBkb2xvciwgcmhvbmN1cyB2ZWwgcnV0cnVtIG1hdHRpcywgc29sbGljaXR1ZGluIHV0IHJpc3VzLiBOdWxsYW0gc2l0IGFtZXQgY29udmFsbGlzIGVzdC4gRXRpYW0gbm9uIHRpbmNpZHVudCBsaWd1bGEuIEZ1c2NlIHN1c2NpcGl0IHByZXRpdW0gZWxpdCBhdCB1bGxhbWNvcnBlci4gUXVpc3F1ZSBzb2xsaWNpdHVkaW4sIGRpYW0gaWQgaW50ZXJkdW0gcG9ydGEsIG1ldHVzIGlwc3VtIHZvbHV0cGF0IGxpYmVybywgaWQgdmVuZW5hdGlzIGZlbGlzIG9yY2kgbm9uIHZlbGl0LiBTdXNwZW5kaXNzZSBwb3RlbnRpLiBNYXVyaXMgcnV0cnVtLCB0b3J0b3Igc2l0IGFtZXQgcGVsbGVudGVzcXVlIHRpbmNpZHVudCwgZXJhdCBxdWFtIHVsdHJpY2llcyBvZGlvLCBpZCBhbGlxdWFtIGVsaXQgbGVvIG5lYyBsZW8uIFBlbGxlbnRlc3F1ZSBqdXN0byBlcm9zLCBydXRydW0gYXQgZmV1Z2lhdCBuZWMsIHBvcnRhIGV0IHRlbGx1cy4gQWVuZWFuIGVnZXQgbWV0dXMgbGVjdHVzLgoKUHJhZXNlbnQgZXVpc21vZCwgdHVycGlzIHF1aXMgbGFvcmVldCBjb25zZXF1YXQsIG5lcXVlIGFudGUgaW1wZXJkaWV0IHF1YW0sIGFjIHNlbXBlciB0b3J0b3IgbmliaCBpbiBudWxsYS4gSW50ZWdlciBzY2VsZXJpc3F1ZSBlcm9zIHZlaGljdWxhIHVybmEgbGFjaW5pYSBhYyBmYWNpbGlzaXMgbWF1cmlzIGFjY3Vtc2FuLiBQaGFzZWxsdXMgYXQgbWF1cmlzIG5pYmguIEN1cmFiaXR1ciBlbmltIGFudGUsIHJ1dHJ1bSBzZWQgYWRpcGlzY2luZyBoZW5kcmVyaXQsIHBlbGxlbnRlc3F1ZSBub24gYXVndWUuIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBOYW0gdGVtcHVzIGV1aXNtb2QgbWFzc2EgYSBkaWN0dW0uIERvbmVjIHNpdCBhbWV0IGp1c3RvIGFjIGRpYW0gdWx0cmljaWVzIHVsdHJpY2llcy4gU2VkIHRpbmNpZHVudCBlcmF0IHF1aXMgcXVhbSB0ZW1wdXMgdmVsIGludGVyZHVtIGVyYXQgcmhvbmN1cy4gSW4gaGFjIGhhYml0YXNzZSBwbGF0ZWEgZGljdHVtc3QuIFZlc3RpYnVsdW0gdmVoaWN1bGEgdmFyaXVzIHNlbSBlZ2V0IGludGVyZHVtLiBDcmFzIGJpYmVuZHVtIGxlbyBuZWMgZmVsaXMgdmVuZW5hdGlzIHNlZCBwaGFyZXRyYSBzZW0gZmV1Z2lhdC4gQ3VtIHNvY2lpcyBuYXRvcXVlIHBlbmF0aWJ1cyBldCBtYWduaXMgZGlzIHBhcnR1cmllbnQgbW9udGVzLCBuYXNjZXR1ciByaWRpY3VsdXMgbXVzLiBTZWQgcXVhbSBvcmNpLCBtb2xsaXMgZWdldCBzYWdpdHRpcyBhY2N1bXNhbiwgdnVscHV0YXRlIHNpdCBhbWV0IGR1aS4gUHJhZXNlbnQgZXUgZWxlbWVudHVtIGFyY3UuCgpMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dXIgYWRpcGlzY2luZyBlbGl0LiBWZXN0aWJ1bHVtIG5pc2wgbWV0dXMsIGhlbmRyZXJpdCB1dCBsYW9yZWV0IHNlZCwgY29uc2VjdGV0dXIgYXQgcHVydXMuIER1aXMgaW50ZXJkdW0gY29uZ3VlIGxvYm9ydGlzLiBOdWxsYW0gc2VkIG1hc3NhIHBvcnRhIGZlbGlzIGVsZWlmZW5kIGNvbnNlcXVhdCBzaXQgYW1ldCBuZWMgbWV0dXMuIEFsaXF1YW0gcGxhY2VyYXQgZGljdHVtIGVyYXQgYXQgZWxlaWZlbmQuIFZlc3RpYnVsdW0gbGliZXJvIGFudGUsIHVsbGFtY29ycGVyIGEgcG9ydHRpdG9yIHN1c2NpcGl0LCBhY2N1bXNhbiB2ZWwgbmlzaS4gRG9uZWMgZXQgbWFnbmEgbmVxdWUuIE5hbSBlbGVtZW50dW0gdWx0cmljZXMganVzdG8sIGVnZXQgc29sbGljaXR1ZGluIHNhcGllbiBpbXBlcmRpZXQgZWdldC4gTnVsbGFtIGF1Y3RvciBkaWN0dW0gbnVuYywgYXQgZmV1Z2lhdCBvZGlvIHZlc3RpYnVsdW0gYS4gU2VkIGVyYXQgbnVsbGEsIHZpdmVycmEgaGVuZHJlcml0IGNvbW1vZG8gaWQsIHVsbGFtY29ycGVyIGFjIG9yY2kuIFBoYXNlbGx1cyBwZWxsZW50ZXNxdWUgZmV1Z2lhdCBzdXNjaXBpdC4gRXRpYW0gZWdlc3RhcyBmZXJtZW50dW0gZW5pbS4gRXRpYW0gZ3JhdmlkYSBpbnRlcmR1bSB0ZWxsdXMgYWMgbGFvcmVldC4gTW9yYmkgbWF0dGlzIGFsaXF1ZXQgZXJvcywgbm9uIHRlbXBvciBlcmF0IHVsbGFtY29ycGVyIGluLiBFdGlhbSBwdWx2aW5hciBpbnRlcmR1bSB0dXJwaXMgYWMgdmVoaWN1bGEuIFNlZCBxdWFtIGp1c3RvLCBhY2N1bXNhbiBpZCBjb25zZWN0ZXR1ciBhLCBhbGlxdWV0IHNlZCBsZW8uIEFlbmVhbiB2aXRhZSBibGFuZGl0IG1hdXJpcy4KCkluIHNlZCBlcm9zIGF1Z3VlLCBub24gcnV0cnVtIG9kaW8uIEV0aWFtIHZpdGFlIGR1aSBuZXF1ZSwgaW4gdHJpc3RpcXVlIG1hc3NhLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgTWFlY2VuYXMgZGljdHVtIGVsaXQgYXQgbGVjdHVzIHRlbXBvciBub24gcGhhcmV0cmEgbmlzbCBoZW5kcmVyaXQuIFNlZCBzZWQgcXVhbSBldSBsZWN0dXMgdWx0cmljZXMgbWFsZXN1YWRhIHRpbmNpZHVudCBhIGVzdC4gTmFtIHZlbCBlcm9zIHJpc3VzLiBNYWVjZW5hcyBlcm9zIGVsaXQsIGJsYW5kaXQgZmVybWVudHVtIHRlbXBvciBlZ2V0LCBsb2JvcnRpcyBpZCBkaWFtLiBWZXN0aWJ1bHVtIGxhY2luaWEgbGFjdXMgdml0YWUgbWFnbmEgdm9sdXRwYXQgZXUgZGlnbmlzc2ltIGVyb3MgY29udmFsbGlzLiBWaXZhbXVzIGFjIHZlbGl0IHRlbGx1cywgYSBjb25ndWUgbmVxdWUuIEludGVnZXIgbWkgbnVsbGEsIHZhcml1cyBub24gbHVjdHVzIGluLCBkaWN0dW0gc2l0IGFtZXQgc2VtLiBVdCBsYW9yZWV0LCBzYXBpZW4gc2l0IGFtZXQgc2NlbGVyaXNxdWUgcG9ydGEsIHB1cnVzIHNhcGllbiB2ZXN0aWJ1bHVtIG5pYmgsIHNlZCBsdWN0dXMgbGliZXJvIG1hc3NhIGFjIGVsaXQuIERvbmVjIGlhY3VsaXMgb2RpbyBlZ2V0IG9kaW8gc2FnaXR0aXMgbmVjIHZlbmVuYXRpcyBsb3JlbSBibGFuZGl0LgoKQWxpcXVhbSBpbXBlcmRpZXQgdGVsbHVzIHBvc3VlcmUganVzdG8gdmVoaWN1bGEgc2VkIHZlc3RpYnVsdW0gYW50ZSB0cmlzdGlxdWUuIEZ1c2NlIGZldWdpYXQgZmF1Y2lidXMgcHVydXMgbmVjIG1vbGVzdGllLiBOdWxsYSB0ZW1wb3IgbmVxdWUgaWQgbWFnbmEgaWFjdWxpcyBxdWlzIHNvbGxpY2l0dWRpbiBlcm9zIHNlbXBlci4gUHJhZXNlbnQgdml2ZXJyYSBzYWdpdHRpcyBsdWN0dXMuIE1vcmJpIHNpdCBhbWV0IG1hZ25hIHNlZCBvZGlvIGdyYXZpZGEgdmFyaXVzLiBVdCBuaXNpIGxpYmVybywgdnVscHV0YXRlIGZldWdpYXQgcHJldGl1bSB0ZW1wdXMsIGVnZXN0YXMgc2l0IGFtZXQganVzdG8uIFBlbGxlbnRlc3F1ZSBjb25zZXF1YXQgdGVtcG9yIG5pc2kgaW4gbG9ib3J0aXMuIFNlZCBmZXJtZW50dW0gY29udmFsbGlzIGR1aSBhYyBzb2xsaWNpdHVkaW4uIEludGVnZXIgYXVjdG9yIGF1Z3VlIGVnZXQgdGVsbHVzIHRlbXB1cyBmcmluZ2lsbGEuIFByb2luIG5lYyBkb2xvciBzYXBpZW4sIG5lYyB0cmlzdGlxdWUgbmliaC4gQWxpcXVhbSBhIHZlbGl0IGF0IG1pIG1hdHRpcyBhbGlxdWV0LgoKUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIEFsaXF1YW0gdWx0cmljZXMgZXJhdCBub24gdHVycGlzIGF1Y3RvciBpZCBvcm5hcmUgbWF1cmlzIHNhZ2l0dGlzLiBRdWlzcXVlIHBvcnR0aXRvciwgdGVsbHVzIHV0IGNvbnZhbGxpcyBzYWdpdHRpcywgbWkgbGliZXJvIGZldWdpYXQgdGVsbHVzLCByaG9uY3VzIHBsYWNlcmF0IGlwc3VtIHRvcnRvciBpZCByaXN1cy4gRG9uZWMgdGluY2lkdW50IGZldWdpYXQgbGVvLiBDcmFzIGlkIG1pIG5lcXVlLCBldSBtYWxlc3VhZGEgZXJvcy4gVXQgbW9sZXN0aWUgbWFnbmEgcXVpcyBsaWJlcm8gcGxhY2VyYXQgbWFsZXN1YWRhLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEFsaXF1YW0gbm9uIG1hdXJpcyBsb3JlbSwgaW4gYWRpcGlzY2luZyBtZXR1cy4gRG9uZWMgZWdldCBpcHN1bSBpbiBlbGl0IGNvbW1vZG8gb3JuYXJlIGJpYmVuZHVtIGEgbmliaC4gVml2YW11cyBvZGlvIGVyYXQsIHBsYWNlcmF0IGFjIHZlc3RpYnVsdW0gZWdldCwgbWFsZXN1YWRhIHV0IG5pc2kuIEV0aWFtIHN1c2NpcGl0IHNvbGxpY2l0dWRpbiBsZW8gc2VtcGVyIHNvbGxpY2l0dWRpbi4gU2VkIHJob25jdXMgcmlzdXMgc2l0IGFtZXQgc2VtIGVsZWlmZW5kIGRpY3R1bSBwcmV0aXVtIHNhcGllbiBlZ2VzdGFzLiBOdWxsYSBhdCB1cm5hIG51bmMsIHZlbCBhbGlxdWV0IGxlby4gUHJhZXNlbnQgdWx0cmljaWVzLCBtaSBldSBwcmV0aXVtIGxvYm9ydGlzLCBlcmF0IG5pYmggZXVpc21vZCBsZW8sIHNpdCBhbWV0IGdyYXZpZGEgc2FwaWVuIGVyb3MgZXQgdHVycGlzLiBEb25lYyBsYWNpbmlhIHZlbmVuYXRpcyBsZWN0dXMsIG5vbiBsYWNpbmlhIG1pIGhlbmRyZXJpdCBzaXQgYW1ldC4gSW50ZWdlciBzZWQgZmVsaXMgdmVsIG9yY2kgYWxpcXVhbSBwdWx2aW5hci4gUGhhc2VsbHVzIGV0IHJpc3VzIGlkIGVyYXQgZXVpc21vZCB0aW5jaWR1bnQuIFNlZCBsdWN0dXMgdGVtcG9yIG5pc2ksIG5lYyB0ZW1wb3IgaXBzdW0gZWxlbWVudHVtIGVnZXQuIEludGVnZXIgbmlzbCB0b3J0b3IsIHZpdmVycmEgaW4gZGFwaWJ1cyBhdCwgbWF0dGlzIGFjIGVyYXQuIEN1cmFiaXR1ciBuZWMgZHVpIGxlY3R1cy4KClBoYXNlbGx1cyBzdXNjaXBpdCwgdG9ydG9yIGV1IHZhcml1cyBmcmluZ2lsbGEsIHNhcGllbiBtYWduYSBlZ2VzdGFzIHJpc3VzLCB1dCBzdXNjaXBpdCBkdWkgbWF1cmlzIHF1aXMgdmVsaXQuIENyYXMgYSBzYXBpZW4gcXVpcyBzYXBpZW4gaGVuZHJlcml0IHRyaXN0aXF1ZSBhIHNpdCBhbWV0IGVsaXQuIFBlbGxlbnRlc3F1ZSBkdWkgYXJjdSwgbWFsZXN1YWRhIGV0IHNvZGFsZXMgc2l0IGFtZXQsIGRhcGlidXMgdmVsIHF1YW0uIFNlZCBub24gYWRpcGlzY2luZyBsaWd1bGEuIFV0IHZ1bHB1dGF0ZSBwdXJ1cyBhdCBuaXNsIHBvc3VlcmUgc29kYWxlcy4gTWFlY2VuYXMgZGlhbSB2ZWxpdCwgdGluY2lkdW50IGlkIG1hdHRpcyBldSwgYWxpcXVhbSBhYyBuaXNpLiBNYWVjZW5hcyBwcmV0aXVtLCBhdWd1ZSBhIHNhZ2l0dGlzIHN1c2NpcGl0LCBsZW8gbGlndWxhIGVsZWlmZW5kIGRvbG9yLCBtb2xsaXMgZmV1Z2lhdCBvZGlvIGF1Z3VlIG5vbiBlcm9zLiBQZWxsZW50ZXNxdWUgc2NlbGVyaXNxdWUgb3JjaSBwcmV0aXVtIHF1YW0gbW9sbGlzIGF0IGxvYm9ydGlzIGR1aSBmYWNpbGlzaXMuIE1vcmJpIGNvbmd1ZSBtZXR1cyBpZCB0b3J0b3IgcG9ydGEgZnJpbmdpbGxhLiBTZWQgbG9yZW0gbWksIG1vbGVzdGllIGZlcm1lbnR1bSBzYWdpdHRpcyBhdCwgZ3JhdmlkYSBhIG5pc2kuIERvbmVjIGV1IHZlc3RpYnVsdW0gdmVsaXQuIEluIHZpdmVycmEsIGVuaW0gZXUgZWxlbWVudHVtIHNvZGFsZXMsIGVuaW0gb2RpbyBkYXBpYnVzIHVybmEsIGVnZXQgY29tbW9kbyBuaXNsIG1hdXJpcyB1dCBvZGlvLiBDdXJhYml0dXIgbmVjIGVuaW0gbnVsbGEuIEluIG5lYyBlbGl0IGlwc3VtLiBOdW5jIGluIG1hc3NhIHN1c2NpcGl0IG1hZ25hIGVsZW1lbnR1bSBmYXVjaWJ1cyBpbiBuZWMgaXBzdW0uIE51bGxhbSBzdXNjaXBpdCBtYWxlc3VhZGEgZWxlbWVudHVtLiBFdGlhbSBzZWQgbWkgaW4gbmliaCB1bHRyaWNpZXMgdmVuZW5hdGlzIG5lYyBwaGFyZXRyYSBtYWduYS4gSW4gcHVydXMgYW50ZSwgcmhvbmN1cyB2ZWwgcGxhY2VyYXQgc2VkLCBmZXJtZW50dW0gc2l0IGFtZXQgZHVpLiBTZWQgYXQgc29kYWxlcyB2ZWxpdC4KCkR1aXMgc3VzY2lwaXQgcGVsbGVudGVzcXVlIHBlbGxlbnRlc3F1ZS4gUHJhZXNlbnQgcG9ydGEgbG9ib3J0aXMgY3Vyc3VzLiBRdWlzcXVlIHNhZ2l0dGlzIHZlbGl0IG5vbiB0ZWxsdXMgYmliZW5kdW0gYXQgc29sbGljaXR1ZGluIGxhY3VzIGFsaXF1ZXQuIFNlZCBuaWJoIHJpc3VzLCBibGFuZGl0IGEgYWxpcXVldCBlZ2V0LCB2ZWhpY3VsYSBldCBlc3QuIFN1c3BlbmRpc3NlIGZhY2lsaXNpcyBiaWJlbmR1bSBhbGlxdWFtLiBGdXNjZSBjb25zZWN0ZXR1ciBjb252YWxsaXMgZXJhdCwgZWdldCBtb2xsaXMgZGlhbSBmZXJtZW50dW0gc29sbGljaXR1ZGluLiBRdWlzcXVlIHRpbmNpZHVudCBwb3J0dGl0b3IgcHJldGl1bS4gTnVsbGFtIGlkIG5pc2wgZXQgdXJuYSB2dWxwdXRhdGUgZGFwaWJ1cy4gRG9uZWMgcXVpcyBsb3JlbSB1cm5hLiBRdWlzcXVlIGlkIGp1c3RvIG5lYyBudW5jIGJsYW5kaXQgY29udmFsbGlzLiBOdW5jIHZvbHV0cGF0LCBtYXNzYSBzb2xsaWNpdHVkaW4gYWRpcGlzY2luZyB2ZXN0aWJ1bHVtLCBtYXNzYSB1cm5hIGNvbmd1ZSBsZWN0dXMsIHNpdCBhbWV0IHVsdHJpY2llcyBhdWd1ZSBvcmNpIGNvbnZhbGxpcyB0dXJwaXMuIE51bGxhIGF0IGxvcmVtIGVsaXQuIE51bmMgdHJpc3RpcXVlLCBxdWFtIGZhY2lsaXNpcyBjb21tb2RvIHBvcnR0aXRvciwgbGFjdXMgbGlndWxhIGFjY3Vtc2FuIG5pc2ksIGV0IGxhb3JlZXQganVzdG8gYW50ZSB2aXRhZSBlcm9zLiBDdXJhYml0dXIgc2VkIGF1Z3VlIGFyY3UuIFBoYXNlbGx1cyBwb3J0dGl0b3IgdmVzdGlidWx1bSBmZWxpcywgdXQgY29uc2VjdGV0dXIgYXJjdSB0ZW1wb3Igbm9uLiBJbiBqdXN0byByaXN1cywgc2VtcGVyIGV0IHN1c2NpcGl0IGlkLCB1bGxhbWNvcnBlciBhdCB1cm5hLiBRdWlzcXVlIHRpbmNpZHVudCwgdXJuYSBuZWMgYWxpcXVhbSB0cmlzdGlxdWUsIG5pYmggb2RpbyBmYXVjaWJ1cyBhdWd1ZSwgaW4gb3JuYXJlIGVuaW0gdHVycGlzIGFjY3Vtc2FuIGRvbG9yLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gU3VzcGVuZGlzc2Ugc29kYWxlcyB2YXJpdXMgdHVycGlzIGV1IGZlcm1lbnR1bS4KCk1vcmJpIHVsdHJpY2llcyBkaWFtIGVnZXQgbWFzc2EgcG9zdWVyZSBsb2JvcnRpcy4gQWxpcXVhbSB2b2x1dHBhdCBwZWxsZW50ZXNxdWUgZW5pbSBldSBwb3J0dGl0b3IuIERvbmVjIGxhY3VzIGZlbGlzLCBjb25zZWN0ZXR1ciBhIHByZXRpdW0gdml0YWUsIGJpYmVuZHVtIG5vbiBlbmltLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gRXRpYW0gdXQgbmliaCBhIHF1YW0gcGVsbGVudGVzcXVlIGF1Y3RvciB1dCBpZCB2ZWxpdC4gRHVpcyBsYWNpbmlhIGp1c3RvIGVnZXQgbWkgcGxhY2VyYXQgYmliZW5kdW0uIEN1bSBzb2NpaXMgbmF0b3F1ZSBwZW5hdGlidXMgZXQgbWFnbmlzIGRpcyBwYXJ0dXJpZW50IG1vbnRlcywgbmFzY2V0dXIgcmlkaWN1bHVzIG11cy4gRG9uZWMgdmVsaXQgdG9ydG9yLCB0ZW1wdXMgbmVjIHRyaXN0aXF1ZSBpZCwgYWxpcXVldCBzaXQgYW1ldCB0dXJwaXMuIFByYWVzZW50IGV0IG5lcXVlIG5lYyBtYWduYSBwb3J0YSBmcmluZ2lsbGEuIE1vcmJpIGlkIGVnZXN0YXMgZXJvcy4gRG9uZWMgc2VtcGVyIHRpbmNpZHVudCB1bGxhbWNvcnBlci4gUGhhc2VsbHVzIHRlbXB1cyBsYWNpbmlhIGhlbmRyZXJpdC4gUXVpc3F1ZSBmYXVjaWJ1cyBwcmV0aXVtIG5lcXVlIG5vbiBjb252YWxsaXMuIE51bmMgbWFsZXN1YWRhIGFjY3Vtc2FuIHJob25jdXMuIENyYXMgbG9ib3J0aXMsIHNlbSBzZWQgZnJpbmdpbGxhIGNvbnZhbGxpcywgYXVndWUgdmVsaXQgc2VtcGVyIG5pc2wsIGNvbW1vZG8gdmFyaXVzIG5pc2kgZGlhbSBhYyBsZW8uCgpRdWlzcXVlIGludGVyZHVtIHRlbGx1cyBhYyBhbnRlIHBvc3VlcmUgdXQgY3Vyc3VzIGxvcmVtIGVnZXN0YXMuIE51bGxhIGZhY2lsaXNpLiBBZW5lYW4gc2VkIG1hc3NhIG5lYyBuaXNpIHNjZWxlcmlzcXVlIHZ1bHB1dGF0ZS4gRXRpYW0gY29udmFsbGlzIGNvbnNlY3RldHVyIGlhY3VsaXMuIE1hZWNlbmFzIGFjIHB1cnVzIHV0IGFudGUgZGlnbmlzc2ltIGF1Y3RvciBhYyBxdWlzIGxvcmVtLiBQZWxsZW50ZXNxdWUgc3VzY2lwaXQgdGluY2lkdW50IG9yY2kuIEZ1c2NlIGFsaXF1YW0gZGFwaWJ1cyBvcmNpLCBhdCBiaWJlbmR1bSBpcHN1bSBhZGlwaXNjaW5nIGVnZXQuIE1vcmJpIHBlbGxlbnRlc3F1ZSBoZW5kcmVyaXQgcXVhbSwgbmVjIHBsYWNlcmF0IHVybmEgdnVscHV0YXRlIHNlZC4gUXVpc3F1ZSB2ZWwgZGlhbSBsb3JlbS4gUHJhZXNlbnQgaWQgZGlhbSBxdWlzIGVuaW0gZWxlbWVudHVtIHJob25jdXMgc2FnaXR0aXMgZWdldCBwdXJ1cy4gUXVpc3F1ZSBmcmluZ2lsbGEgYmliZW5kdW0gbGVvIGluIGxhb3JlZXQuIFZlc3RpYnVsdW0gaWQgbmliaCByaXN1cywgbm9uIGVsZW1lbnR1bSBtZXR1cy4gVXQgYSBmZWxpcyBkaWFtLCBub24gbW9sbGlzIG5pc2wuIENyYXMgZWxpdCBhbnRlLCB1bGxhbWNvcnBlciBxdWlzIGlhY3VsaXMgZXUsIHNvZGFsZXMgdmVsIGVzdC4gQ3VyYWJpdHVyIHF1aXMgbG9ib3J0aXMgZG9sb3IuIEFsaXF1YW0gbWF0dGlzIGdyYXZpZGEgbWV0dXMgcGVsbGVudGVzcXVlIHZ1bHB1dGF0ZS4KClV0IGlkIGF1Z3VlIGlkIGRvbG9yIGx1Y3R1cyBldWlzbW9kIGV0IHF1aXMgdmVsaXQuIE1hZWNlbmFzIGVuaW0gZG9sb3IsIHRlbXB1cyBzaXQgYW1ldCBoZW5kcmVyaXQgZXUsIGZhdWNpYnVzIHZpdGFlIG5lcXVlLiBQcm9pbiBzaXQgYW1ldCB2YXJpdXMgZWxpdC4gUHJvaW4gdmFyaXVzIGZlbGlzIHVsbGFtY29ycGVyIHB1cnVzIGRpZ25pc3NpbSBjb25zZXF1YXQuIENyYXMgY3Vyc3VzIHRlbXB1cyBlcm9zLiBOdW5jIHVsdHJpY2VzIHZlbmVuYXRpcyB1bGxhbWNvcnBlci4gQWxpcXVhbSBldCBmZXVnaWF0IHRlbGx1cy4gUGhhc2VsbHVzIHNpdCBhbWV0IHZlc3RpYnVsdW0gZWxpdC4gUGhhc2VsbHVzIGFjIHB1cnVzIGxhY3VzLCBldCBhY2N1bXNhbiBlcm9zLiBNb3JiaSB1bHRyaWNlcywgcHVydXMgYSBwb3J0YSBzb2RhbGVzLCBvZGlvIG1ldHVzIHBvc3VlcmUgbmVxdWUsIG5lYyBlbGVtZW50dW0gcmlzdXMgdHVycGlzIHNpdCBhbWV0IG1hZ25hLiBTZWQgZXN0IHF1YW0sIHVsdHJpY2llcyBhdCBjb25ndWUgYWRpcGlzY2luZywgbG9ib3J0aXMgaW4ganVzdG8uIFByb2luIGlhY3VsaXMgZGljdHVtIG51bmMsIGV1IGxhb3JlZXQgcXVhbSB2YXJpdXMgdml0YWUuIERvbmVjIHNpdCBhbWV0IGZldWdpYXQgdHVycGlzLiBNYXVyaXMgc2l0IGFtZXQgbWFnbmEgcXVhbSwgYWMgY29uc2VjdGV0dXIgZHVpLiBDdXJhYml0dXIgZWdldCBtYWduYSB0ZWxsdXMsIGV1IHBoYXJldHJhIGZlbGlzLiBEb25lYyBzaXQgYW1ldCB0b3J0b3IgbmlzbC4gQWxpcXVhbSBldCB0b3J0b3IgZmFjaWxpc2lzIGxhY3VzIHRpbmNpZHVudCBjb21tb2RvLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gQ3VyYWJpdHVyIG51bmMgbWFnbmEsIHVsdHJpY2llcyBpZCBjb252YWxsaXMgYXQsIHVsbGFtY29ycGVyIHZpdGFlIG1hc3NhLgoKUGhhc2VsbHVzIHZpdmVycmEgaWFjdWxpcyBwbGFjZXJhdC4gTnVsbGEgY29uc2VxdWF0IGRvbG9yIHNpdCBhbWV0IGVyYXQgZGlnbmlzc2ltIHBvc3VlcmUuIE51bGxhIGxhY2luaWEgYXVndWUgdml0YWUgbWkgdGVtcG9yIGdyYXZpZGEuIFBoYXNlbGx1cyBub24gdGVtcG9yIHRlbGx1cy4gUXVpc3F1ZSBub24gZW5pbSBzZW1wZXIgdG9ydG9yIHNhZ2l0dGlzIGZhY2lsaXNpcy4gQWxpcXVhbSB1cm5hIGZlbGlzLCBlZ2VzdGFzIGF0IHBvc3VlcmUgbmVjLCBhbGlxdWV0IGV1IG5pYmguIFByYWVzZW50IHNlZCB2ZXN0aWJ1bHVtIGVuaW0uIE1hdXJpcyBpYWN1bGlzIHZlbGl0IGR1aSwgZXQgZnJpbmdpbGxhIGVuaW0uIE51bGxhIG5lYyBuaXNpIG9yY2kuIFNlZCB2b2x1dHBhdCwganVzdG8gZWdldCBmcmluZ2lsbGEgYWRpcGlzY2luZywgbmlzbCBudWxsYSBjb25kaW1lbnR1bSBsaWJlcm8sIHNlZCBzb2RhbGVzIGVzdCBlc3QgZXQgb2Rpby4gQ3JhcyBpcHN1bSBkdWksIHZhcml1cyBldSBlbGVtZW50dW0gY29uc2VxdWF0LCBmYXVjaWJ1cyBpbiBsZW8uIFBlbGxlbnRlc3F1ZSBoYWJpdGFudCBtb3JiaSB0cmlzdGlxdWUgc2VuZWN0dXMgZXQgbmV0dXMgZXQgbWFsZXN1YWRhIGZhbWVzIGFjIHR1cnBpcyBlZ2VzdGFzLgoKVXQgbWFsZXN1YWRhIG1vbGVzdGllIGVsZWlmZW5kLiBDdXJhYml0dXIgaWQgZW5pbSBkdWksIGV1IHRpbmNpZHVudCBuaWJoLiBNYXVyaXMgc2l0IGFtZXQgYW50ZSBsZW8uIER1aXMgdHVycGlzIGlwc3VtLCBiaWJlbmR1bSBzZWQgbWF0dGlzIHNpdCBhbWV0LCBhY2N1bXNhbiBxdWlzIGRvbG9yLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgQWVuZWFuIGEgaW1wZXJkaWV0IG1ldHVzLiBRdWlzcXVlIHNvbGxpY2l0dWRpbiBmZWxpcyBpZCBuZXF1ZSB0ZW1wb3Igc2NlbGVyaXNxdWUuIERvbmVjIGF0IG9yY2kgZmVsaXMuIFZpdmFtdXMgdGVtcHVzIGNvbnZhbGxpcyBhdWN0b3IuIERvbmVjIGludGVyZHVtIGV1aXNtb2QgbG9ib3J0aXMuIFNlZCBhdCBsYWN1cyBuZWMgb2RpbyBkaWduaXNzaW0gbW9sbGlzLiBTZWQgc2FwaWVuIG9yY2ksIHBvcnR0aXRvciB0ZW1wdXMgYWNjdW1zYW4gdmVsLCB0aW5jaWR1bnQgbmVjIGFudGUuIE51bmMgcmhvbmN1cyBlZ2VzdGFzIGRhcGlidXMuIFN1c3BlbmRpc3NlIGZlcm1lbnR1bSBkaWN0dW0gZnJpbmdpbGxhLiBOdWxsYW0gbmlzaSBqdXN0bywgZWxlaWZlbmQgYSBjb25zZWN0ZXR1ciBjb252YWxsaXMsIHBvcnR0aXRvciBldCB0b3J0b3IuIFByb2luIHZpdGFlIGxvcmVtIG5vbiBkb2xvciBzdXNjaXBpdCBsYWNpbmlhIGV1IGVnZXQgbnVsbGEuCgpTdXNwZW5kaXNzZSBlZ2VzdGFzLCBzYXBpZW4gc2l0IGFtZXQgYmxhbmRpdCBzY2VsZXJpc3F1ZSwgbnVsbGEgYXJjdSB0cmlzdGlxdWUgZHVpLCBhIHBvcnRhIGp1c3RvIHF1YW0gdml0YWUgYXJjdS4gSW4gbWV0dXMgbGliZXJvLCBiaWJlbmR1bSBub24gdm9sdXRwYXQgdXQsIGxhb3JlZXQgdmVsIHR1cnBpcy4gTnVuYyBmYXVjaWJ1cyB2ZWxpdCBldSBpcHN1bSBjb21tb2RvIG5lYyBpYWN1bGlzIGVyb3Mgdm9sdXRwYXQuIFZpdmFtdXMgY29uZ3VlIGF1Y3RvciBlbGl0IHNlZCBzdXNjaXBpdC4gRHVpcyBjb21tb2RvLCBsaWJlcm8gZXUgdmVzdGlidWx1bSBmZXVnaWF0LCBsZW8gbWkgZGFwaWJ1cyB0ZWxsdXMsIGluIHBsYWNlcmF0IG5pc2wgZHVpIGF0IGVzdC4gVmVzdGlidWx1bSB2aXZlcnJhIHRyaXN0aXF1ZSBsb3JlbSwgb3JuYXJlIGVnZXN0YXMgZXJhdCBydXRydW0gYS4gTnVsbGFtIGF0IGF1Z3VlIG1hc3NhLCB1dCBjb25zZWN0ZXR1ciBpcHN1bS4gUGVsbGVudGVzcXVlIG1hbGVzdWFkYSwgdmVsaXQgdXQgbG9ib3J0aXMgc2FnaXR0aXMsIG5pc2kgbWFzc2Egc2VtcGVyIG9kaW8sIG1hbGVzdWFkYSBzZW1wZXIgcHVydXMgbmlzbCB2ZWwgbGVjdHVzLiBOdW5jIGR1aSBzZW0sIG1hdHRpcyB2aXRhZSBsYW9yZWV0IHZpdGFlLCBzb2xsaWNpdHVkaW4gYWMgbGVvLiBOdWxsYSB2ZWwgZmVybWVudHVtIGVzdC4KClZpdmFtdXMgaW4gb2RpbyBhIG5pc2kgZGlnbmlzc2ltIHJob25jdXMgaW4gaW4gbGFjdXMuIERvbmVjIGV0IG5pc2wgdG9ydG9yLiBEb25lYyBzYWdpdHRpcyBjb25zZXF1YXQgbWksIHZlbCBwbGFjZXJhdCB0ZWxsdXMgY29udmFsbGlzIGlkLiBBbGlxdWFtIGZhY2lsaXNpcyBydXRydW0gbmlzbCBzZWQgcHJldGl1bS4gRG9uZWMgZXQgbGFjaW5pYSBuaXNsLiBBbGlxdWFtIGVyYXQgdm9sdXRwYXQuIEN1cmFiaXR1ciBhYyBwdWx2aW5hciB0ZWxsdXMuIE51bGxhbSB2YXJpdXMgbG9ib3J0aXMgcG9ydGEuIENyYXMgZGFwaWJ1cywgbGlndWxhIHV0IHBvcnRhIHVsdHJpY2llcywgbGVvIGxhY3VzIHZpdmVycmEgcHVydXMsIHF1aXMgbW9sbGlzIHVybmEgcmlzdXMgZXUgbGVvLiBOdW5jIG1hbGVzdWFkYSBjb25zZWN0ZXR1ciBwdXJ1cywgdmVsIGF1Y3RvciBsZWN0dXMgc2NlbGVyaXNxdWUgcG9zdWVyZS4gTWFlY2VuYXMgZHVpIG1hc3NhLCB2ZXN0aWJ1bHVtIGJpYmVuZHVtIGJsYW5kaXQgbm9uLCBpbnRlcmR1bSBlZ2V0IG1hdXJpcy4gUGhhc2VsbHVzIGVzdCBhbnRlLCBwdWx2aW5hciBhdCBpbXBlcmRpZXQgcXVpcywgaW1wZXJkaWV0IHZlbCB1cm5hLiBRdWlzcXVlIGVnZXQgdm9sdXRwYXQgb3JjaS4gUXVpc3F1ZSBldCBhcmN1IHB1cnVzLCB1dCBmYXVjaWJ1cyB2ZWxpdC4KClByYWVzZW50IHNlZCBpcHN1bSB1cm5hLiBQcmFlc2VudCBzYWdpdHRpcyB2YXJpdXMgbWFnbmEsIGlkIGNvbW1vZG8gZG9sb3IgbWFsZXN1YWRhIGFjLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gUXVpc3F1ZSBzaXQgYW1ldCBudW5jIGV1IHNlbSBvcm5hcmUgdGVtcG9yLiBNYXVyaXMgaWQgZG9sb3IgbmVjIGVyYXQgY29udmFsbGlzIHBvcnRhIGluIGxvYm9ydGlzIG5pc2kuIEN1cmFiaXR1ciBoZW5kcmVyaXQgcmhvbmN1cyB0b3J0b3IgZXUgaGVuZHJlcml0LiBQZWxsZW50ZXNxdWUgZXUgYW50ZSB2ZWwgZWxpdCBsdWN0dXMgZWxlaWZlbmQgcXVpcyB2aXZlcnJhIG51bGxhLiBTdXNwZW5kaXNzZSBvZGlvIGRpYW0sIGV1aXNtb2QgZXUgcG9ydHRpdG9yIG1vbGVzdGllLCBzb2xsaWNpdHVkaW4gc2l0IGFtZXQgbnVsbGEuIFNlZCBhbnRlIHVybmEsIGRpY3R1bSBiaWJlbmR1bSByaG9uY3VzIGV0LCBibGFuZGl0IG5lYyBhbnRlLiBTdXNwZW5kaXNzZSB0b3J0b3IgYXVndWUsIGFjY3Vtc2FuIHF1aXMgc3VzY2lwaXQgaWQsIGFjY3Vtc2FuIHNpdCBhbWV0IGVyYXQuIERvbmVjIHBoYXJldHJhIHZhcml1cyBsb2JvcnRpcy4gTWFlY2VuYXMgaXBzdW0gZGlhbSwgZmF1Y2lidXMgZXUgdGVtcHVzIGlkLCBjb252YWxsaXMgbmVjIGVuaW0uIER1aXMgYXJjdSB0dXJwaXMsIGZyaW5naWxsYSBuZWMgZWdlc3RhcyB1dCwgZGlnbmlzc2ltIHRyaXN0aXF1ZSBudWxsYS4gQ3VyYWJpdHVyIHN1c2NpcGl0IGR1aSBub24ganVzdG8gdWx0cmljZXMgcGhhcmV0cmEuIEFsaXF1YW0gZXJhdCB2b2x1dHBhdC4gTnVsbGEgZmFjaWxpc2kuIFF1aXNxdWUgaWQgZmVsaXMgZXUgc2VtIGFsaXF1YW0gZnJpbmdpbGxhLgoKRXRpYW0gcXVpcyBhdWd1ZSBpbiB0ZWxsdXMgY29uc2VxdWF0IGVsZWlmZW5kLiBBZW5lYW4gZGlnbmlzc2ltIGNvbmd1ZSBmZWxpcyBpZCBlbGVtZW50dW0uIER1aXMgZnJpbmdpbGxhIHZhcml1cyBpcHN1bSwgbmVjIHN1c2NpcGl0IGxlbyBzZW1wZXIgdmVsLiBVdCBzb2xsaWNpdHVkaW4sIG9yY2kgYSB0aW5jaWR1bnQgYWNjdW1zYW4sIGRpYW0gbGVjdHVzIGxhb3JlZXQgbGFjdXMsIHZlbCBmZXJtZW50dW0gcXVhbSBlc3QgdmVsIGVyb3MuIEFsaXF1YW0gZnJpbmdpbGxhIHNhcGllbiBhYyBzYXBpZW4gZmF1Y2lidXMgY29udmFsbGlzLiBBbGlxdWFtIGlkIG51bmMgZXUganVzdG8gY29uc2VxdWF0IHRpbmNpZHVudC4gUXVpc3F1ZSBuZWMgbmlzbCBkdWkuIFBoYXNlbGx1cyBhdWd1ZSBsZWN0dXMsIHZhcml1cyB2aXRhZSBhdWN0b3IgdmVsLCBydXRydW0gYXQgcmlzdXMuIFZpdmFtdXMgbGFjaW5pYSBsZW8gcXVpcyBuZXF1ZSB1bHRyaWNlcyBuZWMgZWxlbWVudHVtIGZlbGlzIGZyaW5naWxsYS4gUHJvaW4gdmVsIHBvcnR0aXRvciBsZWN0dXMuCgpDdXJhYml0dXIgc2FwaWVuIGxvcmVtLCBtb2xsaXMgdXQgYWNjdW1zYW4gbm9uLCB1bHRyaWNpZXMgZXQgbWV0dXMuIEN1cmFiaXR1ciB2ZWwgbG9yZW0gcXVpcyBzYXBpZW4gZnJpbmdpbGxhIGxhb3JlZXQuIE1vcmJpIGlkIHVybmEgYWMgb3JjaSBlbGVtZW50dW0gYmxhbmRpdCBlZ2V0IHZvbHV0cGF0IG5lcXVlLiBQZWxsZW50ZXNxdWUgc2VtIG9kaW8sIGlhY3VsaXMgZXUgcGhhcmV0cmEgdml0YWUsIGN1cnN1cyBpbiBxdWFtLiBOdWxsYSBtb2xlc3RpZSBsaWd1bGEgaWQgbWFzc2EgbHVjdHVzIGV0IHB1bHZpbmFyIG5pc2kgcHVsdmluYXIuIE51bmMgZmVybWVudHVtIGF1Z3VlIGEgbGFjdXMgZnJpbmdpbGxhIHJob25jdXMgcG9ydHRpdG9yIGVyYXQgZGljdHVtLiBOdW5jIHNpdCBhbWV0IHRlbGx1cyBldCBkdWkgdml2ZXJyYSBhdWN0b3IgZXVpc21vZCBhdCBuaXNsLiBJbiBzZWQgY29uZ3VlIG1hZ25hLiBQcm9pbiBldCB0b3J0b3IgdXQgYXVndWUgcGxhY2VyYXQgZGlnbmlzc2ltIGEgZXUganVzdG8uIE1vcmJpIHBvcnR0aXRvciBwb3J0YSBsb2JvcnRpcy4gUGVsbGVudGVzcXVlIG5pYmggbGFjdXMsIGFkaXBpc2NpbmcgdXQgdHJpc3RpcXVlIHF1aXMsIGNvbnNlcXVhdCB2aXRhZSB2ZWxpdC4gTWFlY2VuYXMgdXQgbHVjdHVzIGxpYmVyby4gVml2YW11cyBhdWN0b3Igb2RpbyBldCBlcmF0IHNlbXBlciBzYWdpdHRpcy4gVml2YW11cyBpbnRlcmR1bSB2ZWxpdCBpbiByaXN1cyBtYXR0aXMgcXVpcyBkaWN0dW0gYW50ZSByaG9uY3VzLiBJbiBzYWdpdHRpcyBwb3J0dGl0b3IgZXJvcywgYXQgbG9ib3J0aXMgbWV0dXMgdWx0cmljZXMgdmVsLiBDdXJhYml0dXIgbm9uIGFsaXF1YW0gbmlzbC4gVmVzdGlidWx1bSBsdWN0dXMgZmV1Z2lhdCBzdXNjaXBpdC4gRXRpYW0gbm9uIGxhY3VzIHZlbCBudWxsYSBlZ2VzdGFzIGlhY3VsaXMgaWQgcXVpcyByaXN1cy4KCkV0aWFtIGluIGF1Y3RvciB1cm5hLiBGdXNjZSB1bHRyaWNpZXMgbW9sZXN0aWUgY29udmFsbGlzLiBJbiBoYWMgaGFiaXRhc3NlIHBsYXRlYSBkaWN0dW1zdC4gVmVzdGlidWx1bSBhbnRlIGlwc3VtIHByaW1pcyBpbiBmYXVjaWJ1cyBvcmNpIGx1Y3R1cyBldCB1bHRyaWNlcyBwb3N1ZXJlIGN1YmlsaWEgQ3VyYWU7IE1hdXJpcyBpYWN1bGlzIGxvcmVtIGZhdWNpYnVzIHB1cnVzIGdyYXZpZGEgYXQgY29udmFsbGlzIHR1cnBpcyBzb2xsaWNpdHVkaW4uIFN1c3BlbmRpc3NlIGF0IHZlbGl0IGxvcmVtLCBhIGZlcm1lbnR1bSBpcHN1bS4gRXRpYW0gY29uZGltZW50dW0sIGR1aSB2ZWwgY29uZGltZW50dW0gZWxlbWVudHVtLCBzYXBpZW4gc2VtIGJsYW5kaXQgc2FwaWVuLCBldCBwaGFyZXRyYSBsZW8gbmVxdWUgZXQgbGVjdHVzLiBOdW5jIHZpdmVycmEgdXJuYSBpYWN1bGlzIGF1Z3VlIHVsdHJpY2VzIGFjIHBvcnR0aXRvciBsYWN1cyBkaWduaXNzaW0uIEFsaXF1YW0gdXQgdHVycGlzIGR1aS4gU2VkIGVnZXQgYWxpcXVldCBmZWxpcy4gSW4gYmliZW5kdW0gbmliaCBzaXQgYW1ldCBzYXBpZW4gYWNjdW1zYW4gYWNjdW1zYW4gcGhhcmV0cmEgbWFnbmEgbW9sZXN0aWUuCgpNYXVyaXMgYWxpcXVldCB1cm5hIGVnZXQgbGVjdHVzIGFkaXBpc2NpbmcgYXQgY29uZ3VlIHR1cnBpcyBjb25zZXF1YXQuIFZpdmFtdXMgdGluY2lkdW50IGZlcm1lbnR1bSByaXN1cyBldCBmZXVnaWF0LiBOdWxsYSBtb2xlc3RpZSB1bGxhbWNvcnBlciBuaWJoIHNlZCBmYWNpbGlzaXMuIFBoYXNlbGx1cyBldCBjdXJzdXMgcHVydXMuIE5hbSBjdXJzdXMsIGR1aSBkaWN0dW0gdWx0cmljZXMgdml2ZXJyYSwgZXJhdCByaXN1cyB2YXJpdXMgZWxpdCwgZXUgbW9sZXN0aWUgZHVpIGVyb3MgcXVpcyBxdWFtLiBBbGlxdWFtIGV0IGFudGUgbmVxdWUsIGFjIGNvbnNlY3RldHVyIGR1aS4gRG9uZWMgY29uZGltZW50dW0gZXJhdCBpZCBlbGl0IGRpY3R1bSBzZWQgYWNjdW1zYW4gbGVvIHNhZ2l0dGlzLiBQcm9pbiBjb25zZXF1YXQgY29uZ3VlIHJpc3VzLCB2ZWwgdGluY2lkdW50IGxlbyBpbXBlcmRpZXQgZXUuIFZlc3RpYnVsdW0gbWFsZXN1YWRhIHR1cnBpcyBldSBtZXR1cyBpbXBlcmRpZXQgcHJldGl1bS4gQWxpcXVhbSBjb25kaW1lbnR1bSB1bHRyaWNlcyBuaWJoLCBldSBzZW1wZXIgZW5pbSBlbGVpZmVuZCBhLiBFdGlhbSBjb25kaW1lbnR1bSBuaXNsIHF1YW0uCgpQZWxsZW50ZXNxdWUgaWQgbW9sZXN0aWUgbmlzbC4gTWFlY2VuYXMgZXQgbGVjdHVzIGF0IGp1c3RvIG1vbGVzdGllIHZpdmVycmEgc2l0IGFtZXQgc2l0IGFtZXQgbGlndWxhLiBOdWxsYW0gbm9uIHBvcnR0aXRvciBtYWduYS4gUXVpc3F1ZSBlbGVtZW50dW0gYXJjdSBjdXJzdXMgdG9ydG9yIHJ1dHJ1bSBsb2JvcnRpcy4gTW9yYmkgc2l0IGFtZXQgbGVjdHVzIHZpdGFlIGVuaW0gZXVpc21vZCBkaWduaXNzaW0gZWdldCBhdCBuZXF1ZS4gVml2YW11cyBjb25zZXF1YXQgdmVoaWN1bGEgZHVpLCB2aXRhZSBhdWN0b3IgYXVndWUgZGlnbmlzc2ltIGluLiBJbiB0ZW1wdXMgc2VtIHF1aXMganVzdG8gdGluY2lkdW50IHNpdCBhbWV0IGF1Y3RvciB0dXJwaXMgbG9ib3J0aXMuIFBlbGxlbnRlc3F1ZSBub24gZXN0IG51bmMuIFZlc3RpYnVsdW0gbW9sbGlzIGZyaW5naWxsYSBpbnRlcmR1bS4gTWFlY2VuYXMgaXBzdW0gZG9sb3IsIHBoYXJldHJhIGlkIHRyaXN0aXF1ZSBtYXR0aXMsIGx1Y3R1cyB2aXRhZSB1cm5hLiBVdCB1bGxhbWNvcnBlciBhcmN1IGVnZXQgZWxpdCBjb252YWxsaXMgbW9sbGlzLiBQZWxsZW50ZXNxdWUgY29uZGltZW50dW0sIG1hc3NhIGFjIGhlbmRyZXJpdCB0ZW1wb3IsIG1hdXJpcyBwdXJ1cyBibGFuZGl0IGp1c3RvLCBldCBwaGFyZXRyYSBsZW8ganVzdG8gYSBlc3QuIER1aXMgYXJjdSBhdWd1ZSwgZmFjaWxpc2lzIHZlbCBkaWduaXNzaW0gc2VkLCBhbGlxdWFtIHF1aXMgbWFnbmEuIFF1aXNxdWUgbm9uIGNvbnNlcXVhdCBkb2xvci4gU3VzcGVuZGlzc2UgYSB1bHRyaWNlcyBsZW8uCgpEb25lYyB2aXRhZSBwcmV0aXVtIG5pYmguIE1hZWNlbmFzIGJpYmVuZHVtIGJpYmVuZHVtIGRpYW0gaW4gcGxhY2VyYXQuIFV0IGFjY3Vtc2FuLCBtaSB2aXRhZSB2ZXN0aWJ1bHVtIGV1aXNtb2QsIG51bmMganVzdG8gdnVscHV0YXRlIG5pc2ksIG5vbiBwbGFjZXJhdCBtaSB1cm5hIGV0IGRpYW0uIE1hZWNlbmFzIG1hbGVzdWFkYSBsb3JlbSB1dCBhcmN1IG1hdHRpcyBtb2xsaXMuIE51bGxhIGZhY2lsaXNpLiBEb25lYyBlc3QgbGVvLCBiaWJlbmR1bSBldSBwdWx2aW5hciBpbiwgY3Vyc3VzIHZlbCBtZXR1cy4gQWxpcXVhbSBlcmF0IHZvbHV0cGF0LiBOdWxsYW0gZmV1Z2lhdCBwb3J0dGl0b3IgbmVxdWUgaW4gdnVscHV0YXRlLiBRdWlzcXVlIG5lYyBtaSBldSBtYWduYSBjb25zZXF1YXQgY3Vyc3VzIG5vbiBhdCBhcmN1LiBFdGlhbSByaXN1cyBtZXR1cywgc29sbGljaXR1ZGluIGV0IHVsdHJpY2VzIGF0LCB0aW5jaWR1bnQgc2VkIG51bmMuIFNlZCBlZ2V0IHNjZWxlcmlzcXVlIGF1Z3VlLiBVdCBmcmluZ2lsbGEgdmVuZW5hdGlzIHNlbSBub24gZWxlaWZlbmQuIE51bmMgbWF0dGlzLCByaXN1cyBzaXQgYW1ldCB2dWxwdXRhdGUgdmFyaXVzLCByaXN1cyBqdXN0byBlZ2VzdGFzIG1hdXJpcywgaWQgaW50ZXJkdW0gb2RpbyBpcHN1bSBldCBuaXNsLiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dXIgYWRpcGlzY2luZyBlbGl0LiBNb3JiaSBpZCBlcmF0IG9kaW8sIG5lYyBwdWx2aW5hciBlbmltLgoKQ3VyYWJpdHVyIGFjIGZlcm1lbnR1bSBxdWFtLiBNb3JiaSBldSBlcm9zIHNhcGllbiwgdml0YWUgdGVtcHVzIGRvbG9yLiBNYXVyaXMgdmVzdGlidWx1bSBibGFuZGl0IGVuaW0gdXQgdmVuZW5hdGlzLiBBbGlxdWFtIGVnZXN0YXMsIGVyb3MgYXQgY29uc2VjdGV0dXIgdGluY2lkdW50LCBsb3JlbSBhdWd1ZSBpYWN1bGlzIGVzdCwgbmVjIG1vbGxpcyBmZWxpcyBhcmN1IGluIG51bmMuIFNlZCBpbiBvZGlvIHNlZCBsaWJlcm8gcGVsbGVudGVzcXVlIHZvbHV0cGF0IHZpdGFlIGEgYW50ZS4gTW9yYmkgY29tbW9kbyB2b2x1dHBhdCB0ZWxsdXMsIHV0IHZpdmVycmEgcHVydXMgcGxhY2VyYXQgZmVybWVudHVtLiBJbnRlZ2VyIGlhY3VsaXMgZmFjaWxpc2lzIGFyY3UsIGF0IGdyYXZpZGEgbG9yZW0gYmliZW5kdW0gYXQuIEFlbmVhbiBpZCBlcm9zIGVnZXQgZXN0IHNhZ2l0dGlzIGNvbnZhbGxpcyBzZWQgZXQgZHVpLiBEb25lYyBldSBwdWx2aW5hciB0ZWxsdXMuIE51bmMgZGlnbmlzc2ltIHJob25jdXMgdGVsbHVzLCBhdCBwZWxsZW50ZXNxdWUgbWV0dXMgbHVjdHVzIGF0LiBTZWQgb3JuYXJlIGFsaXF1YW0gZGlhbSwgYSBwb3J0dGl0b3IgbGVvIHNvbGxpY2l0dWRpbiBzZWQuIE5hbSB2aXRhZSBsZWN0dXMgbGFjdXMuIEludGVnZXIgYWRpcGlzY2luZyBxdWFtIG5lcXVlLCBibGFuZGl0IHBvc3VlcmUgbGliZXJvLiBTZWQgbGliZXJvIG51bmMsIGVnZXN0YXMgc29kYWxlcyB0ZW1wdXMgc2VkLCBjdXJzdXMgYmxhbmRpdCB0ZWxsdXMuIFZlc3RpYnVsdW0gbWkgcHVydXMsIHVsdHJpY2llcyBxdWlzIHBsYWNlcmF0IHZlbCwgbW9sZXN0aWUgYXQgZHVpLgoKTnVsbGEgY29tbW9kbyBvZGlvIGp1c3RvLiBQZWxsZW50ZXNxdWUgbm9uIG9ybmFyZSBkaWFtLiBJbiBjb25zZWN0ZXR1ciBzYXBpZW4gYWMgbnVuYyBzYWdpdHRpcyBtYWxlc3VhZGEuIE1vcmJpIHVsbGFtY29ycGVyIHRlbXBvciBlcmF0IG5lYyBydXRydW0uIER1aXMgdXQgY29tbW9kbyBqdXN0by4gQ3JhcyBlc3Qgb3JjaSwgY29uc2VjdGV0dXIgc2VkIGludGVyZHVtIHNlZCwgc2NlbGVyaXNxdWUgc2l0IGFtZXQgbnVsbGEuIFZlc3RpYnVsdW0ganVzdG8gbnVsbGEsIHBlbGxlbnRlc3F1ZSBhIHRlbXB1cyBldCwgZGFwaWJ1cyBldCBhcmN1LiBMb3JlbSBpcHN1bSBkb2xvciBzaXQgYW1ldCwgY29uc2VjdGV0dXIgYWRpcGlzY2luZyBlbGl0LiBNb3JiaSB0cmlzdGlxdWUsIGVyb3MgbmVjIGNvbmd1ZSBhZGlwaXNjaW5nLCBsaWd1bGEgc2VtIHJob25jdXMgZmVsaXMsIGF0IG9ybmFyZSB0ZWxsdXMgbWF1cmlzIGFjIHJpc3VzLiBWZXN0aWJ1bHVtIGFudGUgaXBzdW0gcHJpbWlzIGluIGZhdWNpYnVzIG9yY2kgbHVjdHVzIGV0IHVsdHJpY2VzIHBvc3VlcmUgY3ViaWxpYSBDdXJhZTsgUHJvaW4gbWF1cmlzIGR1aSwgdGVtcG9yIGZlcm1lbnR1bSBkaWN0dW0gZXQsIGN1cnN1cyBhIGxlby4gTWFlY2VuYXMgbmVjIG5pc2wgYSB0ZWxsdXMgcGVsbGVudGVzcXVlIHJob25jdXMuIE51bGxhbSB1bHRyaWNlcyBldWlzbW9kIGR1aSBldSBjb25ndWUuCgpJbiBuZWMgdGVtcG9yIHJpc3VzLiBJbiBmYXVjaWJ1cyBuaXNpIGVnZXQgZGlhbSBkaWduaXNzaW0gY29uc2VxdWF0LiBEb25lYyBwdWx2aW5hciBhbnRlIG5lYyBlbmltIG1hdHRpcyBydXRydW0uIFZlc3RpYnVsdW0gbGVvIGF1Z3VlLCBtb2xlc3RpZSBuZWMgZGFwaWJ1cyBpbiwgZGljdHVtIGF0IGVuaW0uIEludGVnZXIgYWxpcXVhbSwgbG9yZW0gZXUgdnVscHV0YXRlIGxhY2luaWEsIG1pIG9yY2kgdGVtcG9yIGVuaW0sIGVnZXQgbWF0dGlzIGxpZ3VsYSBtYWduYSBhIG1hZ25hLiBQcmFlc2VudCBzZWQgZXJhdCB1dCB0b3J0b3IgaW50ZXJkdW0gdml2ZXJyYS4gTG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2NpbmcgZWxpdC4gTnVsbGEgZmFjaWxpc2kuIE1hZWNlbmFzIHNpdCBhbWV0IGxlY3R1cyBsYWN1cy4gTnVuYyB2aXRhZSBwdXJ1cyBpZCBsaWd1bGEgbGFvcmVldCBjb25kaW1lbnR1bS4gRHVpcyBhdWN0b3IgdG9ydG9yIHZlbCBkdWkgcHVsdmluYXIgYSBmYWNpbGlzaXMgYXJjdSBkaWduaXNzaW0uIEluIGhhYyBoYWJpdGFzc2UgcGxhdGVhIGRpY3R1bXN0LiBEb25lYyBzb2xsaWNpdHVkaW4gcGVsbGVudGVzcXVlIGVnZXN0YXMuIFNlZCBzZWQgc2VtIGp1c3RvLiBNYWVjZW5hcyBsYW9yZWV0IGhlbmRyZXJpdCBtYXVyaXMsIHV0IHBvcnR0aXRvciBsb3JlbSBpYWN1bGlzIGFjLiBRdWlzcXVlIG1vbGVzdGllIHNlbSBxdWlzIGxvcmVtIHRlbXBvciBydXRydW0uIFBoYXNlbGx1cyBuaWJoIG1hdXJpcywgcmhvbmN1cyBpbiBjb25zZWN0ZXR1ciBub24sIGFsaXF1ZXQgZXUgbWFzc2EuCgpDdXJhYml0dXIgdmVsaXQgYXJjdSwgcHJldGl1bSBwb3J0YSBwbGFjZXJhdCBxdWlzLCB2YXJpdXMgdXQgbWV0dXMuIFZlc3RpYnVsdW0gdnVscHV0YXRlIHRpbmNpZHVudCBqdXN0bywgdml0YWUgcG9ydHRpdG9yIGxlY3R1cyBpbXBlcmRpZXQgc2l0IGFtZXQuIFZpdmFtdXMgZW5pbSBkb2xvciwgc29sbGljaXR1ZGluIHV0IHNlbXBlciBub24sIG9ybmFyZSBvcm5hcmUgZHVpLiBBbGlxdWFtIHRlbXBvciBmZXJtZW50dW0gc2FwaWVuIGVnZXQgY29uZGltZW50dW0uIEN1cmFiaXR1ciBsYW9yZWV0IGJpYmVuZHVtIGFudGUsIGluIGV1aXNtb2QgbGFjdXMgbGFjaW5pYSBldS4gUGVsbGVudGVzcXVlIGhhYml0YW50IG1vcmJpIHRyaXN0aXF1ZSBzZW5lY3R1cyBldCBuZXR1cyBldCBtYWxlc3VhZGEgZmFtZXMgYWMgdHVycGlzIGVnZXN0YXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIFNlZCBhdCBsaWJlcm8gZXUgdG9ydG9yIHRlbXB1cyBzY2VsZXJpc3F1ZS4gTnVsbGEgZmFjaWxpc2kuIE51bGxhbSB2aXRhZSBuZXF1ZSBpZCBqdXN0byB2aXZlcnJhIHJob25jdXMgcHJldGl1bSBhdCBsaWJlcm8uIEV0aWFtIGVzdCB1cm5hLCBhbGlxdWFtIHZlbCBwdWx2aW5hciBub24sIG9ybmFyZSB2ZWwgcHVydXMuCgpOdWxsYSB2YXJpdXMsIG5pc2kgZWdldCBjb25kaW1lbnR1bSBzZW1wZXIsIG1ldHVzIGVzdCBkaWN0dW0gb2RpbywgdmVsIG1hdHRpcyByaXN1cyBlc3Qgc2VkIHZlbGl0LiBDdW0gc29jaWlzIG5hdG9xdWUgcGVuYXRpYnVzIGV0IG1hZ25pcyBkaXMgcGFydHVyaWVudCBtb250ZXMsIG5hc2NldHVyIHJpZGljdWx1cyBtdXMuIE51bmMgbm9uIGVzdCBuZWMgdGVsbHVzIHVsdHJpY2llcyBtYXR0aXMgdXQgZWdldCB2ZWxpdC4gSW50ZWdlciBjb25kaW1lbnR1bSBhbnRlIGlkIGxvcmVtIGJsYW5kaXQgbGFjaW5pYS4gRG9uZWMgdmVsIHRvcnRvciBhdWd1ZSwgaW4gY29uZGltZW50dW0gbmlzaS4gUGVsbGVudGVzcXVlIHBlbGxlbnRlc3F1ZSBudWxsYSB1dCBudWxsYSBwb3J0dGl0b3IgcXVpcyBzb2RhbGVzIGVuaW0gcnV0cnVtLiBTZWQgYXVndWUgcmlzdXMsIGV1aXNtb2QgYSBhbGlxdWV0IGF0LCB2dWxwdXRhdGUgbm9uIGxpYmVyby4gTnVsbGFtIG5pYmggb2RpbywgZGlnbmlzc2ltIGZlcm1lbnR1bSBwdWx2aW5hciBhYywgY29uZ3VlIGV1IG1pLiBEdWlzIHRpbmNpZHVudCwgbmliaCBpZCB2ZW5lbmF0aXMgcGxhY2VyYXQsIGRpYW0gdHVycGlzIGdyYXZpZGEgbGVvLCBzaXQgYW1ldCBtb2xsaXMgbWFzc2EgZG9sb3IgcXVpcyBtYXVyaXMuIFZpdmFtdXMgc2NlbGVyaXNxdWUgc29kYWxlcyBhcmN1IGV0IGRhcGlidXMuIFN1c3BlbmRpc3NlIHBvdGVudGkuIENyYXMgcXVpcyB0ZWxsdXMgYXJjdSwgcXVpcyBsYW9yZWV0IHNlbS4gRnVzY2UgcG9ydHRpdG9yLCBzYXBpZW4gdmVsIHRyaXN0aXF1ZSBzb2RhbGVzLCB2ZWxpdCBsZW8gcG9ydGEgYXJjdSwgcXVpcyBwZWxsZW50ZXNxdWUgbnVuYyBtZXR1cyBub24gb2Rpby4gTmFtIGFyY3UgbGliZXJvLCB1bGxhbWNvcnBlciB1dCBwaGFyZXRyYSBub24sIGRpZ25pc3NpbSBldCB2ZWxpdC4gUXVpc3F1ZSBkb2xvciBsb3JlbSwgdmVoaWN1bGEgc2l0IGFtZXQgc2NlbGVyaXNxdWUgaW4sIHZhcml1cyBhdCBudWxsYS4gUGVsbGVudGVzcXVlIHZpdGFlIHNlbSBlZ2V0IHRvcnRvciBpYWN1bGlzIHB1bHZpbmFyLiBTZWQgbnVuYyBqdXN0bywgZXVpc21vZCBncmF2aWRhIHB1bHZpbmFyIGVnZXQsIGdyYXZpZGEgZWdldCB0dXJwaXMuIENyYXMgdmVsIGRpY3R1bSBuaXNpLiBOdWxsYW0gbnVsbGEgbGliZXJvLCBncmF2aWRhIHNpdCBhbWV0IGFsaXF1YW0gcXVpcywgY29tbW9kbyB2aXRhZSBvZGlvLiBDcmFzIHZpdGFlIG5pYmggbmVjIGR1aSBwbGFjZXJhdCBzZW1wZXIuCgpWaXZhbXVzIGF0IGZyaW5naWxsYSBlcm9zLiBWaXZhbXVzIGF0IG5pc2wgaWQgbWFzc2EgY29tbW9kbyBmZXVnaWF0IHF1aXMgbm9uIG1hc3NhLiBNb3JiaSB0ZWxsdXMgdXJuYSwgYXVjdG9yIHNpdCBhbWV0IGVsZW1lbnR1bSBzZWQsIHJ1dHJ1bSBub24gbGVjdHVzLiBOdWxsYSBmZXVnaWF0IGR1aSBpbiBzYXBpZW4gb3JuYXJlIGV0IGltcGVyZGlldCBlc3Qgb3JuYXJlLiBQZWxsZW50ZXNxdWUgaGFiaXRhbnQgbW9yYmkgdHJpc3RpcXVlIHNlbmVjdHVzIGV0IG5ldHVzIGV0IG1hbGVzdWFkYSBmYW1lcyBhYyB0dXJwaXMgZWdlc3Rhcy4gVmVzdGlidWx1bSBzZW1wZXIgcnV0cnVtIHRlbXBvci4gU2VkIGluIGZlbGlzIG5pYmgsIHNlZCBhbGlxdWFtIGVuaW0uIEN1cmFiaXR1ciB1dCBxdWFtIHNjZWxlcmlzcXVlIHZlbGl0IHBsYWNlcmF0IGRpY3R1bS4gRG9uZWMgZWxlaWZlbmQgdmVoaWN1bGEgcHVydXMsIGV1IHZlc3RpYnVsdW0gc2FwaWVuIHJ1dHJ1bSBldS4gVml2YW11cyBpbiBvZGlvIHZlbCBlc3QgdnVscHV0YXRlIGlhY3VsaXMuIE51bmMgcnV0cnVtIGZldWdpYXQgcHJldGl1bS4KCk1hZWNlbmFzIGlwc3VtIG5lcXVlLCBhdWN0b3IgcXVpcyBsYWNpbmlhIHZpdGFlLCBldWlzbW9kIGFjIG9yY2kuIERvbmVjIG1vbGVzdGllIG1hc3NhIGNvbnNlcXVhdCBlc3QgcG9ydGEgYWMgcG9ydGEgcHVydXMgdGluY2lkdW50LiBOYW0gYmliZW5kdW0gbGVvIG5lYyBsYWN1cyBtb2xsaXMgbm9uIGNvbmRpbWVudHVtIGRvbG9yIHJob25jdXMuIE51bGxhIGFjIHZvbHV0cGF0IGxvcmVtLiBOdWxsYW0gZXJhdCBwdXJ1cywgY29udmFsbGlzIGVnZXQgY29tbW9kbyBpZCwgdmFyaXVzIHF1aXMgYXVndWUuIE51bGxhbSBhbGlxdWFtIGVnZXN0YXMgbWksIHZlbCBzdXNjaXBpdCBuaXNsIG1hdHRpcyBjb25zZXF1YXQuIFF1aXNxdWUgdmVsIGVnZXN0YXMgc2FwaWVuLiBOdW5jIGxvcmVtIHZlbGl0LCBjb252YWxsaXMgbmVjIGxhb3JlZXQgZXQsIGFsaXF1ZXQgZWdldCBtYXNzYS4gTmFtIGV0IG5pYmggYWMgZHVpIHZlaGljdWxhIGFsaXF1YW0gcXVpcyBldSBhdWd1ZS4gQ3JhcyB2ZWwgbWFnbmEgdXQgZWxpdCByaG9uY3VzIGludGVyZHVtIGlhY3VsaXMgdm9sdXRwYXQgbmlzbC4gU3VzcGVuZGlzc2UgYXJjdSBsb3JlbSwgdmFyaXVzIHJob25jdXMgdGVtcG9yIGlkLCBwdWx2aW5hciBzZWQgdG9ydG9yLiBQZWxsZW50ZXNxdWUgdWx0cmljaWVzIGxhb3JlZXQgb2RpbyBhYyBkaWduaXNzaW0uIEFsaXF1YW0gZGlhbSBhcmN1LCBwbGFjZXJhdCBxdWlzIGVnZXN0YXMgZWdldCwgZmFjaWxpc2lzIGV1IG51bmMuIE1hdXJpcyB2dWxwdXRhdGUsIG5pc2wgc2l0IGFtZXQgbW9sbGlzIGludGVyZHVtLCByaXN1cyB0b3J0b3Igb3JuYXJlIG9yY2ksIHNlZCBlZ2VzdGFzIG9yY2kgZXJvcyBub24gZGlhbS4gVmVzdGlidWx1bSBoZW5kcmVyaXQsIG1ldHVzIHF1aXMgcGxhY2VyYXQgcGVsbGVudGVzcXVlLCBlbmltIHB1cnVzIGZhdWNpYnVzIGR1aSwgc2l0IGFtZXQgdWx0cmljaWVzIGxlY3R1cyBpcHN1bSBpZCBsb3JlbS4gQ2xhc3MgYXB0ZW50IHRhY2l0aSBzb2Npb3NxdSBhZCBsaXRvcmEgdG9ycXVlbnQgcGVyIGNvbnViaWEgbm9zdHJhLCBwZXIgaW5jZXB0b3MgaGltZW5hZW9zLiBQcmFlc2VudCBlZ2V0IGRpYW0gb2RpbywgZXUgYmliZW5kdW0gZWxpdC4gSW4gdmVzdGlidWx1bSBvcmNpIGV1IGVyYXQgdGluY2lkdW50IHRyaXN0aXF1ZS4KCkNyYXMgY29uc2VjdGV0dXIgYW50ZSBldSB0dXJwaXMgcGxhY2VyYXQgc29sbGljaXR1ZGluLiBNYXVyaXMgZXQgbGFjdXMgdG9ydG9yLCBlZ2V0IHBoYXJldHJhIHZlbGl0LiBEb25lYyBhY2N1bXNhbiB1bHRyaWNlcyB0ZW1wb3IuIERvbmVjIGF0IG5pYmggYSBlbGl0IGNvbmRpbWVudHVtIGRhcGlidXMuIEludGVnZXIgc2l0IGFtZXQgdnVscHV0YXRlIGFudGUuIFN1c3BlbmRpc3NlIHBvdGVudGkuIEluIHNvZGFsZXMgbGFvcmVldCBtYXNzYSB2aXRhZSBsYWNpbmlhLiBNb3JiaSB2ZWwgbGFjdXMgZmV1Z2lhdCBhcmN1IHZ1bHB1dGF0ZSBtb2xlc3RpZS4gQWxpcXVhbSBtYXNzYSBtYWduYSwgdWxsYW1jb3JwZXIgYWNjdW1zYW4gZ3JhdmlkYSBxdWlzLCByaG9uY3VzIHB1bHZpbmFyIG51bGxhLiBQcmFlc2VudCBzaXQgYW1ldCBpcHN1bSBkaWFtLCBzaXQgYW1ldCBsYWNpbmlhIG5lcXVlLiBJbiBldCBzYXBpZW4gYXVndWUuIEV0aWFtIGVuaW0gZWxpdCwgdWx0cmljZXMgdmVsIHJ1dHJ1bSBpZCwgc2NlbGVyaXNxdWUgbm9uIGVuaW0uCgpQcm9pbiBldCBlZ2VzdGFzIG5lcXVlLiBQcmFlc2VudCBldCBpcHN1bSBkb2xvci4gTnVuYyBub24gdmFyaXVzIG5pc2wuIEZ1c2NlIGluIHRvcnRvciBuaXNpLiBNYWVjZW5hcyBjb252YWxsaXMgbmVxdWUgaW4gbGlndWxhIGJsYW5kaXQgcXVpcyB2ZWhpY3VsYSBsZW8gbW9sbGlzLiBQZWxsZW50ZXNxdWUgc2FnaXR0aXMgYmxhbmRpdCBsZW8sIGRhcGlidXMgcGVsbGVudGVzcXVlIGxlbyB1bHRyaWNlcyBhYy4gQ3VyYWJpdHVyIGFjIGVnZXN0YXMgbGliZXJvLiBEb25lYyBwcmV0aXVtIHBoYXJldHJhIHByZXRpdW0uIEZ1c2NlIGltcGVyZGlldCwgdHVycGlzIGV1IGFsaXF1YW0gcG9ydGEsIGFudGUgZWxpdCBlbGVpZmVuZCByaXN1cywgbHVjdHVzIGF1Y3RvciBhcmN1IGFudGUgdXQgbnVuYy4gVml2YW11cyBpbiBsZW8gZmVsaXMsIHZpdGFlIGVsZWlmZW5kIGxhY3VzLiBEb25lYyB0ZW1wdXMgYWxpcXVhbSBwdXJ1cyBwb3J0dGl0b3IgdHJpc3RpcXVlLiBTdXNwZW5kaXNzZSBkaWFtIG5lcXVlLCBzdXNjaXBpdCBmZXVnaWF0IGZyaW5naWxsYSBub24sIGVsZWlmZW5kIHNpdCBudWxsYW0uCg== \ No newline at end of file
diff --git a/test/javascript/tests/lots_of_docs.js b/test/javascript/tests/lots_of_docs.js
deleted file mode 100644
index 453c65218..000000000
--- a/test/javascript/tests/lots_of_docs.js
+++ /dev/null
@@ -1,60 +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.
-
-// test saving a semi-large quanitity of documents and do some view queries.
-couchTests.elixir = true;
-couchTests.lots_of_docs = function(debug) {
- return console.log('done in test/elixir/test/lots_of_docs_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- // keep number lowish for now to keep tests fasts. Crank up manually to
- // to really test.
- var numDocsToCreate = 500;
-
- for(var i=0; i < numDocsToCreate; i += 100) {
- var createNow = Math.min(numDocsToCreate - i, 100);
- var docs = makeDocs(i, i + createNow);
- db.bulkSave(docs);
- }
-
- // query all documents, and return the doc.integer member as a key.
- results = db.query(function(doc){ emit(doc.integer, null) });
-
- T(results.total_rows == numDocsToCreate);
-
- // validate the keys are ordered ascending
- for(var i=0; i<numDocsToCreate; i++) {
- T(results.rows[i].key==i);
- }
-
- // do the query again, but with descending output
- results = db.query(function(doc){ emit(doc.integer, null) }, null, {
- descending: true
- });
-
- T(results.total_rows == numDocsToCreate);
-
- // validate the keys are ordered descending
- for(var i=0; i<numDocsToCreate; i++) {
- T(results.rows[numDocsToCreate-1-i].key==i);
- }
-
- // Check _all_docs with descending=true again (now that there are many docs)
- var desc = db.allDocs({descending:true});
- T(desc.total_rows == desc.rows.length);
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/method_override.js b/test/javascript/tests/method_override.js
deleted file mode 100644
index 94d798f96..000000000
--- a/test/javascript/tests/method_override.js
+++ /dev/null
@@ -1,45 +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.
-
-// Allow broken HTTP clients to fake a full method vocabulary with an X-HTTP-METHOD-OVERRIDE header
-couchTests.elixir = true;
-couchTests.method_override = function(debug) {
- return console.log('done in test/elixir/test/method_override_test.exs');
- var result = JSON.parse(CouchDB.request("GET", "/").responseText);
- T(result.couchdb == "Welcome");
-
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
-
- db.createDb();
-
- var doc = {bob : "connie"};
- xhr = CouchDB.request("POST", "/" + db_name + "/fnord", {body: JSON.stringify(doc), headers:{"X-HTTP-Method-Override" : "PUT"}});
- T(xhr.status == 201);
-
- doc = db.open("fnord");
- T(doc.bob == "connie");
-
- xhr = CouchDB.request("POST", "/" + db_name + "/fnord?rev=" + doc._rev, {headers:{"X-HTTP-Method-Override" : "DELETE"}});
- T(xhr.status == 200);
-
- xhr = CouchDB.request("GET", "/" + db_name + "/fnord2", {body: JSON.stringify(doc), headers:{"X-HTTP-Method-Override" : "PUT"}});
- // Method Override is ignored when original Method isn't POST
- T(xhr.status == 404);
-
- doc = db.open("fnord");
- T(doc == null);
-
- // cleanup
- db.deleteDb();
-
-};
diff --git a/test/javascript/tests/multiple_rows.js b/test/javascript/tests/multiple_rows.js
deleted file mode 100644
index b06104460..000000000
--- a/test/javascript/tests/multiple_rows.js
+++ /dev/null
@@ -1,85 +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.
-
-couchTests.elixir = true;
-couchTests.multiple_rows = function(debug) {
- return console.log('done in test/elixir/test/multiple_rows_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var nc = {_id:"NC", cities:["Charlotte", "Raleigh"]};
- var ma = {_id:"MA", cities:["Boston", "Lowell", "Worcester", "Cambridge", "Springfield"]};
- var fl = {_id:"FL", cities:["Miami", "Tampa", "Orlando", "Springfield"]};
-
- T(db.save(nc).ok);
- T(db.save(ma).ok);
- T(db.save(fl).ok);
-
- var generateListOfCitiesAndState = "function(doc) {" +
- " for (var i = 0; i < doc.cities.length; i++)" +
- " emit(doc.cities[i] + \", \" + doc._id, null);" +
- "}";
-
- var results = db.query(generateListOfCitiesAndState);
- var rows = results.rows;
-
- T(rows[0].key == "Boston, MA");
- T(rows[1].key == "Cambridge, MA");
- T(rows[2].key == "Charlotte, NC");
- T(rows[3].key == "Lowell, MA");
- T(rows[4].key == "Miami, FL");
- T(rows[5].key == "Orlando, FL");
- T(rows[6].key == "Raleigh, NC");
- T(rows[7].key == "Springfield, FL");
- T(rows[8].key == "Springfield, MA");
- T(rows[9].key == "Tampa, FL");
- T(rows[10].key == "Worcester, MA");
-
- // add another city to NC
- nc.cities.push("Wilmington");
- T(db.save(nc).ok);
-
- var results = db.query(generateListOfCitiesAndState);
- var rows = results.rows;
-
- T(rows[0].key == "Boston, MA");
- T(rows[1].key == "Cambridge, MA");
- T(rows[2].key == "Charlotte, NC");
- T(rows[3].key == "Lowell, MA");
- T(rows[4].key == "Miami, FL");
- T(rows[5].key == "Orlando, FL");
- T(rows[6].key == "Raleigh, NC");
- T(rows[7].key == "Springfield, FL");
- T(rows[8].key == "Springfield, MA");
- T(rows[9].key == "Tampa, FL");
- T(rows[10].key == "Wilmington, NC");
- T(rows[11].key == "Worcester, MA");
-
- // now delete MA
- T(db.deleteDoc(ma).ok);
-
- var results = db.query(generateListOfCitiesAndState);
- var rows = results.rows;
-
- T(rows[0].key == "Charlotte, NC");
- T(rows[1].key == "Miami, FL");
- T(rows[2].key == "Orlando, FL");
- T(rows[3].key == "Raleigh, NC");
- T(rows[4].key == "Springfield, FL");
- T(rows[5].key == "Tampa, FL");
- T(rows[6].key == "Wilmington, NC");
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/proxyauth.js b/test/javascript/tests/proxyauth.js
deleted file mode 100644
index a91f28c32..000000000
--- a/test/javascript/tests/proxyauth.js
+++ /dev/null
@@ -1,136 +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.
-
-couchTests.elixir = true;
-couchTests.proxyauth = function(debug) {
- // this test proxy authentification handler
- return console.log('done in test/elixir/test/proxyauth_test.exs');
- var users_db_name = get_random_db_name();
- var usersDb = new CouchDB(users_db_name, {"X-Couch-Full-Commit":"false"});
- usersDb.createDb();
-
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
-
- if (debug) debugger;
-
- // Simple secret key generator
- function generateSecret(length) {
- var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- var secret = '';
- for (var i=0; i<length; i++) {
- secret += tab.charAt(Math.floor(Math.random() * 64));
- }
- return secret;
- }
-
- var secret = generateSecret(64);
-
- function TestFun() {
-
- var benoitcUserDoc = CouchDB.prepareUserDoc({
- name: "benoitc@apache.org"
- }, "test");
- T(usersDb.save(benoitcUserDoc).ok);
-
- T(CouchDB.session().userCtx.name == null);
-
- // test that you can use basic auth aginst the users db
- var s = CouchDB.session({
- headers : {
- "Authorization" : "Basic YmVub2l0Y0BhcGFjaGUub3JnOnRlc3Q="
- }
- });
- T(s.userCtx.name == "benoitc@apache.org");
- T(s.info.authenticated == "default");
-
- CouchDB.logout();
-
-/* XXX: None of the rest of this is supported yet in 2.0
- var headers = {
- "X-Auth-CouchDB-UserName": "benoitc@apache.org",
- "X-Auth-CouchDB-Roles": "test",
- "X-Auth-CouchDB-Token": hex_hmac_sha1(secret, "benoitc@apache.org")
- };
-
- var designDoc = {
- _id:"_design/test",
- language: "javascript",
-
- shows: {
- "welcome": stringFun(function(doc,req) {
- return "Welcome " + req.userCtx["name"];
- }),
- "role": stringFun(function(doc, req) {
- return req.userCtx['roles'][0];
- })
- }
- };
-
- db.save(designDoc);
-
- var req = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/welcome",
- {headers: headers});
- T(req.responseText == "Welcome benoitc@apache.org", req.responseText);
-
- req = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/role",
- {headers: headers});
- T(req.responseText == "test");
-
- var xhr = CouchDB.request("PUT", "/_node/node1@127.0.0.1/_config/couch_httpd_auth/proxy_use_secret",{
- body : JSON.stringify("true"),
- headers: {"X-Couch-Persist": "false"}
- });
- T(xhr.status == 200);
-
- req = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/welcome",
- {headers: headers});
- T(req.responseText == "Welcome benoitc@apache.org");
-
- req = CouchDB.request("GET", "/" + db_name + "/_design/test/_show/role",
- {headers: headers});
- T(req.responseText == "test");
-*/
-
- }
-
- run_on_modified_server(
- [{section: "httpd",
- key: "authentication_handlers",
- value:"{chttpd_auth, proxy_authentication_handler}, {chttpd_auth, default_authentication_handler}"},
- {section: "chttpd_auth",
- key: "authentication_db",
- value: users_db_name},
- {section: "chttpd_auth",
- key: "secret",
- value: secret},
- {section: "chttpd_auth",
- key: "x_auth_username",
- value: "X-Auth-CouchDB-UserName"},
- {section: "chttpd_auth",
- key: "x_auth_roles",
- value: "X-Auth-CouchDB-Roles"},
- {section: "chttpd_auth",
- key: "x_auth_token",
- value: "X-Auth-CouchDB-Token"},
- {section: "chttpd_auth",
- key: "proxy_use_secret",
- value: "false"}],
- TestFun
- );
-
- // cleanup
- db.deleteDb();
- usersDb.deleteDb();
-
-};
diff --git a/test/javascript/tests/purge.js b/test/javascript/tests/purge.js
deleted file mode 100644
index 15fd63710..000000000
--- a/test/javascript/tests/purge.js
+++ /dev/null
@@ -1,140 +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.
-couchTests.elixir = true;
-couchTests.purge = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- /*
- purge is not to be confused with a document deletion. It removes the
- document and all edit history from the local instance of the database.
- */
-
- var numDocs = 10;
-
- var designDoc = {
- _id:"_design/test",
- language: "javascript",
- views: {
- all_docs_twice: {map: "function(doc) { emit(doc.integer, null); emit(doc.integer, null) }"},
- single_doc: {map: "function(doc) { if (doc._id == \"1\") { emit(1, null) }}"}
- }
- };
-
- T(db.save(designDoc).ok);
-
- db.bulkSave(makeDocs(1, numDocs + 1));
-
- // go ahead and validate the views before purging
- var rows = db.view("test/all_docs_twice").rows;
- for (var i = 0; i < numDocs; i++) {
- T(rows[2*i].key == i+1);
- T(rows[(2*i)+1].key == i+1);
- }
- T(db.view("test/single_doc").total_rows == 1);
-
- var info = db.info();
- var doc1 = db.open("1");
- var doc2 = db.open("2");
-
- // purge the documents
- var xhr = CouchDB.request("POST", "/" + db_name + "/_purge", {
- body: JSON.stringify({"1":[doc1._rev], "2":[doc2._rev]})
- });
- T(xhr.status == 201);
-
- var result = JSON.parse(xhr.responseText);
- var newInfo = db.info();
-
- T(result.purged["1"] == doc1._rev);
- T(result.purged["2"] == doc2._rev);
-
- T(db.open("1") == null);
- T(db.open("2") == null);
-
- var rows = db.view("test/all_docs_twice").rows;
- for (var i = 2; i < numDocs; i++) {
- T(rows[2*(i-2)].key == i+1);
- T(rows[(2*(i-2))+1].key == i+1);
- }
- T(db.view("test/single_doc").total_rows == 0);
-
- // purge sequences are preserved after compaction (COUCHDB-1021)
- T(db.compact().ok);
- T(db.last_req.status == 202);
- // compaction isn't instantaneous, loop until done
- while (db.info().compact_running) {};
- var compactInfo = db.info();
-
- // purge documents twice in a row without loading views
- // (causes full view rebuilds)
-
- var doc3 = db.open("3");
- var doc4 = db.open("4");
-
- xhr = CouchDB.request("POST", "/" + db_name + "/_purge", {
- body: JSON.stringify({"3":[doc3._rev]})
- });
-
- T(xhr.status == 201);
-
- xhr = CouchDB.request("POST", "/" + db_name + "/_purge", {
- body: JSON.stringify({"4":[doc4._rev]})
- });
-
- T(xhr.status == 201);
- result = JSON.parse(xhr.responseText);
-
- var rows = db.view("test/all_docs_twice").rows;
- for (var i = 4; i < numDocs; i++) {
- T(rows[2*(i-4)].key == i+1);
- T(rows[(2*(i-4))+1].key == i+1);
- }
- T(db.view("test/single_doc").total_rows == 0);
-
- // COUCHDB-1065
- var dbA = new CouchDB("" + db_name + "_a");
- var dbB = new CouchDB("" + db_name + "_b");
- dbA.deleteDb();
- dbA.createDb();
- dbB.deleteDb();
- dbB.createDb();
- var docA = {_id:"test", a:1};
- var docB = {_id:"test", a:2};
- dbA.save(docA);
- dbB.save(docB);
- CouchDB.replicate(dbA.name, dbB.name);
- var xhr = CouchDB.request("POST", "/" + dbB.name + "/_purge", {
- body: JSON.stringify({"test":[docA._rev]})
- });
- TEquals(201, xhr.status, "single rev purge after replication succeeds");
-
- var xhr = CouchDB.request("GET", "/" + dbB.name + "/test?rev=" + docA._rev);
- TEquals(404, xhr.status, "single rev purge removes revision");
-
- var xhr = CouchDB.request("POST", "/" + dbB.name + "/_purge", {
- body: JSON.stringify({"test":[docB._rev]})
- });
- TEquals(201, xhr.status, "single rev purge after replication succeeds");
- var xhr = CouchDB.request("GET", "/" + dbB.name + "/test?rev=" + docB._rev);
- TEquals(404, xhr.status, "single rev purge removes revision");
-
- var xhr = CouchDB.request("POST", "/" + dbB.name + "/_purge", {
- body: JSON.stringify({"test":[docA._rev, docB._rev]})
- });
- TEquals(201, xhr.status, "all rev purge after replication succeeds");
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/reader_acl.js b/test/javascript/tests/reader_acl.js
deleted file mode 100644
index d5a923549..000000000
--- a/test/javascript/tests/reader_acl.js
+++ /dev/null
@@ -1,222 +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.
-
-couchTests.elixir = true;
-couchTests.reader_acl = function(debug) {
- // this tests read access control
-
- var users_db_name = get_random_db_name();
- var usersDb = new CouchDB(users_db_name, {"X-Couch-Full-Commit":"false"});
-
- var db_name = get_random_db_name();
- var secretDb = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
-
-
- function testFun() {
- try {
- // usersDb.deleteDb();
- try {
- usersDb.createDb();
- } catch(e) {
- if(usersDb.last_req.status != 412) {
- throw e;
- }
- }
- // secretDb.deleteDb();
- secretDb.createDb();
-
- // create a user with top-secret-clearance
- var jchrisUserDoc = CouchDB.prepareUserDoc({
- name: "jchris@apache.org",
- roles : ["top-secret"]
- }, "funnybone");
- T(usersDb.save(jchrisUserDoc).ok);
- usersDb.ensureFullCommit();
-
- T(CouchDB.session().userCtx.name == null);
-
- // set secret db to be read controlled
- T(secretDb.save({_id:"baz",foo:"bar"}).ok);
- T(secretDb.open("baz").foo == "bar");
-
- T(secretDb.setSecObj({
- "members" : {
- roles : ["super-secret-club"],
- names : ["joe","barb"]
- }
- }).ok);
- } finally {
- CouchDB.logout();
- }
- try {
- // can't read it as jchris b/c he's missing the needed role
- T(CouchDB.login("jchris@apache.org", "funnybone").ok);
- T(CouchDB.session().userCtx.name == "jchris@apache.org");
-
- try {
- secretDb.open("baz");
- T(false && "can't open a doc from a secret db") ;
- } catch(e) {
- T(true)
- }
-
- CouchDB.logout();
-
- // make anyone with the top-secret role an admin
- // db admins are automatically members
- T(secretDb.setSecObj({
- "admins" : {
- roles : ["top-secret"],
- names : []
- },
- "members" : {
- roles : ["super-secret-club"],
- names : ["joe","barb"]
- }
- }).ok);
-
-
- T(CouchDB.login("jchris@apache.org", "funnybone").ok);
-
- // db admin can read
- // retry as propagation could take time
- retry_part(function(){
- T(secretDb.open("baz").foo == "bar");
- });
-
- // and run temp views - they don't exist any more, so leave out
- /*TEquals(secretDb.query(function(doc) {
- emit(null, null)
- }).total_rows, 1);*/
-
- CouchDB.logout();
- T(CouchDB.session().userCtx.roles.indexOf("_admin") != -1);
-
- // admin now adds the top-secret role to the db's members
- // and removes db-admins
- T(secretDb.setSecObj({
- "admins" : {
- roles : [],
- names : []
- },
- "members" : {
- roles : ["super-secret-club", "top-secret"],
- names : ["joe","barb"]
- }
- }).ok);
-
- // server _admin can always read
- T(secretDb.open("baz").foo == "bar");
-
- // and run temp views - they don't exist any more, so leave out
- /*TEquals(secretDb.query(function(doc) {
- emit(null, null)
- }).total_rows, 1);*/
-
- T(secretDb.save({
- "_id" : "_design/foo",
- views : {
- bar : {
- map : "function(doc){emit(null, null)}"
- }
- }
- }).ok)
-
- // now top-secret users can read too
- T(CouchDB.login("jchris@apache.org", "funnybone").ok);
- T(CouchDB.session().userCtx.roles.indexOf("_admin") == -1);
- T(secretDb.open("baz").foo == "bar");
- // members can query stored views
- T(secretDb.view("foo/bar").total_rows == 1);
-
- // members can't do temp views - they don't exist any more, so leave out
- /*try {
- var results = secretDb.query(function(doc) {
- emit(null, null);
- });
- T(false && "temp view should be admin only");
- } catch (e) {
- T(true && "temp view is admin only");
- }*/
-
- CouchDB.logout();
-
- // works with readers (backwards compat with 1.0)
- T(secretDb.setSecObj({
- "admins" : {
- roles : [],
- names : []
- },
- "readers" : {
- roles : ["super-secret-club", "top-secret"],
- names : ["joe","barb"]
- }
- }).ok);
-
- T(CouchDB.login("jchris@apache.org", "funnybone").ok);
- T(CouchDB.session().userCtx.roles.indexOf("_admin") == -1);
- // retry as propagation could take time
- retry_part(function(){
- T(secretDb.open("baz").foo == "bar");
- });
-
- // can't set non string reader names or roles
- try {
- secretDb.setSecObj({
- "members" : {
- roles : ["super-secret-club", {"top-secret":"awesome"}],
- names : ["joe","barb"]
- }
- })
- T(false && "only string roles");
- } catch (e) {}
-
- try {
- secretDb.setSecObj({
- "members" : {
- roles : ["super-secret-club", {"top-secret":"awesome"}],
- names : ["joe",22]
- }
- });
- T(false && "only string names");
- } catch (e) {}
-
- try {
- secretDb.setSecObj({
- "members" : {
- roles : ["super-secret-club", {"top-secret":"awesome"}],
- names : "joe"
- }
- });
- T(false && "only lists of names");
- } catch (e) {}
- } finally {
- CouchDB.logout();
- }
- };
-
- run_on_modified_server(
- [{section: "httpd",
- key: "authentication_handlers",
- value: "{couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}"},
- {section: "couch_httpd_auth",
- key: "authentication_db", value: users_db_name},
- {section: "chttpd_auth",
- key: "authentication_db", value: users_db_name}],
- testFun // stick to the essentials and do it all in one
- );
-
- usersDb.deleteDb();
- // don't have to delete the backside db since in this case couch_auth_cache only read
- // admin from the config section and so it never auto-created the node local db
- secretDb.deleteDb();
-}
diff --git a/test/javascript/tests/recreate_doc.js b/test/javascript/tests/recreate_doc.js
deleted file mode 100644
index 1aa44ede8..000000000
--- a/test/javascript/tests/recreate_doc.js
+++ /dev/null
@@ -1,157 +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.
-
-couchTests.elixir = true;
-couchTests.recreate_doc = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}, {"w": 3});
- db.createDb();
- if (debug) debugger;
-
- // First create a new document with the ID "foo", and delete it again
- var doc = {_id: "foo", a: "bar", b: 42};
- var result = db.save(doc);
- T(result.ok);
- var firstRev = result.rev;
- T(db.deleteDoc(doc).ok);
-
- // Now create a new document with the same ID, save it, and then modify it
- for (var i = 0; i < 10; i++) {
- doc = {_id: "foo"};
- T(db.save(doc).ok);
- doc = db.open("foo");
- doc.a = "baz";
- T(db.save(doc).ok);
- T(db.deleteDoc(doc).rev != undefined);
- }
-
- try {
- // COUCHDB-292 now attempt to save the document with a prev that's since
- // been deleted and this should generate a conflict exception
- db.save({_id:"foo", _rev:firstRev, bar:1});
- T("no save conflict 1" && false); // we shouldn't hit here
- } catch (e) {
- T(e.error == "conflict");
- }
-
- var binAttDoc = {
- _id: "foo",
- _rev:firstRev,
- _attachments:{
- "foo.txt": {
- content_type:"text/plain",
- data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
- }
- }
- };
- try {
- // same as before, but with binary
- db.save(binAttDoc);
- T("no save conflict 2" && false); // we shouldn't hit here
- } catch (e) {
- T(e.error == "conflict");
- }
-
-
- try {
- // random non-existant prev rev
- db.save({_id:"foo", _rev:"1-asfafasdf", bar:1});
- T("no save conflict 3" && false); // we shouldn't hit here
- } catch (e) {
- T(e.error == "conflict");
- }
-
- try {
- // random non-existant prev rev with bin
- binAttDoc._rev = "1-aasasfasdf";
- db.save(binAttDoc);
- T("no save conflict 4" && false); // we shouldn't hit here
- } catch (e) {
- T(e.error == "conflict");
- }
-
- db.deleteDb();
- // avoid Heisenbugs - have a new name
- db_name = get_random_db_name();
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"}, {"w": 3});
- db.createDb();
-
- // Helper function to create a doc with multiple revisions
- // that are compacted away to ?REV_MISSING.
-
- var createDoc = function(docid) {
- var ret = [{_id: docid, count: 0}];
- T(db.save(ret[0]).ok);
- for(var i = 0; i < 2; i++) {
- ret[ret.length] = {
- _id: docid,
- _rev: ret[ret.length-1]._rev,
- count: ret[ret.length-1].count+1
- };
- T(db.save(ret[ret.length-1]).ok);
- }
-/* TODO: if we need and can, re-enable compaction which per se is not available in the cluster - that way, we at least have all else
- db.compact();
- while(db.info().compact_running) {}
-*/
- return ret;
- }
-
- // Helper function to check that there are no duplicates
- // in the changes feed and that it has proper update
- // sequence ordering.
-
- var checkChanges = function() {
- // Assert that there are no duplicates in _changes.
- var req = CouchDB.request("GET", "/" + db_name + "/_changes");
- var resp = JSON.parse(req.responseText);
- var docids = {};
- var prev_seq = -1;
- for(var i = 0; i < resp.results.length; i++) {
- row = resp.results[i];
- // that won't hold true in clusters
- //T(row.seq > prev_seq, "Unordered _changes feed.");
- T(docids[row.id] === undefined, "Duplicates in _changes feed.");
- prev_seq = row.seq;
- docids[row.id] = true;
- }
- };
-
- // COUCHDB-1265 - Check that the changes feed remains proper
- // after we try and break the update_seq tree.
-
- // This first case is the one originally reported and "fixed"
- // in COUCHDB-1265. Reinserting an old revision into the
- // revision tree causes duplicates in the update_seq tree.
-
- var revs = createDoc("a");
- T(db.save(revs[1], {new_edits: false}).ok);
- T(db.save(revs[revs.length-1]).ok);
- checkChanges();
-
- // The original fix for COUCHDB-1265 is not entirely correct
- // as it didn't consider the possibility that a compaction
- // might run after the original tree screw up.
-
-/* TODO: if we need and can, re-enable compaction which per se is not available in the cluster - that way, we at least have all else
- revs = createDoc("b");
- T(db.save(revs[1], {new_edits: false}).ok);
- db.compact();
- while(db.info().compact_running) {}
- T(db.save(revs[revs.length-1]).ok);
- checkChanges();
-*/
-
- // cleanup
- db.deleteDb();
-
-};
diff --git a/test/javascript/tests/reduce.js b/test/javascript/tests/reduce.js
deleted file mode 100644
index c25ca771c..000000000
--- a/test/javascript/tests/reduce.js
+++ /dev/null
@@ -1,423 +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.
-
-couchTests.elixir = true;
-couchTests.reduce = function(debug) {
- return console.log('done in test/elixir/test/reduce_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
- var numDocs = 500;
- var docs = makeDocs(1,numDocs + 1);
- db.bulkSave(docs);
- var summate = function(N) {return (N+1)*N/2;};
-
- var map = function (doc) {
- emit(doc.integer, doc.integer);
- emit(doc.integer, doc.integer);
- };
- var reduce = function (keys, values) { return sum(values); };
- var result = db.query(map, reduce);
- T(result.rows[0].value == 2*summate(numDocs));
-
- result = db.query(map, reduce, {startkey: 4, endkey: 4});
- T(result.rows[0].value == 8);
-
- result = db.query(map, reduce, {startkey: 4, endkey: 5});
- T(result.rows[0].value == 18);
-
- result = db.query(map, reduce, {startkey: 4, endkey: 6});
- T(result.rows[0].value == 30);
-
- result = db.query(map, reduce, {group:true, limit:3});
- T(result.rows[0].value == 2);
- T(result.rows[1].value == 4);
- T(result.rows[2].value == 6);
-
- for(var i=1; i<numDocs/2; i+=30) {
- result = db.query(map, reduce, {startkey: i, endkey: numDocs - i});
- T(result.rows[0].value == 2*(summate(numDocs-i) - summate(i-1)));
- }
-
- db.deleteDb();
- db_name = get_random_db_name();
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
-
- for(var i=1; i <= 5; i++) {
-
- for(var j=0; j < 10; j++) {
- // these docs are in the order of the keys collation, for clarity
- var docs = [];
- docs.push({keys:["a"]});
- docs.push({keys:["a"]});
- docs.push({keys:["a", "b"]});
- docs.push({keys:["a", "b"]});
- docs.push({keys:["a", "b", "c"]});
- docs.push({keys:["a", "b", "d"]});
- docs.push({keys:["a", "c", "d"]});
- docs.push({keys:["d"]});
- docs.push({keys:["d", "a"]});
- docs.push({keys:["d", "b"]});
- docs.push({keys:["d", "c"]});
- db.bulkSave(docs);
- var total_docs = ((i - 1) * 10 * 11) + ((j + 1) * 11);
- TEquals(total_docs, db.info().doc_count, "doc count should match");
- }
-
- map = function (doc) { emit(doc.keys, 1); };
- reduce = function (keys, values) { return sum(values); };
-
- var results = db.query(map, reduce, {group:true});
-
- //group by exact key match
- T(equals(results.rows[0], {key:["a"],value:20*i}));
- T(equals(results.rows[1], {key:["a","b"],value:20*i}));
- T(equals(results.rows[2], {key:["a", "b", "c"],value:10*i}));
- T(equals(results.rows[3], {key:["a", "b", "d"],value:10*i}));
-
- // test to make sure group reduce and limit params provide valid json
- var results = db.query(map, reduce, {group: true, limit: 2});
- T(equals(results.rows[0], {key: ["a"], value: 20*i}));
- T(equals(results.rows.length, 2));
-
- //group by the first element in the key array
- var results = db.query(map, reduce, {group_level:1});
- T(equals(results.rows[0], {key:["a"],value:70*i}));
- T(equals(results.rows[1], {key:["d"],value:40*i}));
-
- //group by the first 2 elements in the key array
- var results = db.query(map, reduce, {group_level:2});
- T(equals(results.rows[0], {key:["a"],value:20*i}));
- T(equals(results.rows[1], {key:["a","b"],value:40*i}));
- T(equals(results.rows[2], {key:["a","c"],value:10*i}));
- T(equals(results.rows[3], {key:["d"],value:10*i}));
- T(equals(results.rows[4], {key:["d","a"],value:10*i}));
- T(equals(results.rows[5], {key:["d","b"],value:10*i}));
- T(equals(results.rows[6], {key:["d","c"],value:10*i}));
-
- // endkey test with inclusive_end=true
- var results = db.query(map, reduce, {group_level:2,endkey:["d"],inclusive_end:true});
- T(equals(results.rows[0], {key:["a"],value:20*i}));
- T(equals(results.rows[1], {key:["a","b"],value:40*i}));
- T(equals(results.rows[2], {key:["a","c"],value:10*i}));
- T(equals(results.rows[3], {key:["d"],value:10*i}));
- TEquals(4, results.rows.length);
-
- // endkey test with inclusive_end=false
- var results = db.query(map, reduce, {group_level:2,endkey:["d"],inclusive_end:false});
- T(equals(results.rows[0], {key:["a"],value:20*i}));
- T(equals(results.rows[1], {key:["a","b"],value:40*i}));
- T(equals(results.rows[2], {key:["a","c"],value:10*i}));
- TEquals(3, results.rows.length);
- }
-
- // now test out more complex reductions that need to use the combine option.
- db.deleteDb();
- db_name = get_random_db_name();
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
-
- var map = function (doc) { emit(doc.val, doc.val); };
- var reduceCombine = function (keys, values, rereduce) {
- // This computes the standard deviation of the mapped results
- var stdDeviation=0.0;
- var count=0;
- var total=0.0;
- var sqrTotal=0.0;
-
- if (!rereduce) {
- // This is the reduce phase, we are reducing over emitted values from
- // the map functions.
- for(var i in values) {
- total = total + values[i];
- sqrTotal = sqrTotal + (values[i] * values[i]);
- }
- count = values.length;
- }
- else {
- // This is the rereduce phase, we are re-reducing previosuly
- // reduced values.
- for(var i in values) {
- count = count + values[i].count;
- total = total + values[i].total;
- sqrTotal = sqrTotal + values[i].sqrTotal;
- }
- }
-
- var variance = (sqrTotal - ((total * total)/count)) / count;
- stdDeviation = Math.sqrt(variance);
-
- // the reduce result. It contains enough information to be rereduced
- // with other reduce results.
- return {"stdDeviation":stdDeviation,"count":count,
- "total":total,"sqrTotal":sqrTotal};
- };
-
- // Save a bunch a docs.
-
- for(var i=0; i < 10; i++) {
- var docs = [];
- docs.push({val:10});
- docs.push({val:20});
- docs.push({val:30});
- docs.push({val:40});
- docs.push({val:50});
- docs.push({val:60});
- docs.push({val:70});
- docs.push({val:80});
- docs.push({val:90});
- docs.push({val:100});
- db.bulkSave(docs);
- }
-
- var results = db.query(map, reduceCombine);
-
- var difference = results.rows[0].value.stdDeviation - 28.722813232690143;
- // account for floating point rounding error
- T(Math.abs(difference) < 0.0000000001);
-
- function testReducePagination() {
- var ddoc = {
- "_id": "_design/test",
- "language": "javascript",
- "views": {
- "view1": {
- "map": "function(doc) {" +
- "emit(doc.int, doc._id);" +
- "emit(doc.int + 1, doc._id);" +
- "emit(doc.int + 2, doc._id);" +
- "}",
- "reduce": "_count"
- }
- }
- };
- var result, docs = [];
-
- function randVal() {
- return Math.random() * 100000000;
- }
-
- db.deleteDb();
- db_name = get_random_db_name();
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
-
- for (var i = 0; i < 1123; i++) {
- docs.push({"_id": String(i), "int": i});
- }
- db.bulkSave(docs.concat([ddoc]));
-
- // ?group=false tests
- result = db.view('test/view1', {startkey: 400, endkey: 402, foobar: randVal()});
- TEquals(9, result.rows[0].value);
- result = db.view('test/view1', {startkey: 402, endkey: 400, descending: true,
- foobar: randVal()});
- TEquals(9, result.rows[0].value);
-
- result = db.view('test/view1', {startkey: 400, endkey: 402, inclusive_end: false,
- foobar: randVal()});
- TEquals(6, result.rows[0].value);
- result = db.view('test/view1', {startkey: 402, endkey: 400, inclusive_end: false,
- descending: true, foobar: randVal()});
- TEquals(6, result.rows[0].value);
-
- result = db.view('test/view1', {startkey: 400, endkey: 402, endkey_docid: "400",
- foobar: randVal()});
- TEquals(7, result.rows[0].value);
- result = db.view('test/view1', {startkey: 400, endkey: 402, endkey_docid: "400",
- inclusive_end: false, foobar: randVal()});
- TEquals(6, result.rows[0].value);
-
- result = db.view('test/view1', {startkey: 400, endkey: 402, endkey_docid: "401",
- foobar: randVal()});
- TEquals(8, result.rows[0].value);
- result = db.view('test/view1', {startkey: 400, endkey: 402, endkey_docid: "401",
- inclusive_end: false, foobar: randVal()});
- TEquals(7, result.rows[0].value);
-
- result = db.view('test/view1', {startkey: 400, endkey: 402, endkey_docid: "402",
- foobar: randVal()});
- TEquals(9, result.rows[0].value);
- result = db.view('test/view1', {startkey: 400, endkey: 402, endkey_docid: "402",
- inclusive_end: false, foobar: randVal()});
- TEquals(8, result.rows[0].value);
-
- result = db.view('test/view1', {startkey: 402, endkey: 400, endkey_docid: "398",
- descending: true, foobar: randVal()});
- TEquals(9, result.rows[0].value);
- result = db.view('test/view1', {startkey: 402, endkey: 400, endkey_docid: "398",
- descending: true, inclusive_end: false, foobar: randVal()}),
- TEquals(8, result.rows[0].value);
-
- result = db.view('test/view1', {startkey: 402, endkey: 400, endkey_docid: "399",
- descending: true, foobar: randVal()});
- TEquals(8, result.rows[0].value);
- result = db.view('test/view1', {startkey: 402, endkey: 400, endkey_docid: "399",
- descending: true, inclusive_end: false, foobar: randVal()}),
- TEquals(7, result.rows[0].value);
-
- result = db.view('test/view1', {startkey: 402, endkey: 400, endkey_docid: "400",
- descending: true, foobar: randVal()}),
- TEquals(7, result.rows[0].value);
- result = db.view('test/view1', {startkey: 402, endkey: 400, endkey_docid: "400",
- descending: true, inclusive_end: false, foobar: randVal()}),
- TEquals(6, result.rows[0].value);
-
- result = db.view('test/view1', {startkey: 402, startkey_docid: "400", endkey: 400,
- descending: true, foobar: randVal()});
- TEquals(7, result.rows[0].value);
-
- result = db.view('test/view1', {startkey: 402, startkey_docid: "401", endkey: 400,
- descending: true, inclusive_end: false, foobar: randVal()});
- TEquals(5, result.rows[0].value);
-
- // ?group=true tests
- result = db.view('test/view1', {group: true, startkey: 400, endkey: 402,
- foobar: randVal()});
- TEquals(3, result.rows.length);
- TEquals(400, result.rows[0].key);
- TEquals(3, result.rows[0].value);
- TEquals(401, result.rows[1].key);
- TEquals(3, result.rows[1].value);
- TEquals(402, result.rows[2].key);
- TEquals(3, result.rows[2].value);
-
- result = db.view('test/view1', {group: true, startkey: 402, endkey: 400,
- descending: true, foobar: randVal()});
- TEquals(3, result.rows.length);
- TEquals(402, result.rows[0].key);
- TEquals(3, result.rows[0].value);
- TEquals(401, result.rows[1].key);
- TEquals(3, result.rows[1].value);
- TEquals(400, result.rows[2].key);
- TEquals(3, result.rows[2].value);
-
- result = db.view('test/view1', {group: true, startkey: 400, endkey: 402,
- inclusive_end: false, foobar: randVal()});
- TEquals(2, result.rows.length);
- TEquals(400, result.rows[0].key);
- TEquals(3, result.rows[0].value);
- TEquals(401, result.rows[1].key);
- TEquals(3, result.rows[1].value);
-
- result = db.view('test/view1', {group: true, startkey: 402, endkey: 400,
- descending: true, inclusive_end: false, foobar: randVal()});
- TEquals(2, result.rows.length);
- TEquals(402, result.rows[0].key);
- TEquals(3, result.rows[0].value);
- TEquals(401, result.rows[1].key);
- TEquals(3, result.rows[1].value);
-
- result = db.view('test/view1', {group: true, startkey: 400, endkey: 402,
- endkey_docid: "401", foobar: randVal()});
- TEquals(3, result.rows.length);
- TEquals(400, result.rows[0].key);
- TEquals(3, result.rows[0].value);
- TEquals(401, result.rows[1].key);
- TEquals(3, result.rows[1].value);
- TEquals(402, result.rows[2].key);
- TEquals(2, result.rows[2].value);
-
- result = db.view('test/view1', {group: true, startkey: 400, endkey: 402,
- endkey_docid: "400", foobar: randVal()});
- TEquals(3, result.rows.length);
- TEquals(400, result.rows[0].key);
- TEquals(3, result.rows[0].value);
- TEquals(401, result.rows[1].key);
- TEquals(3, result.rows[1].value);
- TEquals(402, result.rows[2].key);
- TEquals(1, result.rows[2].value);
-
- result = db.view('test/view1', {group: true, startkey: 402, startkey_docid: "401",
- endkey: 400, descending: true, foobar: randVal()});
- TEquals(3, result.rows.length);
- TEquals(402, result.rows[0].key);
- TEquals(2, result.rows[0].value);
- TEquals(401, result.rows[1].key);
- TEquals(3, result.rows[1].value);
- TEquals(400, result.rows[2].key);
- TEquals(3, result.rows[2].value);
-
- result = db.view('test/view1', {group: true, startkey: 402, startkey_docid: "400",
- endkey: 400, descending: true, foobar: randVal()});
- TEquals(3, result.rows.length);
- TEquals(402, result.rows[0].key);
- TEquals(1, result.rows[0].value);
- TEquals(401, result.rows[1].key);
- TEquals(3, result.rows[1].value);
- TEquals(400, result.rows[2].key);
- TEquals(3, result.rows[2].value);
-
- result = db.view('test/view1', {group: true, startkey: 402, startkey_docid: "401",
- endkey: 400, descending: true, inclusive_end: false, foobar: randVal()});
- TEquals(2, result.rows.length);
- TEquals(402, result.rows[0].key);
- TEquals(2, result.rows[0].value);
- TEquals(401, result.rows[1].key);
- TEquals(3, result.rows[1].value);
-
- result = db.view('test/view1', {group: true, startkey: 402, startkey_docid: "400",
- endkey: 400, descending: true, inclusive_end: false, foobar: randVal()});
- TEquals(2, result.rows.length);
- TEquals(402, result.rows[0].key);
- TEquals(1, result.rows[0].value);
- TEquals(401, result.rows[1].key);
- TEquals(3, result.rows[1].value);
-
- result = db.view('test/view1', {group: true, startkey: 402, endkey: 400,
- endkey_docid: "398", descending: true, inclusive_end: true, foobar: randVal()});
- TEquals(3, result.rows.length);
- TEquals(402, result.rows[0].key);
- TEquals(3, result.rows[0].value);
- TEquals(401, result.rows[1].key);
- TEquals(3, result.rows[1].value);
- TEquals(400, result.rows[2].key);
- TEquals(3, result.rows[2].value);
-
- result = db.view('test/view1', {group: true, startkey: 402, endkey: 400,
- endkey_docid: "399", descending: true, inclusive_end: true, foobar: randVal()});
- TEquals(3, result.rows.length);
- TEquals(402, result.rows[0].key);
- TEquals(3, result.rows[0].value);
- TEquals(401, result.rows[1].key);
- TEquals(3, result.rows[1].value);
- TEquals(400, result.rows[2].key);
- TEquals(2, result.rows[2].value);
-
- result = db.view('test/view1', {group: true, startkey: 402, endkey: 400,
- endkey_docid: "399", descending: true, inclusive_end: false, foobar: randVal()});
- TEquals(3, result.rows.length);
- TEquals(402, result.rows[0].key);
- TEquals(3, result.rows[0].value);
- TEquals(401, result.rows[1].key);
- TEquals(3, result.rows[1].value);
- TEquals(400, result.rows[2].key);
- TEquals(1, result.rows[2].value);
-
- result = db.view('test/view1', {group: true, startkey: 402, endkey: 400,
- endkey_docid: "400", descending: true, inclusive_end: false, foobar: randVal()});
- TEquals(2, result.rows.length);
- TEquals(402, result.rows[0].key);
- TEquals(3, result.rows[0].value);
- TEquals(401, result.rows[1].key);
- TEquals(3, result.rows[1].value);
-
- db.deleteDb();
- }
-
- testReducePagination();
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/reduce_builtin.js b/test/javascript/tests/reduce_builtin.js
deleted file mode 100644
index 77d8d1b34..000000000
--- a/test/javascript/tests/reduce_builtin.js
+++ /dev/null
@@ -1,206 +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.
-
-couchTests.elixir = true;
-couchTests.reduce_builtin = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var numDocs = 500;
- var docs = makeDocs(1,numDocs + 1);
- db.bulkSave(docs);
-
- var summate = function(N) {return (N+1)*N/2;};
-
- var sumsqr = function(N) {
- var acc = 0;
- for (var i=1; i<=N; ++i) {
- acc += i*i;
- }
- return acc;
- };
-
- // this is the same test as the reduce.js test
- // only we'll let CouchDB run reduce in Erlang
- var map = function (doc) {
- emit(doc.integer, doc.integer);
- emit(doc.integer, doc.integer);
- };
-
- var check_approx_distinct = function(expected, estimated) {
- // see https://en.wikipedia.org/wiki/HyperLogLog
- var err = 1.04 / Math.sqrt(Math.pow(2, 11 - 1));
- return Math.abs(expected - estimated) < expected * err;
- };
-
- var result = db.query(map, "_sum");
- T(result.rows[0].value == 2*summate(numDocs));
- result = db.query(map, "_count");
- T(result.rows[0].value == 1000);
- result = db.query(map, "_stats");
- T(result.rows[0].value.sum == 2*summate(numDocs));
- T(result.rows[0].value.count == 1000);
- T(result.rows[0].value.min == 1);
- T(result.rows[0].value.max == 500);
- T(result.rows[0].value.sumsqr == 2*sumsqr(numDocs));
- result = db.query(map, "_approx_count_distinct");
- T(check_approx_distinct(numDocs, result.rows[0].value));
-
- result = db.query(map, "_sum", {startkey: 4, endkey: 4});
- T(result.rows[0].value == 8);
- result = db.query(map, "_count", {startkey: 4, endkey: 4});
- T(result.rows[0].value == 2);
- result = db.query(map, "_approx_count_distinct", {startkey:4, endkey:4});
- T(check_approx_distinct(1, result.rows[0].value));
-
- result = db.query(map, "_sum", {startkey: 4, endkey: 5});
- T(result.rows[0].value == 18);
- result = db.query(map, "_count", {startkey: 4, endkey: 5});
- T(result.rows[0].value == 4);
- result = db.query(map, "_approx_count_distinct", {startkey:4, endkey:5});
- T(check_approx_distinct(2, result.rows[0].value));
-
-
- result = db.query(map, "_sum", {startkey: 4, endkey: 6});
- T(result.rows[0].value == 30);
- result = db.query(map, "_count", {startkey: 4, endkey: 6});
- T(result.rows[0].value == 6);
- result = db.query(map, "_approx_count_distinct", {startkey: 4, endkey: 6});
- T(check_approx_distinct(3, result.rows[0].value));
-
- result = db.query(map, "_sum", {group:true, limit:3});
- T(result.rows[0].value == 2);
- T(result.rows[1].value == 4);
- T(result.rows[2].value == 6);
-
- result = db.query(map, "_approx_count_distinct", {group:true, limit:3});
- T(check_approx_distinct(1, result.rows[0].value));
- T(check_approx_distinct(1, result.rows[1].value));
- T(check_approx_distinct(1, result.rows[2].value));
-
- for(var i=1; i<numDocs/2; i+=30) {
- result = db.query(map, "_sum", {startkey: i, endkey: numDocs - i});
- T(result.rows[0].value == 2*(summate(numDocs-i) - summate(i-1)));
- }
-
- // test for trailing characters after builtin functions, desired behaviour
- // is to disregard any trailing characters
- // I think the behavior should be a prefix test, so that even "_statsorama"
- // or "_stats\nare\awesome" should work just as "_stats" does. - JChris
-
- var trailing = ["\u000a", "orama", "\nare\nawesome", " ", " \n "];
-
- for(var i=0; i < trailing.length; i++) {
- result = db.query(map, "_sum" + trailing[i]);
- T(result.rows[0].value == 2*summate(numDocs));
- result = db.query(map, "_count" + trailing[i]);
- T(result.rows[0].value == 1000);
- result = db.query(map, "_stats" + trailing[i]);
- T(result.rows[0].value.sum == 2*summate(numDocs));
- T(result.rows[0].value.count == 1000);
- T(result.rows[0].value.min == 1);
- T(result.rows[0].value.max == 500);
- T(result.rows[0].value.sumsqr == 2*sumsqr(numDocs));
- }
-
- db.deleteDb();
- db_name = get_random_db_name();
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
-
- for(var i=1; i <= 5; i++) {
-
- for(var j=0; j < 10; j++) {
- // these docs are in the order of the keys collation, for clarity
- var docs = [];
- docs.push({keys:["a"]});
- docs.push({keys:["a"]});
- docs.push({keys:["a", "b"]});
- docs.push({keys:["a", "b"]});
- docs.push({keys:["a", "b", "c"]});
- docs.push({keys:["a", "b", "d"]});
- docs.push({keys:["a", "c", "d"]});
- docs.push({keys:["d"]});
- docs.push({keys:["d", "a"]});
- docs.push({keys:["d", "b"]});
- docs.push({keys:["d", "c"]});
- db.bulkSave(docs);
- var total_docs = ((i - 1) * 10 * 11) + ((j + 1) * 11);
- TEquals(total_docs, db.info().doc_count, 'doc count should match');
- }
-
- map = function (doc) { emit(doc.keys, 1); };
- // with emitted values being 1, count should be the same as sum
- var builtins = ["_sum", "_count"];
-
- for (var b=0; b < builtins.length; b++) {
- var fun = builtins[b];
- var results = db.query(map, fun, {group:true});
-
- //group by exact key match
- T(equals(results.rows[0], {key:["a"],value:20*i}));
- T(equals(results.rows[1], {key:["a","b"],value:20*i}));
- T(equals(results.rows[2], {key:["a", "b", "c"],value:10*i}));
- T(equals(results.rows[3], {key:["a", "b", "d"],value:10*i}));
-
- // test to make sure group reduce and limit params provide valid json
- var results = db.query(map, fun, {group: true, limit: 2});
- T(equals(results.rows[0], {key: ["a"], value: 20*i}));
- T(equals(results.rows.length, 2));
-
- //group by the first element in the key array
- var results = db.query(map, fun, {group_level:1});
- T(equals(results.rows[0], {key:["a"],value:70*i}));
- T(equals(results.rows[1], {key:["d"],value:40*i}));
-
- //group by the first 2 elements in the key array
- var results = db.query(map, fun, {group_level:2});
- T(equals(results.rows[0], {key:["a"],value:20*i}));
- T(equals(results.rows[1], {key:["a","b"],value:40*i}));
- T(equals(results.rows[2], {key:["a","c"],value:10*i}));
- T(equals(results.rows[3], {key:["d"],value:10*i}));
- T(equals(results.rows[4], {key:["d","a"],value:10*i}));
- T(equals(results.rows[5], {key:["d","b"],value:10*i}));
- T(equals(results.rows[6], {key:["d","c"],value:10*i}));
- };
-
- map = function (doc) { emit(doc.keys, [1, 1]); };
-
- var results = db.query(map, "_sum", {group:true});
- T(equals(results.rows[0], {key:["a"],value:[20*i,20*i]}));
- T(equals(results.rows[1], {key:["a","b"],value:[20*i,20*i]}));
- T(equals(results.rows[2], {key:["a", "b", "c"],value:[10*i,10*i]}));
- T(equals(results.rows[3], {key:["a", "b", "d"],value:[10*i,10*i]}));
-
- var results = db.query(map, "_sum", {group: true, limit: 2});
- T(equals(results.rows[0], {key: ["a"], value: [20*i,20*i]}));
- T(equals(results.rows.length, 2));
-
- var results = db.query(map, "_sum", {group_level:1});
- T(equals(results.rows[0], {key:["a"],value:[70*i,70*i]}));
- T(equals(results.rows[1], {key:["d"],value:[40*i,40*i]}));
-
- var results = db.query(map, "_sum", {group_level:2});
- T(equals(results.rows[0], {key:["a"],value:[20*i,20*i]}));
- T(equals(results.rows[1], {key:["a","b"],value:[40*i,40*i]}));
- T(equals(results.rows[2], {key:["a","c"],value:[10*i,10*i]}));
- T(equals(results.rows[3], {key:["d"],value:[10*i,10*i]}));
- T(equals(results.rows[4], {key:["d","a"],value:[10*i,10*i]}));
- T(equals(results.rows[5], {key:["d","b"],value:[10*i,10*i]}));
- T(equals(results.rows[6], {key:["d","c"],value:[10*i,10*i]}));
- }
-
- // cleanup
- db.deleteDb();
-}
diff --git a/test/javascript/tests/reduce_false.js b/test/javascript/tests/reduce_false.js
deleted file mode 100644
index 69d8b0cf4..000000000
--- a/test/javascript/tests/reduce_false.js
+++ /dev/null
@@ -1,50 +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.
-
-couchTests.elixir = true;
-couchTests.reduce_false = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var numDocs = 5;
- var docs = makeDocs(1,numDocs + 1);
- db.bulkSave(docs);
- var summate = function(N) {return (N+1)*N/2;};
-
- var designDoc = {
- _id:"_design/test",
- language: "javascript",
- views: {
- summate: {map:"function (doc) { emit(doc.integer, doc.integer); }",
- reduce:"function (keys, values) { return sum(values); }"},
- }
- };
- T(db.save(designDoc).ok);
-
- // Test that the reduce works
- var res = db.view('test/summate');
-
- TEquals(1, res.rows.length, "should have 1 row");
- TEquals(summate(5), res.rows[0].value, 'should summate up 5');
-
- //Test that we get our docs back
- res = db.view('test/summate', {reduce: false});
- T(res.rows.length == 5);
- for(var i=0; i<5; i++) {
- T(res.rows[i].value == i+1);
- }
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/reduce_false_temp.js b/test/javascript/tests/reduce_false_temp.js
deleted file mode 100644
index a13b4ab18..000000000
--- a/test/javascript/tests/reduce_false_temp.js
+++ /dev/null
@@ -1,41 +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.
-
-couchTests.skip = true;
-couchTests.reduce_false_temp = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var numDocs = 5;
- var docs = makeDocs(1,numDocs + 1);
- db.bulkSave(docs);
- var summate = function(N) {return (N+1)*N/2;};
-
- var mapFun = "function (doc) { emit(doc.integer, doc.integer); }";
- var reduceFun = "function (keys, values) { return sum(values); }";
-
- // Test that the reduce works
- var res = db.query(mapFun, reduceFun);
- T(res.rows.length == 1 && res.rows[0].value == summate(5));
-
- //Test that we get our docs back
- res = db.query(mapFun, reduceFun, {reduce: false});
- T(res.rows.length == 5);
- for(var i=0; i<5; i++) {
- T(res.rows[i].value == i+1);
- }
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/replicator_db_bad_rep_id.js b/test/javascript/tests/replicator_db_bad_rep_id.js
deleted file mode 100644
index 0912c1bc0..000000000
--- a/test/javascript/tests/replicator_db_bad_rep_id.js
+++ /dev/null
@@ -1,104 +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.
-
-couchTests.elixir = true;
-couchTests.replicator_db_bad_rep_id = function(debug) {
- //return console.log('TODO');
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- // TODO: dice DBs (at least target)
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- //var repDb = replicator_db.repDb;
- var replDb = new CouchDB("_replicator");
- var wait = replicator_db.wait;
- var waitForRep = replicator_db.waitForRep;
- var waitForSeq = replicator_db.waitForSeq;
-
- function rep_doc_with_bad_rep_id() {
- populate_db(dbA, docs1);
- populate_db(dbB, []);
-
- var repDoc = {
- _id: "foo_rep",
-// TODO: fix DB name issue and remove absolute URL again
- source: 'http://localhost:15984/'+dbA.name,
- target: 'http://localhost:15984/'+dbB.name,
- replication_id: "1234abc"
- };
- T(replDb.save(repDoc).ok);
-
- T(waitForRep(replDb, repDoc, "completed", "error") == "completed");
- for (var i = 0; i < docs1.length; i++) {
- var doc = docs1[i];
- var copy = dbB.open(doc._id);
- T(copy !== null);
- T(copy.value === doc.value);
- }
-
- var repDoc1 = replDb.open(repDoc._id);
- T(repDoc1 !== null);
- T(repDoc1.source === repDoc.source);
- T(repDoc1.target === repDoc.target);
- T(repDoc1._replication_state === "completed",
- "replication document with bad replication id failed");
- T(typeof repDoc1._replication_state_time === "string");
- T(typeof repDoc1._replication_id === "undefined");
- }
-
- /*var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: null //repDb.name
- }
- ];*/
-
- //repDb.deleteDb();
- // don't run on modified server as it would be strange on cluster
- // but use "normal" replication DB, create a doc, reliably clear after run
- // on delete fail, the next tests would all fail
- function handleReplDoc(show) {
- var replDoc = replDb.open("foo_rep");
- if(replDoc!=null) {
- if(show) {
- //console.log(JSON.stringify(replDoc));
- }
- replDb.deleteDoc(replDoc);
- }
- }
-
- handleReplDoc();
- try {
- rep_doc_with_bad_rep_id();
- } finally {
- // cleanup or log
- try {
- handleReplDoc(true);
- } catch (e2) {
- console.log("Error during cleanup " + e2);
- }
- }
- //run_on_modified_server(server_config, rep_doc_with_bad_rep_id);
-
- // cleanup
- //repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
-}
diff --git a/test/javascript/tests/replicator_db_by_doc_id.js b/test/javascript/tests/replicator_db_by_doc_id.js
deleted file mode 100644
index bc15b03d2..000000000
--- a/test/javascript/tests/replicator_db_by_doc_id.js
+++ /dev/null
@@ -1,129 +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.
-
-couchTests.elixir = true;
-couchTests.replicator_db_by_doc_id = function(debug) {
- //return console.log('TODO');
-
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- // TODO: dice DBs (at least target)
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- //var repDb = replicator_db.repDb;
- var replDb = new CouchDB("_replicator");
- var wait = replicator_db.wait;
- var waitForRep = replicator_db.waitForRep;
- var waitForSeq = replicator_db.waitForSeq;
-
- function by_doc_ids_replication() {
- // to test that we can replicate docs with slashes in their IDs
- var docs2 = docs1.concat([
- {
- _id: "_design/mydesign",
- language : "javascript"
- }
- ]);
-
- populate_db(dbA, docs2);
- populate_db(dbB, []);
-
- var repDoc = {
- _id: "foo_cont_rep_doc",
- source: "http://" + CouchDB.host + "/" + dbA.name,
- // TODO: fix DB name issue and remove absolute URL again
- target: 'http://localhost:15984/' + dbB.name,
- doc_ids: ["foo666", "foo3", "_design/mydesign", "foo999", "foo1"]
- };
- T(replDb.save(repDoc).ok);
-
- waitForRep(replDb, repDoc, "completed");
- var copy = dbB.open("foo1");
- T(copy !== null);
- T(copy.value === 11);
-
- copy = dbB.open("foo2");
- T(copy === null);
-
- copy = dbB.open("foo3");
- T(copy !== null);
- T(copy.value === 33);
-
- copy = dbB.open("foo666");
- T(copy === null);
-
- copy = dbB.open("foo999");
- T(copy === null);
-
- copy = dbB.open("_design/mydesign");
- // TODO: recheck - but I believe this should be in the target! (see also #written below)
- T(copy !== null);
-
- repDoc = replDb.open(repDoc._id);
- T(typeof repDoc._replication_stats === "object", "doc has stats");
- var stats = repDoc._replication_stats;
- TEquals(3, stats.revisions_checked, "right # of revisions_checked");
- TEquals(3, stats.missing_revisions_found, "right # of missing_revisions_found");
- TEquals(3, stats.docs_read, "right # of docs_read");
- TEquals(3, stats.docs_written, "right # of docs_written");
- TEquals(0, stats.doc_write_failures, "right # of doc_write_failures");
- // sequences are no more meaningful in a cluster
- //TEquals(dbA.info().update_seq, stats.checkpointed_source_seq, "right checkpointed_source_seq");
- }
-
- /*var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- }
- ];*/
-
- //repDb.deleteDb();
- // don't run on modified server as it would be strange on cluster
- // but use "normal" replication DB, create a doc, reliably clear after run
- // on delete fail, the next tests would all fail
- function handleReplDoc(show) {
- var replDoc = replDb.open("foo_cont_rep_doc");
- if(replDoc!=null) {
- if(show) {
- //console.log(JSON.stringify(replDoc));
- }
- replDb.deleteDoc(replDoc);
- }
- }
-
- handleReplDoc();
- try {
- by_doc_ids_replication();
- } finally {
- // cleanup or log
- try {
- handleReplDoc(true);
- } catch (e2) {
- console.log("Error during cleanup " + e2);
- }
- }
- //run_on_modified_server(server_config, by_doc_ids_replication);
-
- // cleanup
- //repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
-}
diff --git a/test/javascript/tests/replicator_db_compact_rep_db.js b/test/javascript/tests/replicator_db_compact_rep_db.js
deleted file mode 100644
index e8ba326f7..000000000
--- a/test/javascript/tests/replicator_db_compact_rep_db.js
+++ /dev/null
@@ -1,119 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_compact_rep_db = function(debug) {
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- var repDb = replicator_db.repDb;
- var usersDb = replicator_db.usersDb;
- var wait = replicator_db.wait;
- var waitForRep = replicator_db.waitForRep;
- var waitForSeq = replicator_db.waitForSeq;
- var wait_rep_doc = replicator_db.wait_rep_doc;
-
- function compact_rep_db() {
- var dbA_copy = new CouchDB("test_suite_rep_db_a_copy");
- var dbB_copy = new CouchDB("test_suite_rep_db_b_copy");
- var repDoc1, repDoc2;
- var xhr, i, doc, copy, new_doc;
- var docs = makeDocs(1, 50);
-
- populate_db(dbA, docs);
- populate_db(dbB, docs);
- populate_db(dbA_copy, []);
- populate_db(dbB_copy, []);
-
- repDoc1 = {
- _id: "rep1",
- source: CouchDB.protocol + CouchDB.host + "/" + dbA.name,
- target: dbA_copy.name,
- continuous: true
- };
- repDoc2 = {
- _id: "rep2",
- source: CouchDB.protocol + CouchDB.host + "/" + dbB.name,
- target: dbB_copy.name,
- continuous: true
- };
-
- TEquals(true, repDb.save(repDoc1).ok);
- TEquals(true, repDb.save(repDoc2).ok);
-
- TEquals(true, repDb.compact().ok);
- TEquals(202, repDb.last_req.status);
-
- waitForSeq(dbA, dbA_copy);
- waitForSeq(dbB, dbB_copy);
-
- while (repDb.info().compact_running) {};
-
- for (i = 0; i < docs.length; i++) {
- copy = dbA_copy.open(docs[i]._id);
- T(copy !== null);
- copy = dbB_copy.open(docs[i]._id);
- T(copy !== null);
- }
-
- new_doc = {
- _id: "foo666",
- value: 666
- };
-
- TEquals(true, dbA.save(new_doc).ok);
- TEquals(true, dbB.save(new_doc).ok);
-
- waitForSeq(dbA, dbA_copy);
- waitForSeq(dbB, dbB_copy);
-
- copy = dbA.open(new_doc._id);
- T(copy !== null);
- TEquals(666, copy.value);
- copy = dbB.open(new_doc._id);
- T(copy !== null);
- TEquals(666, copy.value);
- }
-
- var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- },
- {
- section: "couch_httpd_auth",
- key: "authentication_db",
- value: usersDb.name
- }
- ];
-
- repDb.deleteDb();
- run_on_modified_server(server_config, compact_rep_db);
-
- // cleanup
- repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
- usersDb.deleteDb();
- (new CouchDB("test_suite_rep_db_a_copy")).deleteDb();
- (new CouchDB("test_suite_rep_db_b_copy")).deleteDb();
-
-} \ No newline at end of file
diff --git a/test/javascript/tests/replicator_db_continuous.js b/test/javascript/tests/replicator_db_continuous.js
deleted file mode 100644
index 6d3714988..000000000
--- a/test/javascript/tests/replicator_db_continuous.js
+++ /dev/null
@@ -1,137 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_continuous = function(debug) {
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- var repDb = replicator_db.repDb;
- var wait = replicator_db.wait;
- var waitForRep = replicator_db.waitForRep;
- var waitForSeq = replicator_db.waitForSeq;
-
- function continuous_replication() {
- populate_db(dbA, docs1);
- populate_db(dbB, []);
-
- var repDoc = {
- _id: "foo_cont_rep_doc",
- source: "http://" + CouchDB.host + "/" + dbA.name,
- target: dbB.name,
- continuous: true,
- user_ctx: {
- roles: ["_admin"]
- }
- };
-
- T(repDb.save(repDoc).ok);
-
- waitForSeq(dbA, dbB);
- for (var i = 0; i < docs1.length; i++) {
- var doc = docs1[i];
- var copy = dbB.open(doc._id);
- T(copy !== null);
- T(copy.value === doc.value);
- }
-
- var tasks = JSON.parse(CouchDB.request("GET", "/_active_tasks").responseText);
- TEquals(1, tasks.length, "1 active task");
- TEquals(repDoc._id, tasks[0].doc_id, "replication doc id in active tasks");
-
- // add another doc to source, it will be replicated to target
- var docX = {
- _id: "foo1000",
- value: 1001
- };
-
- T(dbA.save(docX).ok);
-
- waitForSeq(dbA, dbB);
- var copy = dbB.open("foo1000");
- T(copy !== null);
- T(copy.value === 1001);
-
- var repDoc1 = repDb.open(repDoc._id);
- T(repDoc1 !== null);
- T(repDoc1.source === repDoc.source);
- T(repDoc1.target === repDoc.target);
- T(repDoc1._replication_state === "triggered");
- T(typeof repDoc1._replication_state_time === "string");
- T(typeof repDoc1._replication_id === "string");
-
- // Design documents are only replicated to local targets if the respective
- // replication document has a user_ctx filed with the "_admin" role in it.
- var ddoc = {
- _id: "_design/foobar",
- language: "javascript"
- };
-
- T(dbA.save(ddoc).ok);
-
- waitForSeq(dbA, dbB);
- var ddoc_copy = dbB.open("_design/foobar");
- T(ddoc_copy !== null);
- T(ddoc.language === "javascript");
-
- // update the design doc on source, test that the new revision is replicated
- ddoc.language = "erlang";
- T(dbA.save(ddoc).ok);
- T(ddoc._rev.indexOf("2-") === 0);
-
- waitForSeq(dbA, dbB);
- ddoc_copy = dbB.open("_design/foobar");
- T(ddoc_copy !== null);
- T(ddoc_copy._rev === ddoc._rev);
- T(ddoc.language === "erlang");
-
- // stop replication by deleting the replication document
- T(repDb.deleteDoc(repDoc1).ok);
-
- // add another doc to source, it will NOT be replicated to target
- var docY = {
- _id: "foo666",
- value: 999
- };
-
- T(dbA.save(docY).ok);
-
- wait(200); // is there a way to avoid wait here?
- var copy = dbB.open("foo666");
- T(copy === null);
- }
-
-
- var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- }
- ];
-
- repDb.deleteDb();
- run_on_modified_server(server_config, continuous_replication);
-
- // cleanup
- repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
-} \ No newline at end of file
diff --git a/test/javascript/tests/replicator_db_credential_delegation.js b/test/javascript/tests/replicator_db_credential_delegation.js
deleted file mode 100644
index 7ec7711e1..000000000
--- a/test/javascript/tests/replicator_db_credential_delegation.js
+++ /dev/null
@@ -1,149 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_credential_delegation = function(debug) {
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- var repDb = replicator_db.repDb;
- var usersDb = replicator_db.usersDb;
- var wait = replicator_db.wait;
- var waitForRep = replicator_db.waitForRep;
- var waitForSeq = replicator_db.waitForSeq;
- var wait_rep_doc = replicator_db.wait_rep_doc;
-
- function test_replication_credentials_delegation() {
- populate_db(usersDb, []);
-
- var joeUserDoc = CouchDB.prepareUserDoc({
- name: "joe",
- roles: ["god", "erlanger"]
- }, "erly");
- T(usersDb.save(joeUserDoc).ok);
-
- var ddoc = {
- _id: "_design/beer",
- language: "javascript"
- };
- populate_db(dbA, docs1.concat([ddoc]));
- populate_db(dbB, []);
-
- T(dbB.setSecObj({
- admins: {
- names: [],
- roles: ["god"]
- }
- }).ok);
-
- var server_admins_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "admins",
- key: "fdmanana",
- value: "qwerty"
- }
- ];
-
- run_on_modified_server(server_admins_config, function() {
-
- T(CouchDB.login("fdmanana", "qwerty").ok);
- T(CouchDB.session().userCtx.name === "fdmanana");
- T(CouchDB.session().userCtx.roles.indexOf("_admin") !== -1);
-
- var repDoc = {
- _id: "foo_rep_del_doc_1",
- source: dbA.name,
- target: dbB.name,
- user_ctx: {
- name: "joe",
- roles: ["erlanger"]
- }
- };
-
- T(repDb.save(repDoc).ok);
-
- waitForRep(repDb, repDoc, "completed");
- for (var i = 0; i < docs1.length; i++) {
- var doc = docs1[i];
- var copy = dbB.open(doc._id);
- T(copy !== null);
- T(copy.value === doc.value);
- }
-
- // design doc was not replicated, because joe is not an admin of db B
- var doc = dbB.open(ddoc._id);
- T(doc === null);
-
- // now test the same replication but putting the role "god" in the
- // delegation user context property
- var repDoc2 = {
- _id: "foo_rep_del_doc_2",
- source: dbA.name,
- target: dbB.name,
- user_ctx: {
- name: "joe",
- roles: ["erlanger", "god"]
- }
- };
- T(repDb.save(repDoc2).ok);
-
- waitForRep(repDb, repDoc2, "completed");
- for (var i = 0; i < docs1.length; i++) {
- var doc = docs1[i];
- var copy = dbB.open(doc._id);
- T(copy !== null);
- T(copy.value === doc.value);
- }
-
- // because anyone with a 'god' role is an admin of db B, a replication
- // that is delegated to a 'god' role can write design docs to db B
- doc = dbB.open(ddoc._id);
- T(doc !== null);
- T(doc.language === ddoc.language);
- });
- }
-
- var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- },
- {
- section: "couch_httpd_auth",
- key: "authentication_db",
- value: usersDb.name
- }
- ];
-
- repDb.deleteDb();
- run_on_modified_server(server_config, test_replication_credentials_delegation);
-
- // cleanup
- repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
- usersDb.deleteDb();
-} \ No newline at end of file
diff --git a/test/javascript/tests/replicator_db_field_validation.js b/test/javascript/tests/replicator_db_field_validation.js
deleted file mode 100644
index 4442c8825..000000000
--- a/test/javascript/tests/replicator_db_field_validation.js
+++ /dev/null
@@ -1,178 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_field_validation = function(debug) {
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- var repDb = replicator_db.repDb;
- var usersDb = replicator_db.usersDb;
- var wait = replicator_db.wait;
- var waitForRep = replicator_db.waitForRep;
- var waitForSeq = replicator_db.waitForSeq;
- var wait_rep_doc = replicator_db.wait_rep_doc;
-
- function rep_doc_field_validation() {
- var docs = makeDocs(1, 5);
-
- populate_db(dbA, docs);
- populate_db(dbB, []);
-
- var repDoc = {
- _id: "rep1",
- target: dbB.name
- };
-
- try {
- repDb.save(repDoc);
- T(false, "should have failed because source field is missing");
- } catch (x) {
- TEquals("forbidden", x.error);
- }
-
- repDoc = {
- _id: "rep1",
- source: 123,
- target: dbB.name
- };
-
- try {
- repDb.save(repDoc);
- T(false, "should have failed because source field is a number");
- } catch (x) {
- TEquals("forbidden", x.error);
- }
-
- repDoc = {
- _id: "rep1",
- source: dbA.name
- };
-
- try {
- repDb.save(repDoc);
- T(false, "should have failed because target field is missing");
- } catch (x) {
- TEquals("forbidden", x.error);
- }
-
- repDoc = {
- _id: "rep1",
- source: dbA.name,
- target: null
- };
-
- try {
- repDb.save(repDoc);
- T(false, "should have failed because target field is null");
- } catch (x) {
- TEquals("forbidden", x.error);
- }
-
- repDoc = {
- _id: "rep1",
- source: dbA.name,
- target: { url: 123 }
- };
-
- try {
- repDb.save(repDoc);
- T(false, "should have failed because target.url field is not a string");
- } catch (x) {
- TEquals("forbidden", x.error);
- }
-
- repDoc = {
- _id: "rep1",
- source: dbA.name,
- target: { url: dbB.name, auth: null }
- };
-
- try {
- repDb.save(repDoc);
- T(false, "should have failed because target.auth field is null");
- } catch (x) {
- TEquals("forbidden", x.error);
- }
-
- repDoc = {
- _id: "rep1",
- source: dbA.name,
- target: { url: dbB.name, auth: "foo:bar" }
- };
-
- try {
- repDb.save(repDoc);
- T(false, "should have failed because target.auth field is not an object");
- } catch (x) {
- TEquals("forbidden", x.error);
- }
-
- repDoc = {
- _id: "rep1",
- source: dbA.name,
- target: dbB.name,
- continuous: "true"
- };
-
- try {
- repDb.save(repDoc);
- T(false, "should have failed because continuous is not a boolean");
- } catch (x) {
- TEquals("forbidden", x.error);
- }
-
- repDoc = {
- _id: "rep1",
- source: dbA.name,
- target: dbB.name,
- filter: 123
- };
-
- try {
- repDb.save(repDoc);
- T(false, "should have failed because filter is not a string");
- } catch (x) {
- TEquals("forbidden", x.error);
- }
- }
-
- var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- },
- {
- section: "couch_httpd_auth",
- key: "authentication_db",
- value: usersDb.name
- }
- ];
-
- repDb.deleteDb();
- run_on_modified_server(server_config, rep_doc_field_validation);
-
- // cleanup
- repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
- usersDb.deleteDb();
-} \ No newline at end of file
diff --git a/test/javascript/tests/replicator_db_filtered.js b/test/javascript/tests/replicator_db_filtered.js
deleted file mode 100644
index 4c1cfb3d1..000000000
--- a/test/javascript/tests/replicator_db_filtered.js
+++ /dev/null
@@ -1,105 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_filtered = function(debug) {
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- var repDb = replicator_db.repDb;
- var waitForRep = replicator_db.waitForRep;
-
- function filtered_replication() {
- var docs2 = docs1.concat([
- {
- _id: "_design/mydesign",
- language : "javascript",
- filters : {
- myfilter : (function(doc, req) {
- return (doc.value % 2) !== Number(req.query.myparam);
- }).toString()
- }
- }
- ]);
-
- populate_db(dbA, docs2);
- populate_db(dbB, []);
-
- var repDoc = {
- _id: "foo_filt_rep_doc",
- source: "http://" + CouchDB.host + "/" + dbA.name,
- target: dbB.name,
- filter: "mydesign/myfilter",
- query_params: {
- myparam: 1
- }
- };
- T(repDb.save(repDoc).ok);
-
- waitForRep(repDb, repDoc, "completed");
- for (var i = 0; i < docs2.length; i++) {
- var doc = docs2[i];
- var copy = dbB.open(doc._id);
-
- if (typeof doc.value === "number") {
- if ((doc.value % 2) !== 1) {
- T(copy !== null);
- T(copy.value === doc.value);
- } else {
- T(copy === null);
- }
- }
- }
-
- var repDoc1 = repDb.open(repDoc._id);
- T(repDoc1 !== null);
- T(repDoc1.source === repDoc.source);
- T(repDoc1.target === repDoc.target);
- T(repDoc1._replication_state === "completed", "filtered");
- T(typeof repDoc1._replication_state_time === "string");
- T(typeof repDoc1._replication_id === "string");
- T(typeof repDoc1._replication_stats === "object", "doc has stats");
- var stats = repDoc1._replication_stats;
- TEquals(2, stats.revisions_checked, "right # of revisions_checked");
- TEquals(2, stats.missing_revisions_found, "right # of missing_revisions_found");
- TEquals(2, stats.docs_read, "right # of docs_read");
- TEquals(1, stats.docs_written, "right # of docs_written");
- TEquals(1, stats.doc_write_failures, "right # of doc_write_failures");
- TEquals(dbA.info().update_seq, stats.checkpointed_source_seq,
- "right checkpointed_source_seq");
- }
-
-
- var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- }
- ];
-
- repDb.deleteDb();
- run_on_modified_server(server_config, filtered_replication);
-
- // cleanup
- repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
-} \ No newline at end of file
diff --git a/test/javascript/tests/replicator_db_identical.js b/test/javascript/tests/replicator_db_identical.js
deleted file mode 100644
index a51fb6791..000000000
--- a/test/javascript/tests/replicator_db_identical.js
+++ /dev/null
@@ -1,87 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_identical = function(debug) {
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- var repDb = replicator_db.repDb;
- var wait = replicator_db.wait;
- var waitForRep = replicator_db.waitForRep;
- var waitForSeq = replicator_db.waitForSeq;
-
- // test the case where multiple replication docs (different IDs)
- // describe in fact the same replication (source, target, etc)
- function identical_rep_docs() {
- populate_db(dbA, docs1);
- populate_db(dbB, []);
-
- var repDoc1 = {
- _id: "foo_dup_rep_doc_1",
- source: "http://" + CouchDB.host + "/" + dbA.name,
- target: dbB.name
- };
- var repDoc2 = {
- _id: "foo_dup_rep_doc_2",
- source: "http://" + CouchDB.host + "/" + dbA.name,
- target: dbB.name
- };
-
- T(repDb.save(repDoc1).ok);
- T(repDb.save(repDoc2).ok);
-
- waitForRep(repDb, repDoc1, "completed");
- for (var i = 0; i < docs1.length; i++) {
- var doc = docs1[i];
- var copy = dbB.open(doc._id);
- T(copy !== null);
- T(copy.value === doc.value);
- }
-
- repDoc1 = repDb.open("foo_dup_rep_doc_1");
- T(repDoc1 !== null);
- T(repDoc1._replication_state === "completed", "identical");
- T(typeof repDoc1._replication_state_time === "string");
- T(typeof repDoc1._replication_id === "string");
-
- repDoc2 = repDb.open("foo_dup_rep_doc_2");
- T(repDoc2 !== null);
- T(typeof repDoc2._replication_state === "undefined");
- T(typeof repDoc2._replication_state_time === "undefined");
- T(repDoc2._replication_id === repDoc1._replication_id);
- }
-
- var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- }
- ];
-
- repDb.deleteDb();
- run_on_modified_server(server_config, identical_rep_docs);
-
- // cleanup
- repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
-} \ No newline at end of file
diff --git a/test/javascript/tests/replicator_db_identical_continuous.js b/test/javascript/tests/replicator_db_identical_continuous.js
deleted file mode 100644
index 37495ecbd..000000000
--- a/test/javascript/tests/replicator_db_identical_continuous.js
+++ /dev/null
@@ -1,139 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_identical_continuous = function(debug) {
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- var repDb = replicator_db.repDb;
- var wait = replicator_db.wait;
- var waitForRep = replicator_db.waitForRep;
- var waitForSeq = replicator_db.waitForSeq;
- var wait_rep_doc = replicator_db.wait_rep_doc;
-
- // test the case where multiple replication docs (different IDs)
- // describe in fact the same continuous replication (source, target, etc)
- function identical_continuous_rep_docs() {
- populate_db(dbA, docs1);
- populate_db(dbB, []);
-
- var repDoc1 = {
- _id: "foo_dup_cont_rep_doc_1",
- source: "http://" + CouchDB.host + "/" + dbA.name,
- target: dbB.name,
- continuous: true
- };
- var repDoc2 = {
- _id: "foo_dup_cont_rep_doc_2",
- source: "http://" + CouchDB.host + "/" + dbA.name,
- target: dbB.name,
- continuous: true
- };
-
- T(repDb.save(repDoc1).ok);
- T(repDb.save(repDoc2).ok);
-
- waitForSeq(dbA, dbB);
- for (var i = 0; i < docs1.length; i++) {
- var doc = docs1[i];
- var copy = dbB.open(doc._id);
- T(copy !== null);
- T(copy.value === doc.value);
- }
-
- // Rather than a timeout we're just waiting to hear the
- // fourth change to the database. Changes 1 and 2 were
- // us storing repDoc1 and repDoc2. Changes 3 and 4 are
- // the replicator manager updating each document. This
- // just waits until the fourth change before continuing.
- repDb.changes({"feed":"longpoll", "since":3});
-
- repDoc1 = repDb.open("foo_dup_cont_rep_doc_1");
- T(repDoc1 !== null);
- T(repDoc1._replication_state === "triggered");
- T(typeof repDoc1._replication_state_time === "string");
- T(typeof repDoc1._replication_id === "string");
-
- repDoc2 = repDb.open("foo_dup_cont_rep_doc_2");
- T(repDoc2 !== null);
- T(typeof repDoc2._replication_state === "undefined");
- T(typeof repDoc2._replication_state_time === "undefined");
- T(repDoc2._replication_id === repDoc1._replication_id);
-
- var newDoc = {
- _id: "foo666",
- value: 999
- };
- T(dbA.save(newDoc).ok);
-
- waitForSeq(dbA, dbB);
- var copy = dbB.open("foo666");
- T(copy !== null);
- T(copy.value === 999);
-
- // deleting second replication doc, doesn't affect the 1st one and
- // neither it stops the replication
- T(repDb.deleteDoc(repDoc2).ok);
- repDoc1 = repDb.open("foo_dup_cont_rep_doc_1");
- T(repDoc1 !== null);
- T(repDoc1._replication_state === "triggered");
- T(typeof repDoc1._replication_state_time === "string");
-
- var newDoc2 = {
- _id: "foo5000",
- value: 5000
- };
- T(dbA.save(newDoc2).ok);
-
- waitForSeq(dbA, dbB);
- var copy = dbB.open("foo5000");
- T(copy !== null);
- T(copy.value === 5000);
-
- // deleting the 1st replication document stops the replication
- T(repDb.deleteDoc(repDoc1).ok);
- var newDoc3 = {
- _id: "foo1983",
- value: 1983
- };
- T(dbA.save(newDoc3).ok);
-
- wait(wait_rep_doc); //how to remove wait?
- var copy = dbB.open("foo1983");
- T(copy === null);
- }
-
- var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- }
- ];
-
- repDb.deleteDb();
- run_on_modified_server(server_config, identical_continuous_rep_docs);
-
- // cleanup
- repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
-} \ No newline at end of file
diff --git a/test/javascript/tests/replicator_db_invalid_filter.js b/test/javascript/tests/replicator_db_invalid_filter.js
deleted file mode 100644
index a974ad2d4..000000000
--- a/test/javascript/tests/replicator_db_invalid_filter.js
+++ /dev/null
@@ -1,119 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_invalid_filter = function(debug) {
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- var repDb = replicator_db.repDb;
- var usersDb = replicator_db.usersDb;
- var wait = replicator_db.wait;
- var waitForRep = replicator_db.waitForRep;
- var waitForSeq = replicator_db.waitForSeq;
- var wait_rep_doc = replicator_db.wait_rep_doc;
-
- function test_invalid_filter() {
- // COUCHDB-1199 - replication document with a filter field that was invalid
- // crashed the CouchDB server.
- var repDoc1 = {
- _id: "rep1",
- source: "couch_foo_test_db",
- target: "couch_bar_test_db",
- filter: "test/foofilter"
- };
-
- TEquals(true, repDb.save(repDoc1).ok);
-
- waitForRep(repDb, repDoc1, "error");
- repDoc1 = repDb.open(repDoc1._id);
- TEquals("undefined", typeof repDoc1._replication_id);
- TEquals("error", repDoc1._replication_state);
- TEquals("Could not open source database `couch_foo_test_db`: {db_not_found,<<\"couch_foo_test_db\">>}",
- repDoc1._replication_state_reason);
-
- populate_db(dbA, docs1);
- populate_db(dbB, []);
-
- var repDoc2 = {
- _id: "rep2",
- source: dbA.name,
- target: dbB.name,
- filter: "test/foofilter"
- };
-
- TEquals(true, repDb.save(repDoc2).ok);
-
- waitForRep(repDb, repDoc2, "error");
- repDoc2 = repDb.open(repDoc2._id);
- TEquals("undefined", typeof repDoc2._replication_id);
- TEquals("error", repDoc2._replication_state);
- TEquals("Couldn't open document `_design/test` from source database `test_suite_rep_db_a`: {error,<<\"not_found\">>}",
- repDoc2._replication_state_reason);
-
- var ddoc = {
- _id: "_design/mydesign",
- language : "javascript",
- filters : {
- myfilter : (function(doc, req) {
- return true;
- }).toString()
- }
- };
-
- TEquals(true, dbA.save(ddoc).ok);
-
- var repDoc3 = {
- _id: "rep3",
- source: dbA.name,
- target: dbB.name,
- filter: "mydesign/myfilter"
- };
-
- TEquals(true, repDb.save(repDoc3).ok);
-
- waitForRep(repDb, repDoc3, "completed");
- repDoc3 = repDb.open(repDoc3._id);
- TEquals("string", typeof repDoc3._replication_id);
- TEquals("completed", repDoc3._replication_state);
- }
-
- var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- },
- {
- section: "couch_httpd_auth",
- key: "authentication_db",
- value: usersDb.name
- }
- ];
-
- repDb.deleteDb();
- run_on_modified_server(server_config, test_invalid_filter);
-
- // cleanup
- repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
- usersDb.deleteDb();
-} \ No newline at end of file
diff --git a/test/javascript/tests/replicator_db_security.js b/test/javascript/tests/replicator_db_security.js
deleted file mode 100644
index 4994958fc..000000000
--- a/test/javascript/tests/replicator_db_security.js
+++ /dev/null
@@ -1,371 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_security = function(debug) {
- var reset_dbs = function(dbs) {
- dbs.forEach(function(db) {
- db.deleteDb();
- try { db.createDb() } catch (e) {};
- });
- };
-
- var dbs = ["couch_test_rep_db", "couch_test_users_db",
- "test_suite_db_a", "test_suite_db_b", "test_suite_db_c"]
- .map(function(db_name) {
- return new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- });
-
- var repDb = dbs[0];
- var usersDb = dbs[1];
- var dbA = dbs[2];
- var dbB = dbs[3];
- var dbC = dbs[4];
-
- if (debug) debugger;
-
- var loginUser = function(username) {
- var pws = {
- jan: "apple",
- jchris: "mp3",
- fdmanana: "foobar",
- benoitc: "test"
- };
- T(CouchDB.login(username, pws[username]).ok);
- };
-
- var repChanges = function(username) {
- var pws = {
- jan: "apple",
- jchris: "mp3",
- fdmanana: "foobar",
- benoitc: "test"
- };
- T(CouchDB.login(username, pws[username]).ok);
- var changes = CouchDB.request(
- "GET",
- "/" + repDb.name + "/_changes?include_docs=true" +
- "&anti-cache=" + String(Math.round(Math.random() * 100000)));
- return changes = JSON.parse(changes.responseText);
- };
-
- var save_as = function(db, doc, username)
- {
- loginUser(username);
- try {
- return db.save(doc);
- } catch (ex) {
- return ex;
- } finally {
- CouchDB.logout();
- }
- };
-
- var open_as = function(db, docId, username) {
- loginUser(username);
- try {
- return db.open(docId);
- } finally {
- CouchDB.logout();
- }
- };
-
- // from test replicator_db.js
- function waitForDocPos(db, docId, pos) {
- var doc, curPos, t0, t1,
- maxWait = 3000;
-
- doc = db.open(docId);
- curPos = Number(doc._rev.split("-", 1));
- t0 = t1 = new Date();
-
- while ((curPos < pos) && ((t1 - t0) <= maxWait)) {
- doc = db.open(docId);
- curPos = Number(doc._rev.split("-", 1));
- t1 = new Date();
- }
-
- return doc;
- }
-
- var testFun = function()
- {
- reset_dbs(dbs);
-
- // _replicator db
- // in admin party mode, anonymous should be able to create a replication
- var repDoc = {
- _id: "null-owner-rep",
- source: dbA.name,
- target: dbB.name
- };
- var result = repDb.save(repDoc);
- TEquals(true, result.ok, "should allow anonymous replication docs in admin party");
- // new docs should get an owner field enforced. In admin party mode owner is null
- repDoc = repDb.open(repDoc._id);
- TIsnull(repDoc.owner, "owner should be null in admin party");
-
-// Uncomment when _users database security changes are implemented.
-//
-// var jchrisDoc = {
-// _id: "org.couchdb.user:jchris",
-// type: "user",
-// name: "jchris",
-// password: "mp3",
-// roles: []
-// };
- var jchrisDoc = CouchDB.prepareUserDoc({
- name: "jchris",
- roles: []
- }, "mp3");
- usersDb.save(jchrisDoc); // set up a non-admin user
-
-// Uncomment when _users database security changes are implemented.
-//
-// var jchrisDoc = {
-// _id: "org.couchdb.user:fdmanana",
-// type: "user",
-// name: "fdmanana",
-// password: "foobar",
-// roles: []
-// };
- var fdmananaDoc = CouchDB.prepareUserDoc({
- name: "fdmanana",
- roles: []
- }, "foobar");
- usersDb.save(fdmananaDoc); // set up a non-admin user
-
-// Uncomment when _users database security changes are implemented.
-//
-// var benoitcDoc = {
-// _id: "org.couchdb.user:fdmanana",
-// type: "user",
-// name: "fdmanana",
-// password: "foobar",
-// roles: []
-// };
- var benoitcDoc = CouchDB.prepareUserDoc({
- name: "benoitc",
- roles: []
- }, "test");
- usersDb.save(benoitcDoc); // set up a non-admin user
-
- T(repDb.setSecObj({
- "admins" : {
- roles : [],
- names : ["benoitc"]
- }
- }).ok);
-
- run_on_modified_server([
- {
- section: "admins",
- key: "jan",
- value: "apple"
- }
- ], function() {
- // replication docs from admin-party mode in non-admin party mode can not
- // be edited by non-admins (non-server admins)
- repDoc = repDb.open(repDoc._id);
- repDoc.target = dbC.name;
- var result = save_as(repDb, repDoc, "jchris");
- TEquals("forbidden", result.error, "should forbid editing null-owner docs");
-
- // replication docs from admin-party mode in non-admin party mode can only
- // be edited by admins (server admins)
- repDoc = waitForDocPos(repDb, repDoc._id, 3);
- repDoc.target = dbC.name;
- var result = save_as(repDb, repDoc, "jan");
- repDoc = open_as(repDb, repDoc._id, "jchris");
- TEquals(true, result.ok, "should allow editing null-owner docs to admins");
- TEquals("jan", repDoc.owner, "owner should be the admin now");
-
- // user can update their own replication docs (repDoc.owner)
- var jchrisRepDoc = {
- _id: "jchris-rep-doc",
- source: dbC.name,
- target: dbA.name,
- user_ctx: { name: "jchris", roles: [] }
- };
-
- var result = save_as(repDb, jchrisRepDoc, "jchris");
- TEquals(true, result.ok, "should create rep doc");
- jchrisRepDoc = repDb.open(jchrisRepDoc._id);
- TEquals("jchris", jchrisRepDoc.owner, "should assign correct owner");
- jchrisRepDoc = waitForDocPos(repDb, jchrisRepDoc._id, 3);
- jchrisRepDoc = open_as(repDb, jchrisRepDoc._id, "jchris");
- jchrisRepDoc.target = dbB.name;
- var result = save_as(repDb, jchrisRepDoc, "jchris");
- TEquals(true, result.ok, "should allow update of rep doc");
-
- // user should not be able to read from any view
- var ddoc = {
- _id: "_design/reps",
- views: {
- test: {
- map: "function(doc) {" +
- "if (doc._replication_state) { " +
- "emit(doc._id, doc._replication_state);" +
- "}" +
- "}"
- }
- }
- };
-
- save_as(repDb, ddoc, "jan");
-
- try {
- repDb.view("reps/test");
- T(false, "non-admin had view read access");
- } catch (ex) {
- TEquals("forbidden", ex.error,
- "non-admins should not be able to read a view");
- }
-
- // admin should be able to read from any view
- TEquals(true, CouchDB.login("jan", "apple").ok);
- var result = repDb.view("reps/test");
- CouchDB.logout();
- TEquals(2, result.total_rows, "should allow access and list two users");
-
- // test _all_docs, only available for _admins
- try {
- repDb.allDocs({include_docs: true});
- T(false, "non-admin had _all_docs access");
- } catch (ex) {
- TEquals("forbidden", ex.error,
- "non-admins should not be able to access _all_docs");
- }
-
- TEquals(true, CouchDB.login("jan", "apple").ok);
- try {
- repDb.allDocs({include_docs: true});
- } catch (ex) {
- T(false, "admin couldn't access _all_docs");
- }
- CouchDB.logout();
-
- try {
- repDb.view("reps/test");
- T(false, "non-admin had view read access");
- } catch (ex) {
- TEquals("forbidden", ex.error,
- "non-admins should not be able to read a view");
- }
-
- // admin should be able to read from any view
- TEquals(true, CouchDB.login("benoitc", "test").ok);
- var result = repDb.view("reps/test");
- CouchDB.logout();
- TEquals(2, result.total_rows, "should allow access and list two users");
-
- // test _all_docs, only available for _admins
- try {
- repDb.allDocs({include_docs: true});
- T(false, "non-admin had _all_docs access");
- } catch (ex) {
- TEquals("forbidden", ex.error,
- "non-admins should not be able to access _all_docs");
- }
-
- TEquals(true, CouchDB.login("benoitc", "test").ok);
- try {
- repDb.allDocs({include_docs: true});
- } catch (ex) {
- T(false, "admin couldn't access _all_docs");
- }
- CouchDB.logout();
-
- // Verify that users can't access credentials in the "source" and
- // "target" fields of replication documents owned by other users.
- var fdmananaRepDoc = {
- _id: "fdmanana-rep-doc",
- source: "http://fdmanana:foobar@" + CouchDB.host + "/" + dbC.name,
- target: dbA.name,
- user_ctx: { name: "fdmanana", roles: [] }
- };
-
- var result = save_as(repDb, fdmananaRepDoc, "fdmanana");
- TEquals(true, result.ok, "should create rep doc");
- waitForDocPos(repDb, fdmananaRepDoc._id, 3);
- fdmananaRepDoc = open_as(repDb, fdmananaRepDoc._id, "fdmanana");
- TEquals("fdmanana", fdmananaRepDoc.owner, "should assign correct owner");
- TEquals("http://fdmanana:foobar@" + CouchDB.host + "/" + dbC.name,
- fdmananaRepDoc.source, "source field has credentials");
-
- fdmananaRepDoc = open_as(repDb, fdmananaRepDoc._id, "jchris");
- TEquals("fdmanana", fdmananaRepDoc.owner, "should assign correct owner");
- TEquals("http://" + CouchDB.host + "/" + dbC.name,
- fdmananaRepDoc.source, "source field doesn't contain credentials");
-
- // _changes?include_docs=true, users shouldn't be able to see credentials
- // in documents owned by other users.
- var changes = repChanges("jchris");
- var doc = changes.results[changes.results.length - 1].doc;
- TEquals(fdmananaRepDoc._id, doc._id, "Got the right doc from _changes");
- TEquals("http://" + CouchDB.host + "/" + dbC.name,
- doc.source, "source field doesn't contain credentials (doc from _changes)");
- CouchDB.logout();
-
- // _changes?include_docs=true, user should be able to see credentials
- // in documents they own.
- var changes = repChanges("fdmanana");
- var doc = changes.results[changes.results.length - 1].doc;
- TEquals(fdmananaRepDoc._id, doc._id, "Got the right doc from _changes");
- TEquals("http://fdmanana:foobar@" + CouchDB.host + "/" + dbC.name,
- doc.source, "source field contains credentials (doc from _changes)");
- CouchDB.logout();
-
- // _changes?include_docs=true, admins should be able to see credentials
- // from all documents.
- var changes = repChanges("jan");
- var doc = changes.results[changes.results.length - 1].doc;
- TEquals(fdmananaRepDoc._id, doc._id, "Got the right doc from _changes");
- TEquals("http://fdmanana:foobar@" + CouchDB.host + "/" + dbC.name,
- doc.source, "source field contains credentials (doc from _changes)");
- CouchDB.logout();
-
- // _changes?include_docs=true, db admins should be able to see credentials
- // from all documents.
- var changes = repChanges("benoitc");
- var doc = changes.results[changes.results.length - 1].doc;
- TEquals(fdmananaRepDoc._id, doc._id, "Got the right doc from _changes");
- TEquals("http://fdmanana:foobar@" + CouchDB.host + "/" + dbC.name,
- doc.source, "source field contains credentials (doc from _changes)");
- CouchDB.logout();
-
- // ensure "old" replicator docs still work
- // done in replicator_db.js?
-
- // Login as admin so run_on_modified_server can do its cleanup.
- TEquals(true, CouchDB.login("jan", "apple").ok);
- });
- };
-
- run_on_modified_server([
- {
- section: "couch_httpd_auth",
- key: "authentication_db",
- value: usersDb.name
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- }],
- testFun
- );
-
- // cleanup
- usersDb.deleteDb();
- repDb.deleteDb();
-};
diff --git a/test/javascript/tests/replicator_db_simple.js b/test/javascript/tests/replicator_db_simple.js
deleted file mode 100644
index ad0a692d4..000000000
--- a/test/javascript/tests/replicator_db_simple.js
+++ /dev/null
@@ -1,114 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_simple = function(debug) {
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- var repDb = replicator_db.repDb;
- var waitForRep = replicator_db.waitForRep;
-
- function simple_replication() {
- populate_db(dbA, docs1);
- populate_db(dbB, []);
-
- var repDoc = {
- _id: "foo_simple_rep",
- source: dbA.name,
- target: dbB.name
- };
- T(repDb.save(repDoc).ok);
-
- waitForRep(repDb, repDoc, "completed");
- for (var i = 0; i < docs1.length; i++) {
- var doc = docs1[i];
- var copy = dbB.open(doc._id);
- T(copy !== null);
- T(copy.value === doc.value);
- }
-
- var repDoc1 = repDb.open(repDoc._id);
- T(repDoc1 !== null);
- T(repDoc1.source === repDoc.source);
- T(repDoc1.target === repDoc.target);
- T(repDoc1._replication_state === "completed", "simple");
- T(typeof repDoc1._replication_state_time === "string");
- T(typeof repDoc1._replication_id === "string");
- T(typeof repDoc1._replication_stats === "object", "doc has stats");
- var stats = repDoc1._replication_stats;
- TEquals(docs1.length, stats.revisions_checked,
- "right # of revisions_checked");
- TEquals(docs1.length, stats.missing_revisions_found,
- "right # of missing_revisions_found");
- TEquals(docs1.length, stats.docs_read, "right # of docs_read");
- TEquals(docs1.length, stats.docs_written, "right # of docs_written");
- TEquals(0, stats.doc_write_failures, "right # of doc_write_failures");
- TEquals(dbA.info().update_seq, stats.checkpointed_source_seq,
- "right checkpointed_source_seq");
- }
-
- var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- }
- ];
-
- repDb.deleteDb();
- run_on_modified_server(server_config, simple_replication);
-
-/*
- * Disabled, since error state would be set on the document only after
- * the exponential backoff retry done by the replicator database listener
- * terminates, which takes too much time for a unit test.
- */
- /*
- function error_state_replication() {
- populate_db(dbA, docs1);
-
- var repDoc = {
- _id: "foo_error_rep",
- source: dbA.name,
- target: "nonexistent_test_db"
- };
- T(repDb.save(repDoc).ok);
-
- waitForRep(repDb, repDoc, "error");
- var repDoc1 = repDb.open(repDoc._id);
- T(repDoc1 !== null);
- T(repDoc1._replication_state === "error");
- T(typeof repDoc1._replication_state_time === "string");
- T(typeof repDoc1._replication_id === "string");
- }
- */
-/*
- * repDb.deleteDb();
- * restartServer();
- * run_on_modified_server(server_config, error_state_replication);
- */
-
-
- // cleanup
- repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
-} \ No newline at end of file
diff --git a/test/javascript/tests/replicator_db_successive.js b/test/javascript/tests/replicator_db_successive.js
deleted file mode 100644
index d2ff4df0f..000000000
--- a/test/javascript/tests/replicator_db_successive.js
+++ /dev/null
@@ -1,127 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_successive = function(debug) {
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- var repDb = replicator_db.repDb;
- var wait = replicator_db.wait;
- var waitForRep = replicator_db.waitForRep;
- var waitForSeq = replicator_db.waitForSeq;
-
- function successive_identical_replications() {
- populate_db(dbA, docs1);
- populate_db(dbB, []);
-
- var repDoc1 = {
- _id: "foo_ident_rep_1",
- source: dbA.name,
- target: dbB.name
- };
- T(repDb.save(repDoc1).ok);
-
- waitForRep(repDb, repDoc1, "completed");
- for (var i = 0; i < docs1.length; i++) {
- var doc = docs1[i];
- var copy = dbB.open(doc._id);
- T(copy !== null);
- T(copy.value === doc.value);
- }
-
- var repDoc1_copy = repDb.open(repDoc1._id);
- T(repDoc1_copy !== null);
- T(repDoc1_copy.source === repDoc1.source);
- T(repDoc1_copy.target === repDoc1.target);
- T(repDoc1_copy._replication_state === "completed");
- T(typeof repDoc1_copy._replication_state_time === "string");
- T(typeof repDoc1_copy._replication_id === "string");
- T(typeof repDoc1_copy._replication_stats === "object", "doc has stats");
- var stats = repDoc1_copy._replication_stats;
- TEquals(docs1.length, stats.revisions_checked,
- "right # of revisions_checked");
- TEquals(docs1.length, stats.missing_revisions_found,
- "right # of missing_revisions_found");
- TEquals(docs1.length, stats.docs_read, "right # of docs_read");
- TEquals(docs1.length, stats.docs_written, "right # of docs_written");
- TEquals(0, stats.doc_write_failures, "right # of doc_write_failures");
- TEquals(dbA.info().update_seq, stats.checkpointed_source_seq,
- "right checkpointed_source_seq");
-
- var newDoc = {
- _id: "doc666",
- value: 666
- };
- T(dbA.save(newDoc).ok);
-
- wait(200);
- var newDoc_copy = dbB.open(newDoc._id);
- // not replicated because first replication is complete (not continuous)
- T(newDoc_copy === null);
-
- var repDoc2 = {
- _id: "foo_ident_rep_2",
- source: dbA.name,
- target: dbB.name
- };
- T(repDb.save(repDoc2).ok);
-
- waitForRep(repDb, repDoc2, "completed");
- var newDoc_copy = dbB.open(newDoc._id);
- T(newDoc_copy !== null);
- T(newDoc_copy.value === newDoc.value);
-
- var repDoc2_copy = repDb.open(repDoc2._id);
- T(repDoc2_copy !== null);
- T(repDoc2_copy.source === repDoc1.source);
- T(repDoc2_copy.target === repDoc1.target);
- T(repDoc2_copy._replication_state === "completed");
- T(typeof repDoc2_copy._replication_state_time === "string");
- T(typeof repDoc2_copy._replication_id === "string");
- T(repDoc2_copy._replication_id === repDoc1_copy._replication_id);
- T(typeof repDoc2_copy._replication_stats === "object", "doc has stats");
- stats = repDoc2_copy._replication_stats;
- TEquals(1, stats.revisions_checked, "right # of revisions_checked");
- TEquals(1, stats.missing_revisions_found,
- "right # of missing_revisions_found");
- TEquals(1, stats.docs_read, "right # of docs_read");
- TEquals(1, stats.docs_written, "right # of docs_written");
- TEquals(0, stats.doc_write_failures, "right # of doc_write_failures");
- TEquals(dbA.info().update_seq, stats.checkpointed_source_seq,
- "right checkpointed_source_seq");
- }
-
- var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- }
- ];
-
- repDb.deleteDb();
- run_on_modified_server(server_config, successive_identical_replications);
-
- // cleanup
- repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
-} \ No newline at end of file
diff --git a/test/javascript/tests/replicator_db_survives.js b/test/javascript/tests/replicator_db_survives.js
deleted file mode 100644
index e44156d54..000000000
--- a/test/javascript/tests/replicator_db_survives.js
+++ /dev/null
@@ -1,126 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_survives = function(debug) {
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- var repDb = replicator_db.repDb;
- var usersDb = replicator_db.usersDb;
- var wait = replicator_db.wait;
- var waitForRep = replicator_db.waitForRep;
- var waitForSeq = replicator_db.waitForSeq;
- var waitForDocPos = replicator_db.waitForDocPos;
- var wait_rep_doc = replicator_db.wait_rep_doc;
-
- function continuous_replication_survives_restart() {
- var origRepDbName = CouchDB.request(
- "GET", "/_config/replicator/db").responseText;
-
- repDb.deleteDb();
-
- var xhr = CouchDB.request("PUT", "/_config/replicator/db", {
- body : JSON.stringify(repDb.name),
- headers: {"X-Couch-Persist": "false"}
- });
- T(xhr.status === 200);
-
- populate_db(dbA, docs1);
- populate_db(dbB, []);
-
- var repDoc = {
- _id: "foo_cont_rep_survives_doc",
- source: dbA.name,
- target: dbB.name,
- continuous: true
- };
-
- T(repDb.save(repDoc).ok);
-
- waitForSeq(dbA, dbB);
- for (var i = 0; i < docs1.length; i++) {
- var doc = docs1[i];
- var copy = dbB.open(doc._id);
- T(copy !== null);
- T(copy.value === doc.value);
- }
-
- repDb.ensureFullCommit();
- dbA.ensureFullCommit();
-
- restartServer();
-
- xhr = CouchDB.request("PUT", "/_config/replicator/db", {
- body : JSON.stringify(repDb.name),
- headers: {"X-Couch-Persist": "false"}
- });
-
- T(xhr.status === 200);
-
- // add another doc to source, it will be replicated to target
- var docX = {
- _id: "foo1000",
- value: 1001
- };
-
- T(dbA.save(docX).ok);
-
- waitForSeq(dbA, dbB);
- var copy = dbB.open("foo1000");
- T(copy !== null);
- T(copy.value === 1001);
-
- repDoc = waitForDocPos(repDb, "foo_cont_rep_survives_doc", 3);
- T(repDoc !== null);
- T(repDoc.continuous === true);
-
- // stop replication
- T(repDb.deleteDoc(repDoc).ok);
-
- xhr = CouchDB.request("PUT", "/_config/replicator/db", {
- body : origRepDbName,
- headers: {"X-Couch-Persist": "false"}
- });
- T(xhr.status === 200);
- }
-
- var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- },
- {
- section: "couch_httpd_auth",
- key: "authentication_db",
- value: usersDb.name
- }
- ];
-
- repDb.deleteDb();
- run_on_modified_server(server_config, continuous_replication_survives_restart);
-
- // cleanup
- repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
- usersDb.deleteDb();
-}
diff --git a/test/javascript/tests/replicator_db_swap_rep_db.js b/test/javascript/tests/replicator_db_swap_rep_db.js
deleted file mode 100644
index 4eac484c2..000000000
--- a/test/javascript/tests/replicator_db_swap_rep_db.js
+++ /dev/null
@@ -1,170 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_swap_rep_db = function(debug) {
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- var repDb = replicator_db.repDb;
- var usersDb = replicator_db.usersDb;
- var wait = replicator_db.wait;
- var waitForRep = replicator_db.waitForRep;
- var waitForSeq = replicator_db.waitForSeq;
- var wait_rep_doc = replicator_db.wait_rep_doc;
-
- function swap_rep_db() {
- var repDb2 = new CouchDB("test_suite_rep_db_2");
- var dbA = new CouchDB("test_suite_rep_db_a");
- var dbA_copy = new CouchDB("test_suite_rep_db_a_copy");
- var dbB = new CouchDB("test_suite_rep_db_b");
- var dbB_copy = new CouchDB("test_suite_rep_db_b_copy");
- var dbC = new CouchDB("test_suite_rep_db_c");
- var dbC_copy = new CouchDB("test_suite_rep_db_c_copy");
- var repDoc1, repDoc2, repDoc3;
- var xhr, i, doc, copy, new_doc;
-
- populate_db(dbA, docs1);
- populate_db(dbB, docs1);
- populate_db(dbC, docs1);
- populate_db(dbA_copy, []);
- populate_db(dbB_copy, []);
- populate_db(dbC_copy, []);
- populate_db(repDb2, []);
-
- repDoc1 = {
- _id: "rep1",
- source: CouchDB.protocol + CouchDB.host + "/" + dbA.name,
- target: dbA_copy.name,
- continuous: true
- };
- repDoc2 = {
- _id: "rep2",
- source: CouchDB.protocol + CouchDB.host + "/" + dbB.name,
- target: dbB_copy.name,
- continuous: true
- };
- repDoc3 = {
- _id: "rep3",
- source: CouchDB.protocol + CouchDB.host + "/" + dbC.name,
- target: dbC_copy.name,
- continuous: true
- };
-
- TEquals(true, repDb.save(repDoc1).ok);
- TEquals(true, repDb.save(repDoc2).ok);
-
- waitForSeq(dbA, dbA_copy);
- waitForSeq(dbB, dbB_copy);
-
- xhr = CouchDB.request("PUT", "/_config/replicator/db",{
- body : JSON.stringify(repDb2.name),
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status);
-
- // Temporary band-aid, give the replicator db some
- // time to make the switch
- wait(500);
-
- new_doc = {
- _id: "foo666",
- value: 666
- };
-
- TEquals(true, dbA.save(new_doc).ok);
- TEquals(true, dbB.save(new_doc).ok);
- waitForSeq(dbA, dbA_copy);
- waitForSeq(dbB, dbB_copy);
-
- TEquals(true, repDb2.save(repDoc3).ok);
- waitForSeq(dbC, dbC_copy);
-
- for (i = 0; i < docs1.length; i++) {
- doc = docs1[i];
- copy = dbA_copy.open(doc._id);
- T(copy !== null);
- TEquals(doc.value, copy.value);
- copy = dbB_copy.open(doc._id);
- T(copy !== null);
- TEquals(doc.value, copy.value);
- copy = dbC_copy.open(doc._id);
- T(copy !== null);
- TEquals(doc.value, copy.value);
- }
-
- // replications rep1 and rep2 should have been stopped when the replicator
- // database was swapped
- copy = dbA_copy.open(new_doc._id);
- TEquals(null, copy);
- copy = dbB_copy.open(new_doc._id);
- TEquals(null, copy);
-
- xhr = CouchDB.request("PUT", "/_config/replicator/db",{
- body : JSON.stringify(repDb.name),
- headers: {"X-Couch-Persist": "false"}
- });
- TEquals(200, xhr.status);
-
- // after setting the replicator database to the former, replications rep1
- // and rep2 should have been resumed, while rep3 was stopped
- TEquals(true, dbC.save(new_doc).ok);
- wait(1000);
-
- waitForSeq(dbA, dbA_copy);
- waitForSeq(dbB, dbB_copy);
-
- copy = dbA_copy.open(new_doc._id);
- T(copy !== null);
- TEquals(new_doc.value, copy.value);
- copy = dbB_copy.open(new_doc._id);
- T(copy !== null);
- TEquals(new_doc.value, copy.value);
- copy = dbC_copy.open(new_doc._id);
- TEquals(null, copy);
- }
- var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- },
- {
- section: "couch_httpd_auth",
- key: "authentication_db",
- value: usersDb.name
- }
- ];
-
- repDb.deleteDb();
- run_on_modified_server(server_config, swap_rep_db);
-
- // cleanup
- repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
- usersDb.deleteDb();
- (new CouchDB("test_suite_rep_db_2")).deleteDb();
- (new CouchDB("test_suite_rep_db_c")).deleteDb();
- (new CouchDB("test_suite_rep_db_a_copy")).deleteDb();
- (new CouchDB("test_suite_rep_db_b_copy")).deleteDb();
- (new CouchDB("test_suite_rep_db_c_copy")).deleteDb();
-
-} \ No newline at end of file
diff --git a/test/javascript/tests/replicator_db_update_security.js b/test/javascript/tests/replicator_db_update_security.js
deleted file mode 100644
index 73c28f93d..000000000
--- a/test/javascript/tests/replicator_db_update_security.js
+++ /dev/null
@@ -1,92 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_update_security = function(debug) {
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- var repDb = replicator_db.repDb;
- var usersDb = replicator_db.usersDb;
- var wait = replicator_db.wait;
- var waitForRep = replicator_db.waitForRep;
- var waitForSeq = replicator_db.waitForSeq;
- var wait_rep_doc = replicator_db.wait_rep_doc;
-
- function test_rep_db_update_security() {
- var dbA_copy = new CouchDB("test_suite_rep_db_a_copy");
- var dbB_copy = new CouchDB("test_suite_rep_db_b_copy");
- var repDoc1, repDoc2;
- var xhr, i, doc, copy, new_doc;
- var docs = makeDocs(1, 3);
-
- populate_db(dbA, docs);
- populate_db(dbB, docs);
- populate_db(dbA_copy, []);
- populate_db(dbB_copy, []);
-
- repDoc1 = {
- _id: "rep1",
- source: CouchDB.protocol + CouchDB.host + "/" + dbA.name,
- target: dbA_copy.name
- };
- repDoc2 = {
- _id: "rep2",
- source: CouchDB.protocol + CouchDB.host + "/" + dbB.name,
- target: dbB_copy.name
- };
-
- TEquals(true, repDb.save(repDoc1).ok);
- waitForRep(repDb, repDoc1, "completed");
-
- T(repDb.setSecObj({
- readers: {
- names: ["joe"]
- }
- }).ok);
-
- TEquals(true, repDb.save(repDoc2).ok);
- waitForRep(repDb, repDoc2, "completed");
- }
-
- var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- },
- {
- section: "couch_httpd_auth",
- key: "authentication_db",
- value: usersDb.name
- }
- ];
-
- repDb.deleteDb();
- run_on_modified_server(server_config, test_rep_db_update_security);
-
- // cleanup
- repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
- usersDb.deleteDb();
- (new CouchDB("test_suite_rep_db_a_copy")).deleteDb();
- (new CouchDB("test_suite_rep_db_b_copy")).deleteDb();
-} \ No newline at end of file
diff --git a/test/javascript/tests/replicator_db_user_ctx.js b/test/javascript/tests/replicator_db_user_ctx.js
deleted file mode 100644
index 06ca78139..000000000
--- a/test/javascript/tests/replicator_db_user_ctx.js
+++ /dev/null
@@ -1,272 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_user_ctx = function(debug) {
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- var repDb = replicator_db.repDb;
- var usersDb = replicator_db.usersDb;
- var wait = replicator_db.wait;
- var waitForRep = replicator_db.waitForRep;
- var waitForSeq = replicator_db.waitForSeq;
- var wait_rep_doc = replicator_db.wait_rep_doc;
-
- function test_user_ctx_validation() {
- populate_db(dbA, docs1);
- populate_db(dbB, []);
- populate_db(usersDb, []);
-
- var joeUserDoc = CouchDB.prepareUserDoc({
- name: "joe",
- roles: ["erlanger", "bar"]
- }, "erly");
- var fdmananaUserDoc = CouchDB.prepareUserDoc({
- name: "fdmanana",
- roles: ["a", "b", "c"]
- }, "qwerty");
-
- TEquals(true, usersDb.save(joeUserDoc).ok);
- TEquals(true, usersDb.save(fdmananaUserDoc).ok);
-
- T(dbB.setSecObj({
- admins: {
- names: [],
- roles: ["god"]
- },
- readers: {
- names: [],
- roles: ["foo"]
- }
- }).ok);
-
- TEquals(true, CouchDB.login("joe", "erly").ok);
- TEquals("joe", CouchDB.session().userCtx.name);
- TEquals(-1, CouchDB.session().userCtx.roles.indexOf("_admin"));
-
- var repDoc = {
- _id: "foo_rep",
- source: CouchDB.protocol + CouchDB.host + "/" + dbA.name,
- target: dbB.name
- };
-
- try {
- repDb.save(repDoc);
- T(false, "Should have failed, user_ctx missing.");
- } catch (x) {
- TEquals("forbidden", x.error);
- }
-
- repDoc.user_ctx = {
- name: "john",
- roles: ["erlanger"]
- };
-
- try {
- repDb.save(repDoc);
- T(false, "Should have failed, wrong user_ctx.name.");
- } catch (x) {
- TEquals("forbidden", x.error);
- }
-
- repDoc.user_ctx = {
- name: "joe",
- roles: ["bar", "god", "erlanger"]
- };
-
- try {
- repDb.save(repDoc);
- T(false, "Should have failed, a bad role in user_ctx.roles.");
- } catch (x) {
- TEquals("forbidden", x.error);
- }
-
- // user_ctx.roles might contain only a subset of the user's roles
- repDoc.user_ctx = {
- name: "joe",
- roles: ["erlanger"]
- };
-
- TEquals(true, repDb.save(repDoc).ok);
- CouchDB.logout();
-
- waitForRep(repDb, repDoc, "error");
- var repDoc1 = repDb.open(repDoc._id);
- T(repDoc1 !== null);
- TEquals(repDoc.source, repDoc1.source);
- TEquals(repDoc.target, repDoc1.target);
- TEquals("error", repDoc1._replication_state);
- TEquals("string", typeof repDoc1._replication_id);
- TEquals("string", typeof repDoc1._replication_state_time);
-
- TEquals(true, CouchDB.login("fdmanana", "qwerty").ok);
- TEquals("fdmanana", CouchDB.session().userCtx.name);
- TEquals(-1, CouchDB.session().userCtx.roles.indexOf("_admin"));
-
- try {
- T(repDb.deleteDoc(repDoc1).ok);
- T(false, "Shouldn't be able to delete replication document.");
- } catch (x) {
- TEquals("forbidden", x.error);
- }
-
- CouchDB.logout();
- TEquals(true, CouchDB.login("joe", "erly").ok);
- TEquals("joe", CouchDB.session().userCtx.name);
- TEquals(-1, CouchDB.session().userCtx.roles.indexOf("_admin"));
-
- T(repDb.deleteDoc(repDoc1).ok);
- CouchDB.logout();
-
- for (var i = 0; i < docs1.length; i++) {
- var doc = docs1[i];
- var copy = dbB.open(doc._id);
-
- TEquals(null, copy);
- }
-
- T(dbB.setSecObj({
- admins: {
- names: [],
- roles: ["god", "erlanger"]
- },
- readers: {
- names: [],
- roles: ["foo"]
- }
- }).ok);
-
- TEquals(true, CouchDB.login("joe", "erly").ok);
- TEquals("joe", CouchDB.session().userCtx.name);
- TEquals(-1, CouchDB.session().userCtx.roles.indexOf("_admin"));
-
- repDoc = {
- _id: "foo_rep_2",
- source: CouchDB.protocol + CouchDB.host + "/" + dbA.name,
- target: dbB.name,
- user_ctx: {
- name: "joe",
- roles: ["erlanger"]
- }
- };
-
- TEquals(true, repDb.save(repDoc).ok);
- CouchDB.logout();
-
- waitForRep(repDb, repDoc, "complete");
- repDoc1 = repDb.open(repDoc._id);
- T(repDoc1 !== null);
- TEquals(repDoc.source, repDoc1.source);
- TEquals(repDoc.target, repDoc1.target);
- TEquals("completed", repDoc1._replication_state);
- TEquals("string", typeof repDoc1._replication_id);
- TEquals("string", typeof repDoc1._replication_state_time);
-
- for (var i = 0; i < docs1.length; i++) {
- var doc = docs1[i];
- var copy = dbB.open(doc._id);
-
- T(copy !== null);
- TEquals(doc.value, copy.value);
- }
-
- // Admins don't need to supply a user_ctx property in replication docs.
- // If they do not, the implicit user_ctx "user_ctx": {name: null, roles: []}
- // is used, meaning that design documents will not be replicated into
- // local targets
- T(dbB.setSecObj({
- admins: {
- names: [],
- roles: []
- },
- readers: {
- names: [],
- roles: []
- }
- }).ok);
-
- var ddoc = { _id: "_design/foo" };
- TEquals(true, dbA.save(ddoc).ok);
-
- repDoc = {
- _id: "foo_rep_3",
- source: CouchDB.protocol + CouchDB.host + "/" + dbA.name,
- target: dbB.name
- };
-
- TEquals(true, repDb.save(repDoc).ok);
- waitForRep(repDb, repDoc, "complete");
- repDoc1 = repDb.open(repDoc._id);
- T(repDoc1 !== null);
- TEquals(repDoc.source, repDoc1.source);
- TEquals(repDoc.target, repDoc1.target);
- TEquals("completed", repDoc1._replication_state);
- TEquals("string", typeof repDoc1._replication_id);
- TEquals("string", typeof repDoc1._replication_state_time);
-
- var ddoc_copy = dbB.open(ddoc._id);
- T(ddoc_copy === null);
-
- repDoc = {
- _id: "foo_rep_4",
- source: CouchDB.protocol + CouchDB.host + "/" + dbA.name,
- target: dbB.name,
- user_ctx: {
- roles: ["_admin"]
- }
- };
-
- TEquals(true, repDb.save(repDoc).ok);
- waitForRep(repDb, repDoc, "complete");
- repDoc1 = repDb.open(repDoc._id);
- T(repDoc1 !== null);
- TEquals(repDoc.source, repDoc1.source);
- TEquals(repDoc.target, repDoc1.target);
- TEquals("completed", repDoc1._replication_state);
- TEquals("string", typeof repDoc1._replication_id);
- TEquals("string", typeof repDoc1._replication_state_time);
-
- ddoc_copy = dbB.open(ddoc._id);
- T(ddoc_copy !== null);
- }
-
- var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- },
- {
- section: "couch_httpd_auth",
- key: "authentication_db",
- value: usersDb.name
- }
- ];
-
- repDb.deleteDb();
- run_on_modified_server(server_config, test_user_ctx_validation);
-
- // cleanup
- repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
- usersDb.deleteDb();
-} \ No newline at end of file
diff --git a/test/javascript/tests/replicator_db_write_auth.js b/test/javascript/tests/replicator_db_write_auth.js
deleted file mode 100644
index 2ac27c235..000000000
--- a/test/javascript/tests/replicator_db_write_auth.js
+++ /dev/null
@@ -1,102 +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.
-
-couchTests.skip = true;
-couchTests.replicator_db_survives = function(debug) {
- if (debug) debugger;
-
- var populate_db = replicator_db.populate_db;
- var docs1 = replicator_db.docs1;
- var dbA = replicator_db.dbA;
- var dbB = replicator_db.dbB;
- var repDb = replicator_db.repDb;
- var usersDb = replicator_db.usersDb;
- var wait = replicator_db.wait;
- var waitForRep = replicator_db.waitForRep;
- var waitForSeq = replicator_db.waitForSeq;
- var waitForDocPos = replicator_db.waitForDocPos;
- var wait_rep_doc = replicator_db.wait_rep_doc;
-
- function rep_db_write_authorization() {
- populate_db(dbA, docs1);
- populate_db(dbB, []);
-
- var server_admins_config = [
- {
- section: "admins",
- key: "fdmanana",
- value: "qwerty"
- }
- ];
-
- run_on_modified_server(server_admins_config, function() {
- var repDoc = {
- _id: "foo_rep_doc",
- source: dbA.name,
- target: dbB.name,
- continuous: true
- };
-
- T(CouchDB.login("fdmanana", "qwerty").ok);
- T(CouchDB.session().userCtx.name === "fdmanana");
- T(CouchDB.session().userCtx.roles.indexOf("_admin") !== -1);
-
- T(repDb.save(repDoc).ok);
-
- waitForRep(repDb, repDoc, "completed");
-
- for (var i = 0; i < docs1.length; i++) {
- var doc = docs1[i];
- var copy = dbB.open(doc._id);
-
- T(copy !== null);
- T(copy.value === doc.value);
- }
-
- repDoc = repDb.open("foo_rep_doc");
- T(repDoc !== null);
- repDoc.target = "test_suite_foo_db";
- repDoc.create_target = true;
-
- // Only the replicator can update replication documents.
- // Admins can only add and delete replication documents.
- try {
- repDb.save(repDoc);
- T(false && "Should have thrown an exception");
- } catch (x) {
- T(x["error"] === "forbidden");
- }
- });
- }
-
- var server_config = [
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "replicator",
- key: "db",
- value: repDb.name
- }
- ];
-
- repDb.deleteDb();
- run_on_modified_server(server_config, rep_db_write_authorization);
-
- // cleanup
- repDb.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
- usersDb.deleteDb();
-} \ No newline at end of file
diff --git a/test/javascript/tests/rev_stemming.js b/test/javascript/tests/rev_stemming.js
deleted file mode 100644
index 725c0f1c9..000000000
--- a/test/javascript/tests/rev_stemming.js
+++ /dev/null
@@ -1,124 +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.
-
-couchTests.elixir = true;
-couchTests.rev_stemming = function(debug) {
-
- var db_name_orig = get_random_db_name();
- var db_orig = new CouchDB(db_name_orig, {"X-CouchDB-Full-Commit": "false"});
- db_orig.createDb();
-
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
-
- var db_name_b = get_random_db_name();
- var dbB = new CouchDB(db_name_b, {"X-Couch-Full-Commit":"false"});
-
- db.createDb();
- dbB.createDb();
-
- if (debug) debugger;
-
- var newLimit = 5;
-
- T(db.getDbProperty("_revs_limit") == 1000);
-
-/*
- // Make an invalid request to _revs_limit
- // Should return 400
- /// XXX: Currently returns 500
- var xhr = CouchDB.request("PUT", "/" + db.name + "/_revs_limit", {body:"\"foo\""});
- T(xhr.status == 400);
- var result = JSON.parse(xhr.responseText);
- T(result.error == "bad_request");
- T(result.reason == "Rev limit has to be an integer");
-*/
-
- var doc = {_id:"foo",foo:0}
- for( var i=0; i < newLimit + 1; i++) {
- doc.foo++;
- T(db.save(doc).ok);
- }
- var doc0 = db.open("foo", {revs:true});
- T(doc0._revisions.ids.length == newLimit + 1);
-
- var docBar = {_id:"bar",foo:0}
- for( var i=0; i < newLimit + 1; i++) {
- docBar.foo++;
- T(db.save(docBar).ok);
- }
- T(db.open("bar", {revs:true})._revisions.ids.length == newLimit + 1);
-
- T(db.setDbProperty("_revs_limit", newLimit).ok);
-
- for( var i=0; i < newLimit + 1; i++) {
- doc.foo++;
- T(db.save(doc).ok);
- }
- doc0 = db.open("foo", {revs:true});
- T(doc0._revisions.ids.length == newLimit);
-
-
- // If you replicate after you make more edits than the limit, you'll
- // cause a spurious edit conflict.
- CouchDB.replicate(db.name, dbB.name);
- var docB1 = dbB.open("foo",{conflicts:true})
- T(docB1._conflicts == null);
-
- for( var i=0; i < newLimit - 1; i++) {
- doc.foo++;
- T(db.save(doc).ok);
- }
-
- // one less edit than limit, no conflict
- CouchDB.replicate(db.name, dbB.name);
- var docB1 = dbB.open("foo",{conflicts:true})
- T(docB1._conflicts == null);
-
- //now we hit the limit
- for( var i=0; i < newLimit; i++) {
- doc.foo++;
- T(db.save(doc).ok);
- }
-
- CouchDB.replicate(db.name, dbB.name);
-
- var docB2 = dbB.open("foo",{conflicts:true});
-
- // we have a conflict, but the previous replicated rev is always the losing
- // conflict
- T(docB2._conflicts[0] == docB1._rev)
-
- // We having already updated bar before setting the limit, so it's still got
- // a long rev history. compact to stem the revs.
-
- T(db.open("bar", {revs:true})._revisions.ids.length == newLimit);
-
- T(db.compact().ok);
-
- // compaction isn't instantaneous, loop until done
- while (db.info().compact_running) {};
-
- // force reload because ETags don't honour compaction
- var req = db.request("GET", "/" + db.name + "/bar?revs=true", {
- headers:{"if-none-match":"pommes"}
- });
-
- var finalDoc = JSON.parse(req.responseText);
- TEquals(newLimit, finalDoc._revisions.ids.length,
- "should return a truncated revision list");
-
- // cleanup
- db_orig.deleteDb();
- db.deleteDb();
- dbB.deleteDb();
-};
diff --git a/test/javascript/tests/rewrite.js b/test/javascript/tests/rewrite.js
deleted file mode 100644
index a984936d1..000000000
--- a/test/javascript/tests/rewrite.js
+++ /dev/null
@@ -1,513 +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.
-
-
-
-couchTests.rewrite = function(debug) {
- if (debug) debugger;
- var dbNames = ["test_suite_db", "test_suite_db/with_slashes"];
- for (var i=0; i < dbNames.length; i++) {
- var db = new CouchDB(dbNames[i]);
- var dbName = encodeURIComponent(dbNames[i]);
- db.deleteDb();
- db.createDb();
-
-
- run_on_modified_server(
- [{section: "httpd",
- key: "authentication_handlers",
- value: "{couch_httpd_auth, special_test_authentication_handler}"},
- {section:"httpd",
- key: "WWW-Authenticate",
- value: "X-Couch-Test-Auth"}],
-
- function(){
- var designDoc = {
- _id:"_design/test",
- language: "javascript",
- _attachments:{
- "foo.txt": {
- content_type:"text/plain",
- data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
- }
- },
- rewrites: [
- {
- "from": "foo",
- "to": "foo.txt"
- },
- {
- "from": "foo2",
- "to": "foo.txt",
- "method": "GET"
- },
- {
- "from": "hello/:id",
- "to": "_update/hello/:id",
- "method": "PUT"
- },
- {
- "from": "/welcome",
- "to": "_show/welcome"
- },
- {
- "from": "/welcome/:name",
- "to": "_show/welcome",
- "query": {
- "name": ":name"
- }
- },
- {
- "from": "/welcome2",
- "to": "_show/welcome",
- "query": {
- "name": "user"
- }
- },
- {
- "from": "/welcome3/:name",
- "to": "_update/welcome2/:name",
- "method": "PUT"
- },
- {
- "from": "/welcome3/:name",
- "to": "_show/welcome2/:name",
- "method": "GET"
- },
- {
- "from": "/welcome4/*",
- "to" : "_show/welcome3",
- "query": {
- "name": "*"
- }
- },
- {
- "from": "/welcome5/*",
- "to" : "_show/*",
- "query": {
- "name": "*"
- }
- },
- {
- "from": "basicView",
- "to": "_view/basicView",
- },
- {
- "from": "simpleForm/basicView",
- "to": "_list/simpleForm/basicView",
- },
- {
- "from": "simpleForm/basicViewFixed",
- "to": "_list/simpleForm/basicView",
- "query": {
- "startkey": 3,
- "endkey": 8
- }
- },
- {
- "from": "simpleForm/basicViewPath/:start/:end",
- "to": "_list/simpleForm/basicView",
- "query": {
- "startkey": ":start",
- "endkey": ":end"
- },
- "formats": {
- "start": "int",
- "end": "int"
- }
- },
- {
- "from": "simpleForm/complexView",
- "to": "_list/simpleForm/complexView",
- "query": {
- "key": [1, 2]
- }
- },
- {
- "from": "simpleForm/complexView2",
- "to": "_list/simpleForm/complexView",
- "query": {
- "key": ["test", {}]
- }
- },
- {
- "from": "simpleForm/complexView3",
- "to": "_list/simpleForm/complexView",
- "query": {
- "key": ["test", ["test", "essai"]]
- }
- },
- {
- "from": "simpleForm/complexView4",
- "to": "_list/simpleForm/complexView2",
- "query": {
- "key": {"c": 1}
- }
- },
- {
- "from": "simpleForm/complexView5/:a/:b",
- "to": "_list/simpleForm/complexView3",
- "query": {
- "key": [":a", ":b"]
- }
- },
- {
- "from": "simpleForm/complexView6",
- "to": "_list/simpleForm/complexView3",
- "query": {
- "key": [":a", ":b"]
- }
- },
- {
- "from": "simpleForm/complexView7/:a/:b",
- "to": "_view/complexView3",
- "query": {
- "key": [":a", ":b"],
- "include_docs": ":doc"
- },
- "format": {
- "doc": "bool"
- }
-
- },
- {
- "from": "/",
- "to": "_view/basicView",
- },
- {
- "from": "/db/*",
- "to": "../../*"
- }
- ],
- lists: {
- simpleForm: stringFun(function(head, req) {
- log("simpleForm");
- send('<ul>');
- var row, row_number = 0, prevKey, firstKey = null;
- while (row = getRow()) {
- row_number += 1;
- if (!firstKey) firstKey = row.key;
- prevKey = row.key;
- send('\n<li>Key: '+row.key
- +' Value: '+row.value
- +' LineNo: '+row_number+'</li>');
- }
- return '</ul><p>FirstKey: '+ firstKey + ' LastKey: '+ prevKey+'</p>';
- }),
- },
- shows: {
- "welcome": stringFun(function(doc,req) {
- return "Welcome " + req.query["name"];
- }),
- "welcome2": stringFun(function(doc, req) {
- return "Welcome " + doc.name;
- }),
- "welcome3": stringFun(function(doc,req) {
- return "Welcome " + req.query["name"];
- })
- },
- updates: {
- "hello" : stringFun(function(doc, req) {
- if (!doc) {
- if (req.id) {
- return [{
- _id : req.id
- }, "New World"]
- }
- return [null, "Empty World"];
- }
- doc.world = "hello";
- doc.edited_by = req.userCtx;
- return [doc, "hello doc"];
- }),
- "welcome2": stringFun(function(doc, req) {
- if (!doc) {
- if (req.id) {
- return [{
- _id: req.id,
- name: req.id
- }, "New World"]
- }
- return [null, "Empty World"];
- }
- return [doc, "hello doc"];
- })
- },
- views : {
- basicView : {
- map : stringFun(function(doc) {
- if (doc.integer) {
- emit(doc.integer, doc.string);
- }
-
- })
- },
- complexView: {
- map: stringFun(function(doc) {
- if (doc.type == "complex") {
- emit([doc.a, doc.b], doc.string);
- }
- })
- },
- complexView2: {
- map: stringFun(function(doc) {
- if (doc.type == "complex") {
- emit(doc.a, doc.string);
- }
- })
- },
- complexView3: {
- map: stringFun(function(doc) {
- if (doc.type == "complex") {
- emit(doc.b, doc.string);
- }
- })
- }
- }
- }
-
- db.save(designDoc);
-
- var docs = makeDocs(0, 10);
- db.bulkSave(docs);
-
- var docs2 = [
- {"a": 1, "b": 1, "string": "doc 1", "type": "complex"},
- {"a": 1, "b": 2, "string": "doc 2", "type": "complex"},
- {"a": "test", "b": {}, "string": "doc 3", "type": "complex"},
- {"a": "test", "b": ["test", "essai"], "string": "doc 4", "type": "complex"},
- {"a": {"c": 1}, "b": "", "string": "doc 5", "type": "complex"}
- ];
-
- db.bulkSave(docs2);
-
- // test simple rewriting
-
- req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/foo");
- T(req.responseText == "This is a base64 encoded text");
- T(req.getResponseHeader("Content-Type") == "text/plain");
-
- req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/foo2");
- T(req.responseText == "This is a base64 encoded text");
- T(req.getResponseHeader("Content-Type") == "text/plain");
-
-
- // test POST
- // hello update world
-
- var doc = {"word":"plankton", "name":"Rusty"}
- var resp = db.save(doc);
- T(resp.ok);
- var docid = resp.id;
-
- xhr = CouchDB.request("PUT", "/"+dbName+"/_design/test/_rewrite/hello/"+docid);
- T(xhr.status == 201);
- T(xhr.responseText == "hello doc");
- T(/charset=utf-8/.test(xhr.getResponseHeader("Content-Type")))
-
- doc = db.open(docid);
- T(doc.world == "hello");
-
- req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome?name=user");
- T(req.responseText == "Welcome user");
-
- req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome/user");
- T(req.responseText == "Welcome user");
-
- req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome2");
- T(req.responseText == "Welcome user");
-
- xhr = CouchDB.request("PUT", "/"+dbName+"/_design/test/_rewrite/welcome3/test");
- T(xhr.status == 201);
- T(xhr.responseText == "New World");
- T(/charset=utf-8/.test(xhr.getResponseHeader("Content-Type")));
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome3/test");
- T(xhr.responseText == "Welcome test");
-
-/* // XXX: THESE ARE BUGGED and I don't know what the right response is
- req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome4/user");
- T(req.responseText == "Welcome user", req.responseText);
-
- req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome5/welcome3");
- T(req.responseText == "Welcome welcome3", req.responseText);
-*/
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/basicView");
- T(xhr.status == 200, "view call");
- T(/{"total_rows":9/.test(xhr.responseText));
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/");
- T(xhr.status == 200, "view call");
- T(/{"total_rows":9/.test(xhr.responseText));
-
-
- // get with query params
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/basicView?startkey=3&endkey=8");
- T(xhr.status == 200, "with query params");
- T(!(/Key: 1/.test(xhr.responseText)));
- T(/FirstKey: 3/.test(xhr.responseText));
- T(/LastKey: 8/.test(xhr.responseText));
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/basicViewFixed");
- T(xhr.status == 200, "with query params");
- T(!(/Key: 1/.test(xhr.responseText)));
- T(/FirstKey: 3/.test(xhr.responseText));
- T(/LastKey: 8/.test(xhr.responseText));
-
- // get with query params
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/basicViewFixed?startkey=4");
- T(xhr.status == 200, "with query params");
- T(!(/Key: 1/.test(xhr.responseText)));
- T(/FirstKey: 3/.test(xhr.responseText));
- T(/LastKey: 8/.test(xhr.responseText));
-
- // get with query params
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/basicViewPath/3/8");
- T(xhr.status == 200, "with query params");
- T(!(/Key: 1/.test(xhr.responseText)));
- T(/FirstKey: 3/.test(xhr.responseText));
- T(/LastKey: 8/.test(xhr.responseText));
-
- // get with query params
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView");
- T(xhr.status == 200, "with query params");
- T(/FirstKey: [1, 2]/.test(xhr.responseText));
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView2");
- T(xhr.status == 200, "with query params");
- T(/Value: doc 3/.test(xhr.responseText));
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView3");
- T(xhr.status == 200, "with query params");
- T(/Value: doc 4/.test(xhr.responseText));
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView4");
- T(xhr.status == 200, "with query params");
- T(/Value: doc 5/.test(xhr.responseText));
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView5/test/essai");
- T(xhr.status == 200, "with query params");
- T(/Value: doc 4/.test(xhr.responseText));
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView6?a=test&b=essai");
- T(xhr.status == 200, "with query params");
- T(/Value: doc 4/.test(xhr.responseText));
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView7/test/essai?doc=true");
- T(xhr.status == 200, "with query params");
- var result = JSON.parse(xhr.responseText);
- T(typeof(result.rows[0].doc) === "object");
-
- // COUCHDB-2031 - path normalization versus qs params
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/db/_design/test?meta=true");
- T(xhr.status == 200, "path normalization works with qs params");
- var result = JSON.parse(xhr.responseText);
- T(result['_id'] == "_design/test");
- T(typeof(result['_revs_info']) === "object");
-
- // test path relative to server
- T(db.save({
- _id: "_design/test2",
- rewrites: [{
- "from": "uuids",
- "to": "../../../_uuids"
- }]
- }).ok);
-
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design/test2/_rewrite/uuids");
- T(xhr.status == 500);
- var result = JSON.parse(xhr.responseText);
- T(result.error == "insecure_rewrite_rule");
-
- run_on_modified_server(
- [{section: "httpd",
- key: "secure_rewrites",
- value: "false"}],
- function() {
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design/test2/_rewrite/uuids?cache=bust");
- T(xhr.status == 200);
- var result = JSON.parse(xhr.responseText);
- T(result.uuids.length == 1);
- var first = result.uuids[0];
- });
- });
-
-/* // XXX: we have actual failures here that we need to get to
- // test invalid rewrites
- // string
- var ddoc = {
- _id: "_design/invalid",
- rewrites: "[{\"from\":\"foo\",\"to\":\"bar\"}]"
- }
- db.save(ddoc);
- var res = CouchDB.request("GET", "/"+dbName+"/_design/invalid/_rewrite/foo");
- TEquals(400, res.status, "should return 400");
-
- var ddoc_requested_path = {
- _id: "_design/requested_path",
- rewrites:[
- {"from": "show", "to": "_show/origin/0"},
- {"from": "show_rewritten", "to": "_rewrite/show"}
- ],
- shows: {
- origin: stringFun(function(doc, req) {
- return req.headers["x-couchdb-requested-path"];
- })}
- };
-
- db.save(ddoc_requested_path);
- var url = "/"+dbName+"/_design/requested_path/_rewrite/show";
- var res = CouchDB.request("GET", url);
- TEquals(url, res.responseText, "should return the original url");
-
- var url = "/"+dbName+"/_design/requested_path/_rewrite/show_rewritten";
- var res = CouchDB.request("GET", url);
- TEquals(url, res.responseText, "returned the original url");
-*/
-
- var ddoc_loop = {
- _id: "_design/loop",
- rewrites: [{ "from": "loop", "to": "_rewrite/loop"}]
- };
- db.save(ddoc_loop);
-
- // Assert loop detection
- run_on_modified_server(
- [{section: "httpd",
- key: "rewrite_limit",
- value: "2"}],
- function(){
- var url = "/"+dbName+"/_design/loop/_rewrite/loop";
- var xhr = CouchDB.request("GET", url);
- TEquals(400, xhr.status);
- });
-
- // Assert serial execution is not spuriously counted as loop
- run_on_modified_server(
- [{section: "httpd",
- key: "rewrite_limit",
- value: "2"},
- {section: "httpd",
- key: "secure_rewrites",
- value: "false"}],
- function(){
- var url = "/"+dbName+"/_design/test/_rewrite/foo";
- for (var i=0; i < 5; i++) {
- var xhr = CouchDB.request("GET", url);
- TEquals(200, xhr.status);
- }
- });
- // cleanup
- db.deleteDb();
- }
-}
diff --git a/test/javascript/tests/rewrite_js.js b/test/javascript/tests/rewrite_js.js
deleted file mode 100644
index 22de6c940..000000000
--- a/test/javascript/tests/rewrite_js.js
+++ /dev/null
@@ -1,351 +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.
-
-
-
-couchTests.rewrite = function(debug) {
- if (debug) debugger;
- var dbNames = [get_random_db_name(), get_random_db_name() + "test_suite_db/with_slashes"];
- for (var i=0; i < dbNames.length; i++) {
- var db = new CouchDB(dbNames[i]);
- var dbName = encodeURIComponent(dbNames[i]);
- db.deleteDb();
- db.createDb();
-
- var designDoc = {
- _id:"_design/test",
- language: "javascript",
- _attachments:{
- "foo.txt": {
- content_type:"text/plain",
- data: "VGhpcyBpcyBhIGJhc2U2NCBlbmNvZGVkIHRleHQ="
- }
- },
- rewrites: stringFun(function(req) {
- prefix = req.path[4];
- if (prefix === 'foo') {
- return 'foo.txt';
- }
- if (prefix === 'foo2') {
- return {path: 'foo.txt', method: 'GET'};
- }
- if (prefix === 'hello') {
- if (req.method != 'PUT') {
- return
- }
- id = req.path[5];
- return {path: '_update/hello/' + id};
- }
- if (prefix === 'welcome') {
- if (req.path.length == 6){
- name = req.path[5];
- return {path: '_show/welcome', query: {'name': name}};
- }
- return '_show/welcome';
- }
- if (prefix === 'welcome2') {
- return {path: '_show/welcome', query: {'name': 'user'}};
- }
- if (prefix === 'welcome3') {
- name = req.path[5];
- if (req.method == 'PUT') {
- path = '_update/welcome2/' + name;
- } else if (req.method == 'GET') {
- path = '_show/welcome2/' + name;
- } else {
- return;
- }
- return path;
- }
- if (prefix === 'welcome4') {
- return {path: '_show/welcome3', query: {name: req.path[5]}};
- }
- if (prefix === 'welcome5') {
- rest = req.path.slice(5).join('/');
- return {path: '_show/' + rest, query: {name: rest}};
- }
- if (prefix === 'basicView') {
- rest = req.path.slice(5).join('/');
- return {path: '_view/basicView'};
- }
- if (req.path.slice(4).join('/') === 'simpleForm/basicView') {
- return {path: '_list/simpleForm/basicView'};
- }
- if (req.path.slice(4).join('/') === 'simpleForm/basicViewFixed') {
- return {path: '_list/simpleForm/basicView',
- query: {startkey: '"3"', endkey: '"8"'}};
- }
- if (req.path.slice(4).join('/') === 'simpleForm/complexView') {
- return {path: '_list/simpleForm/complexView',
- query: {key: JSON.stringify([1,2])}};
- }
- if (req.path.slice(4).join('/') === 'simpleForm/complexView2') {
- return {path: '_list/simpleForm/complexView',
- query: {key: JSON.stringify(['test', {}])}};
- }
- if (req.path.slice(4).join('/') === 'simpleForm/complexView3') {
- return {path: '_list/simpleForm/complexView',
- query: {key: JSON.stringify(['test', ['test', 'essai']])}};
- }
- if (req.path.slice(4).join('/') === 'simpleForm/complexView4') {
- return {path: '_list/simpleForm/complexView2',
- query: {key: JSON.stringify({"c": 1})}};
- }
- if (req.path.slice(4).join('/') === 'simpleForm/sendBody1') {
- return {path: '_list/simpleForm/complexView2',
- method: 'POST',
- query: {limit: '1'},
- headers:{'Content-type':'application/json'},
- body: JSON.stringify( {keys: [{"c": 1}]} )};
- }
- if (req.path.slice(4).join('/') === '/') {
- return {path: '_view/basicView'};
- }
- if (prefix === 'db') {
- return {path: '../../' + req.path.slice(5).join('/')};
- }
- }),
- lists: {
- simpleForm: stringFun(function(head, req) {
- log("simpleForm");
- send('<ul>');
- var row, row_number = 0, prevKey, firstKey = null;
- while (row = getRow()) {
- row_number += 1;
- if (!firstKey) firstKey = row.key;
- prevKey = row.key;
- send('\n<li>Key: '+row.key
- +' Value: '+row.value
- +' LineNo: '+row_number+'</li>');
- }
- return '</ul><p>FirstKey: '+ firstKey + ' LastKey: '+ prevKey+'</p>';
- }),
- },
- shows: {
- "welcome": stringFun(function(doc,req) {
- return "Welcome " + req.query["name"];
- }),
- "welcome2": stringFun(function(doc, req) {
- return "Welcome " + doc.name;
- }),
- "welcome3": stringFun(function(doc,req) {
- return "Welcome " + req.query["name"];
- })
- },
- updates: {
- "hello" : stringFun(function(doc, req) {
- if (!doc) {
- if (req.id) {
- return [{
- _id : req.id
- }, "New World"]
- }
- return [null, "Empty World"];
- }
- doc.world = "hello";
- doc.edited_by = req.userCtx;
- return [doc, "hello doc"];
- }),
- "welcome2": stringFun(function(doc, req) {
- if (!doc) {
- if (req.id) {
- return [{
- _id: req.id,
- name: req.id
- }, "New World"]
- }
- return [null, "Empty World"];
- }
- return [doc, "hello doc"];
- })
- },
- views : {
- basicView : {
- map : stringFun(function(doc) {
- if (doc.integer) {
- emit(doc.integer, doc.string);
- }
-
- })
- },
- complexView: {
- map: stringFun(function(doc) {
- if (doc.type == "complex") {
- emit([doc.a, doc.b], doc.string);
- }
- })
- },
- complexView2: {
- map: stringFun(function(doc) {
- if (doc.type == "complex") {
- emit(doc.a, doc.string);
- }
- })
- },
- complexView3: {
- map: stringFun(function(doc) {
- if (doc.type == "complex") {
- emit(doc.b, doc.string);
- }
- })
- }
- }
- }
-
- db.save(designDoc);
-
- var docs = makeDocs(0, 10);
- db.bulkSave(docs);
-
- var docs2 = [
- {"a": 1, "b": 1, "string": "doc 1", "type": "complex"},
- {"a": 1, "b": 2, "string": "doc 2", "type": "complex"},
- {"a": "test", "b": {}, "string": "doc 3", "type": "complex"},
- {"a": "test", "b": ["test", "essai"], "string": "doc 4", "type": "complex"},
- {"a": {"c": 1}, "b": "", "string": "doc 5", "type": "complex"}
- ];
-
- db.bulkSave(docs2);
-
- // test simple rewriting
-
- req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/foo");
- T(req.responseText == "This is a base64 encoded text");
- T(req.getResponseHeader("Content-Type") == "text/plain");
-
- req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/foo2");
- T(req.responseText == "This is a base64 encoded text");
- T(req.getResponseHeader("Content-Type") == "text/plain");
-
-
- // test POST
- // hello update world
-
- var doc = {"word":"plankton", "name":"Rusty"}
- var resp = db.save(doc);
- T(resp.ok);
- var docid = resp.id;
-
- xhr = CouchDB.request("PUT", "/"+dbName+"/_design/test/_rewrite/hello/"+docid);
- T(xhr.status == 201);
- T(xhr.responseText == "hello doc");
- T(/charset=utf-8/.test(xhr.getResponseHeader("Content-Type")))
-
- doc = db.open(docid);
- T(doc.world == "hello");
-
- req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome?name=user");
- T(req.responseText == "Welcome user");
-
- req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome/user");
- T(req.responseText == "Welcome user");
-
- req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome2");
- T(req.responseText == "Welcome user");
-
- xhr = CouchDB.request("PUT", "/"+dbName+"/_design/test/_rewrite/welcome3/test");
- T(xhr.status == 201);
- T(xhr.responseText == "New World");
- T(/charset=utf-8/.test(xhr.getResponseHeader("Content-Type")));
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome3/test");
- T(xhr.responseText == "Welcome test");
-
- req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome4/user");
- T(req.responseText == "Welcome user");
-
- req = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/welcome5/welcome3");
- T(req.responseText == "Welcome welcome3");
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/basicView");
- T(xhr.status == 200, "view call");
- T(/{"total_rows":9/.test(xhr.responseText));
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView");
- T(xhr.status == 200, "with query params");
- T(/FirstKey: [1, 2]/.test(xhr.responseText));
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView2");
- T(xhr.status == 200, "with query params");
- T(/Value: doc 3/.test(xhr.responseText));
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView3");
- T(xhr.status == 200, "with query params");
- T(/Value: doc 4/.test(xhr.responseText));
-
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/complexView4");
- T(xhr.status == 200, "with query params");
- T(/Value: doc 5/.test(xhr.responseText));
-
- // COUCHDB-1612 - send body rewriting get to post
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/simpleForm/sendBody1");
- T(xhr.status == 200, "get->post rewrite failed:\n"+xhr.responseText);
- T(/Value: doc 5 LineNo: 1/.test(xhr.responseText), "get->post rewrite responded wrong:\n"+xhr.responseText);
-
- // COUCHDB-2031 - path normalization versus qs params
- xhr = CouchDB.request("GET", "/"+dbName+"/_design/test/_rewrite/db/_design/test?meta=true");
- T(xhr.status == 200, "path normalization works with qs params");
- var result = JSON.parse(xhr.responseText);
- T(result['_id'] == "_design/test");
- T(typeof(result['_revs_info']) === "object");
-
- // test early response
- var ddoc = {
- _id: "_design/response",
- rewrites: stringFun(function(req){
- status = parseInt(req.query.status);
- return {code: status,
- body: JSON.stringify({"status": status}),
- headers: {'x-foo': 'bar', 'Content-Type': 'application/json'}};
- })
- }
- T(db.save(ddoc).ok);
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design/response/_rewrite?status=200");
- T(xhr.status == 200);
- T(xhr.headers['x-foo'] == 'bar');
- T(xhr.responseText == '{"status":200}');
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design/response/_rewrite?status=451");
- T(xhr.status == 451);
- T(xhr.headers['Content-Type'] == 'application/json');
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design/response/_rewrite?status=600");
- T(xhr.status == 500);
-
-
- // test path relative to server
- var ddoc = {
- _id: "_design/relative",
- rewrites: stringFun(function(req){
- return '../../../_uuids'
- })
- }
- T(db.save(ddoc).ok);
- var xhr = CouchDB.request("GET", "/"+dbName+"/_design/relative/_rewrite/uuids");
- T(xhr.status == 200);
- var result = JSON.parse(xhr.responseText);
- T(result.uuids.length == 1);
-
- // test loop
- var ddoc_loop = {
- _id: "_design/loop",
- rewrites: stringFun(function(req) {
- return '_rewrite/loop';
- })
- };
- db.save(ddoc_loop);
- var url = "/"+dbName+"/_design/loop/_rewrite/loop";
- var xhr = CouchDB.request("GET", url);
- TEquals(400, xhr.status);
-
- // cleanup
- db.deleteDb();
- }
-} \ No newline at end of file
diff --git a/test/javascript/tests/security_validation.js b/test/javascript/tests/security_validation.js
deleted file mode 100644
index 6f0bd0f42..000000000
--- a/test/javascript/tests/security_validation.js
+++ /dev/null
@@ -1,330 +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.
-
-couchTests.security_validation = function(debug) {
-
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- var authDb_name = get_random_db_name() + "_authdb";
- var authDb = new CouchDB(authDb_name, {"X-Couch-Full-Commit":"false"});
- authDb.createDb();
- var adminDbA, adminDbB; // used later
- if (debug) debugger;
-
- run_on_modified_server(
- [{section: "httpd",
- key: "authentication_handlers",
- value: "{couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler}"},
- {section: "couch_httpd_auth",
- key: "authentication_db", value: authDb_name},
- {section: "chttpd_auth",
- key: "authentication_db", value: authDb_name}],
-
- function () {
- // the special case handler does not exist (any longer) in clusters, so we have
- // to replicate the behavior using a "normal" DB even though tests might no more
- // run universally (why the "X-Couch-Test-Auth" header was introduced).
- // btw: this needs to be INSIDE configured server to propagate correctly ;-)
- // At least they'd run in the build, though
- T(authDb.save(CouchDB.prepareUserDoc({name: "tom"}, "cat")).ok); // Basic dG9tOmNhdA==
- T(authDb.save(CouchDB.prepareUserDoc({name: "jerry"}, "mouse")).ok); // Basic amVycnk6bW91c2U=
- T(authDb.save(CouchDB.prepareUserDoc({name: "spike"}, "dog")).ok); // Basic c3Bpa2U6ZG9n
- authDb.ensureFullCommit();
-
- // try saving document using the wrong credentials
- var wrongPasswordDb = new CouchDB(db_name + "",
- {"Authorization": "Basic c3Bpa2U6Y2F0"} // spike:cat - which is wrong
- );
-
- try {
- wrongPasswordDb.save({foo:1,author:"Damien Katz"});
- T(false, "Can't get here. Should have thrown an error 1");
- } catch (e) {
- T(e.error == "unauthorized");
- T(wrongPasswordDb.last_req.status == 401);
- }
-
- // test force basic login
- var resp = wrongPasswordDb.request("GET", "/_session?basic=true");
- var err = JSON.parse(resp.responseText);
- T(err.error == "unauthorized");
- T(resp.status == 401);
-
- // Create the design doc that will run custom validation code
- var designDoc = {
- _id:"_design/test",
- language: "javascript",
- validate_doc_update: stringFun(function (newDoc, oldDoc, userCtx, secObj) {
- if (secObj.admin_override) {
- if (userCtx.roles.indexOf('_admin') != -1) {
- // user is admin, they can do anything
- return true;
- }
- }
- // docs should have an author field.
- if (!newDoc._deleted && !newDoc.author) {
- throw {forbidden:
- "Documents must have an author field"};
- }
- if (oldDoc && oldDoc.author != userCtx.name) {
- throw {unauthorized:
- "You are '" + userCtx.name + "', not the author '" + oldDoc.author + "' of this document. You jerk."};
- }
- })
- }
-
- // Save a document normally
- var userDb = new CouchDB("" + db_name + "",
- {"Authorization": "Basic amVycnk6bW91c2U="} // jerry
- );
- // test session
- TEquals("jerry", JSON.parse(userDb.request("GET", "/_session").responseText).userCtx.name);
-
- T(userDb.save({_id:"testdoc", foo:1, author:"jerry"}).ok);
-
- // Attempt to save the design as a non-admin
- try {
- userDb.save(designDoc);
- T(false && "Can't get here. Should have thrown an error on design doc");
- } catch (e) {
- // cluster changes from 401 unauthorized to 403 forbidden
- TEquals("forbidden", e.error);
- TEquals(403, userDb.last_req.status);
- }
-
- // set user as the admin
- T(db.setSecObj({
- admins : {names : ["jerry"]}
- }).ok);
-
- // TODO: when _security is correctly honored (COUCHDB-2990), switch back
- //T(userDb.save(designDoc).ok);
- T(db.save(designDoc).ok);
-
- var user2Db = new CouchDB("" + db_name + "",
- {"Authorization": "Basic dG9tOmNhdA=="} // tom
- );
- // Attempt to save the design as a non-admin (in replication scenario)
- designDoc.foo = "bar";
- designDoc._rev = "2-642e20f96624a0aae6025b4dba0c6fb2";
- try {
- user2Db.save(designDoc, {new_edits : false});
- T(false && "Can't get here. Should have thrown an error on design doc");
- } catch (e) {
- // cluster changes from 401 unauthorized to 403 forbidden
- TEquals("forbidden", e.error);
- TEquals(403, userDb.last_req.status);
- }
-
- // test the _session API
- var resp = userDb.request("GET", "/_session");
- var user = JSON.parse(resp.responseText).userCtx;
- T(user.name == "jerry");
- // test that the roles are listed properly
- TEquals(user.roles, []);
-
-
- // update the document
- var doc = userDb.open("testdoc");
- doc.foo=2;
- T(userDb.save(doc).ok);
-
- // Save a document that's missing an author field (before and after compaction)
- for (var i=0; i<2; i++) {
- try {
- userDb.save({foo:1});
- T(false && "Can't get here. Should have thrown an error 2");
- } catch (e) {
- T(e.error == "forbidden");
- T(userDb.last_req.status == 403);
- }
- // compact. - no more available on clusters (but: test is still valid w/out compaction)
- /*T(db.compact().ok);
- T(db.last_req.status == 202);
- // compaction isn't instantaneous, loop until done
- while (db.info().compact_running) {};*/
- }
-
- // Now attempt to update the document as a different user, Jan
- var doc = user2Db.open("testdoc");
- doc.foo=3;
- try {
- user2Db.save(doc);
- T(false && "Can't get here. Should have thrown an error 3");
- } catch (e) {
- T(e.error == "unauthorized");
- T(user2Db.last_req.status == 401);
- }
-
- // Now have jerry change the author to tom
- doc = userDb.open("testdoc");
- doc.author="tom";
- T(userDb.save(doc).ok);
-
- // Now update the document as tom
- doc = user2Db.open("testdoc");
- doc.foo = 3;
- T(user2Db.save(doc).ok);
-
- // jerry can't delete it
- try {
- userDb.deleteDoc(doc);
- T(false && "Can't get here. Should have thrown an error 4");
- } catch (e) {
- T(e.error == "unauthorized");
- T(userDb.last_req.status == 401);
- }
-
- // admin must save with author field unless admin override
- var resp = db.request("GET", "/_session");
- var user = JSON.parse(resp.responseText).userCtx;
- T(user.name == null);
- // test that we are admin
- TEquals(user.roles, ["_admin"]);
-
- // can't save the doc even though we are admin
- var doc = db.open("testdoc");
- doc.foo=3;
- try {
- db.save(doc);
- T(false && "Can't get here. Should have thrown an error 3");
- } catch (e) {
- T(e.error == "unauthorized");
- T(db.last_req.status == 401);
- }
-
- // now turn on admin override
- T(db.setDbProperty("_security", {admin_override : true}).ok);
- // TODO: re-include after COUCHDB-2990
- //T(db.save(doc).ok);
-
- // try to do something lame
- try {
- db.setDbProperty("_security", ["foo"]);
- T(false && "can't do this");
- } catch(e) {}
-
- // go back to normal
- T(db.setDbProperty("_security", {admin_override : false}).ok);
-
- // Now delete document
- T(user2Db.deleteDoc(doc).ok);
-
- // now test bulk docs
- var docs = [{_id:"bahbah",author:"jerry",foo:"bar"},{_id:"fahfah",foo:"baz"}];
-
- // Create the docs
- var results = db.bulkSave(docs);
-
- T(results[0].rev)
- T(results[0].error == undefined)
- T(results[1].rev === undefined)
- T(results[1].error == "forbidden")
-
- T(db.open("bahbah"));
- T(db.open("fahfah") == null);
-
-
- // now all or nothing with a failure - no more available on cluster
-/* var docs = [{_id:"booboo",author:"Damien Katz",foo:"bar"},{_id:"foofoo",foo:"baz"}];
-
- // Create the docs
- var results = db.bulkSave(docs, {all_or_nothing:true});
-
- T(results.errors.length == 1);
- T(results.errors[0].error == "forbidden");
- T(db.open("booboo") == null);
- T(db.open("foofoo") == null);
-*/
-
- // Now test replication
- var AuthHeaders = {"Authorization": "Basic c3Bpa2U6ZG9n"}; // spike
- adminDbA = new CouchDB("" + db_name + "_a", {"X-Couch-Full-Commit":"false"});
- adminDbB = new CouchDB("" + db_name + "_b", {"X-Couch-Full-Commit":"false"});
- var dbA = new CouchDB("" + db_name + "_a", AuthHeaders);
- var dbB = new CouchDB("" + db_name + "_b", AuthHeaders);
- // looping does not really add value as the scenario is the same anyway (there's nothing 2 be gained from it)
- var A = CouchDB.protocol + CouchDB.host + "/" + db_name + "_a";
- var B = CouchDB.protocol + CouchDB.host + "/" + db_name + "_b";
-
- // (the databases never exist b4 - and we made sure they're deleted below)
- //adminDbA.deleteDb();
- adminDbA.createDb();
- //adminDbB.deleteDb();
- adminDbB.createDb();
-
- // save and replicate a documents that will and will not pass our design
- // doc validation function.
- T(dbA.save({_id:"foo1",value:"a",author:"tom"}).ok);
- T(dbA.save({_id:"foo2",value:"a",author:"spike"}).ok);
- T(dbA.save({_id:"bad1",value:"a"}).ok);
-
- T(CouchDB.replicate(A, B, {headers:AuthHeaders}).ok);
- T(CouchDB.replicate(B, A, {headers:AuthHeaders}).ok);
-
- T(dbA.open("foo1"));
- T(dbB.open("foo1"));
- T(dbA.open("foo2"));
- T(dbB.open("foo2"));
-
- // save the design doc to dbA
- delete designDoc._rev; // clear rev from previous saves
- T(adminDbA.save(designDoc).ok);
-
- // no affect on already saved docs
- T(dbA.open("bad1"));
-
- // Update some docs on dbB. Since the design hasn't replicated, anything
- // is allowed.
-
- // this edit will fail validation on replication to dbA (no author)
- T(dbB.save({_id:"bad2",value:"a"}).ok);
-
- // this edit will fail security on replication to dbA (wrong author
- // replicating the change)
- var foo1 = dbB.open("foo1");
- foo1.value = "b";
- T(dbB.save(foo1).ok);
-
- // this is a legal edit
- var foo2 = dbB.open("foo2");
- foo2.value = "b";
- T(dbB.save(foo2).ok);
-
- var results = CouchDB.replicate({"url": B, "headers": AuthHeaders}, {"url": A, "headers": AuthHeaders}, {headers:AuthHeaders});
- T(results.ok);
- TEquals(1, results.history[0].docs_written);
- TEquals(2, results.history[0].doc_write_failures);
-
- // bad2 should not be on dbA
- T(dbA.open("bad2") == null);
-
- // The edit to foo1 should not have replicated.
- T(dbA.open("foo1").value == "a");
-
- // The edit to foo2 should have replicated.
- T(dbA.open("foo2").value == "b");
- });
-
- // cleanup
- db.deleteDb();
- if(adminDbA){
- adminDbA.deleteDb();
- }
- if(adminDbB){
- adminDbB.deleteDb();
- }
- authDb.deleteDb();
- // don't have to clean the backend authDb since this test only calls
- // couch_auth_cache:get_admin/1 which doesn't auto-create the users db
-};
diff --git a/test/javascript/tests/show_documents.js b/test/javascript/tests/show_documents.js
deleted file mode 100644
index 172a79532..000000000
--- a/test/javascript/tests/show_documents.js
+++ /dev/null
@@ -1,376 +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.
-
-couchTests.show_documents = function(debug) {
-
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var designDoc = {
- _id:"_design/template",
- language: "javascript",
- shows: {
- "hello" : stringFun(function(doc, req) {
- log("hello fun");
- if (doc) {
- return "Hello World";
- } else {
- if(req.id) {
- return "New World";
- } else {
- return "Empty World";
- }
- }
- }),
- "just-name" : stringFun(function(doc, req) {
- if (doc) {
- return {
- body : "Just " + doc.name
- };
- } else {
- return {
- body : "No such doc",
- code : 404
- };
- }
- }),
- "json" : stringFun(function(doc, req) {
- return {
- json : doc
- }
- }),
- "req-info" : stringFun(function(doc, req) {
- return {
- json : req
- }
- }),
- "show-deleted" : stringFun(function(doc, req) {
- if(doc) {
- return doc._id;
- } else {
- return "No doc " + req.id;
- }
- }),
- "render-error" : stringFun(function(doc, req) {
- return noSuchVariable;
- }),
- "empty" : stringFun(function(doc, req) {
- return "";
- }),
- "fail" : stringFun(function(doc, req) {
- return doc._id;
- }),
- "no-set-etag" : stringFun(function(doc, req) {
- return {
- headers : {
- "Etag" : "skipped"
- },
- "body" : "something"
- }
- }),
- "list-api" : stringFun(function(doc, req) {
- start({"X-Couch-Test-Header": "Yeah"});
- send("Hey");
- }),
- "list-api-provides" : stringFun(function(doc, req) {
- provides("text", function(){
- send("foo, ");
- send("bar, ");
- send("baz!");
- })
- }),
- "list-api-provides-and-return" : stringFun(function(doc, req) {
- provides("text", function(){
- send("4, ");
- send("5, ");
- send("6, ");
- return "7!";
- })
- send("1, ");
- send("2, ");
- return "3, ";
- }),
- "list-api-mix" : stringFun(function(doc, req) {
- start({"X-Couch-Test-Header": "Yeah"});
- send("Hey ");
- return "Dude";
- }),
- "list-api-mix-with-header" : stringFun(function(doc, req) {
- start({"X-Couch-Test-Header": "Yeah"});
- send("Hey ");
- return {
- headers: {
- "X-Couch-Test-Header-Awesome": "Oh Yeah!"
- },
- body: "Dude"
- };
- }),
- "accept-switch" : stringFun(function(doc, req) {
- if (req.headers["Accept"].match(/image/)) {
- return {
- // a 16x16 px version of the CouchDB logo
- "base64" :
-["iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAsV",
-"BMVEUAAAD////////////////////////5ur3rEBn////////////////wDBL/",
-"AADuBAe9EB3IEBz/7+//X1/qBQn2AgP/f3/ilpzsDxfpChDtDhXeCA76AQH/v7",
-"/84eLyWV/uc3bJPEf/Dw/uw8bRWmP1h4zxSlD6YGHuQ0f6g4XyQkXvCA36MDH6",
-"wMH/z8/yAwX64ODeh47BHiv/Ly/20dLQLTj98PDXWmP/Pz//39/wGyJ7Iy9JAA",
-"AADHRSTlMAbw8vf08/bz+Pv19jK/W3AAAAg0lEQVR4Xp3LRQ4DQRBD0QqTm4Y5",
-"zMxw/4OleiJlHeUtv2X6RbNO1Uqj9g0RMCuQO0vBIg4vMFeOpCWIWmDOw82fZx",
-"vaND1c8OG4vrdOqD8YwgpDYDxRgkSm5rwu0nQVBJuMg++pLXZyr5jnc1BaH4GT",
-"LvEliY253nA3pVhQqdPt0f/erJkMGMB8xucAAAAASUVORK5CYII="].join(''),
- headers : {
- "Content-Type" : "image/png",
- "Vary" : "Accept" // we set this for proxy caches
- }
- };
- } else {
- return {
- "body" : "accepting text requests",
- headers : {
- "Content-Type" : "text/html",
- "Vary" : "Accept"
- }
- };
- }
- }),
- "provides" : stringFun(function(doc, req) {
- registerType("foo", "application/foo","application/x-foo");
-
- provides("html", function() {
- return "Ha ha, you said \"" + doc.word + "\".";
- });
-
- provides("foo", function() {
- return "foofoo";
- });
- }),
- "withSlash": stringFun(function(doc, req) {
- return { json: doc }
- }),
- "secObj": stringFun(function(doc, req) {
- return { json: req.secObj };
- })
- }
- };
- T(db.save(designDoc).ok);
-
- var doc = {"word":"plankton", "name":"Rusty"}
- var resp = db.save(doc);
- T(resp.ok);
- var docid = resp.id;
-
- // show error
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/");
- T(xhr.status == 404, 'Should be missing');
- T(JSON.parse(xhr.responseText).reason == "Invalid path.");
-
- // hello template world
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/hello/"+docid);
- T(xhr.responseText == "Hello World", "hello");
- T(/charset=utf-8/.test(xhr.getResponseHeader("Content-Type")));
-
-
- // Fix for COUCHDB-379
- T(equals(xhr.getResponseHeader("Server").substr(0,7), "CouchDB"));
-
- // // error stacktraces
- // xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/render-error/"+docid);
- // T(JSON.parse(xhr.responseText).error == "render_error");
-
- // hello template world (no docid)
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/hello");
- T(xhr.responseText == "Empty World");
-
- // hello template world (no docid)
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/empty");
- T(xhr.responseText == "");
-
- // // hello template world (non-existing docid)
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/fail/nonExistingDoc");
- T(xhr.status == 404);
- var resp = JSON.parse(xhr.responseText);
- T(resp.error == "not_found");
-
- // show with doc
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/just-name/"+docid);
- T(xhr.responseText == "Just Rusty");
-
- // show with missing doc
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/just-name/missingdoc");
- T(xhr.status == 404);
- TEquals("No such doc", xhr.responseText);
-
- // show with missing func
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/missing/"+docid);
- T(xhr.status == 404, "function is missing");
-
- // missing design doc
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/missingddoc/_show/just-name/"+docid);
- T(xhr.status == 404);
- var resp = JSON.parse(xhr.responseText);
- T(resp.error == "not_found");
-
- // query parameters
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/req-info/"+docid+"?foo=bar", {
- headers: {
- "Accept": "text/html;text/plain;*/*",
- "X-Foo" : "bar"
- }
- });
- var resp = JSON.parse(xhr.responseText);
- T(equals(resp.headers["X-Foo"], "bar"));
- T(equals(resp.query, {foo:"bar"}));
- T(equals(resp.method, "GET"));
- T(equals(resp.path[5], docid));
- T(equals(resp.info.db_name, "" + db_name + ""));
-
- // accept header switching
- // different mime has different etag
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/accept-switch/"+docid, {
- headers: {"Accept": "text/html;text/plain;*/*"}
- });
- var ct = xhr.getResponseHeader("Content-Type");
- T(/text\/html/.test(ct))
- T("Accept" == xhr.getResponseHeader("Vary"));
- var etag = xhr.getResponseHeader("etag");
-
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/accept-switch/"+docid, {
- headers: {"Accept": "image/png;*/*"}
- });
- T(xhr.responseText.match(/PNG/))
- T("image/png" == xhr.getResponseHeader("Content-Type"));
- var etag2 = xhr.getResponseHeader("etag");
- T(etag2 != etag);
-
- // proper etags
- // show with doc
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/just-name/"+docid);
- // extract the ETag header values
- etag = xhr.getResponseHeader("etag");
- // get again with etag in request
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/just-name/"+docid, {
- headers: {"if-none-match": etag}
- });
- // should be 304
- T(xhr.status == 304);
-
- // update the doc
- doc.name = "Crusty";
- resp = db.save(doc);
- T(resp.ok);
- // req with same etag
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/just-name/"+docid, {
- headers: {"if-none-match": etag}
- });
- // status is 200
- T(xhr.status == 200);
-
- // JS can't set etag
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/no-set-etag/"+docid);
- // extract the ETag header values
- etag = xhr.getResponseHeader("etag");
- T(etag != "skipped")
-
- // test the provides mime matcher
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/provides/"+docid, {
- headers: {
- "Accept": 'text/html,application/atom+xml; q=0.9'
- }
- });
- var ct = xhr.getResponseHeader("Content-Type");
- T(/charset=utf-8/.test(ct))
- T(/text\/html/.test(ct))
- T(xhr.responseText == "Ha ha, you said \"plankton\".");
-
- // registering types works
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/provides/"+docid, {
- headers: {
- "Accept": "application/x-foo"
- }
- });
- T(xhr.getResponseHeader("Content-Type") == "application/x-foo");
- T(xhr.responseText.match(/foofoo/));
-
- // test the provides mime matcher without a match
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/provides/"+docid, {
- headers: {
- "Accept": 'text/monkeys'
- }
- });
- var rs = JSON.parse(xhr.responseText);
- T(rs.error == "not_acceptable")
-
-
- // test inclusion of conflict state
- var doc1 = {_id:"foo", a:1};
- var doc2 = {_id:"foo", a:2};
- db.save(doc1);
-
- var doc3 = {_id:"a/b/c", a:1};
- db.save(doc3);
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/withSlash/a/b/c");
- T(xhr.status == 200);
-
- // hello template world (non-existing docid)
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/hello/nonExistingDoc");
- T(xhr.responseText == "New World");
-
- // test list() compatible API
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/list-api/foo");
- T(xhr.responseText == "Hey");
- TEquals("Yeah", xhr.getResponseHeader("X-Couch-Test-Header"), "header should be cool");
-
- // test list() compatible API with provides function
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/list-api-provides/foo?format=text");
- TEquals(xhr.responseText, "foo, bar, baz!", "should join chunks to response body");
-
- // should keep next result order: chunks + return value + provided chunks + provided return value
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/list-api-provides-and-return/foo?format=text");
- TEquals(xhr.responseText, "1, 2, 3, 4, 5, 6, 7!", "should not break 1..7 range");
-
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/list-api-mix/foo");
- T(xhr.responseText == "Hey Dude");
- TEquals("Yeah", xhr.getResponseHeader("X-Couch-Test-Header"), "header should be cool");
-
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/list-api-mix-with-header/foo");
- T(xhr.responseText == "Hey Dude");
- TEquals("Yeah", xhr.getResponseHeader("X-Couch-Test-Header"), "header should be cool");
- TEquals("Oh Yeah!", xhr.getResponseHeader("X-Couch-Test-Header-Awesome"), "header should be cool");
-
- // test deleted docs
- var doc = {_id:"testdoc",foo:1};
- db.save(doc);
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/show-deleted/testdoc");
- TEquals("testdoc", xhr.responseText, "should return 'testdoc'");
-
- db.deleteDoc(doc);
- var xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/show-deleted/testdoc");
- TEquals("No doc testdoc", xhr.responseText, "should return 'no doc testdoc'");
-
- // (we don't need no modified server!)
- T(db.setDbProperty("_security", {foo: true}).ok);
- T(db.save({_id:"testdoc",foo:1}).ok);
- // nasty source of Heisenbugs - it replicates after a short time, so give it some tries
- // (needs PR #400 and #401 to be merged)
- retry_part(function(){
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/template/_show/secObj");
- var resp = JSON.parse(xhr.responseText);
- T(resp.foo == true);
- }, 10);
-
- // cleanup
- db.deleteDb();
-
-};
diff --git a/test/javascript/tests/stats.js b/test/javascript/tests/stats.js
deleted file mode 100644
index 3a89ddd7d..000000000
--- a/test/javascript/tests/stats.js
+++ /dev/null
@@ -1,358 +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.
-
-// test has become very flaky - needs complete rewrite
-couchTests.skip = true;
-couchTests.stats = function(debug) {
-
- function newDb(doSetup) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- if(doSetup) {
- db.createDb();
- }
- return db;
- };
-
- function getStat(path) {
- var stat = CouchDB.requestStats(path, true);
- return stat ? stat.value : null;
- };
-
- function doView(db) {
- var designDoc = {
- _id:"_design/test", // turn off couch.js id escaping?
- language: "javascript",
- views: {
- all_docs: {map: "function(doc) {emit(doc.integer, null);}"}
- }
- };
- db.save(designDoc);
- db.view("test/all_docs");
- };
-
- function runTest(path, funcs) {
- var db = newDb(true);
- if(funcs.setup) funcs.setup(db);
- var before = getStat(path);
- if(funcs.run) funcs.run(db);
- var after = getStat(path);
- if(funcs.test) funcs.test(before, after);
- db.deleteDb();
- }
-
- if (debug) debugger;
-
- /* Need to delete _users and _replicator or background activity
- will mess with the results of this entire suite. */
- (function() {
- var users = new CouchDB("_users");
- users.deleteDb();
- var replicator = new CouchDB("_replicator");
- replicator.deleteDb();
- })();
-
- (function() {
- var db = newDb(false);
- db.deleteDb();
-
- var before = getStat(["couchdb", "open_databases"]);
- db.createDb();
- var after = getStat(["couchdb", "open_databases"]);
- TEquals(before+8, after, "Creating a db increments open db count.");
- db.deleteDb();
- })();
-
- runTest(["couchdb", "open_databases"], {
- setup: function() {restartServer();},
- run: function(db) {db.open("123");},
- test: function(before, after) {
- T(before<after, "Opening a db increases open db count.");
- }
- });
-
- runTest(["couchdb", "open_databases"], {
- setup: function(db) {restartServer(); db.open("123");},
- run: function(db) {db.deleteDb();},
- test: function(before, after) {
- T(before>after, "Deleting a db decrements open db count.");
- }
- });
-
- /* Improvements in LRU has made this test difficult...
- (function() {
- restartServer();
- var max = 5;
-
- var testFun = function() {
- var pre_dbs = getStat(["couchdb", "open_databases"]) || 0;
- var pre_files = getStat(["couchdb", "open_os_files"]) || 0;
-
- var triggered = false;
- var db = null;
- var dbs = [];
- for(var i = 0; i < max*2; i++) {
- while (true) {
- try {
- db = newDb(true);
- dbs.push(db);
- break;
- } catch(e) {
- // all_dbs_active error!
- triggered = true;
- }
- }
-
- // Trigger a delayed commit
- db.save({"a": "1"});
- }
- T(triggered, "We managed to force a all_dbs_active error.");
-
- var open_dbs = getStat(["couchdb", "open_databases"]);
- TEquals(open_dbs > 0, true, "We actually opened some dbs.");
- TEquals(max, open_dbs, "We only have max db's open.");
-
- for (var i = 0; i < dbs.length; i++) {
- dbs[i].deleteDb();
- }
-
- var post_dbs = getStat(["couchdb", "open_databases"]);
- var post_files = getStat(["couchdb", "open_os_files"]);
- TEquals(pre_dbs, post_dbs, "We have the same number of open dbs.");
- TEquals(pre_files, post_files, "We have the same number of open files.");
- for (var ctr = 0; ctr < dbs.length; ctr++) {
- dbs[ctr].deleteDb();
- }
- };
-
- run_on_modified_server(
- [{section: "couchdb", key: "max_dbs_open", value: "40"}],
- testFun
- );
- })();
- */
-
- // Just fetching the before value is the extra +1 in test
- runTest(["couchdb", "httpd", "requests"], {
- run: function() {CouchDB.request("GET", "/");},
- test: function(before, after) {
- TEquals(before+2, after, "Request counts are incremented properly.");
- }
- });
-
- runTest(["couchdb", "database_reads"], {
- setup: function(db) {db.save({"_id": "test"});},
- run: function(db) {db.open("test");},
- test: function(before, after) {
- T(before<after, "Reading a doc increments docs reads.");
- }
- });
-
- runTest(["couchdb", "database_reads"], {
- setup: function(db) {db.save({"_id": "test"});},
- run: function(db) {db.request("GET", "/");},
- test: function(before, after) {
- TEquals(before, after, "Only doc reads increment doc reads.");
- }
- });
-
- runTest(["couchdb", "database_reads"], {
- setup: function(db) {db.save({"_id": "test"});},
- run: function(db) {db.open("test", {"open_revs": "all"});},
- test: function(before, after) {
- T(before<after, "Reading doc revs increments docs reads.");
- }
- });
-
- runTest(["couchdb", "database_writes"], {
- run: function(db) {db.save({"a": "1"});},
- test: function(before, after) {
- T(before<after, "Saving docs incrememnts doc writes.");
- }
- });
-
- runTest(["couchdb", "database_writes"], {
- run: function(db) {
- CouchDB.request("POST", "/" + db.name + "", {
- headers: {"Content-Type": "application/json"},
- body: '{"a": "1"}'
- });
- },
- test: function(before, after) {
- T(before<after, "POST'ing new docs increments doc writes.");
- }
- });
-
- runTest(["couchdb", "database_writes"], {
- setup: function(db) {db.save({"_id": "test"});},
- run: function(db) {var doc = db.open("test"); db.save(doc);},
- test: function(before, after) {
- T(before<after, "Updating docs incrememnts doc writes.");
- }
- });
-
- runTest(["couchdb", "database_writes"], {
- setup: function(db) {db.save({"_id": "test"});},
- run: function(db) {var doc = db.open("test"); db.deleteDoc(doc);},
- test: function(before, after) {
- T(before<after, "Deleting docs increments doc writes.");
- }
- });
-
- runTest(["couchdb", "database_writes"], {
- setup: function(db) {db.save({"_id": "test"});},
- run: function(db) {
- CouchDB.request("COPY", "/" + db.name + "/test", {
- headers: {"Destination": "copy_of_test"}
- });
- },
- test: function(before, after) {
- T(before<after, "Copying docs increments doc writes.");
- }
- });
-
- runTest(["couchdb", "database_writes"], {
- run: function(db) {
- CouchDB.request("PUT", "/" + db.name + "/bin_doc2/foo2.txt", {
- body: "This is no base64 encoded test",
- headers: {"Content-Type": "text/plain;charset=utf-8"}
- });
- },
- test: function(before, after) {
- T(before<after, "Create with attachment increments doc writes.");
- }
- });
-
- runTest(["couchdb", "database_writes"], {
- setup: function(db) {db.save({"_id": "test"});},
- run: function(db) {
- var doc = db.open("test");
- CouchDB.request("PUT", "/" + db.name + "/test/foo2.txt?rev=" + doc._rev, {
- body: "This is no base64 encoded text",
- headers: {"Content-Type": "text/plainn;charset=utf-8"}
- });
- },
- test: function(before, after) {
- T(before<after, "Adding attachment increments doc writes.");
- }
- });
-
- runTest(["couchdb", "httpd", "bulk_requests"], {
- run: function(db) {db.bulkSave(makeDocs(5));},
- test: function(before, after) {
- TEquals(before+1, after, "The bulk_requests counter is incremented.");
- }
- });
-
- runTest(["couchdb", "httpd", "view_reads"], {
- run: function(db) {doView(db);},
- test: function(before, after) {
- T(before<after, "Reading a view increments view reads.");
- }
- });
-
- runTest(["couchdb", "httpd", "view_reads"], {
- setup: function(db) {db.save({"_id": "test"});},
- run: function(db) {db.open("test");},
- test: function(before, after) {
- TEquals(before, after, "Reading a doc doesn't increment view reads.");
- }
- });
-
- // Relies on getting the stats values being GET requests.
- runTest(["couchdb", "httpd_request_methods", "GET"], {
- test: function(before, after) {
- TEquals(before+1, after, "Get requests are incremented properly.");
- }
- });
-
- runTest(["couchdb", "httpd_request_methods", "GET"], {
- run: function() {CouchDB.request("POST", "/");},
- test: function(before, after) {
- TEquals(before+1, after, "POST requests don't affect GET counter.");
- }
- });
-
- runTest(["couchdb", "httpd_request_methods", "POST"], {
- run: function() {CouchDB.request("POST", "/");},
- test: function(before, after) {
- TEquals(before+1, after, "POST requests are incremented properly.");
- }
- });
-
- runTest(["couchdb", "httpd_status_codes", "404"], {
- run: function() {CouchDB.request("GET", "/nonexistant_db");},
- test: function(before, after) {
- TEquals(before+1, after, "Increments 404 counter on db not found.");
- }
- });
-
- runTest(["couchdb", "httpd_status_codes", "404"], {
- run: function() {CouchDB.request("GET", "/");},
- test: function(before, after) {
- TEquals(before, after, "Getting DB info doesn't increment 404's");
- }
- });
-
- var test_metric = function(metric, expected_fields) {
- for (var k in metric) {
- T(expected_fields.indexOf(k) >= 0, "Unknown property name: " + k);
- }
- for (var k in expected_fields) {
- T(metric[expected_fields[k]] !== undefined, "Missing required property: " + k);
- }
- };
-
- var test_histogram = function(histo) {
- test_metric(histo, ["value", "type", "desc"]);
- test_metric(histo.value, ["min", "max", "arithmetic_mean",
- "geometric_mean", "harmonic_mean", "median", "variance",
- "standard_deviation", "skewness", "kurtosis", "percentile",
- "histogram", "n"]);
- };
-
- var test_counter = function(counter) {
- test_metric(counter, ["value", "desc", "type"]);
- };
-
- var test_metrics = function(metrics) {
- if (metrics.type === "counter") {
- test_counter(metrics);
- } else if (metrics.type === "gauge") {
- test_counter(metrics);
- } else if (metrics.type === "histogram") {
- test_histogram(metrics);
- } else if (metrics.type === undefined) {
- for (var k in metrics) {
- test_metrics(metrics[k]);
- }
- }
- };
-
- (function() {
- var summary = JSON.parse(CouchDB.request("GET", "/_node/node1@127.0.0.1/_stats", {
- headers: {"Accept": "application/json"}
- }).responseText);
- T(typeof(summary) === 'object');
- test_metrics(summary);
- })();
-
- // cleanup
- /* Recreate the deleted _users and _replicator dbs */
- (function() {
- var users = new CouchDB("_users");
- users.createDb();
- var replicator = new CouchDB("_replicator");
- replicator.createDb();
- })();
-
-};
diff --git a/test/javascript/tests/update_documents.js b/test/javascript/tests/update_documents.js
deleted file mode 100644
index 913c99a57..000000000
--- a/test/javascript/tests/update_documents.js
+++ /dev/null
@@ -1,236 +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.
-
-couchTests.elixir = true
-couchTests.update_documents = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var designDoc = {
- _id:"_design/update",
- language: "javascript",
- updates: {
- "hello" : stringFun(function(doc, req) {
- if (!doc) {
- if (req.id) {
- return [
- // Creates a new document with the PUT docid,
- { _id : req.id,
- reqs : [req] },
- // and returns an HTML response to the client.
- "<p>New World</p>"];
- };
- //
- return [null, "<p>Empty World</p>"];
- };
- // we can update the document inline
- doc.world = "hello";
- // we can record aspects of the request or use them in application logic.
- doc.reqs && doc.reqs.push(req);
- doc.edited_by = req.userCtx;
- return [doc, "<p>hello doc</p>"];
- }),
- "in-place" : stringFun(function(doc, req) {
- var field = req.query.field;
- var value = req.query.value;
- var message = "set "+field+" to "+value;
- doc[field] = value;
- return [doc, message];
- }),
- "form-update" : stringFun(function(doc, req) {
- for (var field in req.form) {
- doc[field] = req.form[field];
- }
- var message = "updated doc from form";
- return [doc, message];
- }),
- "bump-counter" : stringFun(function(doc, req) {
- if (!doc.counter) doc.counter = 0;
- doc.counter += 1;
- var message = "<h1>bumped it!</h1>";
- return [doc, message];
- }),
- "error" : stringFun(function(doc, req) {
- superFail.badCrash;
- }),
- "get-uuid" : stringFun(function(doc, req) {
- return [null, req.uuid];
- }),
- "code-n-bump" : stringFun(function(doc,req) {
- if (!doc.counter) doc.counter = 0;
- doc.counter += 1;
- var message = "<h1>bumped it!</h1>";
- resp = {"code": 302, "body": message}
- return [doc, resp];
- }),
- "resp-code" : stringFun(function(doc,req) {
- resp = {"code": 302}
- return [null, resp];
- }),
- "resp-code-and-json" : stringFun(function(doc,req) {
- resp = {"code": 302, "json": {"ok": true}}
- return [{"_id": req["uuid"]}, resp];
- }),
- "binary" : stringFun(function(doc, req) {
- var resp = {
- "headers" : {
- "Content-Type" : "application/octet-stream"
- },
- "base64" : "aGVsbG8gd29ybGQh" // "hello world!" encoded
- };
- return [doc, resp];
- }),
- "empty" : stringFun(function(doc, req) {
- return [{}, 'oops'];
- })
- }
- };
- T(db.save(designDoc).ok);
-
- var doc = {"word":"plankton", "name":"Rusty"}
- var resp = db.save(doc);
- T(resp.ok);
- var docid = resp.id;
-
- // update error
- var xhr = CouchDB.request("POST", "/" + db_name + "/_design/update/_update/");
- T(xhr.status == 404, 'Should be missing');
- T(JSON.parse(xhr.responseText).reason == "Invalid path.");
-
- // hello update world
- xhr = CouchDB.request("PUT", "/" + db_name + "/_design/update/_update/hello/"+docid);
- T(xhr.status == 201);
- T(xhr.responseText == "<p>hello doc</p>");
- T(/charset=utf-8/.test(xhr.getResponseHeader("Content-Type")));
- T(equals(docid, xhr.getResponseHeader("X-Couch-Id")));
-
- doc = db.open(docid);
- T(doc.world == "hello");
-
- // Fix for COUCHDB-379
- T(equals(xhr.getResponseHeader("Server").substr(0,7), "CouchDB"));
-
- // hello update world (no docid)
- xhr = CouchDB.request("POST", "/" + db_name + "/_design/update/_update/hello");
- T(xhr.status == 200);
- T(xhr.responseText == "<p>Empty World</p>");
-
- // no GET allowed
- xhr = CouchDB.request("GET", "/" + db_name + "/_design/update/_update/hello");
- // T(xhr.status == 405); // TODO allow qs to throw error code as well as error message
- T(JSON.parse(xhr.responseText).error == "method_not_allowed");
-
- // // hello update world (non-existing docid)
- xhr = CouchDB.request("GET", "/" + db_name + "/nonExistingDoc");
- T(xhr.status == 404);
- xhr = CouchDB.request("PUT", "/" + db_name + "/_design/update/_update/hello/nonExistingDoc");
- T(xhr.status == 201);
- T(xhr.responseText == "<p>New World</p>");
- xhr = CouchDB.request("GET", "/" + db_name + "/nonExistingDoc");
- T(xhr.status == 200);
-
- // in place update
- xhr = CouchDB.request("PUT", "/" + db_name + "/_design/update/_update/in-place/"+docid+'?field=title&value=test');
- T(xhr.status == 201);
- T(xhr.responseText == "set title to test");
- doc = db.open(docid);
- T(doc.title == "test");
-
- // form update via application/x-www-form-urlencoded
- xhr = CouchDB.request("PUT", "/" + db_name + "/_design/update/_update/form-update/"+docid, {
- headers : {"Content-Type":"application/x-www-form-urlencoded"},
- body : "formfoo=bar&formbar=foo"
- });
- TEquals(201, xhr.status);
- TEquals("updated doc from form", xhr.responseText);
- doc = db.open(docid);
- TEquals("bar", doc.formfoo);
- TEquals("foo", doc.formbar);
-
- // bump counter
- xhr = CouchDB.request("PUT", "/" + db_name + "/_design/update/_update/bump-counter/"+docid, {
- headers : {"X-Couch-Full-Commit":"true"}
- });
- T(xhr.status == 201);
- T(xhr.responseText == "<h1>bumped it!</h1>");
- doc = db.open(docid);
- T(doc.counter == 1);
-
- // _update honors full commit if you need it to
- xhr = CouchDB.request("PUT", "/" + db_name + "/_design/update/_update/bump-counter/"+docid, {
- headers : {"X-Couch-Full-Commit":"true"}
- });
-
- var NewRev = xhr.getResponseHeader("X-Couch-Update-NewRev");
- doc = db.open(docid);
- T(doc['_rev'] == NewRev);
-
-
- T(doc.counter == 2);
-
- // Server provides UUID when POSTing without an ID in the URL
- xhr = CouchDB.request("POST", "/" + db_name + "/_design/update/_update/get-uuid/");
- T(xhr.status == 200);
- T(xhr.responseText.length == 32);
-
- // COUCHDB-1229 - allow slashes in doc ids for update handlers
- // /db/_design/doc/_update/handler/doc/id
-
- var doc = {
- _id:"with/slash",
- counter:1
- };
- db.save(doc);
- xhr = CouchDB.request("PUT", "/" + db_name + "/_design/update/_update/bump-counter/with/slash");
- TEquals(201, xhr.status, "should return a 200 status");
- TEquals("<h1>bumped it!</h1>", xhr.responseText, "should report bumping");
-
- var doc = db.open("with/slash");
- TEquals(2, doc.counter, "counter should be 2");
-
- // COUCHDB-648 - the code in the JSON response should be honored
-
- xhr = CouchDB.request("PUT", "/" + db_name + "/_design/update/_update/code-n-bump/"+docid, {
- headers : {"X-Couch-Full-Commit":"true"}
- });
- T(xhr.status == 302);
- T(xhr.responseText == "<h1>bumped it!</h1>");
- doc = db.open(docid);
- T(doc.counter == 3);
-
- xhr = CouchDB.request("POST", "/" + db_name + "/_design/update/_update/resp-code/");
- T(xhr.status == 302);
-
- xhr = CouchDB.request("POST", "/" + db_name + "/_design/update/_update/resp-code-and-json/");
- TEquals(302, xhr.status);
- T(JSON.parse(xhr.responseText).ok);
-
- // base64 response
- xhr = CouchDB.request("PUT", "/" + db_name + "/_design/update/_update/binary/"+docid, {
- headers : {"X-Couch-Full-Commit":"false"},
- body : 'rubbish'
- });
- T(xhr.status == 201);
- T(xhr.responseText == "hello world!");
- T(/application\/octet-stream/.test(xhr.getResponseHeader("Content-Type")));
-
- // Insert doc with empty id
- xhr = CouchDB.request("PUT", "/" + db_name + "/_design/update/_update/empty/foo");
- TEquals(400, xhr.status);
- TEquals("Document id must not be empty", JSON.parse(xhr.responseText).reason);
-
- // cleanup
- db.deleteDb();
-
-};
diff --git a/test/javascript/tests/users_db.js b/test/javascript/tests/users_db.js
deleted file mode 100644
index 3ce80256c..000000000
--- a/test/javascript/tests/users_db.js
+++ /dev/null
@@ -1,222 +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.
-
-couchTests.elixir = true;
-couchTests.users_db = function(debug) {
-
- // This tests the users db, especially validations
- // this should also test that you can log into the couch
-
- var users_db_name = '_users';
- var usersDb = new CouchDB(users_db_name, {"X-Couch-Full-Commit":"false"});
- try { usersDb.createDb(); } catch (e) { /* ignore if exists*/ }
- // have a 2nd "normal" DB 2 provoke conflicts
- var usersDbAlt = new CouchDB(get_random_db_name(), {"X-Couch-Full-Commit":"false"});
- usersDbAlt.createDb();
-
- // test that you can treat "_user" as a db-name
- // this can complicate people who try to secure the users db with
- // an http proxy and fail to get both the actual db and the _user path
- // maybe it's not the right approach...
- // hard to know what else to do, as we don't let non-admins inspect the config
- // to determine the actual users db name.
-
- function testFun() {
-
- // test that the validation function is installed
- // this will fail When the test is run in isolation,
- // since it doesn’t wait for the ddoc to be created.
- // in a full test suite run, this is fine.
- // dev trick: run `test/javascript/run basics users_db`
- // var ddoc = usersDb.open("_design/_auth");
- // T(ddoc.validate_doc_update);
-
- // test that you can login as a user using basic auth
- var jchrisUserDoc = CouchDB.prepareUserDoc({
- name: "jchris@apache.org"
- }, "funnybone");
- T(usersDb.save(jchrisUserDoc).ok);
-
- T(CouchDB.session().userCtx.name == null);
-
- // test that you can use basic auth aginst the users db
- var s = CouchDB.session({
- headers : {
- // base64_encode("jchris@apache.org:funnybone")
- "Authorization" : "Basic amNocmlzQGFwYWNoZS5vcmc6ZnVubnlib25l"
- }
- });
- T(s.userCtx.name == "jchris@apache.org");
- T(s.info.authenticated == "default");
- T(s.info.authentication_db == "" + users_db_name + "");
- TEquals(["cookie", "default"], s.info.authentication_handlers);
- var s = CouchDB.session({
- headers : {
- "Authorization" : "Basic Xzpf" // name and pass of _:_
- }
- });
- T(s.name == null);
- T(typeof(s.info.authenticated) === 'undefined');
- CouchDB.logout();
-
- // ok, now create a conflicting edit on the jchris doc, and make sure there's no login.
- // (use replication to create the conflict) - need 2 be admin
- CouchDB.login("jan", "apple");
- CouchDB.replicate(usersDb.name, usersDbAlt.name);
- // save in one DB
- var jchrisUser2 = JSON.parse(JSON.stringify(jchrisUserDoc));
- jchrisUser2.foo = "bar";
-
- T(usersDb.save(jchrisUser2).ok);
- try {
- usersDb.save(jchrisUserDoc);
- T(false && "should be an update conflict");
- } catch(e) {
- T(true);
- }
-
- // then in the other
- var jchrisUser3 = JSON.parse(JSON.stringify(jchrisUserDoc));
- jchrisUser3.foo = "barrrr";
- T(usersDbAlt.save(jchrisUser3).ok);
- CouchDB.replicate(usersDbAlt.name, usersDb.name); // now we should have a conflict
-
- var jchrisWithConflict = usersDb.open(jchrisUserDoc._id, {conflicts : true});
- T(jchrisWithConflict._conflicts.length == 1);
- CouchDB.logout();
-
- wait(5000) // wait for auth_cache invalidation
-
- // no login with conflicted user doc
- try {
- var s = CouchDB.session({
- headers : {
- "Authorization" : "Basic amNocmlzQGFwYWNoZS5vcmc6ZnVubnlib25l"
- }
- });
- T(false && "this will throw");
- } catch(e) {
- T(e.error == "unauthorized");
- T(/conflict/.test(e.reason));
- }
-
- // you can delete a user doc
- // there is NO admin party here - so we have to login again
- CouchDB.login("jan", "apple");
- s = CouchDB.session().userCtx;
- //T(s.name == null);
- //console.log(JSON.stringify(usersDb.allDocs()));
- T(s.roles.indexOf("_admin") !== -1);
-// TODO: fix deletion of user docs
-// T(usersDb.deleteDoc(jchrisWithConflict).ok);
-
- // you can't change doc from type "user"
- jchrisUserDoc = usersDb.open(jchrisUserDoc._id);
- jchrisUserDoc.type = "not user";
- try {
- usersDb.save(jchrisUserDoc);
- T(false && "should only allow us to save doc when type == 'user'");
- } catch(e) {
- T(e.reason == "doc.type must be user");
- }
- jchrisUserDoc.type = "user";
-
- // "roles" must be an array
- jchrisUserDoc.roles = "not an array";
- try {
- usersDb.save(jchrisUserDoc);
- T(false && "should only allow us to save doc when roles is an array");
- } catch(e) {
- T(e.reason == "doc.roles must be an array");
- }
- jchrisUserDoc.roles = [];
-
- // "roles" must be an array of strings
- jchrisUserDoc.roles = [12];
- try {
- usersDb.save(jchrisUserDoc);
- T(false && "should only allow us to save doc when roles is an array of strings");
- } catch(e) {
- TEquals(e.reason, "doc.roles can only contain strings");
- }
- jchrisUserDoc.roles = [];
-
- // "roles" must exist
- delete jchrisUserDoc.roles;
- try {
- usersDb.save(jchrisUserDoc);
- T(false && "should only allow us to save doc when roles exists");
- } catch(e) {
- T(e.reason == "doc.roles must exist");
- }
- jchrisUserDoc.roles = [];
-
- // character : is not allowed in usernames
- var joeUserDoc = CouchDB.prepareUserDoc({
- name: "joe:erlang"
- }, "qwerty");
- try {
- usersDb.save(joeUserDoc);
- T(false, "shouldn't allow : in usernames");
- } catch(e) {
- TEquals("Character `:` is not allowed in usernames.", e.reason);
- }
-
- // test that you can login as a user with a password starting with :
- var doc = CouchDB.prepareUserDoc({
- name: "foo@example.org"
- }, ":bar");
- T(usersDb.save(doc).ok);
- CouchDB.logout();
-
- T(CouchDB.session().userCtx.name == null);
-
- // test that you can use basic auth aginst the users db
- var s = CouchDB.session({
- headers : {
- // base64_encode("foo@example.org::bar")
- "Authorization" : "Basic Zm9vQGV4YW1wbGUub3JnOjpiYXI="
- }
- });
- T(s.userCtx.name == "foo@example.org");
-
- };
-
- run_on_modified_server(
- [{section: "couch_httpd_auth",
- key: "authentication_db", value: usersDb.name},
- {section: "chttpd_auth",
- key: "authentication_db", value: usersDb.name},
- {section: "couch_httpd_auth",
- key: "iterations", value: "1"},
- {section: "admins",
- key: "jan", value: "apple"}],
- function() {
- try {
- testFun();
- } finally {
- CouchDB.login("jan", "apple");
- usersDb.deleteDb(); // cleanup
- waitForSuccess(function() {
- var req = CouchDB.request("GET", usersDb.name);
- if (req.status == 404) {
- return true
- }
- throw({});
- }, "usersdb.deleteDb")
- usersDb.createDb();
- usersDbAlt.deleteDb(); // cleanup
- }
- }
- );
- CouchDB.logout();
-}
diff --git a/test/javascript/tests/users_db_security.js b/test/javascript/tests/users_db_security.js
deleted file mode 100644
index faffd8c27..000000000
--- a/test/javascript/tests/users_db_security.js
+++ /dev/null
@@ -1,418 +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.
-
-couchTests.users_db_security = function(debug) {
- var db_name = '_users';
- var usersDb = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- try { usersDb.createDb(); } catch (e) { /* ignore if exists*/ }
-
- if (debug) debugger;
-
- var loginUser = function(username) {
- var pws = {
- jan: "apple",
- jchris: "mp3",
- jchris1: "couch",
- fdmanana: "foobar",
- benoitc: "test"
- };
- // we are changing jchris’s password further down
- // the next two lines keep the code cleaner in
- // the actual tests
- var username1 = username.replace(/[0-9]$/, "");
- var password = pws[username];
- T(CouchDB.login(username1, pws[username]).ok);
- };
-
- var open_as = function(db, docId, username) {
- loginUser(username);
- try {
- return db.open(docId, {"anti-cache": Math.round(Math.random() * 100000)});
- } finally {
- CouchDB.logout();
- }
- };
-
- var view_as = function(db, viewname, username) {
- loginUser(username);
- try {
- return db.view(viewname);
- } finally {
- CouchDB.logout();
- }
- };
-
- var save_as = function(db, doc, username)
- {
- loginUser(username);
- try {
- return db.save(doc);
- } catch (ex) {
- return ex;
- } finally {
- CouchDB.logout();
- }
- };
-
- var changes_as = function(db, username)
- {
- loginUser(username);
- try {
- return db.changes();
- } catch(ex) {
- return ex;
- } finally {
- CouchDB.logout();
- }
- };
-
- var request_as = function(db, ddoc_path, username) {
- loginUser(username);
- try {
- var uri = db.uri + ddoc_path;
- var req = CouchDB.request("GET", uri);
- return req;
- } finally {
- CouchDB.logout();
- }
- };
-
- var testFun = function()
- {
-
- // _users db
- // a doc with a field 'password' should be hashed to 'derived_key'
- // with salt and salt stored in 'salt', 'password' is set to null.
- // Exising 'derived_key' and 'salt' fields are overwritten with new values
- // when a non-null 'password' field exists.
- // anonymous should be able to create a user document
- var userDoc = {
- _id: "org.couchdb.user:jchris",
- type: "user",
- name: "jchris",
- password: "mp3",
- roles: []
- };
-
- // jan's gonna be admin as he's the first user
- TEquals(true, usersDb.save(userDoc).ok, "should save document");
- wait(5000)
- userDoc = open_as(usersDb, "org.couchdb.user:jchris", "jchris");
- TEquals(undefined, userDoc.password, "password field should be null 1");
- TEquals(40, userDoc.derived_key.length, "derived_key should exist");
- TEquals(32, userDoc.salt.length, "salt should exist");
-
- // create server admin
-
- // anonymous should not be able to read an existing user's user document
- var res = usersDb.open("org.couchdb.user:jchris");
- TEquals(null, res, "anonymous user doc read should be not found");
-
- // anonymous should not be able to read /_users/_changes
- try {
- var ch = usersDb.changes();
- T(false, "anonymous can read _changes");
- } catch(e) {
- TEquals("unauthorized", e.error, "anoymous can't read _changes");
- }
-
- // user should be able to read their own document
- var jchrisDoc = open_as(usersDb, "org.couchdb.user:jchris", "jchris");
- TEquals("org.couchdb.user:jchris", jchrisDoc._id);
-
- // user should not be able to read /_users/_changes
- var changes = changes_as(usersDb, "jchris");
- TEquals("unauthorized", changes.error, "user can't read _changes");
-
- // new 'password' fields should trigger new hashing routine
- jchrisDoc.password = "couch";
-
- TEquals(true, save_as(usersDb, jchrisDoc, "jchris").ok);
- // wait(10000);
- var jchrisDoc = open_as(usersDb, "org.couchdb.user:jchris", "jan");
-
- TEquals(undefined, jchrisDoc.password, "password field should be null 2");
- TEquals(40, jchrisDoc.derived_key.length, "derived_key should exist");
- TEquals(32, jchrisDoc.salt.length, "salt should exist");
-
- TEquals(true, userDoc.salt != jchrisDoc.salt, "should have new salt");
- TEquals(true, userDoc.derived_key != jchrisDoc.derived_key,
- "should have new derived_key");
-
- // user should not be able to read another user's user document
- var fdmananaDoc = {
- _id: "org.couchdb.user:fdmanana",
- type: "user",
- name: "fdmanana",
- password: "foobar",
- roles: []
- };
-
- usersDb.save(fdmananaDoc);
- var fdmananaDocAsReadByjchris = open_as(usersDb, "org.couchdb.user:fdmanana", "jchris1");
- TEquals(null, fdmananaDocAsReadByjchris,
- "should not_found opening another user's user doc");
-
-
- // save a db admin
- var benoitcDoc = {
- _id: "org.couchdb.user:benoitc",
- type: "user",
- name: "benoitc",
- password: "test",
- roles: ["user_admin"]
- };
- save_as(usersDb, benoitcDoc, "jan");
-
- TEquals(true, CouchDB.login("jan", "apple").ok);
- T(usersDb.setSecObj({
- "admins" : {
- roles : [],
- names : ["benoitc"]
- }
- }).ok);
- CouchDB.logout();
-
- // user should not be able to read from any view
- var ddoc = {
- _id: "_design/user_db_auth",
- views: {
- test: {
- map: "function(doc) { emit(doc._id, null); }"
- }
- },
- lists: {
- names: "function(head, req) { "
- + "var row; while (row = getRow()) { send(row.key + \"\\n\"); }"
- + "}"
- },
- shows: {
- name: "function(doc, req) { return doc.name; }"
- }
- };
-
- save_as(usersDb, ddoc, "jan");
-
- try {
- usersDb.view("user_db_auth/test");
- T(false, "user had access to view in admin db");
- } catch(e) {
- TEquals("forbidden", e.error,
- "non-admins should not be able to read a view");
- }
-
- // admin should be able to read from any view
- var result = view_as(usersDb, "user_db_auth/test", "jan");
- TEquals(3, result.total_rows, "should allow access and list four users to admin");
-
- // db admin should be able to read from any view
- var result = view_as(usersDb, "user_db_auth/test", "benoitc");
- TEquals(3, result.total_rows, "should allow access and list four users to db admin");
-
-
- // non-admins can't read design docs
- try {
- open_as(usersDb, "_design/user_db_auth", "jchris1");
- T(false, "non-admin read design doc, should not happen");
- } catch(e) {
- TEquals("forbidden", e.error, "non-admins can't read design docs");
- }
-
- // admin shold be able to read _list
- var listPath = ddoc["_id"] + "/_list/names/test";
- var result = request_as(usersDb, listPath, "jan");
- var lines = result.responseText.split("\n");
- T(result.status == 200, "should allow access to db admin");
- TEquals(4, lines.length, "should list users to db admin");
-
- // non-admins can't read _list
- var result = request_as(usersDb, listPath, "jchris1");
- T(result.status == 403, "should deny access to non-admin");
-
- // admin should be able to read _show
- var showPath = ddoc["_id"] + "/_show/name/org.couchdb.user:jchris";
- var result = request_as(usersDb, showPath, "jan");
- T(result.status == 200, "should allow access to db admin");
- TEquals("jchris", result.responseText, "should show username to db admin");
-
- // non-admin should be able to access own _show
- var result = request_as(usersDb, showPath, "jchris1");
- T(result.status == 200, "should allow access to own user record");
- TEquals("jchris", result.responseText, "should show own username");
-
- // non-admin can't read other's _show
- var showPath = ddoc["_id"] + "/_show/name/org.couchdb.user:jan";
- var result = request_as(usersDb, showPath, "jchris1");
- T(result.status == 404, "non-admin can't read others's user docs");
-
- // admin should be able to read and edit any user doc
- fdmananaDoc.password = "mobile";
- var result = save_as(usersDb, fdmananaDoc, "jan");
- TEquals(true, result.ok, "admin should be able to update any user doc");
-
- // admin should be able to read and edit any user doc
- fdmananaDoc.password = "mobile1";
- var result = save_as(usersDb, fdmananaDoc, "benoitc");
- TEquals(true, result.ok, "db admin by role should be able to update any user doc");
-
- TEquals(true, CouchDB.login("jan", "apple").ok);
- T(usersDb.setSecObj({
- "admins" : {
- roles : ["user_admin"],
- names : []
- }
- }).ok);
- CouchDB.logout();
-
- // db admin should be able to read and edit any user doc
- fdmananaDoc.password = "mobile2";
- var result = save_as(usersDb, fdmananaDoc, "benoitc");
- TEquals(true, result.ok, "db admin should be able to update any user doc");
-
- // ensure creation of old-style docs still works
- var robertDoc = CouchDB.prepareUserDoc({ name: "robert" }, "anchovy");
- var result = usersDb.save(robertDoc);
- TEquals(true, result.ok, "old-style user docs should still be accepted");
-
- // log in one last time so run_on_modified_server can clean up the admin account
- TEquals(true, CouchDB.login("jan", "apple").ok);
-
- // run_on_modified_server([
- // {
- // section: "couch_httpd_auth",
- // key: "iterations",
- // value: "1"
- // },
- // {
- // section: "couch_httpd_auth",
- // key: "public_fields",
- // value: "name,type"
- // },
- // {
- // section: "couch_httpd_auth",
- // key: "users_db_public",
- // value: "true"
- // },
- // {
- // section: "admins",
- // key: "jan",
- // value: "apple"
- // }
- // ], function() {
- // var res = usersDb.open("org.couchdb.user:jchris");
- // TEquals("jchris", res.name);
- // TEquals("user", res.type);
- // TEquals(undefined, res.roles);
- // TEquals(undefined, res.salt);
- // TEquals(undefined, res.password_scheme);
- // TEquals(undefined, res.derived_key);
- //
- // TEquals(true, CouchDB.login("jan", "apple").ok);
- //
- // var all = usersDb.allDocs({ include_docs: true });
- // T(all.rows);
- // if (all.rows) {
- // T(all.rows.every(function(row) {
- // if (row.doc) {
- // return Object.keys(row.doc).every(function(key) {
- // return key === 'name' || key === 'type';
- // });
- // } else {
- // if(row.id[0] == "_") {
- // // ignore design docs
- // return true
- // } else {
- // return false;
- // }
- // }
- // }));
- // }
- // // log in one last time so run_on_modified_server can clean up the admin account
- // TEquals(true, CouchDB.login("jan", "apple").ok);
- // });
-
- run_on_modified_server([
- {
- section: "couch_httpd_auth",
- key: "public_fields",
- value: "name"
- },
- {
- section: "couch_httpd_auth",
- key: "users_db_public",
- value: "false"
- }
- ], function() {
- TEquals(true, CouchDB.login("jchris", "couch").ok);
-
- try {
- var all = usersDb.allDocs({ include_docs: true });
- T(false); // should never hit
- } catch(e) {
- TEquals("unauthorized", e.error, "should throw");
- }
-
- // COUCHDB-1888 make sure admins always get all fields
- TEquals(true, CouchDB.login("jan", "apple").ok);
- var all_admin = usersDb.allDocs({ include_docs: "true" });
- TEquals("user", all_admin.rows[2].doc.type,
- "should return type");
-
-
- // log in one last time so run_on_modified_server can clean up the admin account
- TEquals(true, CouchDB.login("jan", "apple").ok);
- });
- };
-
- run_on_modified_server(
- [
- {
- section:"couchdb",
- key:"users_db_security_editable",
- value:"true"
- },
- {
- section: "couch_httpd_auth",
- key: "iterations",
- value: "1"
- },
- {
- section: "admins",
- key: "jan",
- value: "apple"
- }],
- function() {
- try {
- testFun();
- } finally {
- CouchDB.login("jan", "apple");
- usersDb.deleteDb(); // cleanup
- waitForSuccess(function() {
- var req = CouchDB.request("GET", db_name);
- if (req.status == 404) {
- return true
- }
- throw({});
- }, 'usersDb.deleteDb')
- usersDb.createDb();
- waitForSuccess(function() {
- var req = CouchDB.request("GET", db_name);
- if (req.status == 200) {
- return true
- }
- throw({});
- }, 'usersDb.creteDb')
- }
- }
- );
- CouchDB.logout();
-};
diff --git a/test/javascript/tests/utf8.js b/test/javascript/tests/utf8.js
deleted file mode 100644
index cee4d30cb..000000000
--- a/test/javascript/tests/utf8.js
+++ /dev/null
@@ -1,46 +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.
-
-couchTests.elixir = true;
-couchTests.utf8 = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var texts = [];
-
- texts[0] = "1. Ascii: hello"
- texts[1] = "2. Russian: На берегу пустынных волн"
- texts[2] = "3. Math: ∮ E⋅da = Q, n → ∞, ∑ f(i) = ∏ g(i),"
- texts[3] = "4. Geek: STARGΛ̊TE SG-1"
- texts[4] = "5. Braille: ⡌⠁⠧⠑ ⠼⠁⠒ ⡍⠜⠇⠑⠹⠰⠎ ⡣⠕⠌"
- texts[5] = "6. null \u0000 byte"
-
- // check that we can save a reload with full fidelity
- for (var i=0; i<texts.length; i++) {
- T(db.save({_id:i.toString(), text:texts[i]}).ok);
- }
-
- for (var i=0; i<texts.length; i++) {
- T(db.open(i.toString()).text == texts[i]);
- }
-
- // check that views and key collation don't blow up
- var rows = db.query(function(doc) { emit(null, doc.text) }).rows;
- for (var i=0; i<texts.length; i++) {
- T(rows[i].value == texts[i]);
- }
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/uuids.js b/test/javascript/tests/uuids.js
deleted file mode 100644
index 18871ecba..000000000
--- a/test/javascript/tests/uuids.js
+++ /dev/null
@@ -1,148 +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.
-
-couchTests.elixir = true;
-couchTests.uuids = function(debug) {
- return console.log('done in test/elixir/test/uuids_test.exs');
- var etags = [];
- var testHashBustingHeaders = function(xhr) {
- T(xhr.getResponseHeader("Cache-Control").match(/no-cache/));
- T(xhr.getResponseHeader("Pragma") == "no-cache");
-
- var newetag = xhr.getResponseHeader("ETag");
- T(etags.indexOf(newetag) < 0);
- etags[etags.length] = newetag;
-
- // Removing the time based tests as they break easily when
- // running CouchDB on a remote server in regards to the browser
- // running the Futon test suite.
- //
- //var currentTime = new Date();
- //var expiresHeader = Date.parse(xhr.getResponseHeader("Expires"));
- //var dateHeader = Date.parse(xhr.getResponseHeader("Date"));
-
- //T(expiresHeader < currentTime);
- //T(currentTime - dateHeader < 3000);
- };
-
- if (debug) debugger;
-
- // a single UUID without an explicit count
- var xhr = CouchDB.request("GET", "/_uuids");
- T(xhr.status == 200);
- var result = JSON.parse(xhr.responseText);
- T(result.uuids.length == 1);
- var first = result.uuids[0];
- testHashBustingHeaders(xhr);
-
- // a single UUID with an explicit count
- xhr = CouchDB.request("GET", "/_uuids?count=1");
- T(xhr.status == 200);
- result = JSON.parse(xhr.responseText);
- T(result.uuids.length == 1);
- var second = result.uuids[0];
- T(first != second);
-
- // no collisions with 1,000 UUIDs
- xhr = CouchDB.request("GET", "/_uuids?count=1000");
- T(xhr.status == 200);
- result = JSON.parse(xhr.responseText);
- T( result.uuids.length == 1000 );
- var seen = {};
- for(var i in result.uuids) {
- var id = result.uuids[i];
- T(seen[id] === undefined);
- seen[id] = 1;
- }
-
- // ensure we return a 405 on POST
- xhr = CouchDB.request("POST", "/_uuids?count=1000");
- T(xhr.status == 405);
-
- // Test sequential uuids
- var seq_testfun = function() {
- xhr = CouchDB.request("GET", "/_uuids?count=1000");
- T(xhr.status == 200);
- result = JSON.parse(xhr.responseText);
- for(var i = 1; i < result.uuids.length; i++) {
- T(result.uuids[i].length == 32);
- T(result.uuids[i-1] < result.uuids[i], "Sequential uuids are ordered.");
- }
- };
-
- // test max_uuid_count
- var xhr = CouchDB.request("GET", "/_uuids?count=1001");
- TEquals(400, xhr.status, "should error when count > max_count");
-
- run_on_modified_server([{
- "section": "uuids",
- "key": "algorithm",
- "value": "sequential",
- }],
- seq_testfun
- );
-
- // Test utc_random uuids
- var utc_testfun = function() {
- xhr = CouchDB.request("GET", "/_uuids?count=1000");
- T(xhr.status == 200);
- result = JSON.parse(xhr.responseText);
- T(result.uuids[1].length == 32);
-
- // no collisions
- var seen = {};
- for(var i in result.uuids) {
- var id = result.uuids[i];
- T(seen[id] === undefined);
- seen[id] = 1;
- }
-
- // roughly ordered
- var u1 = result.uuids[1].substr(0, 13);
- var u2 = result.uuids[result.uuids.length-1].substr(0, 13);
- T(u1 < u2, "UTC uuids are only roughly ordered, so this assertion may fail occasionally. Don't sweat it.");
- };
-
- run_on_modified_server([{
- "section": "uuids",
- "key": "algorithm",
- "value": "utc_random"
- }],
- utc_testfun
- );
-
- // Test utc_id uuids
- var utc_id_suffix = "frog";
- var suffix_testfun = function() {
- xhr = CouchDB.request("GET", "/_uuids?count=10");
- T(xhr.status == 200);
- result = JSON.parse(xhr.responseText);
- for(var i = 1; i < result.uuids.length; i++) {
- T(result.uuids[i].length == 14 + utc_id_suffix.length);
- T(result.uuids[i].substring(14) == utc_id_suffix);
- T(result.uuids[i-1] < result.uuids[i], "utc_id_suffix uuids are ordered.");
- }
- };
-
- run_on_modified_server([{
- "section": "uuids",
- "key": "algorithm",
- "value": "utc_id"
- }, {
- "section": "uuids",
- "key": "utc_id_suffix",
- "value": utc_id_suffix
- }],
- suffix_testfun
- );
-
- };
diff --git a/test/javascript/tests/view_collation.js b/test/javascript/tests/view_collation.js
deleted file mode 100644
index 3ec9f8a5d..000000000
--- a/test/javascript/tests/view_collation.js
+++ /dev/null
@@ -1,121 +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.
-
-couchTests.elixir = true;
-couchTests.view_collation = function(debug) {
- return console.log('done in test/elixir/test/view_collation_test.exs');
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- // NOTE, the values are already in their correct sort order. Consider this
- // a specification of collation of json types.
-
- var values = [];
-
- // special values sort before all other types
- values.push(null);
- values.push(false);
- values.push(true);
-
- // then numbers
- values.push(1);
- values.push(2);
- values.push(3.0);
- values.push(4);
-
- // then text, case sensitive
- values.push("a");
- values.push("A");
- values.push("aa");
- values.push("b");
- values.push("B");
- values.push("ba");
- values.push("bb");
-
- // then arrays. compared element by element until different.
- // Longer arrays sort after their prefixes
- values.push(["a"]);
- values.push(["b"]);
- values.push(["b","c"]);
- values.push(["b","c", "a"]);
- values.push(["b","d"]);
- values.push(["b","d", "e"]);
-
- // then object, compares each key value in the list until different.
- // larger objects sort after their subset objects.
- values.push({a:1});
- values.push({a:2});
- values.push({b:1});
- values.push({b:2});
- values.push({b:2, a:1}); // Member order does matter for collation.
- // CouchDB preserves member order
- // but doesn't require that clients will.
- // (this test might fail if used with a js engine
- // that doesn't preserve order)
- values.push({b:2, c:2});
-
- for (var i=0; i<values.length; i++) {
- db.save({_id:(i).toString(), foo:values[i]});
- }
-
- var queryFun = function(doc) { emit(doc.foo, null); };
- var rows = db.query(queryFun).rows;
- for (i=0; i<values.length; i++) {
- T(equals(rows[i].key, values[i]));
- }
-
- // everything has collated correctly. Now to check the descending output
- rows = db.query(queryFun, null, {descending: true}).rows;
- for (i=0; i<values.length; i++) {
- T(equals(rows[i].key, values[values.length - 1 -i]));
- }
-
- // now check the key query args
- for (i=1; i<values.length; i++) {
- var queryOptions = {key:values[i]};
- rows = db.query(queryFun, null, queryOptions).rows;
- T(rows.length == 1 && equals(rows[0].key, values[i]));
- }
-
- // test inclusive_end=true (the default)
- // the inclusive_end=true functionality is limited to endkey currently
- // if you need inclusive_start=false for startkey, please do implement. ;)
- var rows = db.query(queryFun, null, {endkey : "b", inclusive_end:true}).rows;
- T(rows[rows.length-1].key == "b");
- // descending=true
- var rows = db.query(queryFun, null, {endkey : "b",
- descending:true, inclusive_end:true}).rows;
- T(rows[rows.length-1].key == "b");
-
- // test inclusive_end=false
- var rows = db.query(queryFun, null, {endkey : "b", inclusive_end:false}).rows;
- T(rows[rows.length-1].key == "aa");
- // descending=true
- var rows = db.query(queryFun, null, {endkey : "b",
- descending:true, inclusive_end:false}).rows;
- T(rows[rows.length-1].key == "B");
-
- var rows = db.query(queryFun, null, {
- endkey : "b", endkey_docid: "10",
- inclusive_end:false}).rows;
- T(rows[rows.length-1].key == "aa");
-
- var rows = db.query(queryFun, null, {
- endkey : "b", endkey_docid: "11",
- inclusive_end:false}).rows;
- T(rows[rows.length-1].key == "b");
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/view_collation_raw.js b/test/javascript/tests/view_collation_raw.js
deleted file mode 100644
index ee990bc4c..000000000
--- a/test/javascript/tests/view_collation_raw.js
+++ /dev/null
@@ -1,134 +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.
-
-couchTests.elixir = true;
-couchTests.view_collation_raw = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- // NOTE, the values are already in their correct sort order. Consider this
- // a specification of collation of json types.
-
- var values = [];
-
- // numbers
- values.push(1);
- values.push(2);
- values.push(3);
- values.push(4);
-
- values.push(false);
- values.push(null);
- values.push(true);
-
- // then object, compares each key value in the list until different.
- // larger objects sort after their subset objects.
- values.push({a:1});
- values.push({a:2});
- values.push({b:1});
- values.push({b:2});
- values.push({b:2, a:1}); // Member order does matter for collation.
- // CouchDB preserves member order
- // but doesn't require that clients will.
- // (this test might fail if used with a js engine
- // that doesn't preserve order)
- values.push({b:2, c:2});
-
- // then arrays. compared element by element until different.
- // Longer arrays sort after their prefixes
- values.push(["a"]);
- values.push(["b"]);
- values.push(["b","c"]);
- values.push(["b","c", "a"]);
- values.push(["b","d"]);
- values.push(["b","d", "e"]);
-
-
- // then text, case sensitive
- values.push("A");
- values.push("B");
- values.push("a");
- values.push("aa");
- values.push("b");
- values.push("ba");
- values.push("bb");
-
- for (var i=0; i<values.length; i++) {
- db.save({_id:(i).toString(), foo:values[i]});
- }
-
- var designDoc = {
- _id:"_design/test", // turn off couch.js id escaping?
- language: "javascript",
- views: {
- test: {map: "function(doc) { emit(doc.foo, null); }",
- options: {collation:"raw"}}
- }
- }
- T(db.save(designDoc).ok);
-
- // Confirm that everything collates correctly.
- var rows = db.view("test/test").rows;
- for (i=0; i<values.length; i++) {
- T(equals(rows[i].key, values[i]));
- }
-
- // Confirm that couch allows raw semantics in key ranges.
- rows = db.view("test/test", {startkey:"Z", endkey:"a"}).rows;
- TEquals(1, rows.length);
- TEquals("a", rows[0].key);
-
- // Check the descending output.
- rows = db.view("test/test", {descending: true}).rows;
- for (i=0; i<values.length; i++) {
- T(equals(rows[i].key, values[values.length - 1 -i]));
- }
-
- // now check the key query args
- for (i=1; i<values.length; i++) {
- rows = db.view("test/test", {key:values[i]}).rows;
- T(rows.length == 1 && equals(rows[0].key, values[i]));
- }
-
- // test inclusive_end=true (the default)
- // the inclusive_end=true functionality is limited to endkey currently
- // if you need inclusive_start=false for startkey, please do implement. ;)
- var rows = db.view("test/test", {endkey : "b", inclusive_end:true}).rows;
- T(rows[rows.length-1].key == "b");
- // descending=true
- var rows = db.view("test/test", {endkey : "b",
- descending:true, inclusive_end:true}).rows;
- T(rows[rows.length-1].key == "b");
-
- // test inclusive_end=false
- var rows = db.view("test/test", {endkey : "b", inclusive_end:false}).rows;
- T(rows[rows.length-1].key == "aa");
- // descending=true
- var rows = db.view("test/test", {endkey : "b",
- descending:true, inclusive_end:false}).rows;
- T(rows[rows.length-1].key == "ba");
-
- var rows = db.view("test/test", {
- endkey : "b", endkey_docid: "10",
- inclusive_end:false}).rows;
- T(rows[rows.length-1].key == "aa");
-
- var rows = db.view("test/test", {
- endkey : "b", endkey_docid: "11",
- inclusive_end:false}).rows;
- T(rows[rows.length-1].key == "aa");
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/view_compaction.js b/test/javascript/tests/view_compaction.js
deleted file mode 100644
index f2af39058..000000000
--- a/test/javascript/tests/view_compaction.js
+++ /dev/null
@@ -1,112 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-couchTests.elixir = true;
-couchTests.view_compaction = function(debug) {
- if (debug) debugger;
-
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
-
- var ddoc = {
- _id: "_design/foo",
- language: "javascript",
- views: {
- view1: {
- map: "function(doc) { emit(doc._id, doc.value) }"
- },
- view2: {
- map: "function(doc) { if (typeof(doc.integer) === 'number') {emit(doc._id, doc.integer);} }",
- reduce: "function(keys, values, rereduce) { return sum(values); }"
- }
- }
- };
- T(db.save(ddoc).ok);
-
- var docs = makeDocs(0, 10000);
- db.bulkSave(docs);
-
- var resp = db.view('foo/view1', {});
- TEquals(10000, resp.rows.length);
-
- resp = db.view('foo/view2', {});
- TEquals(1, resp.rows.length);
-
- resp = db.designInfo("_design/foo");
- TEquals(10001, resp.view_index.update_seq);
-
-
- // update docs
- for (var i = 0; i < docs.length; i++) {
- docs[i].integer = docs[i].integer + 1;
- }
- db.bulkSave(docs);
-
-
- resp = db.view('foo/view1', {});
- TEquals(10000, resp.rows.length);
-
- resp = db.view('foo/view2', {});
- TEquals(1, resp.rows.length);
-
- resp = db.designInfo("_design/foo");
- TEquals(20001, resp.view_index.update_seq);
-
-
- // update docs again...
- for (var i = 0; i < docs.length; i++) {
- docs[i].integer = docs[i].integer + 2;
- }
- db.bulkSave(docs);
-
-
- resp = db.view('foo/view1', {});
- TEquals(10000, resp.rows.length);
-
- resp = db.view('foo/view2', {});
- TEquals(1, resp.rows.length);
-
- resp = db.designInfo("_design/foo");
- TEquals(30001, resp.view_index.update_seq);
-
- var disk_size_before_compact = resp.view_index.sizes.file;
- var data_size_before_compact = resp.view_index.sizes.active;
-
- TEquals("number", typeof data_size_before_compact, "data size is a number");
- T(data_size_before_compact < disk_size_before_compact, "data size < file size");
-
- // compact view group
- var xhr = CouchDB.request("POST", "/" + db.name + "/_compact/foo");
- T(JSON.parse(xhr.responseText).ok === true);
-
- resp = db.designInfo("_design/foo");
- while (resp.view_index.compact_running === true) {
- resp = db.designInfo("_design/foo");
- }
-
-
- resp = db.view('foo/view1', {});
- TEquals(10000, resp.rows.length);
-
- resp = db.view('foo/view2', {});
- TEquals(1, resp.rows.length);
-
- resp = db.designInfo("_design/foo");
- TEquals(30001, resp.view_index.update_seq);
- T(resp.view_index.sizes.file < disk_size_before_compact);
- TEquals("number", typeof resp.view_index.sizes.active, "data size is a number");
- T(resp.view_index.sizes.active < resp.view_index.sizes.file, "data size < file size");
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/view_conflicts.js b/test/javascript/tests/view_conflicts.js
deleted file mode 100644
index b1efa234f..000000000
--- a/test/javascript/tests/view_conflicts.js
+++ /dev/null
@@ -1,57 +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.
-
-couchTests.elixir = true
-couchTests.view_conflicts = function(debug) {
-
- var db_name_a = get_random_db_name();
- var dbA = new CouchDB(db_name_a, {"X-Couch-Full-Commit":"false"});
-
- var db_name_b = get_random_db_name();
- var dbB = new CouchDB(db_name_b, {"X-Couch-Full-Commit":"false"});
-
- dbA.createDb();
- dbB.createDb();
- if (debug) debugger;
-
- var docA = {_id: "foo", bar: 42};
- T(dbA.save(docA).ok);
- CouchDB.replicate(dbA.name, dbB.name);
-
- var docB = dbB.open("foo");
- docB.bar = 43;
- dbB.save(docB);
- docA.bar = 41;
- dbA.save(docA);
- CouchDB.replicate(dbA.name, dbB.name);
-
- var doc = dbB.open("foo", {conflicts: true});
- T(doc._conflicts.length == 1);
- var conflictRev = doc._conflicts[0];
- if (doc.bar == 41) { // A won
- T(conflictRev == docB._rev);
- } else { // B won
- T(doc.bar == 43);
- T(conflictRev == docA._rev);
- }
-
- var results = dbB.query(function(doc) {
- if (doc._conflicts) {
- emit(doc._id, doc._conflicts);
- }
- });
- T(results.rows[0].value[0] == conflictRev);
-
- // cleanup
- dbA.deleteDb();
- dbB.deleteDb();
-};
diff --git a/test/javascript/tests/view_errors.js b/test/javascript/tests/view_errors.js
deleted file mode 100644
index 477422030..000000000
--- a/test/javascript/tests/view_errors.js
+++ /dev/null
@@ -1,211 +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.
-
-couchTests.elixir = true;
-couchTests.view_errors = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- // run_on_modified_server(
- // [{section: "couchdb",
- // key: "os_process_timeout",
- // value: "500"}],
- // function() {
- var doc = {integer: 1, string: "1", array: [1, 2, 3]};
- T(db.save(doc).ok);
-
- // emitting a key value that is undefined should result in that row
- // being included in the view results as null
- var results = db.query(function(doc) {
- emit(doc.undef, null);
- });
- T(results.total_rows == 1);
- T(results.rows[0].key == null);
-
- // if a view function throws an exception, its results are not included in
- // the view index, but the view does not itself raise an error
- var results = db.query(function(doc) {
- doc.undef(); // throws an error
- });
- T(results.total_rows == 0);
-
- // if a view function includes an undefined value in the emitted key or
- // value, it is treated as null
- var results = db.query(function(doc) {
- emit([doc._id, doc.undef], null);
- });
- T(results.total_rows == 1);
- T(results.rows[0].key[1] == null);
-
- // querying a view with invalid params should give a resonable error message
- var xhr = CouchDB.request("POST", "/" + db_name + "/_all_docs?startkey=foo", {
- headers: {"Content-Type": "application/json"},
- body: JSON.stringify({language: "javascript",
- map : "function(doc){emit(doc.integer)}"
- })
- });
- T(JSON.parse(xhr.responseText).error == "bad_request");
-
- // content type must be json
- var xhr = CouchDB.request("POST", "/" + db_name + "/_all_docs", {
- headers: {"Content-Type": "application/x-www-form-urlencoded"},
- body: JSON.stringify({language: "javascript",
- map : "function(doc){}"
- })
- });
- T(xhr.status == 415);
-
- var map = function (doc) {emit(doc.integer, doc.integer);};
-
- try {
- db.query(map, null, {group: true});
- T(0 == 1);
- } catch(e) {
- T(e.error == "query_parse_error");
- }
-
- var designDoc = {
- _id:"_design/test",
- language: "javascript",
- views: {
- "no_reduce": {map:"function(doc) {emit(doc._id, null);}"},
- "with_reduce": {
- map:"function (doc) {emit(doc.integer, doc.integer)};",
- reduce:"function (keys, values) { return sum(values); };"}
- }
- };
- T(db.save(designDoc).ok);
-
- var designDoc2 = {
- _id:"_design/testbig",
- language: "javascript",
- views: {
- "reduce_too_big" : {
- map:"function (doc) {emit(doc.integer, doc.integer)};",
- reduce:"function (keys, values) { var chars = []; for (var i=0; i < 1000; i++) {chars.push('wazzap');};return chars; };"}
- }
- };
- T(db.save(designDoc2).ok);
-
- try {
- db.view("test/no_reduce", {group: true});
- T(0 == 1);
- } catch(e) {
- T(db.last_req.status == 400);
- T(e.error == "query_parse_error");
- }
-
- try {
- db.view("test/no_reduce", {group_level: 1});
- T(0 == 1);
- } catch(e) {
- T(db.last_req.status == 400);
- T(e.error == "query_parse_error");
- }
-
- try {
- db.view("test/no_reduce", {reduce: true});
- T(0 == 1);
- } catch(e) {
- T(db.last_req.status == 400);
- T(e.error == "query_parse_error");
- }
-
- db.view("test/no_reduce", {reduce: false});
- TEquals(200, db.last_req.status, "reduce=false for map views (without"
- + " group or group_level) is allowed");
-
- try {
- db.view("test/with_reduce", {group: true, reduce: false});
- T(0 == 1);
- } catch(e) {
- T(db.last_req.status == 400);
- T(e.error == "query_parse_error");
- }
-
- try {
- db.view("test/with_reduce", {group_level: 1, reduce: false});
- T(0 == 1);
- } catch(e) {
- T(db.last_req.status == 400);
- T(e.error == "query_parse_error");
- }
-
- var designDoc3 = {
- _id:"_design/infinite",
- language: "javascript",
- views: {
- "infinite_loop" :{map:"function(doc) {while(true){emit(doc,doc);}};"}
- }
- };
- T(db.save(designDoc3).ok);
-
- try {
- db.view("infinite/infinite_loop");
- T(0 == 1);
- } catch(e) {
- // This test has two different races. The first is whether
- // the while loop exhausts the JavaScript RAM limits before
- // timing. The second is a race between which of two timeouts
- // fires first. The first timeout is the couch_os_process
- // waiting for data back from couchjs. The second is the
- // gen_server call to couch_os_process.
- T(e.error == "os_process_error" || e.error == "timeout");
- }
-
- // Check error responses for invalid multi-get bodies.
- var path = "/" + db_name + "/_design/test/_view/no_reduce";
- var xhr = CouchDB.request("POST", path, {body: "[]"});
- T(xhr.status == 400);
- result = JSON.parse(xhr.responseText);
- T(result.error == "bad_request");
- T(result.reason == "Request body must be a JSON object");
- var data = "{\"keys\": 1}";
- xhr = CouchDB.request("POST", path, {body:data});
- T(xhr.status == 400);
- result = JSON.parse(xhr.responseText);
- T(result.error == "bad_request");
- T(result.reason == "`keys` member must be an array.");
-
- // if the reduce grows to fast, throw an overflow error
- var path = "/" + db_name + "/_design/testbig/_view/reduce_too_big";
- xhr = CouchDB.request("GET", path);
- T(xhr.status == 200);
- result = JSON.parse(xhr.responseText);
- T(result.rows[0].error == "reduce_overflow_error");
-
- try {
- db.query(function() {emit(null, null)}, null, {startkey: 2, endkey:1});
- T(0 == 1);
- } catch(e) {
- T(e.error == "query_parse_error");
- T(e.reason.match(/no rows can match/i));
- }
-
- // querying a temporary view should give "gone" error message
- var xhr = CouchDB.request("POST", "/" + db_name + "/_temp_view", {
- headers: {"Content-Type": "application/json"},
- body: JSON.stringify({language: "javascript",
- map : "function(doc){emit(doc.integer)}"
- })
- });
- T(xhr.status == 410);
- result = JSON.parse(xhr.responseText);
- T(result.error == "gone");
- T(result.reason == "Temporary views are not supported in CouchDB");
- // });
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/view_include_docs.js b/test/javascript/tests/view_include_docs.js
deleted file mode 100644
index b96227d75..000000000
--- a/test/javascript/tests/view_include_docs.js
+++ /dev/null
@@ -1,196 +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.
-
-couchTests.elixir = true;
-couchTests.view_include_docs = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var docs = makeDocs(0, 100);
- db.bulkSave(docs);
-
- var designDoc = {
- _id:"_design/test",
- language: "javascript",
- views: {
- all_docs: {
- map: "function(doc) { emit(doc.integer, doc.string) }"
- },
- with_prev: {
- map: "function(doc){if(doc.prev) emit(doc._id,{'_rev':doc.prev}); else emit(doc._id,{'_rev':doc._rev});}"
- },
- with_id: {
- map: "function(doc) {if(doc.link_id) { var value = {'_id':doc.link_id}; if (doc.link_rev) {value._rev = doc.link_rev}; emit(doc._id, value);}};"
- },
- summate: {
- map:"function (doc) { if (typeof doc.integer === 'number') {emit(doc.integer, doc.integer)};}",
- reduce:"function (keys, values) { return sum(values); };"
- }
- }
- }
- T(db.save(designDoc).ok);
-
- var resp = db.view('test/all_docs', {include_docs: true, limit: 2});
- T(resp.rows.length == 2);
- T(resp.rows[0].id == "0");
- T(resp.rows[0].doc._id == "0");
- T(resp.rows[1].id == "1");
- T(resp.rows[1].doc._id == "1");
-
- resp = db.view('test/all_docs', {include_docs: true}, [29, 74]);
- T(resp.rows.length == 2);
- T(resp.rows[0].doc._id == "29");
- T(resp.rows[1].doc.integer == 74);
-
- resp = db.allDocs({limit: 2, skip: 1, include_docs: true});
- T(resp.rows.length == 2);
- T(resp.rows[0].doc.integer == 1);
- T(resp.rows[1].doc.integer == 10);
-
- resp = db.allDocs({include_docs: true}, ['not_a_doc']);
- T(resp.rows.length == 1);
- T(!resp.rows[0].doc);
-
- resp = db.allDocs({include_docs: true}, ["1", "foo"]);
- T(resp.rows.length == 2);
- T(resp.rows[0].doc.integer == 1);
- T(!resp.rows[1].doc);
-
- resp = db.allDocs({include_docs: true, limit: 0});
- T(resp.rows.length == 0);
-
- // No reduce support
- try {
- resp = db.view('test/summate', {include_docs: true});
- alert(JSON.stringify(resp));
- T(0==1);
- } catch (e) {
- T(e.error == 'query_parse_error');
- }
-
- // Reduce support when reduce=false
- resp = db.view('test/summate', {reduce: false, include_docs: true});
- T(resp.rows.length == 100);
-
- // Not an error with include_docs=false&reduce=true
- resp = db.view('test/summate', {reduce: true, include_docs: false});
- T(resp.rows.length == 1);
- T(resp.rows[0].value == 4950);
-
- T(db.save({
- "_id": "link-to-10",
- "link_id" : "10"
- }).ok);
-
- // you can link to another doc from a value.
- resp = db.view("test/with_id", {key:"link-to-10"});
- T(resp.rows[0].key == "link-to-10");
- T(resp.rows[0].value["_id"] == "10");
-
- resp = db.view("test/with_id", {key:"link-to-10",include_docs: true});
- T(resp.rows[0].key == "link-to-10");
- T(resp.rows[0].value["_id"] == "10");
- T(resp.rows[0].doc._id == "10");
-
- // Check emitted _rev controls things
- resp = db.allDocs({include_docs: true}, ["0"]);
- var before = resp.rows[0].doc;
-
- var after = db.open("0");
- after.integer = 100;
- after.prev = after._rev;
- resp = db.save(after)
- T(resp.ok);
-
- var after = db.open("0");
- TEquals(resp.rev, after._rev, "fails with firebug running");
- T(after._rev != after.prev, "passes");
- TEquals(100, after.integer, "fails with firebug running");
-
- // should emit the previous revision
- resp = db.view("test/with_prev", {include_docs: true}, ["0"]);
- T(resp.rows[0].doc._id == "0");
- T(resp.rows[0].doc._rev == before._rev);
- T(!resp.rows[0].doc.prev);
- T(resp.rows[0].doc.integer == 0);
-
- // there's no compaction on cluster (and the test ist questionable to say the least: mvcc is no version control after all) - but keep rest of test
- /*var xhr = CouchDB.request("POST", "/" + db_name + "/_compact");
- T(xhr.status == 202)
- while (db.info().compact_running) {}
-
- resp = db.view("test/with_prev", {include_docs: true}, ["0", "23"]);
- T(resp.rows.length == 2);
- T(resp.rows[0].key == "0");
- T(resp.rows[0].id == "0");
- T(!resp.rows[0].doc);
- T(resp.rows[0].doc == null);
- T(resp.rows[1].doc.integer == 23);*/
-
- // COUCHDB-549 - include_docs=true with conflicts=true
-
- var db_name_a = get_random_db_name();
- var db_name_b = get_random_db_name();
-
- var dbA = new CouchDB(db_name_a, {"X-Couch-Full-Commit":"false"});
- var dbB = new CouchDB(db_name_b, {"X-Couch-Full-Commit":"false"});
-
- dbA.createDb();
- dbB.createDb();
-
- var ddoc = {
- _id: "_design/mydesign",
- language : "javascript",
- views : {
- myview : {
- map: (function(doc) {
- emit(doc.value, 1);
- }).toString()
- }
- }
- };
- TEquals(true, dbA.save(ddoc).ok);
-
- var doc1a = {_id: "foo", value: 1, str: "1"};
- TEquals(true, dbA.save(doc1a).ok);
-
- var doc1b = {_id: "foo", value: 1, str: "666"};
- TEquals(true, dbB.save(doc1b).ok);
-
- var doc2 = {_id: "bar", value: 2, str: "2"};
- TEquals(true, dbA.save(doc2).ok);
-
- TEquals(true, CouchDB.replicate(dbA.name, dbB.name).ok);
-
- doc1b = dbB.open("foo", {conflicts: true});
- TEquals(true, doc1b._conflicts instanceof Array);
- TEquals(1, doc1b._conflicts.length);
- var conflictRev = doc1b._conflicts[0];
-
- doc2 = dbB.open("bar", {conflicts: true});
- TEquals("undefined", typeof doc2._conflicts);
-
- resp = dbB.view("mydesign/myview", {include_docs: true, conflicts: true});
-
- TEquals(2, resp.rows.length);
- TEquals(true, resp.rows[0].doc._conflicts instanceof Array);
- TEquals(1, resp.rows[0].doc._conflicts.length);
- TEquals(conflictRev, resp.rows[0].doc._conflicts[0]);
- TEquals("undefined", typeof resp.rows[1].doc._conflicts);
-
- // cleanup
- db.deleteDb();
- dbA.deleteDb();
- dbB.deleteDb();
-};
diff --git a/test/javascript/tests/view_multi_key_all_docs.js b/test/javascript/tests/view_multi_key_all_docs.js
deleted file mode 100644
index 8969c88c9..000000000
--- a/test/javascript/tests/view_multi_key_all_docs.js
+++ /dev/null
@@ -1,99 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-couchTests.elixir = true;
-couchTests.view_multi_key_all_docs = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var docs = makeDocs(0, 100);
- db.bulkSave(docs);
-
- var keys = ["10","15","30","37","50"];
- var rows = db.allDocs({},keys).rows;
- T(rows.length == keys.length);
- for(var i=0; i<rows.length; i++)
- T(rows[i].id == keys[i]);
-
- // keys in GET parameters
- rows = db.allDocs({keys:keys}, null).rows;
- T(rows.length == keys.length);
- for(var i=0; i<rows.length; i++)
- T(rows[i].id == keys[i]);
-
- rows = db.allDocs({limit: 1}, keys).rows;
- T(rows.length == 1);
- T(rows[0].id == keys[0]);
-
- // keys in GET parameters
- rows = db.allDocs({limit: 1, keys: keys}, null).rows;
- T(rows.length == 1);
- T(rows[0].id == keys[0]);
-
- rows = db.allDocs({skip: 2}, keys).rows;
- T(rows.length == 3);
- for(var i=0; i<rows.length; i++)
- T(rows[i].id == keys[i+2]);
-
- // keys in GET parameters
- rows = db.allDocs({skip: 2, keys: keys}, null).rows;
- T(rows.length == 3);
- for(var i=0; i<rows.length; i++)
- T(rows[i].id == keys[i+2]);
-
- rows = db.allDocs({descending: "true"}, keys).rows;
- T(rows.length == keys.length);
- for(var i=0; i<rows.length; i++)
- T(rows[i].id == keys[keys.length-i-1]);
-
- // keys in GET parameters
- rows = db.allDocs({descending: "true", keys: keys}, null).rows;
- T(rows.length == keys.length);
- for(var i=0; i<rows.length; i++)
- T(rows[i].id == keys[keys.length-i-1]);
-
- rows = db.allDocs({descending: "true", skip: 3, limit:1}, keys).rows;
- T(rows.length == 1);
- T(rows[0].id == keys[1]);
-
- // keys in GET parameters
- rows = db.allDocs({descending: "true", skip: 3, limit:1, keys: keys}, null).rows;
- T(rows.length == 1);
- T(rows[0].id == keys[1]);
-
- // Check we get invalid rows when the key doesn't exist
- rows = db.allDocs({}, ["1111", "i_dont_exist", "0"]).rows;
- T(rows.length == 3);
- T(rows[0].error == "not_found");
- T(!rows[0].id);
- T(rows[1].error == "not_found");
- T(!rows[1].id);
- T(rows[2].id == rows[2].key && rows[2].key == "0");
-
- // keys in GET parameters
- rows = db.allDocs({keys: ["1211", "i_dont_exist", "0"]}, null).rows;
- T(rows.length == 3);
- T(rows[0].error == "not_found");
- T(!rows[0].id);
- T(rows[1].error == "not_found");
- T(!rows[1].id);
- T(rows[2].id == rows[2].key && rows[2].key == "0");
-
- // empty keys
- rows = db.allDocs({keys: []}, null).rows;
- T(rows.length == 0);
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/view_multi_key_design.js b/test/javascript/tests/view_multi_key_design.js
deleted file mode 100644
index 20e52a2d0..000000000
--- a/test/javascript/tests/view_multi_key_design.js
+++ /dev/null
@@ -1,235 +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.
-
-couchTests.elixir = true;
-couchTests.view_multi_key_design = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var docs = makeDocs(0, 100);
- db.bulkSave(docs);
-
- var designDoc = {
- _id:"_design/test",
- language: "javascript",
- views: {
- all_docs: {
- map: "function(doc) { emit(doc.integer, doc.string) }"
- },
- multi_emit: {
- map: "function(doc) {for(var i = 0 ; i < 3 ; i++) { emit(i, doc.integer) ; } }"
- },
- summate: {
- map:"function (doc) {emit(doc.integer, doc.integer)};",
- reduce:"function (keys, values) { return sum(values); };"
- }
- }
- };
- T(db.save(designDoc).ok);
-
- // Test that missing keys work too
- var keys = [101,30,15,37,50];
- var reduce = db.view("test/summate",{group:true},keys).rows;
- T(reduce.length == keys.length-1); // 101 is missing
- for(var i=0; i<reduce.length; i++) {
- T(keys.indexOf(reduce[i].key) != -1);
- T(reduce[i].key == reduce[i].value);
- }
-
- // First, the goods:
- var keys = [10,15,30,37,50];
- var rows = db.view("test/all_docs",{},keys).rows;
- for(var i=0; i<rows.length; i++) {
- T(keys.indexOf(rows[i].key) != -1);
- T(rows[i].key == rows[i].value);
- }
-
- // with GET keys
- rows = db.view("test/all_docs",{keys:keys},null).rows;
- for(var i=0;i<rows.length; i++) {
- T(keys.indexOf(rows[i].key) != -1);
- T(rows[i].key == rows[i].value);
- }
-
- // with empty keys
- rows = db.view("test/all_docs",{keys:[]},null).rows;
- T(rows.length == 0);
-
- var reduce = db.view("test/summate",{group:true},keys).rows;
- T(reduce.length == keys.length);
- for(var i=0; i<reduce.length; i++) {
- T(keys.indexOf(reduce[i].key) != -1);
- T(reduce[i].key == reduce[i].value);
- }
-
- // with GET keys
- reduce = db.view("test/summate",{group:true,keys:keys},null).rows;
- T(reduce.length == keys.length);
- for(var i=0; i<reduce.length; i++) {
- T(keys.indexOf(reduce[i].key) != -1);
- T(reduce[i].key == reduce[i].value);
- }
-
- // Test that invalid parameter combinations get rejected
- var badargs = [{startkey:0}, {endkey:0}, {key: 0}, {group_level: 2}];
- var getbadargs = [{startkey:0, keys:keys}, {endkey:0, keys:keys},
- {key:0, keys:keys}, {group_level: 2, keys:keys}];
- for(var i in badargs)
- {
- try {
- db.view("test/all_docs",badargs[i],keys);
- T(0==1);
- } catch (e) {
- T(e.error == "query_parse_error");
- }
-
- try {
- db.view("test/all_docs",getbadargs[i],null);
- T(0==1);
- } catch (e) {
- T(e.error = "query_parse_error");
- }
- }
-
- try {
- db.view("test/summate",{},keys);
- T(0==1);
- } catch (e) {
- T(e.error == "query_parse_error");
- }
-
- try {
- db.view("test/summate",{keys:keys},null);
- T(0==1);
- } catch (e) {
- T(e.error == "query_parse_error");
- }
-
- // Test that a map & reduce containing func support keys when reduce=false
- var resp = db.view("test/summate", {reduce: false}, keys);
- T(resp.rows.length == 5);
-
- resp = db.view("test/summate", {reduce: false, keys: keys}, null);
- T(resp.rows.length == 5);
-
- // Check that limiting by startkey_docid and endkey_docid get applied
- // as expected.
- var curr = db.view("test/multi_emit", {startkey_docid: 21, endkey_docid: 23}, [0, 2]).rows;
- var exp_key = [ 0, 0, 0, 2, 2, 2] ;
- var exp_val = [21, 22, 23, 21, 22, 23] ;
- T(curr.length == 6);
- for( var i = 0 ; i < 6 ; i++)
- {
- T(curr[i].key == exp_key[i]);
- T(curr[i].value == exp_val[i]);
- }
-
- curr = db.view("test/multi_emit", {startkey_docid: 21, endkey_docid: 23, keys: [0, 2]}, null).rows;
- T(curr.length == 6);
- for( var i = 0 ; i < 6 ; i++)
- {
- T(curr[i].key == exp_key[i]);
- T(curr[i].value == exp_val[i]);
- }
-
- // Check limit works
- curr = db.view("test/all_docs", {limit: 1}, keys).rows;
- T(curr.length == 1);
- T(curr[0].key == 10);
-
- curr = db.view("test/all_docs", {limit: 1, keys: keys}, null).rows;
- T(curr.length == 1);
- T(curr[0].key == 10);
-
- // Check offset works
- curr = db.view("test/multi_emit", {skip: 1}, [0]).rows;
- T(curr.length == 99);
- // values are arbitrary as too many keys are the same
- //T(curr[0].value == 1);
-
- curr = db.view("test/multi_emit", {skip: 1, keys: [0]}, null).rows;
- T(curr.length == 99);
- // values are arbitrary as too many keys are the same
- //T(curr[0].value == 1);
-
- // Check that dir works
- curr = db.view("test/multi_emit", {descending: "true"}, [1]).rows;
- T(curr.length == 100);
- // values are arbitrary as too many keys are the same
- //T(curr[0].value == 99);
- //T(curr[99].value == 0);
-
- curr = db.view("test/multi_emit", {descending: "true", keys: [1]}, null).rows;
- T(curr.length == 100);
- // values are arbitrary as too many keys are the same
- //T(curr[0].value == 99);
- //T(curr[99].value == 0);
-
- // Check a couple combinations
- curr = db.view("test/multi_emit", {descending: "true", skip: 3, limit: 2}, [2]).rows;
- T(curr.length, 2);
- // values are arbitrary as too many keys are the same
- //T(curr[0].value == 96);
- //T(curr[1].value == 95);
-
- curr = db.view("test/multi_emit", {descending: "true", skip: 3, limit: 2, keys: [2]}, null).rows;
- T(curr.length, 2);
- // values are arbitrary as too many keys are the same
- //T(curr[0].value == 96);
- //T(curr[1].value == 95);
-
- curr = db.view("test/multi_emit", {skip: 0, limit: 1, startkey_docid: "13"}, [0]).rows;
- // that's the maximum we can get
- T(curr.length == 1);
- T(curr[0].value == 13);
-
- curr = db.view("test/multi_emit", {skip: 2, limit: 3, startkey_docid: "13"}, [0]).rows;
- T(curr.length == 3);
- // values are arbitrary as too many keys are the same
- //T(curr[0].value == 15);
- //T(curr[1].value == 16);
- //T(curr[2].value == 17);
-
- curr = db.view("test/multi_emit", {skip: 2, limit: 3, startkey_docid: "13", keys: [0]}, null).rows;
- T(curr.length == 3);
- // values are arbitrary as too many keys are the same
- //T(curr[0].value == 15);
- //T(curr[1].value == 16);
- //T(curr[2].value == 17);
-
- curr = db.view("test/multi_emit",
- {skip: 1, limit: 5, startkey_docid: "25", endkey_docid: "27"}, [1]).rows;
- T(curr.length == 2);
- // that's again the maximum we can get
- T(curr[0].value == 26 || curr[0].value == 27);
-
- curr = db.view("test/multi_emit",
- {skip: 1, limit: 5, startkey_docid: "25", endkey_docid: "27", keys: [1]}, null).rows;
- T(curr.length == 2);
- // that's again the maximum we can get
- T(curr[0].value == 26 || curr[0].value == 27);
-
- curr = db.view("test/multi_emit",
- {skip: 1, limit: 5, startkey_docid: "28", endkey_docid: "26", descending: "true"}, [1]).rows;
- T(curr.length == 2);
- // that's again the maximum we can get
- T(curr[0].value == 26 || curr[0].value == 27);
-
- curr = db.view("test/multi_emit",
- {skip: 1, limit: 5, startkey_docid: "28", endkey_docid: "26", descending: "true", keys: [1]}, null).rows;
- T(curr.length == 2);
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/view_multi_key_temp.js b/test/javascript/tests/view_multi_key_temp.js
deleted file mode 100644
index 2bed6e7bf..000000000
--- a/test/javascript/tests/view_multi_key_temp.js
+++ /dev/null
@@ -1,44 +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.
-
-couchTests.skip = true;
-couchTests.view_multi_key_temp = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var docs = makeDocs(0, 100);
- db.bulkSave(docs);
-
- var queryFun = function(doc) { emit(doc.integer, doc.integer) };
- var reduceFun = function (keys, values) { return sum(values); };
-
- var keys = [10,15,30,37,50];
- var rows = db.query(queryFun, null, {}, keys).rows;
- for(var i=0; i<rows.length; i++) {
- T(keys.indexOf(rows[i].key) != -1);
- T(rows[i].key == rows[i].value);
- }
-
- var reduce = db.query(queryFun, reduceFun, {group:true}, keys).rows;
- for(var i=0; i<reduce.length; i++) {
- T(keys.indexOf(reduce[i].key) != -1);
- T(reduce[i].key == reduce[i].value);
- }
-
- rows = db.query(queryFun, null, {}, []).rows;
- T(rows.length == 0);
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/view_offsets.js b/test/javascript/tests/view_offsets.js
deleted file mode 100644
index 179c96360..000000000
--- a/test/javascript/tests/view_offsets.js
+++ /dev/null
@@ -1,118 +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.
-
-couchTests.elixir = true;
-
-couchTests.view_offsets = function(debug) {
- if (debug) debugger;
-
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
-
- var designDoc = {
- _id : "_design/test",
- views : {
- offset : {
- map : "function(doc) { emit([doc.letter, doc.number], doc); }",
- }
- }
- };
- T(db.save(designDoc).ok);
-
- var docs = [
- {_id : "a1", letter : "a", number : 1, foo: "bar"},
- {_id : "a2", letter : "a", number : 2, foo: "bar"},
- {_id : "a3", letter : "a", number : 3, foo: "bar"},
- {_id : "b1", letter : "b", number : 1, foo: "bar"},
- {_id : "b2", letter : "b", number : 2, foo: "bar"},
- {_id : "b3", letter : "b", number : 3, foo: "bar"},
- {_id : "b4", letter : "b", number : 4, foo: "bar"},
- {_id : "b5", letter : "b", number : 5, foo: "bar"},
- {_id : "c1", letter : "c", number : 1, foo: "bar"},
- {_id : "c2", letter : "c", number : 2, foo: "bar"},
- ];
- db.bulkSave(docs);
-
- var check = function(startkey, offset) {
- var opts = {startkey: startkey, descending: true};
- T(db.view("test/offset", opts).offset == offset);
- };
-
- [
- [["c", 2], 0],
- [["c", 1], 1],
- [["b", 5], 2],
- [["b", 4], 3],
- [["b", 3], 4],
- [["b", 2], 5],
- [["b", 1], 6],
- [["a", 3], 7],
- [["a", 2], 8],
- [["a", 1], 9]
- ].forEach(function(row){ check(row[0], row[1]);});
-
- var runTest = function () {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- // (the DB will never exist per se)
- //db.deleteDb();
- db.createDb();
-
- var designDoc = {
- _id : "_design/test",
- views : {
- offset : {
- map : "function(doc) { emit([doc.letter, doc.number], doc);}",
- }
- }
- };
- T(db.save(designDoc).ok);
-
- var docs = [
- {_id : "a1", letter : "a", number : 1, foo : "bar"},
- {_id : "a2", letter : "a", number : 2, foo : "bar"},
- {_id : "a3", letter : "a", number : 3, foo : "bar"},
- {_id : "b1", letter : "b", number : 1, foo : "bar"},
- {_id : "b2", letter : "b", number : 2, foo : "bar"},
- {_id : "b3", letter : "b", number : 3, foo : "bar"},
- {_id : "b4", letter : "b", number : 4, foo : "bar"},
- {_id : "b5", letter : "b", number : 5, foo : "bar"},
- {_id : "c1", letter : "c", number : 1, foo : "bar"},
- {_id : "c2", letter : "c", number : 2, foo : "bar"}
- ];
- db.bulkSave(docs);
-
- var res1 = db.view("test/offset", {
- startkey: ["b",4], startkey_docid: "b4", endkey: ["b"],
- limit: 2, descending: true, skip: 1
- })
-
- var res2 = db.view("test/offset", {startkey: ["c", 3]});
- var res3 = db.view("test/offset", {
- startkey: ["b", 6],
- endkey: ["b", 7]
- });
-
- // delete (temp) DB now
- db.deleteDb();
-
- return res1.offset == 4 && res2.offset == docs.length && res3.offset == 8;
-
- };
-
- for(var i = 0; i < 15; i++) T(runTest());
-
- // cleanup
- db.deleteDb();
-}
-
diff --git a/test/javascript/tests/view_pagination.js b/test/javascript/tests/view_pagination.js
deleted file mode 100644
index 6da5f8d48..000000000
--- a/test/javascript/tests/view_pagination.js
+++ /dev/null
@@ -1,151 +0,0 @@
-// Licensed under the Apache License, Version 2.0 (the "License"); you may not
-// use this file except in compliance with the License. You may obtain a copy of
-// the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations under
-// the License.
-
-couchTests.elixir = true;
-
-couchTests.view_pagination = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var docs = makeDocs(0, 100);
- db.bulkSave(docs);
-
- var queryFun = function(doc) { emit(doc.integer, null); };
- var i;
-
- // page through the view ascending
- for (i = 0; i < docs.length; i += 10) {
- var queryResults = db.query(queryFun, null, {
- startkey: i,
- startkey_docid: i,
- limit: 10
- });
- T(queryResults.rows.length == 10);
- TEquals(docs.length, queryResults.total_rows, "doc.length should match query.length");
- T(queryResults.offset == i);
- var j;
- for (j = 0; j < 10;j++) {
- T(queryResults.rows[j].key == i + j);
- }
-
- // test aliases start_key and start_key_doc_id
- queryResults = db.query(queryFun, null, {
- start_key: i,
- start_key_doc_id: i,
- limit: 10
- });
- T(queryResults.rows.length == 10);
- T(queryResults.total_rows == docs.length);
- T(queryResults.offset == i);
- for (j = 0; j < 10;j++) {
- T(queryResults.rows[j].key == i + j);
- }
- }
-
- // page through the view descending
- for (i = docs.length - 1; i >= 0; i -= 10) {
- var queryResults = db.query(queryFun, null, {
- startkey: i,
- startkey_docid: i,
- descending: true,
- limit: 10
- });
- T(queryResults.rows.length == 10);
- T(queryResults.total_rows == docs.length);
- T(queryResults.offset == docs.length - i - 1);
- var j;
- for (j = 0; j < 10; j++) {
- T(queryResults.rows[j].key == i - j);
- }
- }
-
- // ignore decending=false. CouchDB should just ignore that.
- for (i = 0; i < docs.length; i += 10) {
- var queryResults = db.query(queryFun, null, {
- startkey: i,
- startkey_docid: i,
- descending: false,
- limit: 10
- });
- T(queryResults.rows.length == 10);
- T(queryResults.total_rows == docs.length);
- T(queryResults.offset == i);
- var j;
- for (j = 0; j < 10;j++) {
- T(queryResults.rows[j].key == i + j);
- }
- }
-
- function testEndkeyDocId(queryResults) {
- T(queryResults.rows.length == 35);
- T(queryResults.total_rows == docs.length);
- T(queryResults.offset == 1);
- T(queryResults.rows[0].id == "1");
- T(queryResults.rows[1].id == "10");
- T(queryResults.rows[2].id == "11");
- T(queryResults.rows[3].id == "12");
- T(queryResults.rows[4].id == "13");
- T(queryResults.rows[5].id == "14");
- T(queryResults.rows[6].id == "15");
- T(queryResults.rows[7].id == "16");
- T(queryResults.rows[8].id == "17");
- T(queryResults.rows[9].id == "18");
- T(queryResults.rows[10].id == "19");
- T(queryResults.rows[11].id == "2");
- T(queryResults.rows[12].id == "20");
- T(queryResults.rows[13].id == "21");
- T(queryResults.rows[14].id == "22");
- T(queryResults.rows[15].id == "23");
- T(queryResults.rows[16].id == "24");
- T(queryResults.rows[17].id == "25");
- T(queryResults.rows[18].id == "26");
- T(queryResults.rows[19].id == "27");
- T(queryResults.rows[20].id == "28");
- T(queryResults.rows[21].id == "29");
- T(queryResults.rows[22].id == "3");
- T(queryResults.rows[23].id == "30");
- T(queryResults.rows[24].id == "31");
- T(queryResults.rows[25].id == "32");
- T(queryResults.rows[26].id == "33");
- T(queryResults.rows[27].id == "34");
- T(queryResults.rows[28].id == "35");
- T(queryResults.rows[29].id == "36");
- T(queryResults.rows[30].id == "37");
- T(queryResults.rows[31].id == "38");
- T(queryResults.rows[32].id == "39");
- T(queryResults.rows[33].id == "4");
- T(queryResults.rows[34].id == "40");
- }
-
- // test endkey_docid
- var queryResults = db.query(function(doc) { emit(null, null); }, null, {
- startkey: null,
- startkey_docid: 1,
- endkey: null,
- endkey_docid: 40
- });
- testEndkeyDocId(queryResults);
-
- // test aliases end_key_doc_id and end_key
- queryResults = db.query(function(doc) { emit(null, null); }, null, {
- start_key: null,
- start_key_doc_id: 1,
- end_key: null,
- end_key_doc_id: 40
- });
- testEndkeyDocId(queryResults);
-
- // cleanup
- db.deleteDb();
- };
diff --git a/test/javascript/tests/view_sandboxing.js b/test/javascript/tests/view_sandboxing.js
deleted file mode 100644
index 0e5f308a9..000000000
--- a/test/javascript/tests/view_sandboxing.js
+++ /dev/null
@@ -1,169 +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.
-
-couchTests.elixir = true
-couchTests.view_sandboxing = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- var doc = {integer: 1, string: "1", array: [1, 2, 3]};
- T(db.save(doc).ok);
-
- // make sure that attempting to change the document throws an error
- var results = db.query(function(doc) {
- doc.integer = 2;
- emit(null, doc);
- }, null, {"include_docs": true});
- // either we have an error or our doc is unchanged
- T(results.total_rows == 0 || results.rows[0].doc.integer == 1);
-
- var results = db.query(function(doc) {
- doc.array[0] = 0;
- emit(null, doc);
- }, null, {"include_docs": true});
- // either we have an error or our doc is unchanged
- T(results.total_rows == 0 || results.rows[0].doc.array[0] == 1);
-
- // make sure that a view cannot invoke interpreter internals such as the
- // garbage collector
- var results = db.query(function(doc) {
- gc();
- emit(null, doc);
- });
- T(results.total_rows == 0);
-
- // make sure that a view cannot access the map_funs array defined used by
- // the view server
- var results = db.query(function(doc) { map_funs.push(1); emit(null, doc); });
- T(results.total_rows == 0);
-
- // make sure that a view cannot access the map_results array defined used by
- // the view server
- var results = db.query(function(doc) { map_results.push(1); emit(null, doc); });
- T(results.total_rows == 0);
-
- // test for COUCHDB-925
- // altering 'doc' variable in map function affects other map functions
- var ddoc = {
- _id: "_design/foobar",
- language: "javascript",
- views: {
- view1: {
- map:
- (function(doc) {
- if (doc.values) {
- doc.values = [666];
- }
- if (doc.tags) {
- doc.tags.push("qwerty");
- }
- if (doc.tokens) {
- doc.tokens["c"] = 3;
- }
- }).toString()
- },
- view2: {
- map:
- (function(doc) {
- if (doc.values) {
- emit(doc._id, doc.values);
- }
- if (doc.tags) {
- emit(doc._id, doc.tags);
- }
- if (doc.tokens) {
- emit(doc._id, doc.tokens);
- }
- }).toString()
- }
- }
- };
- var doc1 = {
- _id: "doc1",
- values: [1, 2, 3]
- };
- var doc2 = {
- _id: "doc2",
- tags: ["foo", "bar"],
- tokens: {a: 1, b: 2}
- };
-
- db.deleteDb();
- // avoid Heisenbugs when files are not cleared entirely
- db_name = get_random_db_name();
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- T(db.save(ddoc).ok);
- T(db.save(doc1).ok);
- T(db.save(doc2).ok);
-
- var view1Results = db.view(
- "foobar/view1", {bypass_cache: Math.round(Math.random() * 1000)});
- var view2Results = db.view(
- "foobar/view2", {bypass_cache: Math.round(Math.random() * 1000)});
-
- TEquals(0, view1Results.rows.length, "view1 has 0 rows");
- TEquals(3, view2Results.rows.length, "view2 has 3 rows");
-
- TEquals(doc1._id, view2Results.rows[0].key);
- TEquals(doc2._id, view2Results.rows[1].key);
- TEquals(doc2._id, view2Results.rows[2].key);
-
- // https://bugzilla.mozilla.org/show_bug.cgi?id=449657
- TEquals(3, view2Results.rows[0].value.length,
- "Warning: installed SpiderMonkey version doesn't allow sealing of arrays");
- if (view2Results.rows[0].value.length === 3) {
- TEquals(1, view2Results.rows[0].value[0]);
- TEquals(2, view2Results.rows[0].value[1]);
- TEquals(3, view2Results.rows[0].value[2]);
- }
-
- // we can't be 100% sure about the order for the same key
- T(view2Results.rows[1].value["a"] == 1 || view2Results.rows[1].value[0] == "foo");
- T(view2Results.rows[1].value["b"] == 2 || view2Results.rows[1].value[1] == "bar");
- T(view2Results.rows[2].value["a"] == 1 || view2Results.rows[2].value[0] == "foo");
- T(view2Results.rows[2].value["b"] == 2 || view2Results.rows[2].value[1] == "bar");
- TEquals('undefined', typeof view2Results.rows[1].value["c"], "doc2.tokens object was not sealed");
- TEquals('undefined', typeof view2Results.rows[2].value["c"], "doc2.tokens object was not sealed");
-
-/* (see above)
- TEquals(2, view2Results.rows[2].value.length,
- "Warning: installed SpiderMonkey version doesn't allow sealing of arrays");
- if (view2Results.rows[2].value.length === 2) {
- TEquals("foo", view2Results.rows[2].value[0]);
- TEquals("bar", view2Results.rows[2].value[1]);
- }
-*/
-
- // cleanup
- db.deleteDb();
-
- // test that runtime code evaluation can be prevented
- db_name = get_random_db_name();
- db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
-
- var doc = {integer: 1, string: "1", array: [1, 2, 3]};
- T(db.save(doc).ok);
-
- var results = db.query(function(doc) {
- var glob = emit.constructor('return this')();
- emit(doc._id, null);
- });
-
- TEquals(0, results.rows.length);
-
- // cleanup
- db.deleteDb();
-};
diff --git a/test/javascript/tests/view_update_seq.js b/test/javascript/tests/view_update_seq.js
deleted file mode 100644
index 8b3a3fb84..000000000
--- a/test/javascript/tests/view_update_seq.js
+++ /dev/null
@@ -1,119 +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.
-
-couchTests.elixir = true;
-couchTests.view_update_seq = function(debug) {
- var db_name = get_random_db_name();
- var db = new CouchDB(db_name, {"X-Couch-Full-Commit":"false"});
- db.createDb();
- if (debug) debugger;
-
- TEquals("0", db.info().update_seq.substr(0, 1), "db should be empty");
-
- var resp = db.allDocs({update_seq:true});
-
- T(resp.rows.length == 0);
- TEquals("0", resp.update_seq.substr(0, 1), "db should be empty");
-
- var designDoc = {
- _id:"_design/test",
- language: "javascript",
- autoupdate: false,
- views: {
- all_docs: {
- map: "function(doc) { emit(doc.integer, doc.string) }"
- },
- summate: {
- map:"function (doc) { if (typeof doc.integer === 'number') { emit(doc.integer, doc.integer)}; }",
- reduce:"function (keys, values) { return sum(values); };"
- }
- }
- };
-
- var seqInt = function(val) {
- if (typeof(val) === 'string') {
- return parseInt(val.split('-')[0]);
- } else {
- return val;
- }
- };
-
- T(db.save(designDoc).ok);
-
- TEquals(1, seqInt(db.info().update_seq));
-
- resp = db.allDocs({update_seq:true});
-
- T(resp.rows.length == 1);
- TEquals(1, seqInt(resp.update_seq));
-
- var docs = makeDocs(0, 100);
- db.bulkSave(docs);
-
- resp = db.allDocs({limit: 1});
- T(resp.rows.length == 1);
- T(!resp.update_seq, "all docs");
-
- resp = db.allDocs({limit: 1, update_seq:true});
- T(resp.rows.length == 1);
- TEquals(101, seqInt(resp.update_seq));
-
- resp = db.view('test/all_docs', {limit: 1, update_seq:true});
- T(resp.rows.length == 1);
- TEquals(101, seqInt(resp.update_seq));
-
- resp = db.view('test/all_docs', {limit: 1, update_seq:false});
- T(resp.rows.length == 1);
- T(!resp.update_seq, "view");
-
- resp = db.view('test/summate', {update_seq:true});
- T(resp.rows.length == 1);
- TEquals(101, seqInt(resp.update_seq));
-
- db.save({"id":"0", "integer": 1});
- resp = db.view('test/all_docs', {limit: 1,stale: "ok", update_seq:true});
- T(resp.rows.length == 1);
- TEquals(101, seqInt(resp.update_seq));
-
- db.save({"id":"00", "integer": 2});
- resp = db.view('test/all_docs',
- {limit: 1, stale: "update_after", update_seq: true});
- T(resp.rows.length == 1);
- TEquals(101, seqInt(resp.update_seq));
-
- // wait 5 seconds for the next assertions to pass in very slow machines
- var t0 = new Date(), t1;
- do {
- CouchDB.request("GET", "/");
- t1 = new Date();
- } while ((t1 - t0) < 5000);
-
- resp = db.view('test/all_docs', {limit: 1, stale: "ok", update_seq: true});
- T(resp.rows.length == 1);
- TEquals(103, seqInt(resp.update_seq));
-
- resp = db.view('test/all_docs', {limit: 1, update_seq:true});
- T(resp.rows.length == 1);
- TEquals(103, seqInt(resp.update_seq));
-
- resp = db.view('test/all_docs',{update_seq:true},["0","1"]);
- TEquals(103, seqInt(resp.update_seq));
-
- resp = db.view('test/all_docs',{update_seq:true},["0","1"]);
- TEquals(103, seqInt(resp.update_seq));
-
- resp = db.view('test/summate',{group:true, update_seq:true},[0,1]);
- TEquals(103, seqInt(resp.update_seq));
-
- // cleanup
- db.deleteDb();
-};