aboutsummaryrefslogtreecommitdiffstats
path: root/test/rlx_test_utils.erl
blob: 37d9c7a5101742db816f42f375fb0a230089c5e8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
%%% @author Tristan Sloughter <[email protected]>
%%% @copyright (C) 2015, Tristan Sloughter
-module(rlx_test_utils).

-compile(export_all).

create_app(Dir, Name, Vsn, Deps, LibDeps) ->
    AppDir = filename:join([Dir, Name ++ "-" ++ Vsn]),
    write_app_file(AppDir, Name, Vsn, app_modules(Name), Deps, LibDeps),
    write_src_file(AppDir, Name),
    compile_src_files(AppDir),
    rlx_app_info:new(erlang:list_to_atom(Name), Vsn, AppDir,
                     Deps, []).

create_full_app(Dir, Name, Vsn, Deps, LibDeps) ->
    AppDir = filename:join([Dir, Name ++ "-" ++ Vsn]),
    write_full_app_files(AppDir, Name, Vsn, Deps, LibDeps),
    compile_src_files(AppDir),
    rlx_app_info:new(erlang:list_to_atom(Name), Vsn, AppDir,
                     Deps, []).

create_empty_app(Dir, Name, Vsn, Deps, LibDeps) ->
    AppDir = filename:join([Dir, Name ++ "-" ++ Vsn]),
    write_app_file(AppDir, Name, Vsn, [], Deps, LibDeps),
    rlx_app_info:new(erlang:list_to_atom(Name), Vsn, AppDir,
                     Deps, []).

app_modules(Name) ->
    [list_to_atom(M ++ Name) ||
        M <- ["a_real_beam"]].

write_src_file(Dir, Name) ->
    Src = filename:join([Dir, "src", "a_real_beam" ++ Name ++ ".erl"]),
    ok = filelib:ensure_dir(Src),
    ok = file:write_file(Src, beam_file_contents("a_real_beam"++Name)).

write_appup_file(AppInfo, DownVsn) ->
    Dir = rlx_app_info:dir(AppInfo),
    Name = rlx_util:to_string(rlx_app_info:name(AppInfo)),
    Vsn = rlx_app_info:vsn_as_string(AppInfo),
    Filename = filename:join([Dir, "ebin", Name ++ ".appup"]),
    ok = filelib:ensure_dir(Filename),
    ok = ec_file:write_term(Filename, {Vsn, [{DownVsn, []}], [{DownVsn, []}]}).

write_app_file(Dir, Name, Version, Modules, Deps, LibDeps) ->
    Filename = filename:join([Dir, "ebin", Name ++ ".app"]),
    ok = filelib:ensure_dir(Filename),
    ok = ec_file:write_term(Filename, get_app_metadata(Name, Version, Modules,
                                                       Deps, LibDeps)).

compile_src_files(Dir) ->
    %% compile all *.erl files in src to ebin
    SrcDir = filename:join([Dir, "src"]),
    OutputDir = filename:join([Dir, "ebin"]),
    lists:foreach(fun(SrcFile) ->
                          {ok, _} = compile:file(SrcFile, [{outdir, OutputDir},
                                                           return_errors])
                  end, ec_file:find(SrcDir, "\\.erl")),
    ok.

get_app_metadata(Name, Vsn, Modules, Deps, LibDeps) ->
    {application, erlang:list_to_atom(Name),
     [{description, ""},
      {vsn, Vsn},
      {modules, Modules},
      {included_applications, LibDeps},
      {registered, []},
      {applications, Deps}]}.

write_full_app_files(Dir, Name, Vsn, Deps, LibDeps) ->
    %% write out the .app file
    AppFilename = filename:join([Dir, "ebin", Name ++ ".app"]),
    ok = filelib:ensure_dir(AppFilename),
    ok = ec_file:write_term(AppFilename,
                            get_full_app_metadata(Name, Vsn, Deps, LibDeps)),
    %% write out the _app.erl file
    ApplicationFilename = filename:join([Dir, "src", Name ++ "_app.erl"]),
    ok = filelib:ensure_dir(ApplicationFilename),
    ok = file:write_file(ApplicationFilename, full_application_contents(Name)),
    %% write out the supervisor
    SupervisorFilename = filename:join([Dir, "src", Name ++ "_sup.erl"]),
    ok = filelib:ensure_dir(SupervisorFilename),
    ok = file:write_file(SupervisorFilename, supervisor_contents(Name)),
    %% and finally the gen_server
    GenServerFilename = filename:join([Dir, "src", Name ++ "_srv.erl"]),
    ok = filelib:ensure_dir(GenServerFilename),
    ok = file:write_file(GenServerFilename, gen_server_contents(Name)),
    ok.

get_full_app_metadata(Name, Vsn, Deps, LibDeps) ->
    {application, erlang:list_to_atom(Name),
    [{description, ""},
     {vsn, Vsn},
     {modules, [goal_app_app,goal_app_sup,goal_app_srv]},
     {mod, {erlang:list_to_atom(Name ++  "_app"),
            []}},
     {included_applications, LibDeps},
     {registered, []},
     {applications, Deps}]}.

