1 | /* a file to start prob_cli with coverage/profiling info enabled (for SICStus 4.2 and later) */ | |
2 | ||
3 | :- prolog_flag(compiling,_,debugcode). | |
4 | :- prolog_flag(source_info,_,on). | |
5 | :- prolog_flag(profiling,_,on). | |
6 | ||
7 | :- include(coverage_term_expander). | |
8 | ||
9 | :- use_module(prob_cli). | |
10 | ||
11 | :- use_module(coverage_tools). | |
12 | :- use_module(test_runner). | |
13 | :- use_module(tools_strings,[ajoin/2]). | |
14 | :- use_module(version). | |
15 | :- use_module(extension('pltables/pltables')). | |
16 | ||
17 | :- use_module(library(samsort), [merge/3]). | |
18 | :- use_module(library(system)). | |
19 | :- use_module(library(codesio)). | |
20 | :- use_module(library(lists)). | |
21 | :- use_module(library(file_systems)). | |
22 | :- use_module(library(sets),[subtract/3]). | |
23 | ||
24 | % use module_info/3 because we are not in a module here | |
25 | :- module_info(prob_cov,group,coverage_analysis). | |
26 | :- module_info(prob_cov,description,'ProB start file with coverage tests activated. Includes predicates to execute certain tests. Used by Jenkins.'). | |
27 | ||
28 | % now in test_runner: | |
29 | %generate_makefile :- | |
30 | % generate_makefile('Makefile_Coverage_Groups', write_coverage_target). | |
31 | %write_coverage_target(G) :- | |
32 | % format('~w:\n\tsicstus -l src/prob_cov.pl --goal "coverage_group_data(\'~w\'), halt ; halt."',[G,G]),nl,nl. | |
33 | ||
34 | % compute coverage for a testcase category (see testcases.pl for categories) | |
35 | coverage_group_data(Category) :- | |
36 | % ids_in_category(Category,IDs), | |
37 | % load_coverage_files(IDs,CoverageData), | |
38 | run_silently, | |
39 | run_tests_by_category(Category,all), | |
40 | format('Obtaining coverage data for category ~w~n',[Category]), | |
41 | coverage_data(CoverageData), | |
42 | write_coverage_data(Category,CoverageData). | |
43 | ||
44 | % write collected coverage information to a Datafile | |
45 | write_coverage_data(FileName,Data) :- | |
46 | ajoin(['./temp_coverage_data/', FileName],Path), | |
47 | format('Writing coverage data to ~w~n',[Path]), | |
48 | open(Path,write,Stream), | |
49 | Out=cov(Data), | |
50 | write_canonical(Stream,Out), | |
51 | write(Stream,'.'), | |
52 | close(Stream). | |
53 | ||
54 | read_coverage_data(Path,Data) :- | |
55 | open(Path,read,S), | |
56 | read(S,cov(Data)), | |
57 | close(S). | |
58 | ||
59 | relevant_categories(units,[unit]). | |
60 | relevant_categories(laws,[laws]). | |
61 | relevant_categories(units-and-laws,[unit,laws]). | |
62 | relevant_categories(regression,Groups) :- | |
63 | all_categories(All), | |
64 | subtract(All,[unit,laws],Groups). | |
65 | relevant_categories(all,All) :- | |
66 | all_categories(All). | |
67 | relevant_categories(data_validation,[data_validation]). | |
68 | relevant_categories(X,[X]) :- atom(X). | |
69 | relevant_categories(X,X) :- is_list(X). | |
70 | ||
71 | header(units, 'Unit Tests'). | |
72 | header(laws, 'Law Checking'). | |
73 | header(units-and-laws,'Unit and Law Tests'). | |
74 | header(regression,'Regression Tests'). | |
75 | header(all,'All Tests'). | |
76 | header(data_validation,'Data Validation Tests'). | |
77 | %header(last,'Last Test Case'). | |
78 | header(X,Joined) :- atom(X), !, ajoin(['Testcases with Group ', X],Joined). | |
79 | header(X,Joined) :- is_list(X), maplist(atom,X), !, ajoin(['Testcases with Groups ', X],Joined). | |
80 | ||
81 | atom_header(Keyword, Header) :- | |
82 | header(Keyword,Tests), | |
83 | datime(datime(Year,Month,Day,Hour,Min,_Sec)), | |
84 | revision(CurrentCommit), | |
85 | format_to_codes('Coverage Report (~w, generated ~w.~w.~w ~w:~w, commit ~w)', [Tests,Day,Month,Year,Hour,Min,CurrentCommit], Codes), | |
86 | atom_codes(Header, Codes). | |
87 | ||
88 | :- use_module(tools,[ensure_atom/2]). | |
89 | load_coverage_files(IDs,CoverageData) :- | |
90 | maplist(ensure_atom,IDs,AtomicIDs), | |
91 | file_members_of_directory('./temp_coverage_data/',CoverageFiles), | |
92 | write('Reading Coverage Files'), nl, | |
93 | read_coverage_files(CoverageFiles,AtomicIDs,CoverageData). | |
94 | ||
95 | ||
96 | read_coverage_files(Files,RelevantIDs,CoverageData) :- | |
97 | read_coverage_files(Files,RelevantIDs,[],CoverageData). | |
98 | ||
99 | read_coverage_files([],_IDs,DataSoFar,DataSoFar). | |
100 | read_coverage_files([Name-Path|Files],IDs,DataSoFar,CovData) :- | |
101 | member(Name,IDs), !, | |
102 | format('.... Reading ~w~n',[Name]), | |
103 | read_coverage_data(Path,Content), | |
104 | % coverage data should already be sorted, only merge-step | |
105 | format(' .... Merging Coverage Lists~n',[]), | |
106 | merge(DataSoFar,Content,AppendedData), | |
107 | format(' .... Merging Coverage Data~n',[]), | |
108 | merge_coverage_data(AppendedData,NewData), | |
109 | length(DataSoFar,L1), length(NewData,L2), L is L2-L1, | |
110 | format(' .... ~w tags in old, ~w tags in new, ~w difference~n',[L1,L2,L]), | |
111 | garbage_collect, | |
112 | read_coverage_files(Files,IDs,NewData,CovData). | |
113 | read_coverage_files([_|Files],IDs,DataSoFar,CovData) :- | |
114 | read_coverage_files(Files,IDs,DataSoFar,CovData). | |
115 | ||
116 | merge_coverage_data([],[]). | |
117 | merge_coverage_data([C],[C]). | |
118 | merge_coverage_data([H1,H2|T],Out) :- | |
119 | merge_coverage_counter(H1,H2,HMerged), !, | |
120 | merge_coverage_data([HMerged|T],Out). | |
121 | merge_coverage_data([H1,H2|T],[H1|Out]) :- | |
122 | merge_coverage_data([H2|T],Out). | |
123 | ||
124 | merge_coverage_counter(counter(File,PredSpec,ClauseNo,LineNr)-Tag1, | |
125 | counter(File,PredSpec,ClauseNo,LineNr)-Tag2, | |
126 | counter(File,PredSpec,ClauseNo,LineNr)-TagOut) :- | |
127 | merge_coverage_tags(Tag1,Tag2,TagOut). | |
128 | ||
129 | merge_coverage_tags(Tag1,Tag2,TagOut) :- | |
130 | Tag1 =.. [Functor1,Count1], Tag2 =.. [Functor2,Count2], !, | |
131 | Count3 is Count1 + Count2, | |
132 | (Functor1 = Functor2 | |
133 | -> TagOut =.. [Functor1,Count3] | |
134 | ; TagOut =.. [nondet,Count3]). | |
135 | ||
136 | generate_report(Now,descriptions) :- !, | |
137 | ajoin(['./coverage_reports/html/descriptions/descriptions-',Now,'.html'],FilenameHTML), | |
138 | ajoin(['./coverage_reports/tex/descriptions/descriptions-',Now,'.tex'],FilenameTEX), | |
139 | gen_pltables_descriptions_table(descriptionstable, [headline('Module Descriptions')], | |
140 | [kernel, interpreter]), | |
141 | tables_to_html([descriptionstable], FilenameHTML), | |
142 | tables_to_latex([descriptionstable], FilenameTEX). | |
143 | ||
144 | generate_report(Now,Keyword) :- | |
145 | format('Generating coverage report for keyword: ~w~n',[Keyword]), | |
146 | relevant_categories(Keyword,Categories), | |
147 | load_coverage_files(Categories,CoverageInfo), | |
148 | % store coverage data of certain keywords, i.e. | |
149 | % to generate units-and-laws report by reading the units and the laws reports | |
150 | % and merging them | |
151 | write_coverage_data(Keyword,CoverageInfo), | |
152 | get_file_coverage_info(CoverageInfo,FinalCoverageInfo), | |
153 | atom_header(Keyword,Header), | |
154 | ajoin(['./coverage_reports/html/',Keyword,'/',Keyword,'-',Now,'.html'],FilenameHTML), | |
155 | ajoin(['./coverage_reports/tex/',Keyword,'/',Keyword,'-',Now,'.html'],FilenameTEX), | |
156 | ajoin(['./coverage_reports/xml/',Keyword,'/',Keyword,'-',Now,'.xml'],FilenameXML), | |
157 | ajoin(['./coverage_reports/color/',Keyword,'/'],ColorizedPath), | |
158 | ajoin(['../../color/',Keyword,'/'],ColorizedURL), | |
159 | ajoin(['./coverage_reports/emma/',Keyword,'.xml'],FilenameEmma), | |
160 | export(FinalCoverageInfo,Header,FilenameHTML,FilenameTEX,FilenameXML,ColorizedPath,ColorizedURL,FilenameEmma). | |
161 | ||
162 | export(Info,Header,FilenameHTML,FilenameTEX,FilenameXML,ColorizedPath,ColorizedURL,EmmaPath) :- | |
163 | write('colorising source files line by line'), nl, full_flush, | |
164 | colorize_source_files(Info, ColorizedPath), | |
165 | write('colorising source files line by line done'), nl, full_flush, | |
166 | write('generation coverage report tables'), nl, full_flush, | |
167 | gen_pltables_coverage_rows(Info, [headline(Header)],[kernel,interpreter],ColorizedURL), | |
168 | write('generation coverage report tables done'), nl, full_flush, | |
169 | write('exporting tables to html, tex and xml'), nl, full_flush, | |
170 | export_tables(FilenameHTML,FilenameTEX,FilenameXML), | |
171 | write('exporting tables to html, tex and xml done'), nl, full_flush, | |
172 | write('exporting coverage data to emma'), nl, full_flush, | |
173 | export_emma(EmmaPath), | |
174 | write('exporting coverage data to emma done'), nl, full_flush. | |
175 | ||
176 | % from old prob_cov.pl - now ported to new table module | |
177 | pci :- print_coverage_info. | |
178 | pci(X) :- print_coverage_info(X). | |
179 | hci :- | |
180 | get_file_coverage_info(Info), | |
181 | gen_pltables_coverage_rows(Info, [], [kernel, interpreter]), | |
182 | export_tables_html_stream(user_output). | |
183 | hci_file :- | |
184 | get_file_coverage_info(Info), | |
185 | gen_pltables_coverage_rows(Info, [], [kernel, interpreter]), | |
186 | export_tables_html('out.html'). | |
187 | lci :- | |
188 | get_file_coverage_info(Info), | |
189 | gen_pltables_coverage_rows(Info, [], [kernel, interpreter]), | |
190 | export_tables_latex_stream(user_output). | |
191 | lci_file :- | |
192 | get_file_coverage_info(Info), | |
193 | gen_pltables_coverage_rows(Info, [], [kernel, interpreter]), | |
194 | export_tables_latex('out.tex'). |