Add initial code
[ta/build-tools.git] / tools / script / ci_build_diff_test.py
1 # Copyright 2019 Nokia
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # pylint: disable=line-too-long,invalid-name
16 import json
17
18 from tools.script.ci_build_diff import main
19 from tools.script.ci_build_diff_test_data import component_added, component_changed_old, \
20     component_changed_new, component_removed, caas_grafana1, caas_grafana2, caas_grafana2_sub, \
21     caas_grafana1_sub, caas_grafana1_v2, caas_grafana1_v2sub, caas_grafana1_r2, \
22     caas_grafana1_r2sub, grafana_v1, grafana_v2, caas_grafana3, caas_grafana3_sub, caas_abc1_sub, \
23     caas_abc1, caas_abc1_r2, caas_abc1_sub_r2, abc1_v2, abc1, abc2, abc3, \
24     caas_grafana1_sub_new_field
25
26
27 def test_no_output_args(tmpdir):
28     input_old, input_new = _gen_input_json(tmpdir)
29     main([str(input_old), str(input_new)])
30
31
32 def test_no_changes(tmpdir):
33     input_old, _ = _gen_input_json(tmpdir)
34     output_csv = tmpdir.join('diff.csv')
35     output_json = tmpdir.join('diff.json')
36     main([str(input_old), str(input_old),
37           '--output-csv', str(output_csv),
38           '--output-json', str(output_json)])
39     assert output_csv.read() == 'sep=,'
40     assert json.loads(output_json.read()) == {"added": {},
41                                               "changed": {},
42                                               "removed": {},
43                                               "counts": {
44                                                   "added": 0,
45                                                   "changed": 0,
46                                                   "removed": 0
47                                               }}
48
49
50 def test_no_changes_if_json_field_is_added(tmpdir):
51     """
52     Make sure diff is ok e.g. when new build has new field in json
53     """
54     _assert_json_out(tmpdir,
55                      [caas_grafana1_sub],
56                      [caas_grafana1_sub_new_field],
57                      {"added": {},
58                       "changed": {},
59                       "removed": {},
60                       "counts": {
61                           "added": 0,
62                           "changed": 0,
63                           "removed": 0
64                       }})
65
66
67 def test_multiple_rpms(tmpdir):
68     _assert_json_out(tmpdir,
69                      [component_changed_old, component_removed],
70                      [component_changed_new, component_added],
71                      {"added": {component_added['Name']: [component_added]},
72                       "changed": {component_changed_old['Name']: {'old': [component_changed_old],
73                                                                   'new': [component_changed_new]}},
74                       "removed": {component_removed['Name']: [component_removed]},
75                       "counts": {
76                           "added": 1,
77                           "changed": 1,
78                           "removed": 1
79                       }})
80
81
82 def test_component_name_change(tmpdir):
83     """
84     Sub-component does not change although RPM containing it changes
85     """
86     _assert_json_out(tmpdir,
87                      [caas_grafana1, caas_grafana1_sub],
88                      [caas_grafana2, caas_grafana2_sub],
89                      {"added": {caas_grafana2['Name']: [caas_grafana2]},
90                       "changed": {},
91                       "removed": {caas_grafana1['Name']: [caas_grafana1]},
92                       "counts": {
93                           "added": 1,
94                           "changed": 0,
95                           "removed": 1
96                       }})
97
98
99 def test_component_version_change(tmpdir):
100     _assert_json_out(tmpdir,
101                      [caas_grafana1, caas_grafana1_sub],
102                      [caas_grafana1_v2, caas_grafana1_v2sub],
103                      {"added": {},
104                       "changed": {caas_grafana1['Name']: {'old': [caas_grafana1],
105                                                           'new': [caas_grafana1_v2]},
106                                   caas_grafana1_sub['Name']: {'old': [caas_grafana1_sub],
107                                                               'new': [caas_grafana1_v2sub]}},
108                       "removed": {},
109                       "counts": {
110                           "added": 0,
111                           "changed": 2,
112                           "removed": 0
113                       }})
114
115
116 def test_component_release_change(tmpdir):
117     _assert_json_out(tmpdir,
118                      [caas_grafana1, caas_grafana1_sub],
119                      [caas_grafana1_r2, caas_grafana1_r2sub],
120                      {"added": {},
121                       "changed": {caas_grafana1['Name']: {'old': [caas_grafana1],
122                                                           'new': [caas_grafana1_r2]}},
123                       "removed": {},
124                       "counts": {
125                           "added": 0,
126                           "changed": 1,
127                           "removed": 0
128                       }})
129
130
131 def test_same_name_component_added(tmpdir):
132     _assert_json_out(tmpdir,
133                      [caas_grafana1, caas_grafana1_sub],
134                      [caas_grafana1, caas_grafana1_sub, grafana_v1],
135                      {"added": {},
136                       "changed": {grafana_v1['Name']: {'old': [caas_grafana1_sub],
137                                                        'new': [caas_grafana1_sub, grafana_v1]}},
138                       "removed": {},
139                       "counts": {
140                           "added": 0,
141                           "changed": 1,
142                           "removed": 0
143                       }})
144
145
146 def test_same_name_component_removed(tmpdir):
147     _assert_json_out(tmpdir,
148                      [caas_grafana1, caas_grafana1_sub, grafana_v1],
149                      [caas_grafana1, caas_grafana1_sub],
150                      {"added": {},
151                       "changed": {grafana_v1['Name']: {'old': [caas_grafana1_sub, grafana_v1],
152                                                        'new': [caas_grafana1_sub]}},
153                       "removed": {},
154                       "counts": {
155                           "added": 0,
156                           "changed": 1,
157                           "removed": 0
158                       }})
159
160
161 def test_same_name_component_changed(tmpdir):
162     _assert_json_out(tmpdir,
163                      [caas_grafana1, caas_grafana1_sub, grafana_v1],
164                      [caas_grafana1, caas_grafana1_sub, grafana_v2],
165                      {"added": {},
166                       "changed": {grafana_v1['Name']: {'old': [caas_grafana1_sub, grafana_v1],
167                                                        'new': [caas_grafana1_sub, grafana_v2]}},
168                       "removed": {},
169                       "counts": {
170                           "added": 0,
171                           "changed": 1,
172                           "removed": 0
173                       }})
174
175
176 def test_epic(tmpdir):
177     _assert_json_out(tmpdir,
178                      [caas_grafana1, caas_grafana1_sub,
179                       caas_grafana2, caas_grafana2_sub,
180                       grafana_v1],
181                      [caas_grafana1_r2, caas_grafana1_r2sub,
182                       grafana_v2,
183                       caas_grafana3, caas_grafana3_sub],
184                      {"added": {caas_grafana3['Name']: [caas_grafana3]},
185                       "changed": {caas_grafana1['Name']: {'old': [caas_grafana1],
186                                                           'new': [caas_grafana1_r2]},
187                                   grafana_v1['Name']: {
188                                       'old': [caas_grafana1_sub, caas_grafana2_sub, grafana_v1],
189                                       'new': [caas_grafana1_r2sub, caas_grafana3_sub, grafana_v2]}},
190                       "removed": {caas_grafana2['Name']: [caas_grafana2]},
191                       "counts": {
192                           "added": 1,
193                           "changed": 2,
194                           "removed": 1
195                       }})
196
197
198 def _assert_json_out(tmpdir, from_build, to_build, expected_output):
199     input_old, input_new = _gen_input_json(tmpdir, from_build, to_build)
200     output_json = tmpdir.join('diff.json')
201     main([str(input_old), str(input_new), '--output-json', str(output_json)])
202     assert json.loads(output_json.read()) == expected_output
203
204
205 def test_csv(tmpdir):
206     input_old, input_new = _gen_input_json(tmpdir,
207                                            [caas_abc1, caas_abc1_sub, abc1, abc2],
208                                            [caas_abc1_r2, caas_abc1_sub_r2, abc1_v2, abc3])
209     output_csv = tmpdir.join('diff.csv')
210     main([str(input_old), str(input_new), '--output-csv', str(output_csv)])
211     rows = [['name',
212              'old_components', 'old_srpms', 'old_licenses',
213              'new_components', 'new_srpms', 'new_licenses'],
214             ['abc',
215              'abc:v1(abc-v1-r1.src.rpm)\nabc:v1(caas-abc-v1-r1.src.rpm)',
216              'abc-v1-r1.src.rpm\ncaas-abc-v1-r1.src.rpm',
217              'GPL\nUnknown',
218              'abc:v1(caas-abc-v1-r2.src.rpm)\nabc:v2(abc-v2-r1.src.rpm)',
219              'caas-abc-v1-r2.src.rpm\nabc-v2-r1.src.rpm',
220              'Unknown\nGPL'],
221             ['abc2',
222              'abc2:v1(abc2-v1-r1.src.rpm)', 'abc2-v1-r1.src.rpm', 'GPL',
223              'None', 'None', 'None'],
224             ['abc3',
225              'None', 'None', 'None',
226              'abc3:v1(abc3-v1-r1.src.rpm)', 'abc3-v1-r1.src.rpm', 'GPL'],
227             ['caas-abc',
228              'caas-abc:v1(caas-abc-v1-r1.src.rpm)', 'caas-abc-v1-r1.src.rpm', 'Commercial',
229              'caas-abc:v1(caas-abc-v1-r2.src.rpm)', 'caas-abc-v1-r2.src.rpm', 'Commercial']]
230     expected_csv = '\r\n'.join(['sep=,'] + [_get_csv_row(row) for row in rows])
231     assert output_csv.read() == expected_csv
232
233
234 def _get_csv_row(items):
235     return ','.join(['"{}"'.format(i) for i in items])
236
237
238 def _gen_input_json(tmpdir, _from=None, _to=None):
239     if _from is None:
240         _from = [component_changed_old, component_removed]
241     if _to is None:
242         _to = [component_changed_new, component_added]
243     input_old = tmpdir.join('input_old.json')
244     input_new = tmpdir.join('input_new.json')
245     json_old = json.dumps(_from)
246     json_new = json.dumps(_to)
247     input_old.write(json_old)
248     input_new.write(json_new)
249     return input_old, input_new