2 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Unit tests for cros_portage_upgrade.py."""
8 from __future__ import print_function
15 from chromite.lib import cros_test_lib
16 from chromite.lib import table
17 from chromite.scripts import merge_package_status as mps
19 # pylint: disable=W0212,R0904
21 class MergeTest(cros_test_lib.OutputTestCase, cros_test_lib.TempDirTestCase):
22 """Test the functionality of merge_package_status."""
24 # These taken from cros_portage_upgrade column names.
25 COL_VER_x86 = 'Current x86 Version'
26 COL_VER_arm = 'Current arm Version'
28 COL_CROS_TARGET = 'ChromeOS Root Target'
29 COL_HOST_TARGET = 'Host Root Target'
30 COL_CMP_ARCH = 'Comparing arm vs x86 Versions'
32 COLUMNS = [mps.COL_PACKAGE,
40 ROW0 = {mps.COL_PACKAGE: 'lib/foo',
42 mps.COL_OVERLAY: 'portage',
45 mps.COL_TARGET: 'virtual/target-os-dev virtual/target-sdk'}
46 ROW0_FINAL = dict(ROW0)
47 ROW0_FINAL[mps.COL_PACKAGE] = ROW0[mps.COL_PACKAGE] + ':' + ROW0[mps.COL_SLOT]
48 ROW0_FINAL[COL_CROS_TARGET] = 'virtual/target-os-dev'
49 ROW0_FINAL[COL_HOST_TARGET] = 'virtual/target-sdk'
50 ROW0_FINAL[COL_CMP_ARCH] = 'same'
52 ROW1 = {mps.COL_PACKAGE: 'dev/bar',
54 mps.COL_OVERLAY: 'chromiumos-overlay',
56 COL_VER_arm: '1.2.3-r1',
57 mps.COL_TARGET: 'virtual/target-os'}
58 ROW1_FINAL = dict(ROW1)
59 ROW1_FINAL[COL_CROS_TARGET] = 'virtual/target-os'
60 ROW1_FINAL[COL_HOST_TARGET] = ''
61 ROW1_FINAL[COL_CMP_ARCH] = 'different'
63 ROW2 = {mps.COL_PACKAGE: 'lib/foo',
65 mps.COL_OVERLAY: 'portage',
68 mps.COL_TARGET: 'virtual/target-os-dev world'}
69 ROW2_FINAL = dict(ROW2)
70 ROW2_FINAL[mps.COL_PACKAGE] = ROW2[mps.COL_PACKAGE] + ':' + ROW2[mps.COL_SLOT]
71 ROW2_FINAL[COL_CROS_TARGET] = 'virtual/target-os-dev'
72 ROW2_FINAL[COL_HOST_TARGET] = 'world'
73 ROW2_FINAL[COL_CMP_ARCH] = ''
76 self._table = self._CreateTableWithRows(self.COLUMNS,
77 [self.ROW0, self.ROW1, self.ROW2])
79 def _CreateTableWithRows(self, cols, rows):
80 mytable = table.Table(list(cols))
83 mytable.AppendRow(dict(row))
86 def _CreateTmpCsvFile(self, table_obj):
87 _fd, path = tempfile.mkstemp(text=True)
88 tmpfile = open(path, 'w')
89 table_obj.WriteCSV(tmpfile)
93 def _GetFullRowFor(self, row, cols):
94 return dict((col, row.get(col, '')) for col in cols)
96 def assertRowsEqual(self, row1, row2):
97 # Determine column superset
98 cols = set(row1.keys() + row2.keys())
99 self.assertEquals(self._GetFullRowFor(row1, cols),
100 self._GetFullRowFor(row2, cols))
102 def testGetCrosTargetRank(self):
103 cros_rank = mps._GetCrosTargetRank('virtual/target-os')
104 crosdev_rank = mps._GetCrosTargetRank('virtual/target-os-dev')
105 crostest_rank = mps._GetCrosTargetRank('virtual/target-os-test')
106 other_rank = mps._GetCrosTargetRank('foobar')
108 self.assertTrue(cros_rank)
109 self.assertTrue(crosdev_rank)
110 self.assertTrue(crostest_rank)
111 self.assertFalse(other_rank)
112 self.assertTrue(cros_rank < crosdev_rank)
113 self.assertTrue(crosdev_rank < crostest_rank)
115 def testProcessTargets(self):
117 ['virtual/target-os', 'virtual/target-os-dev'],
118 ['world', 'virtual/target-os', 'virtual/target-os-dev',
119 'virtual/target-os-test'],
120 ['world', 'virtual/target-sdk', 'virtual/target-os-dev',
121 'virtual/target-os-test'],
124 ['virtual/target-os-dev'],
125 ['virtual/target-os-test', 'world'],
126 ['virtual/target-os-test', 'virtual/target-sdk', 'world'],
129 ['virtual/target-os'],
130 ['virtual/target-os', 'world'],
131 ['virtual/target-os-dev', 'virtual/target-sdk', 'world'],
134 for targets, good_out, rev_out in zip(test_in, test_out, test_rev_out):
135 output = mps.ProcessTargets(targets)
136 self.assertEquals(output, good_out)
137 output = mps.ProcessTargets(targets, reverse_cros=True)
138 self.assertEquals(output, rev_out)
140 def testLoadTable(self):
141 path = self._CreateTmpCsvFile(self._table)
142 csv_table = mps.LoadTable(path)
143 self.assertEquals(self._table, csv_table)
146 def testLoadAndMergeTables(self):
147 # Create a second table to merge with standard table.
148 row0_2 = {mps.COL_PACKAGE: 'lib/foo',
150 mps.COL_OVERLAY: 'portage',
151 self.COL_VER_arm: '1.2.4',
152 mps.COL_TARGET: 'virtual/target-os-dev world'}
153 row1_2 = {mps.COL_PACKAGE: 'dev/bar',
155 mps.COL_OVERLAY: 'chromiumos-overlay',
156 self.COL_VER_arm: '1.2.3-r1',
157 mps.COL_TARGET: 'virtual/target-os-test'}
158 row2_2 = {mps.COL_PACKAGE: 'dev/newby',
160 mps.COL_OVERLAY: 'chromiumos-overlay',
161 self.COL_VER_arm: '3.2.1',
162 mps.COL_TARGET: 'virtual/target-os virtual/target-sdk'}
163 cols = [col for col in self.COLUMNS if col != self.COL_VER_x86]
164 table_2 = self._CreateTableWithRows(cols,
165 [row0_2, row1_2, row2_2])
167 # Minor patch to main table for this test.
168 self._table.GetRowByIndex(2)[self.COL_VER_arm] = '1.2.4'
170 with self.OutputCapturer():
171 path1 = self._CreateTmpCsvFile(self._table)
172 path2 = self._CreateTmpCsvFile(table_2)
174 combined_table1 = mps.MergeTables([self._table, table_2])
175 combined_table2 = mps.LoadAndMergeTables([path1, path2])
177 final_row0 = {mps.COL_PACKAGE: 'dev/bar',
179 mps.COL_OVERLAY: 'chromiumos-overlay',
180 self.COL_VER_x86: '1.2.3',
181 self.COL_VER_arm: '1.2.3-r1',
182 mps.COL_TARGET: 'virtual/target-os'}
183 final_row1 = {mps.COL_PACKAGE: 'dev/newby',
185 mps.COL_OVERLAY: 'chromiumos-overlay',
186 self.COL_VER_x86: '',
187 self.COL_VER_arm: '3.2.1',
188 mps.COL_TARGET: 'virtual/target-os virtual/target-sdk'}
189 final_row2 = {mps.COL_PACKAGE: 'lib/foo',
191 mps.COL_OVERLAY: 'portage',
192 self.COL_VER_x86: '1.2.3',
193 self.COL_VER_arm: '1.2.3',
194 mps.COL_TARGET: 'virtual/target-os-dev virtual/target-sdk'}
195 final_row3 = {mps.COL_PACKAGE: 'lib/foo',
197 mps.COL_OVERLAY: 'portage',
198 self.COL_VER_x86: '1.2.3',
199 self.COL_VER_arm: '1.2.4',
200 mps.COL_TARGET: 'virtual/target-os-dev world'}
202 final_rows = (final_row0, final_row1, final_row2, final_row3)
203 for ix, row_out in enumerate(final_rows):
204 self.assertRowsEqual(row_out, combined_table1[ix])
205 self.assertRowsEqual(row_out, combined_table2[ix])
210 def testFinalizeTable(self):
211 self.assertEquals(3, self._table.GetNumRows())
212 self.assertEquals(len(self.COLUMNS), self._table.GetNumColumns())
214 with self.OutputCapturer():
215 mps.FinalizeTable(self._table)
217 self.assertEquals(3, self._table.GetNumRows())
218 self.assertEquals(len(self.COLUMNS) + 3, self._table.GetNumColumns())
220 final_rows = (self.ROW0_FINAL, self.ROW1_FINAL, self.ROW2_FINAL)
221 for ix, row_out in enumerate(final_rows):
222 self.assertRowsEqual(row_out, self._table[ix])
224 class MainTest(cros_test_lib.MoxOutputTestCase):
225 """Test argument handling at the main method level."""
228 """Test that --help is functioning"""
229 with self.OutputCapturer() as output:
230 # Running with --help should exit with code==0
233 except exceptions.SystemExit as e:
234 self.assertEquals(e.args[0], 0)
236 # Verify that a message beginning with "Usage: " was printed
237 stdout = output.GetStdout()
238 self.assertTrue(stdout.startswith('Usage: '),
239 msg='Expected output starting with "Usage: " but got:\n%s' %
242 def testMissingOut(self):
243 """Test that running without --out exits with an error."""
244 with self.OutputCapturer():
245 # Running without --out should exit with code!=0
248 except exceptions.SystemExit as e:
249 self.assertNotEquals(e.args[0], 0)
251 # Verify that output ends in error.
252 self.AssertOutputEndsInError()
254 def testMissingPackage(self):
255 """Test that running without a package argument exits with an error."""
256 with self.OutputCapturer():
257 # Running without a package should exit with code!=0
259 mps.main(['--out=any-out'])
260 except exceptions.SystemExit as e:
261 self.assertNotEquals(e.args[0], 0)
263 # Verify that output ends in error.
264 self.AssertOutputEndsInError()
267 """Verify that running main method runs expected functons.
269 Expected: LoadAndMergeTables, WriteTable.
271 self.mox.StubOutWithMock(mps, 'LoadAndMergeTables')
272 self.mox.StubOutWithMock(mps, 'WriteTable')
273 mps.LoadAndMergeTables(mox.IgnoreArg()).AndReturn('csv_table')
274 mps.WriteTable(mox.Regex(r'csv_table'), 'any-out')
277 mps.main(['--out=any-out', 'any-package'])
280 if __name__ == '__main__':