Increase unit test coverage 85/11985/1
authorTommy Carpenter <tommy@research.att.com>
Tue, 12 Sep 2017 15:52:41 +0000 (11:52 -0400)
committerTommy Carpenter <tommy@research.att.com>
Tue, 12 Sep 2017 15:55:09 +0000 (11:55 -0400)
Issue-ID: DCAEGEN2-99
Change-Id: I16840cef4230bc5123421c7b6a975cefe1c4d136
Signed-off-by: Tommy Carpenter <tommy@research.att.com>
Changelog.md
bin/build_and_run.sh
bin/build_and_test.sh
rebar.config
src/cdapbroker.app.src
src/resource_handler.erl
src/resource_handler_tests.erl
swagger/swagger.html
swagger/swagger.json
swagger/swagger.yaml
test/apitest/apitest_SUITE.erl

index 6beae6f..c0631f3 100644 (file)
@@ -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
index 8d48716..5273cee 100755 (executable)
@@ -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";
index b0456f4..d5bbf6c 100755 (executable)
@@ -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";
index 331d11a..34b28a6 100644 (file)
@@ -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"}}},
index 611d873..eb39868 100644 (file)
@@ -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,
index 798f457..1a0760d 100644 (file)
@@ -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}.
index 75e5302..111666b 100644 (file)
                             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).
index fd1d2e2..560157f 100644 (file)
@@ -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>
     
     
index 205fcb2..da4ddd6 100644 (file)
@@ -1,7 +1,7 @@
 {
     "swagger": "2.0",
     "info": {
-        "version": "4.0.6",
+        "version": "4.0.7",
         "title": "CDAP Broker API"
     },
     "paths": {
index 899efbe..6449088 100644 (file)
@@ -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:
index c15dffc..d948330 100644 (file)
@@ -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 == "[]".
-