Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 22 additions & 11 deletions src/dev_b32_name.erl
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,20 @@ encode(ID) when ?IS_ID(ID) ->

%%% Tests

%% @doc If the sudbdomain provided isn't a valid ARNS or a 52 char subdomain
%% it should return 404 instead of HyperBEAM page.
invalid_arns_and_not_52char_host_resolution_gives_404_test() ->
dev_b32_name_test_() ->
{inparallel, [
{timeout, 30, fun invalid_arns_and_not_52char_host_resolution_gives_404_case/0},
fun key_to_id_case/0,
{timeout, 30, fun empty_path_manifest_case/0},
{timeout, 30, fun resolve_52char_subdomain_asset_if_txid_not_present_case/0},
{timeout, 30, fun subdomain_matches_path_id_and_loads_asset_case/0},
fun subdomain_matches_path_id_case/0,
fun subdomain_does_not_match_path_id_case/0,
{timeout, 30, fun manifest_subdomain_matches_path_id_case/0},
{timeout, 30, fun manifest_subdomain_does_not_match_path_id_case/0}
]}.

invalid_arns_and_not_52char_host_resolution_gives_404_case() ->
Opts = dev_name:test_arns_opts(),
Node = hb_http_server:start_node(Opts),
?assertMatch(
Expand All @@ -62,15 +73,15 @@ invalid_arns_and_not_52char_host_resolution_gives_404_test() ->
).

%% @doc Unit test for 52 char subdomain to TX ID logic
key_to_id_test() ->
key_to_id_case() ->
Subdomain = <<"4nuojs5tw6xtfjbq47dqk6ak7n6tqyr3uxgemkq5z5vmunhxphya">>,
?assertEqual(
<<"42jky7O3rzKkMOfHBXgK-304YjulzEYqHc9qyjT3efA">>,
decode(Subdomain)
).

%% @doc Resolving a 52 char subdomain without a TXID in the path should work.
empty_path_manifest_test() ->
empty_path_manifest_case() ->
TestPath = <<"/">>,
Opts = manifest_opts(),
%% Test to load manifest with only subdomain
Expand All @@ -96,7 +107,7 @@ empty_path_manifest_test() ->

%% @doc Loading assets from a manifest where only a 52 char subdomain is
%% provided should work.
resolve_52char_subdomain_asset_if_txid_not_present_test() ->
resolve_52char_subdomain_asset_if_txid_not_present_case() ->
TestPath = <<"/assets/ArticleBlock-Dtwjc54T.js">>,
Opts = manifest_opts(),
%% Test to load asset with only subdomain (no TX ID present).
Expand All @@ -122,7 +133,7 @@ resolve_52char_subdomain_asset_if_txid_not_present_test() ->

%% @doc Loading assets from a manifest where a 52 char subdomain and TX ID
%% is provided should work.
subdomain_matches_path_id_and_loads_asset_test() ->
subdomain_matches_path_id_and_loads_asset_case() ->
TestPath = <<"/42jky7O3rzKkMOfHBXgK-304YjulzEYqHc9qyjT3efA/assets/ArticleBlock-Dtwjc54T.js">>,
Opts = manifest_opts(),
%% Test to load asset with only subdomain (no TX ID present).
Expand All @@ -148,7 +159,7 @@ subdomain_matches_path_id_and_loads_asset_test() ->

