aboutsummaryrefslogblamecommitdiffstats
path: root/lib/tools/test/make_SUITE.erl
blob: 02da4f4ace6620d7f0f20ab6c450aa02e6e7b34b (plain) (tree)
1
2
3
4
5
6
7
8
9


                   
                                                        
  


                                                                   
  






                                                                           




                    
                     
 
                                           










                                                                             
                                         
 
         
                                                                       
                                    

            
                                          
                                 
 





                         
                                     
                          

                                    
                         
 














                                                                                  


                                                     
                                        





                                                                   

       
                                          
                                       


                             


                                              
 

                                                                      
 

                          

       

























                                                     


































                                                                      













                                                                  



                                                                      





                                                                    


                                  





                                    












                                                        



                                        




                                             

                                                    




                                                                    



                                                         







                                                                  


                                          


                                                 




                                                             
 
                         

           
                                                                       
                                          
                                                    

                                 
                               
                                                    
                            

                      
                            






                                                                   

                  
                                                   





                                                                     
                                                          
                                      
                      

                                                          
                                     

                    
                                                             


                            

                                                                   

                             
                           
 
                         

       
                                                                
                                          
                                                    

                                 
                               
                                                    
                            



                                                    
                                          

                        

                                               

                                                                 

                  
                                                   


                           
                                          

                             
                           
 
                         

       

                                                                
                                          
                                                    

                                 
                               
                                                    
                            




                                                    
                                                         

                        

                                            


                                                                   

                  
                                                   


                            
                                                          

                             
                           
 
                         















                                            


                                                       
              

                          
                                      
                 
        
%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 1996-2017. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%%     http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%% %CopyrightEnd%
%%
-module(make_SUITE).

-compile(export_all).

-include_lib("common_test/include/ct.hrl").

-include_lib("kernel/include/file.hrl").

%% in ./make_SUITE_data there are test-files used by this
%% test suite. There are 4 files named test1.erl ... test5.erl.
%% The test files are attacked in various ways in order to put make on trial.
%% 
%% Also, and Emakefile exists in ./make_SUITE_data. This file specifies
%% that the file :"test5.erl" shall be compiled with the 'S' option,
%% i.e. produce "test5.S" instead of "test5.<objext>"

suite() -> [{ct_hooks,[ts_install_cth]}].

all() -> 
    [make_all, make_files, load, netload, recompile_on_changed_include,
     emake_opts, {group, otp_6057}].

groups() -> 
    [{otp_6057,[],[otp_6057_a, otp_6057_b,
                   otp_6057_c]}].

init_per_suite(Config) ->
    Config.

end_per_suite(_Config) ->
    ok.

init_per_group(_GroupName, Config) ->
    otp_6057_init(Config).

end_per_group(_GroupName, Config) ->
    otp_6057_end(Config).

init_per_testcase(_,Config) ->
    Config.

end_per_testcase(netload,_Config) ->
    %% Stop slave - in case of failure
    Nodes = nodes(),
    case [N || N <- Nodes,
               "make_SUITE_netload" == hd(string:lexemes(atom_to_list(N),"@"))] of
        [Node] ->
            ct_slave:stop(Node);
        _ ->
            ok
    end;
end_per_testcase(_,_Config) ->
    ok.

test_files() -> ["test1", "test2", "test3", "test4"].

