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 05:58:42 UTC

[couchdb] 01/01: Improve couch_js_tests

This is an automated email from the ASF dual-hosted git repository.

vatamane pushed a commit to branch a-few-couch-js-test-improvements
in repository https://gitbox.apache.org/repos/asf/couchdb.git

commit 2256ded576aa69e6724ee0beca50c9e47f1feaf9
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.
    
    - 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 forceably 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 | 73 +++++++++++++++++++++++++++------
 1 file changed, 61 insertions(+), 12 deletions(-)

diff --git a/src/couch/test/eunit/couch_js_tests.erl b/src/couch/test/eunit/couch_js_tests.erl
index ea28d4040..9f112324c 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,
@@ -36,17 +38,60 @@ should_create_sandbox() ->
     % 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"
+        "          try {\n"
+        "            emit(false, typeof(Couch.compile_function));\n"
+        "          } catch (e) {\n"
+        "            emit(true, e.message);\n"
+        "          }\n"
+        "        }"
+    >>,
+    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).
+
+should_reset_properly() ->
+    Src = <<
+        "function(doc) {\n"
+        "            var a = [0,1,2];\n"
+        "            emit(a.indexOf(0), Object.foo);\n"
+        "            Object.foo = 43;\n"
+        "            [].constructor.prototype.indexOf = function(x) {return 42;};\n"
+        "        }"
+    >>,
+    Proc = couch_query_servers:get_os_process(<<"javascript">>),
+    true = couch_query_servers:proc_prompt(Proc, [<<"add_fun">>, Src]),
+    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).
+
+should_freeze_doc_object() ->
+    Src = <<
+        "function(doc) {\n"
+        "            emit(doc.foo, doc.bar);\n"
+        "            doc.foo = 1042;\n"
+        "            doc.bar = 1043;\n"
+        "            emit(doc.foo, doc.bar);\n"
+        "        }"
     >>,
     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 = {[{<<"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).
 
 should_roundtrip_utf8() ->
     % Try round tripping UTF-8 both directions through
@@ -68,7 +113,8 @@ 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).
 
 should_roundtrip_modified_utf8() ->
     % Mimicking the test case from the mailing list
@@ -87,7 +133,8 @@ 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).
 
 should_replace_broken_utf16() ->
     % This test reverse the surrogate pair of
@@ -107,7 +154,8 @@ 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).
 
 should_allow_js_string_mutations() ->
     % This binary corresponds to this string: мама мыла раму
@@ -168,7 +216,8 @@ should_allow_js_string_mutations() ->
         [[<<"substring">>, Washed]],
         [[<<"slice">>, Mom]]
     ],
-    ?assertEqual(Expect, Result).
+    ?assertEqual(Expect, Result),
+    couch_query_servers:ret_os_process(Proc).
 
 should_exit_on_oom() ->
     Src = <<