diff options
-rw-r--r-- | Changelog.md | 4 | ||||
-rwxr-xr-x | bin/build_and_run.sh | 2 | ||||
-rwxr-xr-x | bin/build_and_test.sh | 2 | ||||
-rw-r--r-- | rebar.config | 4 | ||||
-rw-r--r-- | src/cdapbroker.app.src | 2 | ||||
-rw-r--r-- | src/resource_handler.erl | 61 | ||||
-rw-r--r-- | src/resource_handler_tests.erl | 34 | ||||
-rw-r--r-- | swagger/swagger.html | 2 | ||||
-rw-r--r-- | swagger/swagger.json | 2 | ||||
-rw-r--r-- | swagger/swagger.yaml | 2 | ||||
-rw-r--r-- | test/apitest/apitest_SUITE.erl | 33 |
11 files changed, 86 insertions, 62 deletions
diff --git a/Changelog.md b/Changelog.md index 6beae6f..c0631f3 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [4.0.7] - Sep 12 2017 +* Further unit testing +* Update dependency to a Leptus PR that fixes the CORS port issue + ## [4.0.6] - Sep 11 2017 * Get meck working for better unit tests * More unit tests diff --git a/bin/build_and_run.sh b/bin/build_and_run.sh index 8d48716..5273cee 100755 --- a/bin/build_and_run.sh +++ b/bin/build_and_run.sh @@ -1,5 +1,7 @@ #!/usr/local/bin/fish rm -rf /tmp/log/cdapbroker/*; +rm -rf _build/; +rebar3 upgrade; rebar3 release; set -x CDAP_CLUSTER_TO_MANAGE "cdap"; set -x CONSUL_HOST "XXXX"; diff --git a/bin/build_and_test.sh b/bin/build_and_test.sh index b0456f4..d5bbf6c 100755 --- a/bin/build_and_test.sh +++ b/bin/build_and_test.sh @@ -1,5 +1,7 @@ #!/usr/local/bin/fish rm -rf /tmp/log/cdapbroker/*; +rm -rf _build/* +rebar3 upgrade; rebar3 release; set -x NEXUS_RAW_ROOT "XXXX"; set -x CDAP_CLUSTER_TO_MANAGE "cdap"; diff --git a/rebar.config b/rebar.config index 331d11a..34b28a6 100644 --- a/rebar.config +++ b/rebar.config @@ -1,6 +1,6 @@ {relx, [ {release, - {cdapbroker,"4.0.6"}, + {cdapbroker,"4.0.7"}, [cdapbroker] }, %{extend_start_script,true}, @@ -15,7 +15,7 @@ {deps, [ {jiffy, ".*", {git, "git://github.com/davisp/jiffy.git", {branch, "master"}}}, %{leptus, ".*", {git, "git://github.com/s1n4/leptus.git", {branch, "master"}}}, - {leptus, ".*", {git, "git://github.com/tommyjcarpenter/leptus.git", {branch, "version"}}}, + {leptus, ".*", {git, "git://github.com/tommyjcarpenter/leptus.git", {branch, "master"}}}, {lager, ".*", {git, "git://github.com/basho/lager.git", {branch, "master"}}}, %generate RFC compliant UUIDs {uuid, ".*", {git, "https://github.com/avtobiff/erlang-uuid.git", {branch, "master"}}}, diff --git a/src/cdapbroker.app.src b/src/cdapbroker.app.src index 611d873..eb39868 100644 --- a/src/cdapbroker.app.src +++ b/src/cdapbroker.app.src @@ -1,6 +1,6 @@ {application, cdapbroker, [{description, "Interface between Consul and CDAP in DCAE"}, - {vsn, "4.0.6"}, + {vsn, "4.0.7"}, {registered, []}, {mod, { cdapbroker_app, []}}, {applications, diff --git a/src/resource_handler.erl b/src/resource_handler.erl index 798f457..1a0760d 100644 --- a/src/resource_handler.erl +++ b/src/resource_handler.erl @@ -7,8 +7,6 @@ -export([get/3, put/3, delete/3, post/3]). -export([cross_domains/3]). --export([appname_to_field_vals/2]). - %%for keeping state %%The application record is defined in application.hrl %%In Mnesia, the first element is the type of record and the second element is the key @@ -31,6 +29,8 @@ %lazy shorthand to write info audit records. man I miss defines in python. c ftw. -define(AUDI(Req, Bts, XER, Rcode), audit(info, Req, [{bts, Bts}, {xer,XER}, {rcode, RCode}, {mod, mod()}])). +%need this for the ?MODULE:FUNCTION to work with meck unit tests +-export([delete_app_helper/4, appname_to_field_vals/2]). %%% %%Helper functions @@ -332,7 +332,35 @@ handle_put(Req, State, XER, Appname, ReqBody, RequestUrl) -> end end. +handle_post_multidelete_app(Req, State, XER, ReqBody) -> + %handler method for the multi delete post ala AWS + case + try + B = maps:get(<<"appnames">>, jiffy:decode(ReqBody, [return_maps])), + true = erlang:is_list(B), + B + catch _:_ -> + invalid + end + of + invalid -> {400, "Invalid PUT Body", State}; + IDs -> + case IDs of + [] -> {200, "EMPTY PUT BODY", State}; + _ -> + %<<"*">> -> + %this block deleted all apps, but decided this backdoor wasn't very RESTy + %% {atomic, Apps} = mnesia:transaction(fun() -> mnesia:match_object(application, {application, '_', '_', '_', '_', '_', '_', '_', '_', '_'}, read) end), + % AppsToDelete = lists:map(fun(X) -> {application, Appname, _,_,_,_,_,_,_,_} = X, Appname end, Apps), + Returns = lists:map(fun(X) -> ?MODULE:delete_app_helper(X, State, XER, Req) end, IDs), + RL = lists:map(fun({RC, _, _}) -> RC end, Returns), + {200, jiffy:encode(RL), State} + end + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%% %%% HTTP API CALLBACKS %%% +%%%%%%%%%%%%%%%%%%%%%%%%%% init(_Route, _Req, State) -> {ok, State}. terminate(_Reason, _Route, _Req, _State) -> @@ -340,8 +368,7 @@ terminate(_Reason, _Route, _Req, _State) -> %%%FOR Cors support %%%Note! only matches on host. Does not handle ports. See: https://github.com/s1n4/leptus/issues/55 cross_domains(_Route, _Req, State) -> - {['_'], State}. - + {['_'], State}. %%%GET Methods get("/", Req, State) -> %The broker's "info" endpoint; returns some possibly useful information @@ -429,33 +456,11 @@ put("/application/:appname/reconfigure", Req, State) -> {RCode, RBody, RState} = handle_reconfigure_put(Req, State, XER, Appname, ReqBody), ?AUDI(Req, Bts, XER, Rcode), {RCode, RBody, RState}. - %%%POST methods post("/application/delete", Req, State) -> %This follows the AWS S3 Multi Key Delete: http://docs.aws.amazon.com/AmazonS3/latest/API/multiobjectdeleteapi.html - %Except I added an additional special value called "*" {Bts, XER} = init_api_call(Req), - {RCode, RBody, RState} = case try - B = maps:get(<<"appnames">>, jiffy:decode(leptus_req:body_raw(Req), [return_maps])), - true = erlang:is_list(B), - B - catch _:_ -> - invalid - end - of - invalid -> {400, "Invalid PUT Body", State}; - IDs -> - case IDs of - [] -> {200, "EMPTY PUT BODY", State}; - _ -> - %<<"*">> -> - %this block deleted all apps, but decided this backdoor wasn't very RESTy - %% {atomic, Apps} = mnesia:transaction(fun() -> mnesia:match_object(application, {application, '_', '_', '_', '_', '_', '_', '_', '_', '_'}, read) end), - % AppsToDelete = lists:map(fun(X) -> {application, Appname, _,_,_,_,_,_,_,_} = X, Appname end, Apps), - Returns = lists:map(fun(X) -> delete_app_helper(X, State, XER, Req) end, IDs), - RL = lists:map(fun({RC, _, _}) -> RC end, Returns), - {200, jiffy:encode(RL), State} - end - end, + ReqBody = leptus_req:body_raw(Req), + {RCode, RBody, RState} = handle_post_multidelete_app(Req, State, XER, ReqBody), ?AUDI(Req, Bts, XER, Rcode), {RCode, RBody, RState}. diff --git a/src/resource_handler_tests.erl b/src/resource_handler_tests.erl index 75e5302..111666b 100644 --- a/src/resource_handler_tests.erl +++ b/src/resource_handler_tests.erl @@ -25,10 +25,11 @@ parse_put_body/1, parse_reconfiguration_put_body/1, handle_reconfigure_put/5, - handle_put/6 + handle_put/6, + handle_post_multidelete_app/4 ]). -parse_put_body_test() -> +put_test() -> Valid = {[ {<<"cdap_application_type">>, <<"program-flowlet">>}, {<<"namespace">>, <<"ns">>}, @@ -160,4 +161,33 @@ reconfiguration_put_test() -> meck:unload(resource_handler). +delete_test() -> + EmptyD = dict:new(), + + %test failure: appnames missing + Invalid1 = jiffy:encode({[{<<"ids">>, [<<"hwtest">>]}]}), + ?assert(handle_post_multidelete_app(notused, EmptyD, notused, Invalid1) == {400,"Invalid PUT Body", EmptyD}), + + %test invalid: not a list + Invalid2 = jiffy:encode({[{<<"appnames">>, <<"hwtest">>}]}), + ?assert(handle_post_multidelete_app(notused, EmptyD, notused, Invalid2) == {400,"Invalid PUT Body", EmptyD}), + + %mock out delete_app_helper(X, State, XER, Req) + meck:new(resource_handler, [passthrough]), + meck:expect(resource_handler, + delete_app_helper, + fun(Appname, State, _XER, _Req) -> + case Appname of + <<"noexist">> -> {404, "Tried to delete an application that was not registered", State}; + <<"exist">> -> {200, "", State} + end + end), + %est empty + Empty = jiffy:encode({[{<<"appnames">>, []}]}), + ?assert(handle_post_multidelete_app(notused, EmptyD, notused, Empty) == {200, "EMPTY PUT BODY", EmptyD}), + + %test one app that is registered (in the mock...) and one app that is not regustered + Valid = jiffy:encode({[{<<"appnames">>, [<<"exist">>, <<"noexist">>]}]}), + ?assert(handle_post_multidelete_app(notused, EmptyD, notused, Valid) == {200, <<"[200,404]">>, EmptyD}), + meck:unload(resource_handler). diff --git a/swagger/swagger.html b/swagger/swagger.html index fd1d2e2..560157f 100644 --- a/swagger/swagger.html +++ b/swagger/swagger.html @@ -12,7 +12,7 @@ <body> <div class="container"> <h1>CDAP Broker API</h1> - <p class="sw-info">Version: <span class="sw-info-version">4.0.6</span></p> + <p class="sw-info">Version: <span class="sw-info-version">4.0.7</span></p> <p></p> diff --git a/swagger/swagger.json b/swagger/swagger.json index 205fcb2..da4ddd6 100644 --- a/swagger/swagger.json +++ b/swagger/swagger.json @@ -1,7 +1,7 @@ { "swagger": "2.0", "info": { - "version": "4.0.6", + "version": "4.0.7", "title": "CDAP Broker API" }, "paths": { diff --git a/swagger/swagger.yaml b/swagger/swagger.yaml index 899efbe..6449088 100644 --- a/swagger/swagger.yaml +++ b/swagger/swagger.yaml @@ -5,7 +5,7 @@ swagger: '2.0' # This is your document metadata info: - version: "4.0.6" + version: "4.0.7" title: CDAP Broker API paths: diff --git a/test/apitest/apitest_SUITE.erl b/test/apitest/apitest_SUITE.erl index c15dffc..d948330 100644 --- a/test/apitest/apitest_SUITE.erl +++ b/test/apitest/apitest_SUITE.erl @@ -21,7 +21,7 @@ -include_lib("common_test/include/ct.hrl"). -include("../../src/application.hrl"). -export([all/0, groups/0, init_per_suite/1, end_per_suite/1]). --export([server_health_test/1, app_deploy/1, hydrator_deploy/1, app_teardown/1, app_test/1, app_reconfigure/1, test_failures/1, app_botch_flows/1, app_botch_delete/1, app_botch_consul_delete/1, delete_all/1, +-export([server_health_test/1, app_deploy/1, hydrator_deploy/1, app_teardown/1, app_test/1, app_reconfigure/1, test_failures/1, app_botch_flows/1, app_botch_delete/1, app_botch_consul_delete/1, hydrator_app_teardown/1, hydrator_test/1, hydrator_wdeps_deploy/1, hydrator_wdeps_test/1, @@ -39,8 +39,7 @@ all() -> [ {group, hydratorapi}, {group, apibotchedflows}, {group, apibotcheddeleted}, - {group, apibotchedconsuldeleted}, - {group, apideleteall} + {group, apibotchedconsuldeleted} ]. groups() -> [ {progapi, %prog-flow test @@ -89,13 +88,6 @@ groups() -> [ app_deploy, app_botch_consul_delete, app_teardown - ]}, - {apideleteall, - [], - [ - server_health_test, - app_deploy, - delete_all ]} ]. @@ -289,7 +281,11 @@ init_per_suite(_C) -> ] . -end_per_suite(_C) -> +end_per_suite(C) -> + %teardown the fake service and make sure it is gone + erlang:display("Tearing down fake service"), + {200, Srv} = setup_fake_testing_service(C, teardown), + true = Srv == "[]", _ = application:stop(cdapbroker). server_health_test(C) -> @@ -763,18 +759,3 @@ test_failures(C) -> {<<"program_preferences">>, [{[{<<"program_type">>,<<"flows">>}, {<<"program_id">>, <<"WhoFlow">>}, {<<"program_pref">>, ?PLG(whoflowpref, C)}]}]} ]}, {404, _} = httpabs:put(?XER, URL, "application/json", jiffy:encode(Body3)). - -delete_all(C) -> - %test invalid key - Body1 = jiffy:encode({[{<<"ids">>, [<<"hwtest">>]}]}), - {400,"State: Bad Request. Return Body: Invalid PUT Body"} = httpabs:post(?XER, ?SC([?PLG(broker_url, C), "/application/delete"]), "application/json", Body1), - %test invalid: not a list - Body2 = jiffy:encode({[{<<"appnames">>, <<"hwtest">>}]}), - {400,"State: Bad Request. Return Body: Invalid PUT Body"} = httpabs:post(?XER, ?SC([?PLG(broker_url, C), "/application/delete"]), "application/json", Body2), - %test undeploy a real app and also an app that is not deployed - Body3 = jiffy:encode({[{<<"appnames">>, [<<"hwtest">>, <<"dissapointment">>]}]}), - {200, "[200,404]"} = httpabs:post(?XER, ?SC([?PLG(broker_url, C), "/application/delete"]), "application/json", Body3), - %teardown the fake service and make sure it is gone - {200, Srv} = setup_fake_testing_service(C, teardown), - true = Srv == "[]". - |