You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by rn...@apache.org on 2015/09/02 20:31:00 UTC

[1/5] couchdb-couch-epi git commit: Fix test suite

Repository: couchdb-couch-epi
Updated Branches:
  refs/heads/master a57fc94ef -> 1d30ba1b0


Fix test suite

COUCHDB-2796


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/commit/d7eabf64
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/tree/d7eabf64
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/diff/d7eabf64

Branch: refs/heads/master
Commit: d7eabf6439d0a1f8c7788b4c2a2766206d6a1bbb
Parents: a57fc94
Author: ILYA Khlopotov <ii...@ca.ibm.com>
Authored: Wed Sep 2 07:07:19 2015 -0700
Committer: ILYA Khlopotov <ii...@ca.ibm.com>
Committed: Wed Sep 2 09:52:41 2015 -0700

----------------------------------------------------------------------
 src/couch_epi_data_gen.erl           |  98 ++++++++++++-----------
 src/couch_epi_functions_gen.erl      |  38 +++++----
 test/couch_epi_data_source_tests.erl |  90 ---------------------
 test/couch_epi_functions_tests.erl   | 126 ------------------------------
 test/couch_epi_tests.erl             |  56 ++++++++++++-
 5 files changed, 131 insertions(+), 277 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/d7eabf64/src/couch_epi_data_gen.erl
----------------------------------------------------------------------
diff --git a/src/couch_epi_data_gen.erl b/src/couch_epi_data_gen.erl
index 75601cf..e4e0889 100644
--- a/src/couch_epi_data_gen.erl
+++ b/src/couch_epi_data_gen.erl
@@ -220,66 +220,76 @@ fold_defs(Defs, Acc, Fun) ->
 -include_lib("eunit/include/eunit.hrl").
 
 basic_test() ->
-    Module = foo_bar_baz_bugz,
-    Data1 = [some_nice_data],
-    Data2 = "other data",
-    Data3 = {"even more data"},
-    Defs1 = [{foo, Data1}],
-    Defs2 = lists:usort([{foo, Data2}, {bar, Data3}]),
+    try
+        Module = foo_bar_baz_bugz,
 
-    set(Module, app1, Defs1),
-    set(Module, app2, Defs2),
+        meck:new(couch_epi_module_keeper, [passthrough]),
+        meck:expect(couch_epi_module_keeper, save, fun
+            (Handle, Source, Modules) -> save(Handle, Source, Modules)
+        end),
 
-    ?assertEqual([bar, foo], lists:usort(Module:keys())),
-    ?assertEqual([app1, app2], lists:usort(Module:subscribers())),
+        Data1 = [some_nice_data],
+        Data2 = "other data",
+        Data3 = {"even more data"},
+        Defs1 = [{foo, Data1}],
+        Defs2 = lists:usort([{foo, Data2}, {bar, Data3}]),
 
-    ?assertEqual(Data1, Module:get(app1, foo)),
-    ?assertEqual(Data2, Module:get(app2, foo)),
-    ?assertEqual(Data3, Module:get(app2, bar)),
+        set(Module, app1, Defs1),
+        set(Module, app2, Defs2),
 
-    ?assertEqual(undefined, Module:get(bad, key)),
-    ?assertEqual(undefined, Module:get(source, bad)),
+        ?assertEqual([bar, foo], lists:usort(Module:keys())),
+        ?assertEqual([app1, app2], lists:usort(Module:subscribers())),
 
-    ?assertEqual("3KZ4EG4WBF4J683W8GSDDPYR3", Module:version(app1)),
-    ?assertEqual("4EFUU47W9XDNMV9RMZSSJQU3Y", Module:version(app2)),
+        ?assertEqual(Data1, Module:get(app1, foo)),
+        ?assertEqual(Data2, Module:get(app2, foo)),
+        ?assertEqual(Data3, Module:get(app2, bar)),
 
-    ?assertEqual({error,{unknown,bad}}, Module:version(bad)),
+        ?assertEqual(undefined, Module:get(bad, key)),
+        ?assertEqual(undefined, Module:get(source, bad)),
 
-    ?assertEqual(
-        [{app1,"3KZ4EG4WBF4J683W8GSDDPYR3"},
-         {app2,"4EFUU47W9XDNMV9RMZSSJQU3Y"}], lists:usort(Module:version())),
+        ?assertEqual("3KZ4EG4WBF4J683W8GSDDPYR3", Module:version(app1)),
+        ?assertEqual("4EFUU47W9XDNMV9RMZSSJQU3Y", Module:version(app2)),
 
-    ?assertEqual(
-       [{app1,[some_nice_data]},{app2,"other data"}],
-       lists:usort(Module:by_key(foo))),
+        ?assertEqual({error,{unknown,bad}}, Module:version(bad)),
 
-    ?assertEqual([], lists:usort(Module:by_key(bad))),
+        ?assertEqual(
+            [{app1,"3KZ4EG4WBF4J683W8GSDDPYR3"},
+             {app2,"4EFUU47W9XDNMV9RMZSSJQU3Y"}], lists:usort(Module:version())),
 
-    ?assertEqual(
-        [
-            {bar, [{app2, {"even more data"}}]},
-            {foo, [{app2, "other data"}, {app1, [some_nice_data]}]}
-        ],
-        lists:usort(Module:by_key())),
+        ?assertEqual(
+           [{app1,[some_nice_data]},{app2,"other data"}],
+           lists:usort(Module:by_key(foo))),
 
