blob: cbc4ff0a425d47a61cb549b13fc55124b23caaa8 [file] [log] [blame]
Anthonios Partheniouaff037a2021-04-21 11:00:09 -04001# Copyright 2021 Google LLC
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"""ChangeSummary tests."""
16
17__author__ = "partheniou@google.com (Anthonios Partheniou)"
18
19import pathlib
20import shutil
21import unittest
22
23import pandas as pd
24
25from changesummary import ChangeSummary
26from changesummary import ChangeType
27from changesummary import DirectoryDoesNotExist
28
29SCRIPTS_DIR = pathlib.Path(__file__).parent.resolve()
30NEW_ARTIFACTS_DIR = SCRIPTS_DIR / "test_resources" / "new_artifacts_dir"
31CURRENT_ARTIFACTS_DIR = SCRIPTS_DIR / "test_resources" / "current_artifacts_dir"
32TEMP_DIR = SCRIPTS_DIR / "test_resources" / "temp"
33
34
35class TestChangeSummary(unittest.TestCase):
36 def setUp(self):
37 # Clear temporary directory
38 shutil.rmtree(TEMP_DIR, ignore_errors=True)
39 # Create temporary directory
40 pathlib.Path(TEMP_DIR).mkdir()
41
42 self.cs = ChangeSummary(NEW_ARTIFACTS_DIR, CURRENT_ARTIFACTS_DIR, TEMP_DIR, [])
43
44 def test_raises_on_directory_not_found_new_artifacts_dir(self):
45 with self.assertRaises(DirectoryDoesNotExist):
46 ChangeSummary(
47 "invalid_artifact_dir", CURRENT_ARTIFACTS_DIR, TEMP_DIR, []
48 ).detect_discovery_changes()
49
50 def test_raises_on_directory_not_found_current_artifacts_dir(self):
51 with self.assertRaises(DirectoryDoesNotExist):
52 ChangeSummary(
53 NEW_ARTIFACTS_DIR, "invalid_artifact_dir", TEMP_DIR, []
54 ).detect_discovery_changes()
55
56 def test_raises_on_directory_not_found_temp_dir(self):
57 # Remove temporary directory
58 shutil.rmtree(TEMP_DIR, ignore_errors=True)
59
60 with self.assertRaises(DirectoryDoesNotExist):
61 ChangeSummary(
62 NEW_ARTIFACTS_DIR, CURRENT_ARTIFACTS_DIR, "invalid_temp_dir", []
63 ).detect_discovery_changes()
64
65 # Create temporary directory
66 pathlib.Path(TEMP_DIR).mkdir()
67
68 ChangeSummary(
69 NEW_ARTIFACTS_DIR, CURRENT_ARTIFACTS_DIR, TEMP_DIR, []
70 ).detect_discovery_changes()
71
72 def test_raises_on_directory_not_found(self):
73 with self.assertRaises(DirectoryDoesNotExist):
74 self.cs._raise_if_directory_not_found(directory="invalid_dir")
75
76 def test_load_json_to_dataframe_returns_empty_df_if_file_path_invalid(self):
77 df = self.cs._load_json_to_dataframe(file_path="invalid_path")
78 self.assertTrue(df.empty)
79
80 def test_load_json_to_dataframe_returns_expected_data(self):
81 doc_path = NEW_ARTIFACTS_DIR / "drive.v3.json"
82 df = self.cs._load_json_to_dataframe(file_path=doc_path)
83 self.assertEqual(df["name"].iloc[0], "drive")
84 self.assertEqual(df["version"].iloc[0], "v3")
85
86 def test_get_discovery_differences_for_new_doc_returns_expected_dataframe(self):
87 df = self.cs._get_discovery_differences("drive.v3.json")
88 # Assume that `drive.v3.json` is a new discovery artifact that doesn't
89 # exist in `CURRENT_ARTIFACTS_DIR`.
90 self.assertEqual(df["Name"].iloc[0], "drive")
91 self.assertEqual(df["Version"].iloc[0], "v3")
92
93 # All rows in the dataframe should have `True` in the `Added` column
94 # and `False` in the `Deleted` column.
95 # pd.Dataframe().all() will return `True` if all elements are `True`.
96 self.assertTrue(df["Added"].all())
97 self.assertTrue((~df["Deleted"]).all())
98
Anthonios Partheniou6a884222021-05-10 22:14:57 -040099 # There should be 4 unique key differences
100 self.assertEqual(len(df), 4)
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400101
Anthonios Partheniou6a884222021-05-10 22:14:57 -0400102 # Expected Result for key 'schemas.FileList'
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400103 # Key Added Deleted Name Version ChangeType Count
Anthonios Partheniou6a884222021-05-10 22:14:57 -0400104 # schemas.FileList True False drive v3 2 8
105 self.assertTrue(df[df["Key"] == "schemas.FileList"].Added.iloc[0])
106 self.assertFalse(df[df["Key"] == "schemas.FileList"].Deleted.iloc[0])
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400107 self.assertEqual(
Anthonios Partheniou6a884222021-05-10 22:14:57 -0400108 df[df["Key"] == "schemas.FileList"].ChangeType.iloc[0], ChangeType.ADDED
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400109 )
Anthonios Partheniou6a884222021-05-10 22:14:57 -0400110 self.assertEqual(df[df["Key"] == "schemas.FileList"].Count.iloc[0], 8)
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400111
112 def test_get_discovery_differences_for_deleted_doc_returns_expected_dataframe(self):
113 df = self.cs._get_discovery_differences("cloudtasks.v2.json")
114 # Assuming that `cloudtasks.v2.json` is a discovery artifact that doesn't
115 # exist in `NEW_ARTIFACTS_DIR`.
116 self.assertEqual(df["Name"].iloc[0], "cloudtasks")
117 self.assertEqual(df["Version"].iloc[0], "v2")
118
119 # All rows in the dataframe should have `False` in the `Added` column
120 # and `True` in the `Deleted` column.
121 # pd.Dataframe().all() will return `True` if all elements are `True`.
122 self.assertTrue((~df["Added"]).all())
123 self.assertTrue(df["Deleted"].all())
124
Anthonios Partheniou6a884222021-05-10 22:14:57 -0400125 # There should be 6 unique key differences
126 self.assertEqual(len(df), 6)
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400127
128 # Expected Result for key 'schemas.Task'
129 # Key Added Deleted Name Version ChangeType Count
130 # schemas.Task False True cloudtasks v2 1 18
131 self.assertFalse(df[df["Key"] == "schemas.Task"].Added.iloc[0])
132 self.assertTrue(df[df["Key"] == "schemas.Task"].Deleted.iloc[0])
133 self.assertEqual(
134 df[df["Key"] == "schemas.Task"].ChangeType.iloc[0], ChangeType.DELETED
135 )
136 self.assertEqual(df[df["Key"] == "schemas.Task"].Count.iloc[0], 18)
137
138 def test_get_discovery_differences_for_changed_doc_returns_expected_dataframe(self):
139 # Assuming that `bigquery.v2.json` is a discovery artifact has
140 # changed. There will be a mix of keys being added, changed or deleted.
141 df = self.cs._get_discovery_differences("bigquery.v2.json")
142
143 self.assertEqual(df["Name"].iloc[0], "bigquery")
144 self.assertEqual(df["Version"].iloc[0], "v2")
145
146 # There should be 28 unique key differences
Anthonios Partheniou6a884222021-05-10 22:14:57 -0400147 # 1 unique keys changed, 1 unique keys added, 2 unique keys deleted
148 self.assertEqual(len(df), 4)
149 self.assertEqual(len(df[df["ChangeType"] == ChangeType.CHANGED]), 1)
150 self.assertEqual(len(df[df["ChangeType"] == ChangeType.ADDED]), 1)
151 self.assertEqual(len(df[df["ChangeType"] == ChangeType.DELETED]), 2)
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400152
153 # Expected Result for key 'schemas.PrincipalComponentInfo'
154 # Key Added Deleted Name Version ChangeType Count
155 # schemas.PrincipalComponentInfo False True bigquery v2 1 10
156 key = "schemas.PrincipalComponentInfo"
157 self.assertFalse(df[df["Key"] == key].Added.iloc[0])
158 self.assertTrue(df[df["Key"] == key].Deleted.iloc[0])
159 self.assertEqual(df[df["Key"] == key].ChangeType.iloc[0], ChangeType.DELETED)
160 self.assertEqual(df[df["Key"] == key].Count.iloc[0], 10)
161
162 def test_build_summary_message_returns_expected_result(self):
163 msg = self.cs._build_summary_message(api_name="bigquery", is_feature=True)
164 self.assertEqual(msg, "feat(bigquery): update the api")
165 msg = self.cs._build_summary_message(api_name="bigquery", is_feature=False)
166 self.assertEqual(msg, "fix(bigquery): update the api")
167
168 def test_get_stable_versions(self):
169 # These versions should be considered stable
170 s = pd.Series(["v1", "v1.4", "v1.4.5"])
171 self.assertTrue(self.cs._get_stable_versions(s).all().iloc[0])
172
173 # These versions should not be considered stable
174 s = pd.Series(["v1b1", "v1alpha", "v1beta1"])
175 self.assertTrue((~self.cs._get_stable_versions(s)).all().iloc[0])
176
177 def test_detect_discovery_changes(self):
178 files_changed = ["bigquery.v2.json", "cloudtasks.v2.json", "drive.v3.json"]
179 cs = ChangeSummary(
180 NEW_ARTIFACTS_DIR, CURRENT_ARTIFACTS_DIR, TEMP_DIR, files_changed
181 )
182 cs.detect_discovery_changes()
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400183 result = pd.read_csv(TEMP_DIR / "allapis.dataframe")
184
185 # bigquery was added
Anthonios Partheniou6a884222021-05-10 22:14:57 -0400186 # 4 key changes in total.
187 # 1 unique keys changed, 1 unique keys added, 2 unique keys deleted
188 self.assertEqual(len(result[result["Name"] == "bigquery"]), 4)
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400189 self.assertEqual(
Anthonios Partheniou6a884222021-05-10 22:14:57 -0400190 len(result[(result["Name"] == "bigquery") & result["Added"]]), 1
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400191 )
Anthonios Partheniou6a884222021-05-10 22:14:57 -0400192
193 # Confirm that key "schemas.ProjectReference.newkey" exists for bigquery
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400194 self.assertEqual(
Anthonios Partheniou6a884222021-05-10 22:14:57 -0400195 result[
196 (result["Name"] == "bigquery") & (result["Added"]) & (result["Count"] == 1)
197 ]["Key"].iloc[0],
198 "schemas.ProjectReference.newkey",
199 )
200
201 self.assertEqual(
202 len(result[(result["Name"] == "bigquery") & result["Deleted"]]), 2
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400203 )
204 self.assertTrue(result[result["Name"] == "bigquery"].IsStable.all())
205 self.assertTrue(result[result["Name"] == "bigquery"].IsFeatureAggregate.all())
206 self.assertEqual(
207 result[result["Name"] == "bigquery"].Summary.iloc[0],
208 "feat(bigquery): update the api",
209 )
210
211 # cloudtasks was deleted
Anthonios Partheniou6a884222021-05-10 22:14:57 -0400212 # 6 key changes in total. All 6 key changes should be deletions.
213 self.assertEqual(len(result[result["Name"] == "cloudtasks"]), 6)
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400214 self.assertEqual(
215 len(result[(result["Name"] == "cloudtasks") & result["Added"]]), 0
216 )
217 self.assertEqual(
Anthonios Partheniou6a884222021-05-10 22:14:57 -0400218 len(result[(result["Name"] == "cloudtasks") & result["Deleted"]]), 6
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400219 )
220 self.assertTrue(result[(result["Name"] == "cloudtasks")].IsStable.all())
221 self.assertTrue(
222 result[(result["Name"] == "cloudtasks")].IsFeatureAggregate.all()
223 )
224 self.assertEqual(
225 result[(result["Name"] == "cloudtasks")].Summary.iloc[0],
226 "feat(cloudtasks): update the api",
227 )
228
229 # drive was updated
Anthonios Partheniou6a884222021-05-10 22:14:57 -0400230 # 4 key changes in total. All 4 key changes should be additions
231 self.assertEqual(len(result[result["Name"] == "drive"]), 4)
232 self.assertEqual(len(result[(result["Name"] == "drive") & result["Added"]]), 4)
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400233 self.assertEqual(
234 len(result[(result["Name"] == "drive") & result["Deleted"]]), 0
235 )
236 self.assertTrue(result[(result["Name"] == "drive")].IsStable.all())
Anthonios Partheniou6a884222021-05-10 22:14:57 -0400237 self.assertTrue(result[(result["Name"] == "drive")].IsFeatureAggregate.all())
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400238 self.assertEqual(
239 result[(result["Name"] == "drive")].Summary.iloc[0],
240 "feat(drive): update the api",
241 )
242
Anthonios Partheniou6a884222021-05-10 22:14:57 -0400243
Anthonios Partheniouaff037a2021-04-21 11:00:09 -0400244if __name__ == "__main__":
245 unittest.main()