full_application_contents(Name) ->
    "-module("++Name++"_app).\n"
    "-behaviour(application).\n"
    "-export([start/2, stop/1]).\n"
    "start(_StartType, _StartArgs) ->\n"
    "   "++Name++"_sup:start_link().\n"
    "stop(_State) ->\n"
    "   ok.\n".

supervisor_contents(Name) ->
    "-module("++Name++"_sup).\n"
    "-behaviour(supervisor).\n"
    "-export([start_link/0]).\n"
    "-export([init/1]).\n"
    "-define(SERVER, ?MODULE).\n"
    "start_link() ->\n"
    "    supervisor:start_link({local, ?SERVER}, ?MODULE, []).\n"
    "init([]) ->\n"
    "    {ok, { {one_for_all, 0, 1},\n"
    "            [{"++Name++"_srv, {"++Name++"_srv, start_link, []},\n"
    "              transient, 5000, worker, ["++Name++"_srv]}\n"
    "            ]\n"
    "         }}.\n".

gen_server_contents(Name) ->
    "-module("++Name++"_srv).\n"
    "-behaviour(gen_server).\n"
    "-record(state, {}).\n"
    "-export([start_link/0]).\n"
    "-export([init/1,handle_call/3,handle_cast/2,\n"
    "         handle_info/2,terminate/2,code_change/3]).\n"
    "start_link() ->\n"
    "    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).\n"
    "init([]) ->\n"
    "    erlang:send_after(4000, self(), register_signal),"
    "    {ok, #state{}}.\n"
    "handle_call(_Event, _From, State) ->\n"
    "    {reply, ok, State}.\n"
    "handle_cast(_Event, State) ->\n"
    "    {noreply, State}.\n"
    "handle_info(register_signal, State) ->\n"
    "   erlang:register(goal_app_srv_signal, spawn(fun() -> timer:sleep(200000) end)),\n"
    "   {noreply, State};\n"
    "handle_info(_Info, State) ->\n"
    "    {noreply, State}.\n"
    "terminate(_Reason, _State) ->\n"
    "    ok.\n"
    "code_change(_OldVsn, State, _Extra) ->\n"
    "    {ok, State}.\n".

create_random_name(Name) ->
    Name ++ erlang:integer_to_list(random_uniform(1000000)).

create_random_vsn() ->
    lists:flatten([erlang:integer_to_list(random_uniform(100)),
                   ".", erlang:integer_to_list(random_uniform(100)),
                   ".", erlang:integer_to_list(random_uniform(100))]).

write_config(Filename, Values) ->
    ok = filelib:ensure_dir(Filename),
    ok = ec_file:write(Filename,
                       [io_lib:format("~p.\n", [Val]) || Val <- Values]).

beam_file_contents(Name) ->
    "-module("++Name++").".

test_template_contents() ->
    "{erts_vsn, \"{{erts_vsn}}\"}.\n"
     "{release_erts_version, \"{{release_erts_version}}\"}.\n"
        "{release_name, {{release_name}}}.\n"
        "{rel_vsn, \"{{release_version}}\"}.\n"
        "{release_version, \"{{release_version}}\"}.\n"
        "{log, \"{{log}}\"}.\n"
        "{output_dir, \"{{output_dir}}\"}.\n"
        "{target_dir, \"{{target_dir}}\"}.\n"
        "{config_file, \"{{ config_file }}\"}.\n"
        "{sys_config, \"{{sys_config}}\"}.\n"
        "{root_dir, \"{{root_dir}}\"}.\n"
        "{default_release_name, {{default_release_name}}}.\n"
        "{default_release_version, \"{{default_release_version}}\"}.\n"
        "{default_release, \"{{default_release}}\"}.\n"
        "{yahoo4, \"{{yahoo4}}\"}.\n"
        "{yahoo, \"{{yahoo}}\"}.\n"
        "{foo_dir, \"{{foo_dir}}\"}.\n"
        "{foo_yahoo, \"{{foo_yahoo}}\"}.\n"
        "{google, \"{{google}}\"}.\n"
        "{prop1, \"{{prop1}}\"}.\n"
        "{prop2, {{prop2}}}.\n".

escript_contents() ->
    "#!/usr/bin/env escript\n"
    "\n"
    "main(_Args) ->\n"
    "io:format(\"~s\n\",\n"
    "    [os:getenv(\"RELEASE_ROOT_DIR\")]).\n".

-ifdef(rand_module).
random_uniform(N) ->
    rand:uniform(N).
-else.
random_uniform(N) ->
    random:seed(os:timestamp()),
    random:uniform(N).
-endif.

list_to_term(String) ->
    {ok, T, _} = erl_scan:string(String++"."),
    case erl_parse:parse_term(T) of
        {ok, Term} ->
            Term;
        {error, Error} ->
            Error
    end.

unescape_string(String) ->
    re:replace(String, "\"", "",
               [global, {return, list}]).