+        ?assertEqual([], lists:usort(Module:by_key(bad))),
 
-    ?assertEqual(Defs1, lists:usort(Module:by_source(app1))),
-    ?assertEqual(Defs2, lists:usort(Module:by_source(app2))),
+        ?assertEqual(
+            [
+                {bar, [{app2, {"even more data"}}]},
+                {foo, [{app2, "other data"}, {app1, [some_nice_data]}]}
+            ],
+            lists:usort(Module:by_key())),
 
-    ?assertEqual([], lists:usort(Module:by_source(bad))),
 
-    ?assertEqual(
-        [
-            {app1, [{foo, [some_nice_data]}]},
-            {app2, [{foo, "other data"}, {bar, {"even more data"}}]}
-        ],
-        lists:usort(Module:by_source())),
+        ?assertEqual(Defs1, lists:usort(Module:by_source(app1))),
+        ?assertEqual(Defs2, lists:usort(Module:by_source(app2))),
 
-    ?assertEqual(
-        lists:usort([Data1, Data2, Data3]), lists:usort(Module:all())),
-    ?assertEqual(lists:usort([Data1, Data2]), lists:usort(Module:all(foo))),
-    ?assertEqual([], lists:usort(Module:all(bad))),
+        ?assertEqual([], lists:usort(Module:by_source(bad))),
 
+        ?assertEqual(
+            [
+                {app1, [{foo, [some_nice_data]}]},
+                {app2, [{foo, "other data"}, {bar, {"even more data"}}]}
+            ],
+            lists:usort(Module:by_source())),
+
+        ?assertEqual(
+            lists:usort([Data1, Data2, Data3]), lists:usort(Module:all())),
+        ?assertEqual(lists:usort([Data1, Data2]), lists:usort(Module:all(foo))),
+        ?assertEqual([], lists:usort(Module:all(bad))),
+        ok
+    after
+        meck:unload(couch_epi_module_keeper)
+    end,
     ok.
 
 -endif.

http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/d7eabf64/src/couch_epi_functions_gen.erl
----------------------------------------------------------------------
diff --git a/src/couch_epi_functions_gen.erl b/src/couch_epi_functions_gen.erl
index 6d93787..84ecc5f 100644
--- a/src/couch_epi_functions_gen.erl
+++ b/src/couch_epi_functions_gen.erl
@@ -330,26 +330,36 @@ bar() ->
     [].
 
 basic_test() ->
-    Module = foo_bar_dispatcher,
-    add(Module, app1, [?MODULE]),
+    try
+        Module = foo_bar_dispatcher,
+        meck:new(couch_epi_module_keeper, [passthrough]),
+        meck:expect(couch_epi_module_keeper, save, fun
+            (Handle, Source, Modules) -> save(Handle, Source, Modules)
+        end),
+
+        add(Module, app1, [?MODULE]),
 
-    ?assertMatch([?MODULE], modules(Module, foo, 2)),
+        ?assertMatch([?MODULE], modules(Module, foo, 2)),
 
-    ?assert(is_list(Module:version(app1))),
+        ?assert(is_list(Module:version(app1))),
 
-    Defs1 = lists:usort(Module:definitions()),
-    ?assertMatch([{app1, [{?MODULE, _}]}], Defs1),
-    [{app1, [{?MODULE, Exports}]}] = Defs1,
-    ?assert(lists:member({bar, 0}, Exports)),
+        Defs1 = lists:usort(Module:definitions()),
+        ?assertMatch([{app1, [{?MODULE, _}]}], Defs1),
+        [{app1, [{?MODULE, Exports}]}] = Defs1,
+        ?assert(lists:member({bar, 0}, Exports)),
 
-    add(Module, app2, [?MODULE]),
-    Defs2 = lists:usort(Module:definitions()),
-    ?assertMatch([{app1, [{?MODULE, _}]}, {app2, [{?MODULE, _}]}], Defs2),
+        add(Module, app2, [?MODULE]),
+        Defs2 = lists:usort(Module:definitions()),
+        ?assertMatch([{app1, [{?MODULE, _}]}, {app2, [{?MODULE, _}]}], Defs2),
 
-    ?assertMatch([{app1, Hash}, {app2, Hash}], Module:version()),
+        ?assertMatch([{app1, Hash}, {app2, Hash}], Module:version()),
 