make_all(Config) when is_list(Config) ->
    Current = prepare_data_dir(Config),
    up_to_date = make:all(),
    ok = ensure_exists(test_files()),
    ok = ensure_exists(["test5"],".S"), % Emakefile: [{test5,['S']}
    file:set_cwd(Current),
    ensure_no_messages(),
    ok.

make_files(Config) when is_list(Config) ->
    Current = prepare_data_dir(Config),

    %% Make files that exist.

    Files = [test1, test2],
    up_to_date = make:files(Files), % ok files
    ok = ensure_exists(Files),

    error = make:files([test1,test7]), % non existing file
    up_to_date = make:files([test1,test2],[debug_info]), % with option

    file:set_cwd(Current),
    ensure_no_messages(),
    ok.

load(Config) ->
    Current = prepare_data_dir(Config),
    code:purge(test1),
    code:delete(test1),
    false = code:is_loaded(test1),
    up_to_date = make:files([test1], [load]),
    {file,_} = code:is_loaded(test1),
    file:set_cwd(Current),
    ensure_no_messages(),
    ok.

netload(Config) ->
    Current = prepare_data_dir(Config),
    code:purge(test1),
    code:delete(test1),
    false = code:is_loaded(test1),
    {ok,Node} = ct_slave:start(make_SUITE_netload),
    up_to_date = make:files([test1], [netload]),
    timer:sleep(1000), % async, so give some time
    {file,F} = code:is_loaded(test1),
    {file,F} = rpc:call(Node,code,is_loaded,[test1]),
    ct_slave:stop(Node),
    file:set_cwd(Current),
    ensure_no_messages(),
    ok.

recompile_on_changed_include(Config) ->
    Current = prepare_data_dir(Config),

    Files = [test_incl1,"incl_src/test_incl2"],
    up_to_date = make:files(Files),
    ok = ensure_exists([test_incl1,test_incl2]),

    {ok, FileInfo11} = file:read_file_info("test_incl1.beam"),
    Date11 = FileInfo11#file_info.mtime,
    {ok, FileInfo21} = file:read_file_info("test_incl2.beam"),
    Date21 = FileInfo21#file_info.mtime,
    timer:sleep(2000),

    %% Touch the include file
    {ok,Bin} = file:read_file("test_incl.hrl"),
    ok = file:delete("test_incl.hrl"),
    ok = file:write_file("test_incl.hrl",Bin),

    up_to_date = make:files(Files),

    {ok, FileInfo12} = file:read_file_info("test_incl1.beam"),
    case FileInfo12#file_info.mtime of
        Date11 -> ct:fail({"file not recompiled", "test_incl1.beam"});
        _Date12 -> ok
    end,
    {ok, FileInfo22} = file:read_file_info("test_incl2.beam"),
    case FileInfo22#file_info.mtime of
        Date21 -> ct:fail({"file not recompiled", "test_incl2.beam"});
        _Date22 -> ok
    end,

    file:set_cwd(Current),
    ensure_no_messages(),
    ok.

emake_opts(Config) when is_list(Config) ->
    Current = prepare_data_dir(Config),

    %% prove that emake is used in opts instead of local Emakefile
    Opts = [{emake, [test8, test9]}],
    error = make:all(Opts),
    error = make:files([test9], Opts),
    "test8.beam" = ensure_exists([test8]),
    "test9.beam" = ensure_exists([test9]),
    "test5.S" = ensure_exists(["test5"],".S"),

    file:set_cwd(Current),
    ensure_no_messages(),
    ok.

%% Moves to the data directory of this suite, clean it from any object
%% files (*.jam for a JAM emulator).  Returns the previous directory.
prepare_data_dir(Config) ->
    {ok, Current} = file:get_cwd(),
    {value, {data_dir, Dir}} = lists:keysearch(data_dir, 1, Config),
    file:set_cwd(Dir),
    {ok, Files} = file:list_dir("."),
    delete_obj(Files, code:objfile_extension()),
    ensure_no_messages(),
    Current.

delete_obj([File|Rest], ObjExt) ->
    case filename:extension(File) of
        ObjExt -> file:delete(File);
        ".S" -> file:delete(File);
        _ -> ok
    end,
    delete_obj(Rest, ObjExt);
delete_obj([], _) ->
    ok.



%% Ensure that the given object files exists.
ensure_exists(Names) ->
    ensure_exists(Names, code:objfile_extension()).

ensure_exists([Name|Rest], ObjExt) when is_atom(Name) ->
    ensure_exists([atom_to_list(Name)|Rest], ObjExt);
ensure_exists([Name|Rest], ObjExt) ->
    case filelib:is_regular(Name++ObjExt) of
        true ->
            ensure_exists(Rest, ObjExt);
        false ->
            Name++ObjExt
    end;
ensure_exists([], _) ->
    ok.

otp_6057_init(Config) when is_list(Config) ->
    DataDir = proplists:get_value(data_dir, Config),
    PrivDir = proplists:get_value(priv_dir, Config),

    %% Create the directories PrivDir/otp_6057/src1, /src2 and /ebin
    Src1 = filename:join([PrivDir, otp_6057, src1]),
    Src2 = filename:join([PrivDir, otp_6057, src2]),
    Ebin = filename:join([PrivDir, otp_6057, ebin]),
    ok = file:make_dir(filename:join(PrivDir, otp_6057)),
    ok = file:make_dir(Src1),
    ok = file:make_dir(Src2),
    ok = file:make_dir(Ebin),

    %% Copy test1.erl and test2.erl to src1, and test3.erl to src2
    Test1orig = filename:join(DataDir, "test1.erl"),
    Test2orig = filename:join(DataDir, "test2.erl"),
    Test3orig = filename:join(DataDir, "test3.erl"),
    Test1 = filename:join(Src1, "test1.erl"),
    Test2 = filename:join(Src1, "test2.erl"),
    Test3 = filename:join(Src2, "test3.erl"),
    {ok, _} = file:copy(Test1orig, Test1),
    {ok, _} = file:copy(Test2orig, Test2),
    {ok, _} = file:copy(Test3orig, Test3),

    %% Create an Emakefile in src1
    Emakefile = filename:join(Src1, "Emakefile"),
    {ok, Fd} = file:open(Emakefile, write),
    ok = io:write(Fd, {["test1.erl","test2","../src2/test3"],
                       [{outdir,"../ebin"}]}),
    ok = io:fwrite(Fd, ".~n", []),
    ok = file:close(Fd),

    ensure_no_messages(),
    Config.

%% Test that make:all/0, suite/0 looks for object file in correct place
otp_6057_a(Config) when is_list(Config) ->
    PrivDir = proplists:get_value(priv_dir, Config),

    %% Go to src1, saving old CWD
    {ok, CWD} = file:get_cwd(),
    Src1 = filename:join([PrivDir, otp_6057, src1]),
    ok = file:set_cwd(Src1),

    %% Call make:all()
    up_to_date = make:all(),

    %% Ensure that all beam files are created in the ebin directory
    Ebin = filename:join([PrivDir, otp_6057, ebin]),
    Test1 = filename:join(Ebin, test1),
    Test2 = filename:join(Ebin, test2),
    Test3 = filename:join(Ebin, test3),
    case ensure_exists([Test1, Test2, Test3]) of
        ok -> ok;
        Missing ->
            ct:fail({"missing beam file", Missing})
    end,

    %% Check creation date of test1.beam and make sure it is not
    %% recompiled if make:all() is called again.
    %% (Sleep a while, if the file is recompiled within a second then
    %%  mtime will be the same).
    {ok, FileInfo1} = file:read_file_info(Test1++".beam"),
    Date1 = FileInfo1#file_info.mtime,
    timer:sleep(2000),
    up_to_date = make:all(),
    {ok, FileInfo2} = file:read_file_info(Test1++".beam"),
    case FileInfo2#file_info.mtime of
        Date1 -> ok;
        _Date2 ->
            ct:fail({"recompiled beam file", Test1++".beam"})
    end,

    %% Remove the beam files
    ok =
    ensure_removed([Test1++".beam",Test2++".beam",Test2++".beam"]),

    %% Return to original CWD
    ok = file:set_cwd(CWD),

    ensure_no_messages(),
    ok.

%% Test that make:files/1 can handle a file in another directory
otp_6057_b(Config) when is_list(Config) ->
    PrivDir = proplists:get_value(priv_dir, Config),

    %% Go to src1, saving old CWD
    {ok, CWD} = file:get_cwd(),
    Src1 = filename:join([PrivDir, otp_6057, src1]),
    ok = file:set_cwd(Src1),

    %% Ensure there is no beam file already
    Ebin = filename:join([PrivDir, otp_6057, ebin]),
    Test3 = filename:join(Ebin, "test3"),
    ok = ensure_removed([Test3++".beam"]),

    %% Call make:files/1
    up_to_date = make:files(["../src2/test3"]),

    %% Ensure that the beam file is created in the ebin directory
    case ensure_exists([Test3]) of
        ok -> ok;
        Missing ->
            ct:fail({"missing beam file", Missing})
    end,

    %% Remove the beam file
    ok = ensure_removed([Test3++".beam"]),

    %% Return to original CWD
    ok = file:set_cwd(CWD),

    ensure_no_messages(),
    ok.

%% Test that make:files/1 find options in Emakefile if a file is
%% given with the .erl extension there
otp_6057_c(Config) when is_list(Config) ->
    PrivDir = proplists:get_value(priv_dir, Config),

    %% Go to src1, saving old CWD
    {ok, CWD} = file:get_cwd(),
    Src1 = filename:join([PrivDir, otp_6057, src1]),
    ok = file:set_cwd(Src1),

    %% Ensure there are no beam files already
    Ebin = filename:join([PrivDir, otp_6057, ebin]),
    Test1 = filename:join(Ebin, "test1"),
    Test2 = filename:join(Ebin, "test2"),
    ok = ensure_removed([Test1++".beam",Test2++".beam"]),

    %% Call make:files/1
    up_to_date = make:files([test1, test2]),

    %% Ensure that the beam files are created in the ebin directory
    Ebin = filename:join([PrivDir, otp_6057, ebin]),
    case ensure_exists([Test1, Test2]) of
        ok -> ok;
        Missing ->
            ct:fail({"missing beam file", Missing})
    end,

    %% Remove the beam files
    ok = ensure_removed([Test1++".beam", Test2++".beam"]),

    %% Return to original CWD
    ok = file:set_cwd(CWD),

    ensure_no_messages(),
    ok.

otp_6057_end(Config) when is_list(Config) ->
    Config.

ensure_removed([File|Files]) ->
    file:delete(File),
    ensure_removed(Files);
ensure_removed([]) ->
    ok.

ensure_no_messages() ->
    ensure_no_messages(0).

ensure_no_messages(N) ->
    receive
        Any ->
            io:format("Unexpected message: ~p", [Any]),
            ensure_no_messages(N+1)
    after 0 ->
              case N of
                  0 -> ok;
                  N -> ct:fail(failed)
              end
    end.