You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2023/03/16 13:42:31 UTC
[couchdb] branch main updated: Improve couch_js_tests
This is an automated email from the ASF dual-hosted git repository.
vatamane pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/couchdb.git
The following commit(s) were added to refs/heads/main by this push:
new b9762479f Improve couch_js_tests
b9762479f is described below
commit b9762479fa9dd43bfa799ac4eb60f7394aa999ea
Author: Nick Vatamaniuc <va...@gmail.com>
AuthorDate: Thu Mar 16 01:42:52 2023 -0400
Improve couch_js_tests
There are a few minor improvements:
- Add more tests to check sandboxing resets, and that docs are "frozen".
- Remove the extra `\n` and `"` around function body lines. Erlang can do
multi-line binaries just fine. Mark the sections with %erlfmt-ignore to the
formatter doesn't complain.
- Generalize `should_create_sandbox` test to check for the `not defined` string
only. Experimenting with QuickJS noticed that it uses single quotes
around`'Object.foo' is not defined` and SM doesn't. So check for `not
defined` part only as it's obvious enough what the check is about.
- Make sure to return test procs back to the pool. Previously, none of the
tests returned the processes back into the pool, and when the tests ended,
they were forcibly killed which resulted in log noise that looked like:
```
erl_child_setup: failed with error 32 on line 265
erl_child_setup: failed with error 32 on line 265
...
```
---
src/couch/test/eunit/couch_js_tests.erl | 171 +++++++++++++++++++++-----------
1 file changed, 111 insertions(+), 60 deletions(-)
diff --git a/src/couch/test/eunit/couch_js_tests.erl b/src/couch/test/eunit/couch_js_tests.erl
index ea28d4040..789b36321 100644
--- a/src/couch/test/eunit/couch_js_tests.erl
+++ b/src/couch/test/eunit/couch_js_tests.erl
@@ -22,6 +22,8 @@ couch_js_test_() ->
fun test_util:stop_couch/1,
[
fun should_create_sandbox/0,
+ fun should_reset_properly/0,
+ fun should_freeze_doc_object/0,
fun should_roundtrip_utf8/0,
fun should_roundtrip_modified_utf8/0,
fun should_replace_broken_utf16/0,
@@ -31,36 +33,80 @@ couch_js_test_() ->
}
}.
+%% erlfmt-ignore
should_create_sandbox() ->
% Try and detect whether we can see out of the
% sandbox or not.
- Src = <<
- "function(doc) {\n"
- " try {\n"
- " emit(false, typeof(Couch.compile_function));\n"
- " } catch (e) {\n"
- " emit(true, e.message);\n"
- " }\n"
- "}\n"
- >>,
+ Src = <<"
+ function(doc) {
+ try {
+ emit(false, typeof(Couch.compile_function));
+ } catch (e) {
+ emit(true, e.message);
+ }
+ }
+ ">>,
+ Proc = couch_query_servers:get_os_process(<<"javascript">>),
+ true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src]),
+ Result = couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, {[]}]),
+ ?assertMatch([[[true, <<_/binary>>]]], Result),
+ [[[true, ErrMsg]]] = Result,
+ ?assertNotEqual([], binary:matches(ErrMsg, <<"not defined">>)),
+ couch_query_servers:ret_os_process(Proc).
+
+%% erlfmt-ignore
+should_reset_properly() ->
+ Src = <<"
+ function(doc) {
+ var a = [0,1,2];
+ emit(a.indexOf(0), Object.foo);
+ Object.foo = 43;
+ [].constructor.prototype.indexOf = function(x) {return 42;};
+ }
+ ">>,
Proc = couch_query_servers:get_os_process(<<"javascript">>),
true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src]),
- Result = couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, <<"{}">>]),
- ?assertEqual([[[true, <<"Couch is not defined">>]]], Result).
+ Doc = {[]},
+ Result1 = couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, Doc]),
+ ?assertEqual([[[0, null]]], Result1),
+ Result2 = couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, Doc]),
+ ?assertEqual([[[42, 43]]], Result2),
+ true = couch_query_servers:proc_prompt(Proc, [<<"reset">>]),
+ true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src]),
+ Result3 = couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, Doc]),
+ ?assertEqual([[[0, null]]], Result3),
+ couch_query_servers:ret_os_process(Proc).
+%% erlfmt-ignore
+should_freeze_doc_object() ->
+ Src = <<"
+ function(doc) {
+ emit(doc.foo, doc.bar);
+ doc.foo = 1042;
+ doc.bar = 1043;
+ emit(doc.foo, doc.bar);
+ }
+ ">>,
+ Proc = couch_query_servers:get_os_process(<<"javascript">>),
+ true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src]),
+ Doc = {[{<<"bar">>, 1041}]},
+ Result1 = couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, Doc]),
+ ?assertEqual([[[null, 1041], [null, 1041]]], Result1),
+ Result2 = couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, Doc]),
+ ?assertEqual([[[null, 1041], [null, 1041]]], Result2),
+ couch_query_servers:ret_os_process(Proc).
+
+%% erlfmt-ignore
should_roundtrip_utf8() ->
% Try round tripping UTF-8 both directions through
% couchjs. These tests use hex encoded values of
% Ä (C384) and Ü (C39C) so as to avoid odd editor/Erlang encoding
% strangeness.
Src = <<
- "function(doc) {\n"
- " emit(doc.value, \"",
- 16#C3,
- 16#9C,
- "\");\n"
- "}\n"
- >>,
+ "function(doc) {
+ emit(doc.value, \"", 16#C3, 16#9C, "\");
+ }
+ ">>,
Proc = couch_query_servers:get_os_process(<<"javascript">>),
true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src]),
Doc =
@@ -68,18 +114,17 @@ should_roundtrip_utf8() ->
{<<"value">>, <<16#C3, 16#84>>}
]},
Result = couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, Doc]),
- ?assertEqual([[[<<16#C3, 16#84>>, <<16#C3, 16#9C>>]]], Result).
+ ?assertEqual([[[<<16#C3, 16#84>>, <<16#C3, 16#9C>>]]], Result),
+ couch_query_servers:ret_os_process(Proc).
+%% erlfmt-ignore
should_roundtrip_modified_utf8() ->
% Mimicking the test case from the mailing list
- Src = <<
- "function(doc) {\n"
- " emit(doc.value.toLowerCase(), \"",
- 16#C3,
- 16#9C,
- "\");\n"
- "}\n"
- >>,
+ Src = <<"
+ function(doc) {
+ emit(doc.value.toLowerCase(), \"", 16#C3, 16#9C, "\");
+ }
+ ">>,
Proc = couch_query_servers:get_os_process(<<"javascript">>),
true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src]),
Doc =
@@ -87,16 +132,18 @@ should_roundtrip_modified_utf8() ->
{<<"value">>, <<16#C3, 16#84>>}
]},
Result = couch_query_servers:proc_prompt(Proc, [<<"map_doc">>, Doc]),
- ?assertEqual([[[<<16#C3, 16#A4>>, <<16#C3, 16#9C>>]]], Result).
+ ?assertEqual([[[<<16#C3, 16#A4>>, <<16#C3, 16#9C>>]]], Result),
+ couch_query_servers:ret_os_process(Proc).
+%% erlfmt-ignore
should_replace_broken_utf16() ->
% This test reverse the surrogate pair of
% the Boom emoji U+1F4A5
- Src = <<
- "function(doc) {\n"
- " emit(doc.value.split(\"\").reverse().join(\"\"), 1);\n"
- "}\n"
- >>,
+ Src = <<"
+ function(doc) {
+ emit(doc.value.split(\"\").reverse().join(\"\"), 1);
+ }
+ ">>,
Proc = couch_query_servers:get_os_process(<<"javascript">>),
true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src]),
Doc =
@@ -107,8 +154,10 @@ should_replace_broken_utf16() ->
% Invalid UTF-8 gets replaced with the 16#FFFD replacement
% marker
Markers = list_to_binary(xmerl_ucs:to_utf8([16#FFFD, 16#FFFD])),
- ?assertEqual([[[Markers, 1]]], Result).
+ ?assertEqual([[[Markers, 1]]], Result),
+ couch_query_servers:ret_os_process(Proc).
+%% erlfmt-ignore
should_allow_js_string_mutations() ->
% This binary corresponds to this string: мама мыла раму
% Which I'm told translates to: "mom was washing the frame"
@@ -142,21 +191,21 @@ should_allow_js_string_mutations() ->
>>,
Mom = <<16#D0, 16#BC, 16#D0, 16#B0, 16#D0, 16#BC, 16#D0, 16#B0>>,
Washed = <<16#D0, 16#BC, 16#D1, 16#8B, 16#D0, 16#BB, 16#D0, 16#B0>>,
- Src1 = <<
- "function(doc) {\n"
- " emit(\"length\", doc.value.length);\n"
- "}\n"
- >>,
- Src2 = <<
- "function(doc) {\n"
- " emit(\"substring\", doc.value.substring(5, 9));\n"
- "}\n"
- >>,
- Src3 = <<
- "function(doc) {\n"
- " emit(\"slice\", doc.value.slice(0, 4));\n"
- "}\n"
- >>,
+ Src1 = <<"
+ function(doc) {
+ emit(\"length\", doc.value.length);
+ }
+ ">>,
+ Src2 = <<"
+ function(doc) {
+ emit(\"substring\", doc.value.substring(5, 9));
+ }
+ ">>,
+ Src3 = <<"
+ function(doc) {
+ emit(\"slice\", doc.value.slice(0, 4));
+ }
+ ">>,
Proc = couch_query_servers:get_os_process(<<"javascript">>),
true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src1]),
true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src2]),
@@ -168,19 +217,21 @@ should_allow_js_string_mutations() ->
[[<<"substring">>, Washed]],
[[<<"slice">>, Mom]]
],
- ?assertEqual(Expect, Result).
+ ?assertEqual(Expect, Result),
+ couch_query_servers:ret_os_process(Proc).
+%% erlfmt-ignore
should_exit_on_oom() ->
- Src = <<
- "var state = [];\n"
- "function(doc) {\n"
- " var val = \"0123456789ABCDEF\";\n"
- " for(var i = 0; i < 665535; i++) {\n"
- " state.push([val, val]);\n"
- " emit(null, null);\n"
- " }\n"
- "}\n"
- >>,
+ Src = <<"
+ var state = [];
+ function(doc) {
+ var val = \"0123456789ABCDEF\";
+ for(var i = 0; i < 665535; i++) {
+ state.push([val, val]);
+ emit(null, null);
+ }
+ }
+ ">>,
Proc = couch_query_servers:get_os_process(<<"javascript">>),
true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src]),
trigger_oom(Proc).