%% @doc Validate the behavior when a subdomain and primary path ID match. The
%% duplicated ID in the request message stream should be ignored.
subdomain_matches_path_id_test() ->
subdomain_matches_path_id_case() ->
#{ id1 := ID1, opts := Opts } = test_opts(),
?assertMatch(
{ok, 1},
Expand All @@ -164,7 +175,7 @@ subdomain_matches_path_id_test() ->

%% @doc Validate the behavior when a subdomain and primary path ID match. Both
%% IDs should be executed, the subdomain first then the path ID.
subdomain_does_not_match_path_id_test() ->
subdomain_does_not_match_path_id_case() ->
#{ id1 := ID1, id2 := ID2, opts := Opts }
= test_opts(),
?assertMatch(
Expand All @@ -181,7 +192,7 @@ subdomain_does_not_match_path_id_test() ->

%% @doc When both 52 char subdomain and TX ID are provided and equal, ignore
%% the TXID from the assets path.
manifest_subdomain_matches_path_id_test() ->
manifest_subdomain_matches_path_id_case() ->
TestPath = <<"/42jky7O3rzKkMOfHBXgK-304YjulzEYqHc9qyjT3efA">>,
Opts = manifest_opts(),
Subdomain = <<"4nuojs5tw6xtfjbq47dqk6ak7n6tqyr3uxgemkq5z5vmunhxphya">>,
Expand All @@ -208,7 +219,7 @@ manifest_subdomain_matches_path_id_test() ->
%% the subdomain TXID is loaded, and tries to access the assets path defined.
%% In this case, sinse no assets exists with this TX ID, it should load the
%% index.
manifest_subdomain_does_not_match_path_id_test() ->
manifest_subdomain_does_not_match_path_id_case() ->
TestPath = <<"/1rTy7gQuK9lJydlKqCEhtGLp2WWG-GOrVo5JdiCmaxs">>,
Opts = manifest_opts(),
Subdomain = <<"4nuojs5tw6xtfjbq47dqk6ak7n6tqyr3uxgemkq5z5vmunhxphya">>,
Expand Down
61 changes: 44 additions & 17 deletions src/dev_push.erl
Original file line number Diff line number Diff line change
Expand Up @@ -770,13 +770,35 @@ parse_redirect(Location, Opts) ->

%%% Tests

full_push_test_() ->
dev_push_test_() ->
{inparallel, push_test_cases()}.

push_test_cases() ->
[
full_push_case_(),
push_as_identity_case_(),
multi_process_push_case_(),
push_prompts_encoding_change_case_(),
remote_routed_push_case_(),
oracle_push_case_()
]
++
genesis_wasm_cases().

-ifdef(ENABLE_GENESIS_WASM).
genesis_wasm_cases() -> [nested_push_prompts_encoding_change_case_()].
-else.
genesis_wasm_cases() -> [].
-endif.

full_push_case_() ->
{timeout, 30, fun() ->
dev_process_test_vectors:init(),
Opts = #{
process_async_cache => false,
priv_wallet => hb:wallet(),
cache_control => <<"always">>
cache_control => <<"always">>,
store => [hb_test_utils:test_store(hb_store_lmdb)]
},
Base = dev_process_test_vectors:aos_process(Opts),
hb_cache:write(Base, Opts),
Expand Down Expand Up @@ -808,7 +830,7 @@ full_push_test_() ->
)
end}.

push_as_identity_test_() ->
push_as_identity_case_() ->
{timeout, 90, fun() ->
dev_process_test_vectors:init(),
% Create a new identity for the scheduler.
Expand All @@ -817,13 +839,15 @@ push_as_identity_test_() ->
SchedulingID = hb_util:human_id(SchedulingWallet),
ComputeWallet = ar_wallet:new(),
ComputeID = hb_util:human_id(ComputeWallet),
TestStore = [hb_test_utils:test_store(hb_store_lmdb)],
Opts = #{
priv_wallet => DefaultWallet,
cache_control => <<"always">>,
store => TestStore,
identities => #{
SchedulingID => #{
priv_wallet => SchedulingWallet,
store => [hb_test_utils:test_store()]
store => [hb_test_utils:test_store(hb_store_lmdb)]
},
ComputeID => #{
priv_wallet => ComputeWallet
Expand Down Expand Up @@ -889,12 +913,13 @@ push_as_identity_test_() ->
)
end}.

multi_process_push_test_() ->
multi_process_push_case_() ->
{timeout, 30, fun() ->
dev_process_test_vectors:init(),
Opts = #{
priv_wallet => hb:wallet(),
cache_control => <<"always">>
cache_control => <<"always">>,
store => [hb_test_utils:test_store(hb_store_lmdb)]
},
Proc1 = dev_process_test_vectors:aos_process(Opts),
hb_cache:write(Proc1, Opts),
Expand Down Expand Up @@ -1030,7 +1055,7 @@ push_with_redirect_hint_test_disabled() ->
?assertEqual({ok, <<"GOT PONG">>}, AfterPush)
end}.