-    ?assertMatch([], Module:dispatch(?MODULE, bar, [])),
-    ?assertMatch({1, 2}, Module:dispatch(?MODULE, foo, [1, 2])),
+        ?assertMatch([], Module:dispatch(?MODULE, bar, [])),
+        ?assertMatch({1, 2}, Module:dispatch(?MODULE, foo, [1, 2])),
+        ok
+    after
+        meck:unload(couch_epi_module_keeper)
+    end,
 
     ok.
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/d7eabf64/test/couch_epi_data_source_tests.erl
----------------------------------------------------------------------
diff --git a/test/couch_epi_data_source_tests.erl b/test/couch_epi_data_source_tests.erl
deleted file mode 100644
index f5d701f..0000000
--- a/test/couch_epi_data_source_tests.erl
+++ /dev/null
@@ -1,90 +0,0 @@
-% Licensed under the Apache License, Version 2.0 (the "License"); you may not
-% use this file except in compliance with the License. You may obtain a copy of
-% the License at
-%
-% http://www.apache.org/licenses/LICENSE-2.0
-%
-% Unless required by applicable law or agreed to in writing, software
-% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-% License for the specific language governing permissions and limitations under
-% the License.
-
--module(couch_epi_data_source_tests).
-
--include_lib("couch/include/couch_eunit.hrl").
-
--define(DATA_FILE1, ?ABS_PATH("test/fixtures/app_data1.cfg")).
--define(DATA_FILE2, ?ABS_PATH("test/fixtures/app_data2.cfg")).
-
--record(ctx, {file, handle, pid}).
-
-setup() ->
-    Key = {test_app, descriptions},
-    File = ?tempfile(),
-    {ok, _} = file:copy(?DATA_FILE1, File),
-    {ok, Pid} = couch_epi_data_source:start_link(
-        test_app, {epi_key, Key}, {file, File}, [{interval, 100}]),
-    ok = couch_epi_data_source:wait(Pid),
-    #ctx{
-        pid = Pid,
-        file = File,
-        handle = couch_epi_data_gen:get_handle(Key)}.
-
-
-teardown(#ctx{pid = Pid, file = File}) ->
-    file:delete(File),
-    couch_epi_data_source:stop(Pid),
-    catch meck:unload(compile),
-    ok.
-
-
-epi_data_source_reload_test_() ->
-    {
-        "data_source reload tests",
-        {
-            foreach,
-            fun setup/0,
-            fun teardown/1,
-            [
-                fun ensure_reload_if_manually_triggered/1,
-                fun ensure_reload_if_changed/1,
-                fun ensure_no_reload_when_no_change/1
-            ]
-        }
-    }.
-
-ensure_reload_if_manually_triggered(#ctx{pid = Pid, file = File}) ->
-    ?_test(begin
-        ok = meck:new(compile, [passthrough, unstick]),
-        ok = meck:expect(compile, forms, fun(_, _) -> {error, reload} end),
-        {ok, _} = file:copy(?DATA_FILE2, File),
-        Result = couch_epi_data_source:reload(Pid),
-        ?assertMatch({error,{badmatch,{error,reload}}}, Result)
-    end).
-
-ensure_reload_if_changed(#ctx{file = File, handle = Handle}) ->
-    ?_test(begin
-        ?assertMatch(
-            [[{type,counter},{desc,foo}]],
-            couch_epi_data_gen:get(Handle, [complex, key, 1])),
-        {ok, _} = file:copy(?DATA_FILE2, File),
-        timer:sleep(150),
-        ?assertMatch(
-            [[{type,counter},{desc,bar}]],
-            couch_epi_data_gen:get(Handle, [complex, key, 2]))
-    end).
-
-ensure_no_reload_when_no_change(#ctx{handle = Handle}) ->
-    ok = meck:new(compile, [passthrough, unstick]),
-    ok = meck:expect(compile, forms, fun(_, _) ->
-        {error, compile_should_not_be_called} end),
-    ?_test(begin
-        ?assertMatch(
-            [[{type,counter},{desc,foo}]],
-            couch_epi_data_gen:get(Handle, [complex, key, 1])),
-        timer:sleep(200),
-        ?assertMatch(
-            [],
-            couch_epi_data_gen:get(Handle, [complex, key, 2]))
-    end).

http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/d7eabf64/test/couch_epi_functions_tests.erl
----------------------------------------------------------------------
diff --git a/test/couch_epi_functions_tests.erl b/test/couch_epi_functions_tests.erl
deleted file mode 100644
index 6b035b9..0000000
--- a/test/couch_epi_functions_tests.erl
+++ /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.
-
--module(couch_epi_functions_tests).
-
--include_lib("couch/include/couch_eunit.hrl").
-
--define(MODULE1(Name), "
-    -export([foo/2, bar/0, inc/1]).
-    foo(A1, A2) ->
-        {A1, A2}.
-
-    bar() ->
-        [].
-
-    inc(A) ->
-        A + 1.
-").
-
--define(MODULE2(Name), "
-    -export([baz/1, inc/1]).
-    baz(A1) ->
-        A1.
-
-    inc(A) ->
-        A + 1.
-").
-
-setup() ->
-    setup([{interval, 100}]).
-
-setup(Opts) ->
-    ServiceId = my_service,
-    Module = my_test_module,
-    ok = generate_module(Module, ?MODULE1(Module)),
-    {ok, Pid} = couch_epi_functions:start_link(
-        test_app, {epi_key, ServiceId}, {modules, [Module]}, Opts),
-    ok = couch_epi_functions:wait(Pid),
-    {Pid, Module, ServiceId, couch_epi_functions_gen:get_handle(ServiceId)}.
-
-teardown({Pid, Module, _, _Handle}) ->
-    code:purge(Module),
-    couch_epi_functions:stop(Pid),
-    catch meck:unload(compile),
-    ok.
-
-generate_module(Name, Body) ->
-    Tokens = couch_epi_codegen:scan(Body),
-    couch_epi_codegen:generate(Name, Tokens).
-
-upgrade_release(Pid) ->
-    sys:suspend(Pid),
-    'ok' = sys:change_code(Pid, couch_epi_functions, 'undefined', []),
-    sys:resume(Pid),
-    ok.
-
-epi_functions_test_() ->
-    {
-        "functions reload tests",
-        {
-            foreach,
-            fun setup/0,
-            fun teardown/1,
-            [
-                fun ensure_reload_if_changed/1,
-                fun ensure_no_reload_when_no_change/1
-            ]
-        }
-    }.
-
-epi_functions_manual_reload_test_() ->
-    {
-        "functions manual reload tests",
-        {
-            foreach,
-            fun() -> setup([{interval, 10000}]) end,
-            fun teardown/1,
-            [
-                fun ensure_reload_if_manually_triggered/1
-            ]
-        }
-    }.
-
-ensure_reload_if_manually_triggered({Pid, Module, _ServiceId, _Handle}) ->
-    ?_test(begin
-        ok = generate_module(Module, ?MODULE2(Module)),
-        ok = meck:new(compile, [passthrough, unstick]),
-        ok = meck:expect(compile, forms, fun(_, _) -> {error, reload} end),
-        Result = couch_epi_functions:reload(Pid),
-        ?assertMatch({error,{badmatch,{error,reload}}}, Result)
-    end).
-
-ensure_reload_if_changed({Pid, Module, ServiceId, _Handle}) ->
-    ?_test(begin
-        ?assertMatch(
-            [{1, 2}],
-            couch_epi_functions_gen:apply(ServiceId, foo, [1, 2], [])),
-        ok = generate_module(Module, ?MODULE2(Module)),
-        upgrade_release(Pid),
-        ?assertMatch(
-            [3],
-            couch_epi_functions_gen:apply(ServiceId, baz, [3], []))
-    end).
-
-ensure_no_reload_when_no_change({Pid, _Module, ServiceId, _Handle}) ->
-    ok = meck:new(compile, [passthrough, unstick]),
-    ok = meck:expect(compile, forms, fun(_, _) ->
-        {error, compile_should_not_be_called} end),
-    ?_test(begin
-        ?assertMatch(
-            [{1, 2}],
-            couch_epi_functions_gen:apply(ServiceId, foo, [1, 2], [])),
-        upgrade_release(Pid),
-        ?assertMatch(
-            [],
-            couch_epi_functions_gen:apply(ServiceId, baz, [3], []))
-    end).

http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/d7eabf64/test/couch_epi_tests.erl
----------------------------------------------------------------------
diff --git a/test/couch_epi_tests.erl b/test/couch_epi_tests.erl
index 227a79f..78eab4d 100644
--- a/test/couch_epi_tests.erl
+++ b/test/couch_epi_tests.erl
@@ -229,16 +229,22 @@ epi_reload_test_() ->
         couch_epi_data_source,
         couch_epi_functions
     ],
+    Funs = [
+        fun ensure_reload_if_manually_triggered/2,
+        fun ensure_reload_if_changed/2,
+        fun ensure_no_reload_when_no_change/2
+    ],
     {
         "epi reload tests",
         {
             foreachx,
             fun setup/1,
             fun teardown/2,
-            [{M, fun ensure_reloaded/2} || M <- Modules]
+            [{M, Fun} || M <- Modules, Fun <- Funs]
         }
     }.
 
+
 apply_options_test_() ->
     Funs = [fun ensure_apply_is_called/2],
     make_case("Apply with options: ", valid_options_permutations(), Funs).
@@ -416,16 +422,60 @@ check_subscribers(_Module, #ctx{handle = Handle}) ->
     ?_assertMatch([test_app], couch_epi:subscribers(Handle)).
 
 
-ensure_reloaded(Module, #ctx{pid = Pid, key = Key} = Ctx) ->
+ensure_reload_if_manually_triggered(Module, #ctx{pid = Pid, key = Key} = Ctx) ->
     ?_test(begin
         subscribe(Ctx, test_app, Key),
         update_definitions(Module, Ctx),
         Module:reload(Pid),
-        timer:sleep(200),
+        timer:sleep(50),
+        Result = get(Ctx, is_called),
+        ?assertNotMatch(error, Result)
+    end).
+
+ensure_reload_if_changed(couch_epi_data_source =  Module,
+        #ctx{key = Key, handle = Handle} = Ctx) ->
+    ?_test(begin
+        Version = Handle:version(),
+        subscribe(Ctx, test_app, Key),
+        update_definitions(Module, Ctx),
+        timer:sleep(250),
+        ?assertNotEqual(Version, Handle:version()),
+        Result = get(Ctx, is_called),
+        ?assertNotMatch(error, Result)
+    end);
+ensure_reload_if_changed(Module,
+        #ctx{key = Key, handle = Handle} = Ctx) ->
+    ?_test(begin
+        Version = Handle:version(),
+        subscribe(Ctx, test_app, Key),
+        update(Module, Ctx),
+        ?assertNotEqual(Version, Handle:version()),
+        timer:sleep(100), %% Allow some time for notify to be called
         Result = get(Ctx, is_called),
         ?assertNotMatch(error, Result)
     end).
 
+ensure_no_reload_when_no_change(couch_epi_functions = Module,
+        #ctx{pid = Pid, key = Key, handle = Handle} = Ctx) ->
+    ?_test(begin
+        Version = Handle:version(),
+        subscribe(Ctx, test_app, Key),
+        upgrade_release(Pid, Module),
+        ?assertEqual(Version, Handle:version()),
+        Result = get(Ctx, is_called),
+        ?assertMatch(error, Result)
+    end);
+ensure_no_reload_when_no_change(Module,
+        #ctx{key = Key, handle = Handle} = Ctx) ->
+    ?_test(begin
+        Version = Handle:version(),
+        subscribe(Ctx, test_app, Key),
+        timer:sleep(450),
+        ?assertEqual(Version, Handle:version()),
+        Result = get(Ctx, is_called),
+        ?assertMatch(error, Result)
+    end).
+
 
 %% ------------------------------------------------------------------
 %% Internal Function Definitions


[4/5] couchdb-couch-epi git commit: Don't use try/catch to handle missing plugins

Posted by rn...@apache.org.
Don't use try/catch to handle missing plugins

COUCHDB-2796


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/commit/36b2be55
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/tree/36b2be55
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/diff/36b2be55

Branch: refs/heads/master
Commit: 36b2be55a89f766df44b05d988d040e6a3125529
Parents: 7f32e4f
Author: ILYA Khlopotov <ii...@ca.ibm.com>
Authored: Wed Sep 2 09:37:46 2015 -0700
Committer: ILYA Khlopotov <ii...@ca.ibm.com>
Committed: Wed Sep 2 09:53:39 2015 -0700

----------------------------------------------------------------------
 src/couch_epi_data.erl          | 18 ++-------------
 src/couch_epi_data_gen.erl      | 44 +++++++++++++++++++++++-------------
 src/couch_epi_data_source.erl   | 12 +---------
 src/couch_epi_functions_gen.erl | 37 ++++++++++++++++--------------
 4 files changed, 51 insertions(+), 60 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/36b2be55/src/couch_epi_data.erl
----------------------------------------------------------------------
diff --git a/src/couch_epi_data.erl b/src/couch_epi_data.erl
index 680e5f5..b685dae 100644
--- a/src/couch_epi_data.erl
+++ b/src/couch_epi_data.erl
@@ -126,7 +126,7 @@ safe_set(Hash, #state{} = State) ->
         key = Key} = State,
     try
         Data = get_from_module(Module),
-        OldData = current(Handle, Subscriber),
+        OldData = couch_epi_data_gen:current_data(Handle, Subscriber),
         ok = couch_epi_data_gen:set(Handle, Subscriber, Data),
         couch_epi_server:notify(Subscriber, Key, {data, OldData}, {data, Data}),
         {ok, State#state{hash = Hash}}
@@ -135,21 +135,7 @@ safe_set(Hash, #state{} = State) ->
     end.
 
 get_from_module(Module) ->
-    try
-        Module:data()
-    catch
-        error:undef -> []
-    end.
-
-current(Handle, Subscriber) ->
-    try
-        case couch_epi_data_gen:by_source(Handle, Subscriber) of
-            undefined -> [];
-            Data -> Data
-        end
-    catch error:undef ->
-        []
-    end.
+    Module:data().
 
 maybe_start_keeper(Key) ->
     Handle = couch_epi_data_gen:get_handle(Key),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/36b2be55/src/couch_epi_data_gen.erl
----------------------------------------------------------------------
diff --git a/src/couch_epi_data_gen.erl b/src/couch_epi_data_gen.erl
index ad84b80..d7e0c65 100644
--- a/src/couch_epi_data_gen.erl
+++ b/src/couch_epi_data_gen.erl
@@ -24,6 +24,7 @@
 -export([keys/1, subscribers/1]).
 
 -export([save/3]).
+-export([current_data/2]).
 
 set(Handle, Source, Data) ->
     case is_updated(Handle, Source, Data) of
@@ -174,32 +175,43 @@ module_name({Service, Key}) when is_list(Service) andalso is_list(Key) ->
 
 is_updated(Handle, Source, Data) ->
     Sig = couch_epi_util:hash(Data),
-    try Handle:version(Source) of
-        {error, {unknown, Source}} -> true;
-        {error, Reason} -> throw(Reason);
-        Sig -> false;
-        _ -> true
-    catch
-        error:undef -> true;
-        Class:Reason ->
-            throw({Class, {Source, Reason}})
-    end.
+    if_exists(Handle, version, 1, true, fun() ->
+        try Handle:version(Source) of
+            {error, {unknown, Source}} -> true;
+            {error, Reason} -> throw(Reason);
+            Sig -> false;
+            _ -> true
+        catch
+            Class:Reason ->
+                throw({Class, {Source, Reason}})
+        end
+    end).
 
 save(Handle, undefined, []) ->
-    case get_current_data(Handle) of
+    case current_data(Handle) of
         [] -> generate(Handle, []);
         _Else -> ok
     end;
 save(Handle, Source, Data) ->
-    CurrentData = get_current_data(Handle),
+    CurrentData = current_data(Handle),
     NewDefs = lists:keystore(Source, 1, CurrentData, {Source, Data}),
     generate(Handle, NewDefs).
 
-get_current_data(Handle) ->
-    try Handle:by_source()
-    catch error:undef -> []
-    end.
+current_data(Handle, Subscriber) ->
+    if_exists(Handle, by_source, 1, [], fun() ->
+        Handle:by_source(Subscriber)
+    end).
 
+current_data(Handle) ->
+    if_exists(Handle, by_source, 0, [], fun() ->
+        Handle:by_source()
+    end).
+
+if_exists(Handle, Func, Arity, Default, Fun) ->
+    case erlang:function_exported(Handle, Func, Arity) of
+        true -> Fun();
+        false -> Default
+    end.
 
 defined_keys(Defs) ->
     Keys = fold_defs(Defs, [], fun({_Source, Key, _Data}, Acc) ->

http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/36b2be55/src/couch_epi_data_source.erl
----------------------------------------------------------------------
diff --git a/src/couch_epi_data_source.erl b/src/couch_epi_data_source.erl
index f44430d..f905e8f 100644
--- a/src/couch_epi_data_source.erl
+++ b/src/couch_epi_data_source.erl
@@ -161,7 +161,7 @@ safe_set(Hash, Data, #state{} = State) ->
         key = Key} = State,
 
     try
-        OldData = current(Handle, Subscriber),
+        OldData = couch_epi_data_gen:current_data(Handle, Subscriber),
         ok = couch_epi_data_gen:set(Handle, Subscriber, Data),
         couch_epi_server:notify(Subscriber, Key, {data, OldData}, {data, Data}),
         {ok, State#state{hash = Hash}}
@@ -181,16 +181,6 @@ hash_of_file(FilePath) ->
     {ok, Data} = file:read_file(FilePath),
     couch_epi_util:md5(Data).
 
-current(Handle, Subscriber) ->
-    try
-        case couch_epi_data_gen:by_source(Handle, Subscriber) of
-            undefined -> [];
-            Data -> Data
-        end
-    catch error:undef ->
-        []
-    end.
-
 maybe_start_keeper(Key) ->
     Handle = couch_epi_data_gen:get_handle(Key),
     couch_epi_module_keeper:maybe_start_keeper(couch_epi_data_gen, Handle).

http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/36b2be55/src/couch_epi_functions_gen.erl
----------------------------------------------------------------------
diff --git a/src/couch_epi_functions_gen.erl b/src/couch_epi_functions_gen.erl
index 2fba66f..8c63b9c 100644
--- a/src/couch_epi_functions_gen.erl
+++ b/src/couch_epi_functions_gen.erl
@@ -190,16 +190,17 @@ module_name(ServiceId) when is_list(ServiceId) ->
 
 is_updated(Handle, Source, Modules) ->
     Sig = hash(Modules),
-    try Handle:version(Source) of
-        {error, {unknown, Source}} -> true;
-        {error, Reason} -> throw(Reason);
-        Sig -> false;
-        _ -> true
-    catch
-        error:undef -> true;
-        Class:Reason ->
-            throw({Class, {Source, Reason}})
-    end.
+    if_exists(Handle, version, 1, true, fun() ->
+        try Handle:version(Source) of
+            {error, {unknown, Source}} -> true;
+            {error, Reason} -> throw(Reason);
+            Sig -> false;
+            _ -> true
+        catch
+            Class:Reason ->
+                throw({Class, {Source, Reason}})
+        end
+    end).
 
 save(Handle, undefined, []) ->
     case get_current_definitions(Handle) of
@@ -218,8 +219,14 @@ definitions(Source, Modules) ->
     {Source, SrcDefs}.
 
 get_current_definitions(Handle) ->
-    try Handle:definitions()
-    catch error:undef -> []
+    if_exists(Handle, definitions, 0, [], fun() ->
+        Handle:definitions()
+    end).
+
+if_exists(Handle, Func, Arity, Default, Fun) ->
+    case erlang:function_exported(Handle, Func, Arity) of
+        true -> Fun();
+        false -> Default
     end.
 
 defined_providers(Defs) ->
@@ -300,11 +307,7 @@ parse_opts([], Acc) ->
     Acc.
 
 providers(Handle, Function, Arity, #opts{ignore_providers = true}) ->
-    try
-        Handle:providers(Function, Arity)
-    catch
-        error:undef -> []
-    end;
+    Handle:providers(Function, Arity);
 providers(Handle, Function, Arity, #opts{}) ->
     Handle:providers(Function, Arity).
 


[5/5] couchdb-couch-epi git commit: Remove support for ignore_providers option

Posted by rn...@apache.org.
Remove support for ignore_providers option

COUCHDB-2796


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/commit/1d30ba1b
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/tree/1d30ba1b
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/diff/1d30ba1b

Branch: refs/heads/master
Commit: 1d30ba1b05ca48e0482ad2df7cb617ebb5b07c29
Parents: 36b2be5
Author: ILYA Khlopotov <ii...@ca.ibm.com>
Authored: Wed Sep 2 10:03:44 2015 -0700
Committer: ILYA Khlopotov <ii...@ca.ibm.com>
Committed: Wed Sep 2 10:03:44 2015 -0700

----------------------------------------------------------------------
 README.md                       | 1 -
 src/couch_epi.erl               | 1 -
 src/couch_epi_functions_gen.erl | 4 ----
 3 files changed, 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/1d30ba1b/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index b3f2b5f..e6bddb6 100644
--- a/README.md
+++ b/README.md
@@ -107,7 +107,6 @@ There are multiple ways of doing the apply which is controlled by Opts
   - ignore_errors - the call is wrapped into try/catch
   - concurrent - spawn a new process for every service provider
   - pipe - use output of one service provider as an input for the next one
-  - ignore_providers - do not fail if there are no providers for the service are available
 
 Notes:
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/1d30ba1b/src/couch_epi.erl
----------------------------------------------------------------------
diff --git a/src/couch_epi.erl b/src/couch_epi.erl
index 7bd4ea1..7388ac2 100644
--- a/src/couch_epi.erl
+++ b/src/couch_epi.erl
@@ -46,7 +46,6 @@
 
 -type apply_opt()
     :: ignore_errors
-        | ignore_providers
         | concurrent
         | pipe.
 

http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/1d30ba1b/src/couch_epi_functions_gen.erl
----------------------------------------------------------------------
diff --git a/src/couch_epi_functions_gen.erl b/src/couch_epi_functions_gen.erl
index 8c63b9c..be04644 100644
--- a/src/couch_epi_functions_gen.erl
+++ b/src/couch_epi_functions_gen.erl
@@ -301,13 +301,9 @@ parse_opts([pipe|Rest], #opts{} = Acc) ->
     parse_opts(Rest, Acc#opts{pipe = true});
 parse_opts([concurrent|Rest], #opts{} = Acc) ->
     parse_opts(Rest, Acc#opts{concurrent = true});
-parse_opts([ignore_providers|Rest], #opts{} = Acc) ->
-    parse_opts(Rest, Acc#opts{ignore_providers = true});
 parse_opts([], Acc) ->
     Acc.
 
-providers(Handle, Function, Arity, #opts{ignore_providers = true}) ->
-    Handle:providers(Function, Arity);
 providers(Handle, Function, Arity, #opts{}) ->
     Handle:providers(Function, Arity).
 


[2/5] couchdb-couch-epi git commit: Introduce 'couch_epi:register_service/1'

Posted by rn...@apache.org.
Introduce 'couch_epi:register_service/1'

COUCHDB-2796


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/commit/fa126087
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/tree/fa126087
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/diff/fa126087

Branch: refs/heads/master
Commit: fa1260878f631d17119d3be788a19479dd982364
Parents: d7eabf6
Author: ILYA Khlopotov <ii...@ca.ibm.com>
Authored: Wed Sep 2 08:10:52 2015 -0700
Committer: ILYA Khlopotov <ii...@ca.ibm.com>
Committed: Wed Sep 2 09:52:56 2015 -0700

----------------------------------------------------------------------
 src/couch_epi.erl               | 14 ++++++++++++++
 src/couch_epi_data_gen.erl      |  5 +++++
 src/couch_epi_functions_gen.erl |  5 +++++
 src/couch_epi_module_keeper.erl | 16 +++++++++++++++-
 test/couch_epi_tests.erl        |  3 +++
 5 files changed, 42 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/fa126087/src/couch_epi.erl
----------------------------------------------------------------------
diff --git a/src/couch_epi.erl b/src/couch_epi.erl
index 417b3fc..7bd4ea1 100644
--- a/src/couch_epi.erl
+++ b/src/couch_epi.erl
@@ -14,6 +14,7 @@
 
 %% subscribtion management
 -export([subscribe/5, unsubscribe/1, get_handle/1]).
+-export([register_service/1]).
 
 %% queries and introspection
 -export([
@@ -164,3 +165,16 @@ all(Handle, ServiceId, Function, Args, Opts) ->
 
 is_configured(Handle, Function, Arity) ->
     [] /= couch_epi_functions_gen:modules(Handle, Function, Arity).
+
+
+-spec register_service({ServiceId :: service_id(), Key :: key()}) -> ok;
+                (ServiceId :: service_id()) -> ok.
+
+register_service({_ServiceId, _Key} = EPIKey) ->
+    register_service(couch_epi_data_gen, EPIKey);
+register_service(ServiceId) when is_atom(ServiceId) ->
+    register_service(couch_epi_functions_gen, ServiceId).
+
+register_service(Codegen, Key) ->
+    Handle = Codegen:get_handle(Key),
+    couch_epi_module_keeper:register_service(Codegen, Handle).

http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/fa126087/src/couch_epi_data_gen.erl
----------------------------------------------------------------------
diff --git a/src/couch_epi_data_gen.erl b/src/couch_epi_data_gen.erl
index e4e0889..ad84b80 100644
--- a/src/couch_epi_data_gen.erl
+++ b/src/couch_epi_data_gen.erl
@@ -185,6 +185,11 @@ is_updated(Handle, Source, Data) ->
             throw({Class, {Source, Reason}})
     end.
 
+save(Handle, undefined, []) ->
+    case get_current_data(Handle) of
+        [] -> generate(Handle, []);
+        _Else -> ok
+    end;
 save(Handle, Source, Data) ->
     CurrentData = get_current_data(Handle),
     NewDefs = lists:keystore(Source, 1, CurrentData, {Source, Data}),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/fa126087/src/couch_epi_functions_gen.erl
----------------------------------------------------------------------
diff --git a/src/couch_epi_functions_gen.erl b/src/couch_epi_functions_gen.erl
index 84ecc5f..2fba66f 100644
--- a/src/couch_epi_functions_gen.erl
+++ b/src/couch_epi_functions_gen.erl
@@ -201,6 +201,11 @@ is_updated(Handle, Source, Modules) ->
             throw({Class, {Source, Reason}})
     end.
 
+save(Handle, undefined, []) ->
+    case get_current_definitions(Handle) of
+        [] -> generate(Handle, []);
+        _Else -> ok
+    end;
 save(Handle, Source, Modules) ->
     CurrentDefs = get_current_definitions(Handle),
     Definitions = definitions(Source, Modules),

http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/fa126087/src/couch_epi_module_keeper.erl
----------------------------------------------------------------------
diff --git a/src/couch_epi_module_keeper.erl b/src/couch_epi_module_keeper.erl
index f538cf5..2d8c439 100644
--- a/src/couch_epi_module_keeper.erl
+++ b/src/couch_epi_module_keeper.erl
@@ -19,6 +19,8 @@
 %% ------------------------------------------------------------------
 
 -export([maybe_start_keeper/2]).
+-export([register_service/2]).
+
 -export([start_link/2, save/3]).
 -export([stop/1]).
 
@@ -35,8 +37,17 @@
 %% API Function Definitions
 %% ------------------------------------------------------------------
 
+register_service(Codegen, Module) ->
+    {ok, Server} = maybe_start_keeper(Codegen, Module),
+    compile_dummy_module(Server).
+
 maybe_start_keeper(Codegen, Module) ->
-    catch couch_epi_keeper_sup:start_child(Codegen, Module).
+    case couch_epi_keeper_sup:start_child(Codegen, Module) of
+        {ok, Pid} ->
+            {ok, Pid};
+        {error, {already_started, Pid}} ->
+            {ok, Pid}
+    end.
 
 start_link(Codegen, Module) ->
     gen_server:start_link({local, Module}, ?MODULE, [Codegen, Module], []).
@@ -76,3 +87,6 @@ code_change(_OldVsn, State, _Extra) ->
 %% ------------------------------------------------------------------
 %% Internal Function Definitions
 %% ------------------------------------------------------------------
+
+compile_dummy_module(Server) ->
+    save(Server, undefined, []).

http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/fa126087/test/couch_epi_tests.erl
----------------------------------------------------------------------
diff --git a/test/couch_epi_tests.erl b/test/couch_epi_tests.erl
index 78eab4d..a43ade9 100644
--- a/test/couch_epi_tests.erl
+++ b/test/couch_epi_tests.erl
@@ -91,6 +91,7 @@ setup(couch_epi_data_source) ->
         test_app, {epi_key, Key}, {file, File}, [{interval, 100}]),
     ok = couch_epi_data_source:wait(Pid),
     KV = state_storage(),
+    ok = couch_epi:register_service(Key),
     #ctx{
         file = File,
         key = Key,
@@ -108,6 +109,7 @@ setup(couch_epi_data) ->
         test_app, {epi_key, Key}, provider, []),
     ok = couch_epi_data:wait(Pid),
     KV = state_storage(),
+    ok = couch_epi:register_service(Key),
     #ctx{
         key = Key,
         handle = couch_epi:get_handle(Key),
@@ -126,6 +128,7 @@ setup(couch_epi_functions) ->
         [{interval, 100}]),
     ok = couch_epi_functions:wait(Pid),
     KV = state_storage(),
+    ok = couch_epi:register_service(Key),
     #ctx{
         key = Key,
         handle = couch_epi:get_handle(Key),


[3/5] couchdb-couch-epi git commit: Call maybe_start_keeper for couch_epi_data_source

Posted by rn...@apache.org.
Call maybe_start_keeper for couch_epi_data_source

COUCHDB-2796


Project: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/commit/7f32e4f4
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/tree/7f32e4f4
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/diff/7f32e4f4

Branch: refs/heads/master
Commit: 7f32e4f48d129688f89bfe863be2a33d08e5c46e
Parents: fa12608
Author: ILYA Khlopotov <ii...@ca.ibm.com>
Authored: Wed Sep 2 08:11:36 2015 -0700
Committer: ILYA Khlopotov <ii...@ca.ibm.com>
Committed: Wed Sep 2 09:53:08 2015 -0700

----------------------------------------------------------------------
 src/couch_epi_data_source.erl | 5 +++++
 1 file changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-couch-epi/blob/7f32e4f4/src/couch_epi_data_source.erl
----------------------------------------------------------------------
diff --git a/src/couch_epi_data_source.erl b/src/couch_epi_data_source.erl
index bbeed70..f44430d 100644
--- a/src/couch_epi_data_source.erl
+++ b/src/couch_epi_data_source.erl
@@ -54,6 +54,7 @@ childspec(Id, App, EpiKey, Locator, Options) ->
     }.
 
 start_link(SubscriberApp, {epi_key, Key}, Src, Options) ->
+    maybe_start_keeper(Key),
     {ok, Locator} = locate(SubscriberApp, Src),
     gen_server:start_link(?MODULE, [SubscriberApp, Locator, Key, Options], []).
 
@@ -189,3 +190,7 @@ current(Handle, Subscriber) ->
     catch error:undef ->
         []
     end.
+
+maybe_start_keeper(Key) ->
+    Handle = couch_epi_data_gen:get_handle(Key),
+    couch_epi_module_keeper:maybe_start_keeper(couch_epi_data_gen, Handle).