diff options
author | Trygve Laugstøl <trygvis@inamo.no> | 2024-02-23 07:08:18 +0100 |
---|---|---|
committer | Trygve Laugstøl <trygvis@inamo.no> | 2024-02-23 07:08:18 +0100 |
commit | 5a9cdd3cc89507d4d74f8bded56ce5e037b3b56e (patch) | |
tree | 982ca2e7f9ac4e8c350dfb5c4f60bcfdfff5afaf /learn-you-some-erlang/m8ball | |
parent | 05ae56e5e89abf2993f84e6d52b250131f247c35 (diff) | |
download | erlang-workshop-5a9cdd3cc89507d4d74f8bded56ce5e037b3b56e.tar.gz erlang-workshop-5a9cdd3cc89507d4d74f8bded56ce5e037b3b56e.tar.bz2 erlang-workshop-5a9cdd3cc89507d4d74f8bded56ce5e037b3b56e.tar.xz erlang-workshop-5a9cdd3cc89507d4d74f8bded56ce5e037b3b56e.zip |
wip
Diffstat (limited to 'learn-you-some-erlang/m8ball')
-rw-r--r-- | learn-you-some-erlang/m8ball/Emakefile | 2 | ||||
-rw-r--r-- | learn-you-some-erlang/m8ball/config/a.config | 9 | ||||
-rw-r--r-- | learn-you-some-erlang/m8ball/config/b.config | 9 | ||||
-rw-r--r-- | learn-you-some-erlang/m8ball/config/c.config | 9 | ||||
-rw-r--r-- | learn-you-some-erlang/m8ball/ebin/m8ball.app | 13 | ||||
-rw-r--r-- | learn-you-some-erlang/m8ball/logs/.track-this | 0 | ||||
-rw-r--r-- | learn-you-some-erlang/m8ball/src/m8ball.erl | 24 | ||||
-rw-r--r-- | learn-you-some-erlang/m8ball/src/m8ball_server.erl | 46 | ||||
-rw-r--r-- | learn-you-some-erlang/m8ball/src/m8ball_sup.erl | 16 | ||||
-rw-r--r-- | learn-you-some-erlang/m8ball/test/dist_m8ball_SUITE.erl | 32 | ||||
-rw-r--r-- | learn-you-some-erlang/m8ball/test/dist_m8ball_SUITE_data/backup.config | 9 | ||||
-rw-r--r-- | learn-you-some-erlang/m8ball/test/dist_m8ball_SUITE_data/main.config | 9 | ||||
-rw-r--r-- | learn-you-some-erlang/m8ball/test/m8ball.spec | 5 | ||||
-rw-r--r-- | learn-you-some-erlang/m8ball/test/m8ball_dist.spec | 20 | ||||
-rw-r--r-- | learn-you-some-erlang/m8ball/test/m8ball_server_SUITE.erl | 45 |
15 files changed, 248 insertions, 0 deletions
diff --git a/learn-you-some-erlang/m8ball/Emakefile b/learn-you-some-erlang/m8ball/Emakefile new file mode 100644 index 0000000..b203ea3 --- /dev/null +++ b/learn-you-some-erlang/m8ball/Emakefile @@ -0,0 +1,2 @@ +{["src/*", "test/*"], + [{i,"include"}, {outdir, "ebin"}]}. diff --git a/learn-you-some-erlang/m8ball/config/a.config b/learn-you-some-erlang/m8ball/config/a.config new file mode 100644 index 0000000..983d5e1 --- /dev/null +++ b/learn-you-some-erlang/m8ball/config/a.config @@ -0,0 +1,9 @@ +[{kernel, + [{distributed, [{m8ball, + 5000, + [a@ferdmbp, {b@ferdmbp, c@ferdmbp}]}]}, + {sync_nodes_mandatory, [b@ferdmbp, c@ferdmbp]}, + {sync_nodes_timeout, 30000} + ] + } +]. diff --git a/learn-you-some-erlang/m8ball/config/b.config b/learn-you-some-erlang/m8ball/config/b.config new file mode 100644 index 0000000..2d0ccfc --- /dev/null +++ b/learn-you-some-erlang/m8ball/config/b.config @@ -0,0 +1,9 @@ +[{kernel, + [{distributed, [{m8ball, + 5000, + [a@ferdmbp, {b@ferdmbp, c@ferdmbp}]}]}, + {sync_nodes_mandatory, [a@ferdmbp, c@ferdmbp]}, + {sync_nodes_timeout, 30000} + ] + } +]. diff --git a/learn-you-some-erlang/m8ball/config/c.config b/learn-you-some-erlang/m8ball/config/c.config new file mode 100644 index 0000000..3dd3609 --- /dev/null +++ b/learn-you-some-erlang/m8ball/config/c.config @@ -0,0 +1,9 @@ +[{kernel, + [{distributed, [{m8ball, + 5000, + [a@ferdmbp, {b@ferdmbp, c@ferdmbp}]}]}, + {sync_nodes_mandatory, [a@ferdmbp, b@ferdmbp]}, + {sync_nodes_timeout, 30000} + ] + } +]. diff --git a/learn-you-some-erlang/m8ball/ebin/m8ball.app b/learn-you-some-erlang/m8ball/ebin/m8ball.app new file mode 100644 index 0000000..352c1d4 --- /dev/null +++ b/learn-you-some-erlang/m8ball/ebin/m8ball.app @@ -0,0 +1,13 @@ +{application, m8ball, + [{vsn, "1.0.0"}, + {description, "Answer vital questions"}, + {modules, [m8ball, m8ball_sup, m8ball_server]}, + {applications, [stdlib, kernel, crypto]}, + {registered, [m8ball, m8ball_sup, m8ball_server]}, + {mod, {m8ball, []}}, + {env, [ + {answers, {<<"Yes">>, <<"No">>, <<"Doubtful">>, + <<"I don't like your tone">>, <<"Of course">>, + <<"Of course not">>, <<"*backs away slowly and runs away*">>}} + ]} + ]}. diff --git a/learn-you-some-erlang/m8ball/logs/.track-this b/learn-you-some-erlang/m8ball/logs/.track-this new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/learn-you-some-erlang/m8ball/logs/.track-this diff --git a/learn-you-some-erlang/m8ball/src/m8ball.erl b/learn-you-some-erlang/m8ball/src/m8ball.erl new file mode 100644 index 0000000..041601b --- /dev/null +++ b/learn-you-some-erlang/m8ball/src/m8ball.erl @@ -0,0 +1,24 @@ +-module(m8ball). +-behaviour(application). +-export([start/2, stop/1]). +-export([ask/1]). + +%%%%%%%%%%%%%%%%% +%%% CALLBACKS %%% +%%%%%%%%%%%%%%%%% + +%% start({failover, Node}, Args) is only called +%% when a start_phase key is defined. +start(normal, []) -> + m8ball_sup:start_link(); +start({takeover, _OtherNode}, []) -> + m8ball_sup:start_link(). + +stop(_State) -> + ok. + +%%%%%%%%%%%%%%%%% +%%% INTERFACE %%% +%%%%%%%%%%%%%%%%% +ask(Question) -> + m8ball_server:ask(Question). diff --git a/learn-you-some-erlang/m8ball/src/m8ball_server.erl b/learn-you-some-erlang/m8ball/src/m8ball_server.erl new file mode 100644 index 0000000..4e821ad --- /dev/null +++ b/learn-you-some-erlang/m8ball/src/m8ball_server.erl @@ -0,0 +1,46 @@ +-module(m8ball_server). +-behaviour(gen_server). +-export([start_link/0, stop/0, ask/1]). +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + code_change/3, terminate/2]). + +%%%%%%%%%%%%%%%%% +%%% INTERFACE %%% +%%%%%%%%%%%%%%%%% +start_link() -> + gen_server:start_link({global, ?MODULE}, ?MODULE, [], []). + +stop() -> + gen_server:call({global, ?MODULE}, stop). + +ask(_Question) -> % the question doesn't matter! + gen_server:call({global, ?MODULE}, question). + +%%%%%%%%%%%%%%%%% +%%% CALLBACKS %%% +%%%%%%%%%%%%%%%%% +init([]) -> + <<A:32, B:32, C:32>> = crypto:rand_bytes(12), + random:seed(A,B,C), + {ok, []}. + +handle_call(question, _From, State) -> + {ok, Answers} = application:get_env(m8ball, answers), + Answer = element(random:uniform(tuple_size(Answers)), Answers), + {reply, Answer, State}; +handle_call(stop, _From, State) -> + {stop, normal, ok, State}; +handle_call(_Call, _From, State) -> + {noreply, State}. + +handle_cast(_Cast, State) -> + {noreply, State}. + +handle_info(_Info, State) -> + {noreply, State}. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +terminate(_Reason, _State) -> + ok. diff --git a/learn-you-some-erlang/m8ball/src/m8ball_sup.erl b/learn-you-some-erlang/m8ball/src/m8ball_sup.erl new file mode 100644 index 0000000..ca5e426 --- /dev/null +++ b/learn-you-some-erlang/m8ball/src/m8ball_sup.erl @@ -0,0 +1,16 @@ +-module(m8ball_sup). +-behaviour(supervisor). +-export([start_link/0, init/1]). + +start_link() -> + supervisor:start_link({global,?MODULE}, ?MODULE, []). + +init([]) -> + {ok, {{one_for_one, 1, 10}, + [{m8ball, + {m8ball_server, start_link, []}, + permanent, + 5000, + worker, + [m8ball_server] + }]}}. diff --git a/learn-you-some-erlang/m8ball/test/dist_m8ball_SUITE.erl b/learn-you-some-erlang/m8ball/test/dist_m8ball_SUITE.erl new file mode 100644 index 0000000..3afba6e --- /dev/null +++ b/learn-you-some-erlang/m8ball/test/dist_m8ball_SUITE.erl @@ -0,0 +1,32 @@ +-module(dist_m8ball_SUITE). +-include_lib("common_test/include/ct.hrl"). +-export([all/0, groups/0, init_per_group/2, end_per_group/2]). +-export([can_contact/1]). + +all() -> [{group, main}, {group, backup}]. + +groups() -> [{main, + [], + [can_contact]}, + {backup, + [], + [can_contact]}]. + +init_per_group(main, Config) -> + application:start(crypto), + application:start(m8ball), + Config; +init_per_group(backup, Config) -> + application:start(crypto), + application:start(m8ball), + Config. + +end_per_group(main, _Config) -> + %application:stop(m8ball), + ok; +end_per_group(backup, _Config) -> + %application:stop(m8ball), + ok. + +can_contact(_Config) -> + <<_/binary>> = m8ball:ask(<<"Some Question">>). diff --git a/learn-you-some-erlang/m8ball/test/dist_m8ball_SUITE_data/backup.config b/learn-you-some-erlang/m8ball/test/dist_m8ball_SUITE_data/backup.config new file mode 100644 index 0000000..7fbe260 --- /dev/null +++ b/learn-you-some-erlang/m8ball/test/dist_m8ball_SUITE_data/backup.config @@ -0,0 +1,9 @@ +[{kernel, + [{distributed, [{m8ball, + 5000, + ['a@li101-172.members.linode.com', 'b@li101-172.members.linode.com']}]}, + {sync_nodes_mandatory, ['a@li101-172.members.linode.com']}, + {sync_nodes_timeout, 5000} + ] + } +]. diff --git a/learn-you-some-erlang/m8ball/test/dist_m8ball_SUITE_data/main.config b/learn-you-some-erlang/m8ball/test/dist_m8ball_SUITE_data/main.config new file mode 100644 index 0000000..bcac447 --- /dev/null +++ b/learn-you-some-erlang/m8ball/test/dist_m8ball_SUITE_data/main.config @@ -0,0 +1,9 @@ +[{kernel, + [{distributed, [{m8ball, + 5000, + ['a@li101-172.members.linode.com', 'b@li101-172.members.linode.com']}]}, + {sync_nodes_mandatory, ['b@li101-172.members.linode.com']}, + {sync_nodes_timeout, 5000} + ] + } +]. diff --git a/learn-you-some-erlang/m8ball/test/m8ball.spec b/learn-you-some-erlang/m8ball/test/m8ball.spec new file mode 100644 index 0000000..51d9cf3 --- /dev/null +++ b/learn-you-some-erlang/m8ball/test/m8ball.spec @@ -0,0 +1,5 @@ +{include, "../include/"}. +{alias, root, "/home/ferd/code/learn-you-some-erlang/m8ball/test"}. +{logdir, "/home/ferd/code/learn-you-some-erlang/m8ball/logs"}. + +{suites, root, all}. diff --git a/learn-you-some-erlang/m8ball/test/m8ball_dist.spec b/learn-you-some-erlang/m8ball/test/m8ball_dist.spec new file mode 100644 index 0000000..c49a6ca --- /dev/null +++ b/learn-you-some-erlang/m8ball/test/m8ball_dist.spec @@ -0,0 +1,20 @@ +{node, master, 'ct@li101-172.members.linode.com'}. +{node, a, 'a@li101-172.members.linode.com'}. +{node, b, 'b@li101-172.members.linode.com'}. + +{init, a, [{node_start, [{monitor_master, true}, + {boot_timeout, 10000}, + {erl_flags, "-pa /home/ferd/code/learn-you-some-erlang/m8ball/ebin/ " + "-config /home/ferd/code/learn-you-some-erlang/m8ball/test/dist_m8ball_SUITE_data/main.config"}]}]}. +{init, b, [{node_start, [{monitor_master, true}, + {boot_timeout, 10000}, + {erl_flags, "-pa /home/ferd/code/learn-you-some-erlang/m8ball/ebin/ " + "-config /home/ferd/code/learn-you-some-erlang/m8ball/test/dist_m8ball_SUITE_data/backup.config"}]}]}. + +{include, "../include/"}. +{alias, root, "/home/ferd/code/learn-you-some-erlang/m8ball/test"}. +{logdir, "/home/ferd/code/learn-you-some-erlang/m8ball/logs"}. +{logdir, master, "/home/ferd/code/learn-you-some-erlang/m8ball/logs"}. + +{groups, a, root, dist_m8ball_SUITE, main}. +{groups, b, root, dist_m8ball_SUITE, backup}. diff --git a/learn-you-some-erlang/m8ball/test/m8ball_server_SUITE.erl b/learn-you-some-erlang/m8ball/test/m8ball_server_SUITE.erl new file mode 100644 index 0000000..6bc4156 --- /dev/null +++ b/learn-you-some-erlang/m8ball/test/m8ball_server_SUITE.erl @@ -0,0 +1,45 @@ +-module(m8ball_server_SUITE). +-include_lib("common_test/include/ct.hrl"). +-export([all/0, init_per_testcase/2, end_per_testcase/2]). +-export([random_answer/1, binary_answer/1, determined_answers/1, + reload_answers/1]). + +all() -> [random_answer, binary_answer, determined_answers, + reload_answers]. + +init_per_testcase(_Test, Config) -> + Answers = [<<"Outlook not so good">>, + <<"I don't think so">>, + <<"Yes, definitely">>, + <<"STOP SHAKING ME">>], + application:set_env(m8ball, answers, list_to_tuple(Answers)), + m8ball_server:start_link(), + [{answers, Answers} | Config]. + +end_per_testcase(_Test, _Config) -> + m8ball_server:stop(). + +%% The answer should come from the config +random_answer(_Config) -> + Answers1 = [m8ball_server:ask("Dummy question") || _ <- lists:seq(1,15)], + Answers2 = [m8ball_server:ask("Dummy question") || _ <- lists:seq(1,15)], + true = 1 < length(sets:to_list(sets:from_list(Answers1))), + true = Answers1 =/= Answers2. + +binary_answer(_Config) -> + Answers = [m8ball_server:ask("Dummy question") || _ <- lists:seq(1,15)], + L = length(Answers), + L = length(lists:filter(fun erlang:is_binary/1, Answers)). + +determined_answers(Config) -> + Answers = ?config(answers, Config), + Res = [m8ball_server:ask("Dummy question") || _ <- lists:seq(1,15)], + true = lists:all(fun(X) -> lists:member(X, Answers) end, Res). + +reload_answers(_Config) -> + Ref = make_ref(), + application:set_env(m8ball, answers, {Ref}), + [Ref,Ref,Ref] = [m8ball_server:ask("Question") || _ <- lists:seq(1,3)]. + + +%% NOTE: do distributed testing in m8ball_SUITE or something |