push_prompts_encoding_change_test_() ->
push_prompts_encoding_change_case_() ->
{timeout, 30, fun push_prompts_encoding_change/0}.
push_prompts_encoding_change() ->
dev_process_test_vectors:init(),
Expand Down Expand Up @@ -1069,7 +1094,7 @@ push_prompts_encoding_change() ->
),
?assertMatch({error, #{ <<"status">> := 422 }}, Res).

remote_routed_push_test_() ->
remote_routed_push_case_() ->
{timeout, 60, fun remote_routed_push/0}.
remote_routed_push() ->
% Creates a network of nodes and processes with the following structure:
Expand All @@ -1095,9 +1120,9 @@ remote_routed_push() ->
%
% We start by generating the isolated wallets and stores for each node.
N1Wallet = ar_wallet:new(),
N1Store = [hb_test_utils:test_store()],
N1Store = [hb_test_utils:test_store(hb_store_lmdb)],
N2Wallet = ar_wallet:new(),
N2Store = [hb_test_utils:test_store()],
N2Store = [hb_test_utils:test_store(hb_store_lmdb)],
% Next, create the second node and process. We do this before node 1 such
% that the routes of node 1 and the target of process 1's message are known
% when we create them.
Expand Down Expand Up @@ -1228,24 +1253,26 @@ remote_routed_push() ->
hb_ao:resolve(LoadedProc2, <<"now/at-slot">>, N2Opts)
).

oracle_push_test_() -> {timeout, 30, fun oracle_push/0}.
oracle_push_case_() -> {timeout, 30, fun oracle_push/0}.
oracle_push() ->
dev_process_test_vectors:init(),
Client = dev_process_test_vectors:aos_process(),
{ok, _} = hb_cache:write(Client, #{}),
{ok, _} = dev_process_test_vectors:schedule_aos_call(Client, oracle_script()),
TestStore = [hb_test_utils:test_store(hb_store_lmdb)],
Opts = #{ priv_wallet => hb:wallet(), store => TestStore },
Client = dev_process_test_vectors:aos_process(Opts),
{ok, _} = hb_cache:write(Client, Opts),
{ok, _} = dev_process_test_vectors:schedule_aos_call(Client, oracle_script(), Opts),
Res =
#{
<<"path">> => <<"push">>,
<<"slot">> => 0
},
{ok, PushResult} = hb_ao:resolve(Client, Res, #{ priv_wallet => hb:wallet() }),
{ok, PushResult} = hb_ao:resolve(Client, Res, Opts),
?event({result, PushResult}),
ComputeRes =
hb_ao:resolve(
Client,
<<"now/results/data">>,
#{ priv_wallet => hb:wallet() }
Opts
),
?event({compute_res, ComputeRes}),
?assertMatch({ok, _}, ComputeRes).
Expand All @@ -1254,7 +1281,7 @@ oracle_push() ->
%% @doc Test that a message that generates another message which resides on an
%% ANS-104 scheduler leads to `~push@1.0` re-signing the message correctly.
%% Requires `ENABLE_GENESIS_WASM' to be enabled.
nested_push_prompts_encoding_change_test_() ->
nested_push_prompts_encoding_change_case_() ->
{timeout, 30, fun nested_push_prompts_encoding_change/0}.
nested_push_prompts_encoding_change() ->
dev_process_test_vectors:init(),
Expand Down
5 changes: 3 additions & 2 deletions src/hb_ao_device.erl
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,9 @@ maybe_normalize_device_key(Key, Mode) ->
%% a tuple of the form {error, Reason} is returned.
load(Map, _Opts) when is_map(Map) -> {ok, Map};
load(ID, _Opts) when is_atom(ID) ->
try ID:module_info(), {ok, ID}
catch _:_ -> {error, not_loadable}
case code:ensure_loaded(ID) of
{module, ID} -> {ok, ID};
{error, _} -> {error, not_loadable}
end;
load(ID, Opts) when ?IS_ID(ID) ->
?event(device_load, {requested_load, {id, ID}}, Opts),
Expand Down