Index: chromite/chromite_unittest.py |
diff --git a/chromite/chromite_unittest.py b/chromite/chromite_unittest.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..14b0ee60e882b6d7c91f0fdf92d90b663dca7b3a |
--- /dev/null |
+++ b/chromite/chromite_unittest.py |
@@ -0,0 +1,374 @@ |
+#!/usr/bin/python |
+# |
+# Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+"""Unit tests for chromite.py.""" |
+ |
+import doctest |
+import os |
+import re |
+import unittest |
+ |
+import chromite |
+from lib import text_menu |
+import mox |
+ |
+ |
+class _DeathException(Exception): |
+ """A bogus exception used by the mock out of Die.""" |
+ pass |
+ |
+ |
+class TestFindCommand(unittest.TestCase): |
+ """Test chromite._FindCommand.""" |
+ |
+ def setUp(self): |
+ """Test initialization.""" |
+ # Create our mox and stub out function calls used by _FindCommand()... |
+ self.mox = mox.Mox() |
+ self.mox.StubOutWithMock(chromite, 'Die') |
+ self.mox.StubOutWithMock(chromite, 'Info') |
+ self.mox.StubOutWithMock(text_menu, 'TextMenu') |
+ |
+ def tearDown(self): |
+ """Test cleanup.""" |
+ # Unset stubs... |
+ self.mox.UnsetStubs() |
+ |
+ def testInvalidCommand(self): |
+ """Test that _FindCommand('implode') causes Die().""" |
+ # Should be a call to Die. We'll have it fake a _DeathException... |
+ chromite.Die(mox.IsA(basestring)).AndRaise(_DeathException) |
+ |
+ # Run the command and verify proper mocks were called... |
+ self.mox.ReplayAll() |
+ self.assertRaises(_DeathException, chromite._FindCommand, 'implode') |
+ self.mox.VerifyAll() |
+ |
+ def testBlankCommandWithQuit(self): |
+ """Test that _FindCommand('') shows menu, mocking quit. |
+ |
+ This tests the case that the user quit out of the menu without choosing |
+ anything. |
+ """ |
+ # Should be one call to TextMenu, which will return None for quit. |
+ text_menu.TextMenu(mox.IsA(list), |
+ mox.IsA(basestring), |
+ menu_width=0).AndReturn(None) |
+ |
+ # Run the command and verify proper mocks were called... |
+ self.mox.ReplayAll() |
+ cmd_str = chromite._FindCommand('') |
+ self.mox.VerifyAll() |
+ |
+ self.assertEquals(cmd_str, None, |
+ '_FindCommand should have returned None from TextMenu') |
+ |
+ def testBlankCommandWithChoice0(self): |
+ """Test that _FindCommand('') shows menu, mocking choice 0. |
+ |
+ This tests the case that the user chose choice 0 for the menu. |
+ """ |
+ # Should be one call to TextMenu, which will return item 0. |
+ text_menu.TextMenu(mox.IsA(list), |
+ mox.IsA(basestring), |
+ menu_width=0).AndReturn(0) |
+ |
+ # Run the command and verify proper mocks were called... |
+ self.mox.ReplayAll() |
+ cmd_str = chromite._FindCommand('') |
+ self.mox.VerifyAll() |
+ |
+ self.assertTrue(isinstance(cmd_str, basestring), |
+ '_FindCommand should return a string') |
+ self.assertTrue(bool(cmd_str), |
+ '_FindCommand should not return a blank string') |
+ |
+ def _TestExactCommand(self, cmd_to_find): |
+ """Helper for tests that try to find an exact match. |
+ |
+ Args: |
+ cmd_to_find: The name of the command to find, like 'Build', ... |
+ """ |
+ # Expect no mocks to be called... |
+ |
+ # Run the command and verify proper mocks were called... |
+ self.mox.ReplayAll() |
+ cmd_str = chromite._FindCommand(cmd_to_find) |
+ self.mox.VerifyAll() |
+ |
+ self.assertEqual(cmd_str, cmd_to_find.lower(), |
+ '_FindCommand("%s") should return "%s" back.' % |
+ (cmd_to_find, cmd_to_find.lower())) |
+ |
+ def testCaseSensitiveBuild(self): |
+ """Test that _FindCommand('build') returns 'build'. |
+ |
+ The command matching should be case sensitive. |
+ """ |
+ self._TestExactCommand('build') |
+ |
+ def testCaseInsensitiveBuild(self): |
sosa
2011/01/11 04:44:22
Up to you but you may want to mock out the "known"
diandersAtChromium
2011/01/12 00:04:45
Added TODO for this.
On 2011/01/11 04:44:22, sosa
|
+ """Test that _FindCommand('BUiLD') returns 'build'. |
+ |
+ The command matching should be case insensitive. |
+ """ |
+ self._TestExactCommand('BUiLD') |
+ |
+ def testShCommand(self): |
+ """Test that _FindCommand('sh') returns 'shell'. |
+ |
+ This serves two purposes: |
+ 1. Test the 'prefix' feature of _FindCommand |
+ 2. Validate that nobody has introduced another command that starts with |
+ 'sh', since it's expected that many people will use this to invoke the |
+ shell. |
+ """ |
+ # _FindCommand should give us a message that it has interpreted sh as shell. |
+ chromite.Info(mox.IsA(basestring)) |
+ |
+ # Run the command and verify proper mocks were called... |
+ self.mox.ReplayAll() |
+ cmd_str = chromite._FindCommand('sh') |
+ self.mox.VerifyAll() |
+ |
+ self.assertEqual(cmd_str, 'shell', |
+ '_FindCommand("sh") should return "shell" back.') |
+ |
+ |
+class TestFindSpec(unittest.TestCase): |
+ """Test chromite._FindSpec.""" |
+ |
+ def setUp(self): |
+ """Test initialization.""" |
+ # Create our mox and stub out function calls used by _FindSpec()... |
sosa
2011/01/11 04:44:22
It almost seems for the setup and teardown's you s
diandersAtChromium
2011/01/12 00:04:45
Not going to in this case, though I can see your p
|
+ self.mox = mox.Mox() |
+ self.mox.StubOutWithMock(os, 'listdir') |
+ self.mox.StubOutWithMock(os.path, 'isfile') |
+ self.mox.StubOutWithMock(chromite, 'Die') |
+ self.mox.StubOutWithMock(chromite, 'Info') |
+ self.mox.StubOutWithMock(text_menu, 'TextMenu') |
+ |
+ def tearDown(self): |
+ """Test cleanup.""" |
+ # Unset stubs... |
+ self.mox.UnsetStubs() |
+ |
+ def testInvalidSpec(self): |
+ """Test that _FindSpec('bogusSpec') causes Die().""" |
+ # Pass this spec name... |
+ spec_name = 'bogusSpec' |
+ |
+ # We'll tell mox to say that these specs exist... |
+ dir_list = ['x87-toadstool.spec', 'x87-luigi.SPeC', 'x88-princess.spec', |
+ '_default'] |
+ |
+ # This spec doesn't represent any full path. |
+ os.path.isfile(spec_name).AndReturn(False) |
+ |
+ # This spec isn't found in our search path. |
+ os.path.isfile(mox.Regex('^/.*%s.spec$' % spec_name)).MultipleTimes( |
+ ).AndReturn(False) |
+ |
+ # Give the fake directory listing... |
+ os.listdir(mox.IsA(basestring)).MultipleTimes().AndReturn(dir_list) |
+ |
+ # Should be a call to Die. We'll have it fake a _DeathException... |
+ chromite.Die(mox.IsA(basestring)).AndRaise(_DeathException) |
+ |
+ # Run the command and verify proper mocks were called... |
+ self.mox.ReplayAll() |
+ self.assertRaises(_DeathException, chromite._FindSpec, 'bogusSpec') |
+ self.mox.VerifyAll() |
+ |
+ def testFullPath(self): |
+ """Test that _FindSpec(full_path) returns full_path. |
+ |
+ _FindSpec is defined so that if you pass a full file path to it, it |
+ should just return that. It doesn't need to have any special suffix or |
+ live in a spec folder. |
+ """ |
+ # Pass this spec name... |
+ spec_name = __file__ |
+ |
+ # Just say that this is a full path... |
+ os.path.isfile(spec_name).AndReturn(True) |
+ |
+ # Run the command and verify proper mocks were called... |
+ self.mox.ReplayAll() |
+ path = chromite._FindSpec(spec_name) |
+ self.mox.VerifyAll() |
+ |
+ self.assertEqual(path, spec_name, |
+ '_FindSpec() should just return param if full path.') |
+ |
+ def testExactSpecName(self): |
+ """Test that _FindSpec(exact_spec_name) returns the path for the spec.""" |
+ # We'll search for this bogus spec; we'll use mox to pretend it exists in |
+ # the search path. |
+ spec_name = 'y87-luigi' |
+ |
+ # This spec doesn't represent any full path |
+ os.path.isfile(spec_name).AndReturn(False) |
+ |
+ # When we look through the search path for this spec (with .spec at |
+ # the end), we will consider the spec to be found. |
+ os.path.isfile(mox.Regex('^/.*%s.spec$' % spec_name)).AndReturn(True) |
+ |
+ # Run the command and verify proper mocks were called... |
+ self.mox.ReplayAll() |
+ spec_path = chromite._FindSpec(spec_name) |
+ self.mox.VerifyAll() |
+ |
+ self.assertTrue(re.search('^/.*%s.spec$' % spec_name, spec_path), |
+ '_FindSpec() should have returned absolute path for spec.') |
+ |
+ def testUniqueSpecName(self): |
+ """Test that _FindSpec(unique_part_name) returns the path for the spec.""" |
+ # We'll search for this spec. Weird capitalization on purpose to test |
+ # case sensitiveness. |
+ spec_name = 'ToaDSTooL' |
+ |
+ # We'll tell mox to say that these specs exist in the first directory... |
+ dir_list = ['_default', |
+ 'x87-luigi.spec', 'x87-toadstool.SPeC', 'x88-princess.spec'] |
+ |
+ # We expect it to find this spec. |
+ expected_result = 'x87-toadstool.SPeC' |
+ |
+ # Self-checks for test code... |
+ assert dir_list == sorted(dir_list) |
+ |
+ # This spec doesn't represent any full path. |
+ os.path.isfile(spec_name).AndReturn(False) |
+ |
+ # This spec isn't found in our search path. |
+ os.path.isfile(mox.Regex('^/.*%s.spec$' % spec_name)).MultipleTimes( |
+ ).AndReturn(False) |
+ |
+ # Return our directory listing. |
+ # TODO(dianders): How to make first mocked call return dir_list and |
+ # subsequent return [] |
+ os.listdir(mox.IsA(basestring)).AndReturn(dir_list) |
+ |
+ # Run the command and verify proper mocks were called... |
+ self.mox.ReplayAll() |
+ spec_path = chromite._FindSpec(spec_name) |
+ self.mox.VerifyAll() |
+ |
+ self.assertTrue(re.search('^/.*%s$' % expected_result, spec_path), |
+ '_FindSpec("%s") incorrectly returned "%s".' % |
+ (spec_name, spec_path)) |
+ |
+ def _TestBlankSpecName(self, menu_return): |
+ """Helper for tests passing a blank spec name. |
+ |
+ Args: |
+ menu_return: This value is returned by TextMenu. Could be none or an |
+ integer index into the dir_list of this function. |
+ """ |
+ # We'll search for this spec. |
+ spec_name = '' |
+ |
+ # We'll tell mox to say that these specs exist in the first directory... |
+ # ...only valid specs to make it easier to compare things. |
+ dir_list = ['x87-luigi.spec', 'x87-toadstool.SPeC', 'x88-princess.spec'] |
+ num_specs = len(dir_list) |
+ |
+ # Self-checks for test code... |
+ assert menu_return < len(dir_list) |
+ assert dir_list == sorted(dir_list) |
+ |
+ # This spec doesn't represent any full path. |
+ os.path.isfile(spec_name).AndReturn(False) |
+ |
+ # Return our directory listing. |
+ # TODO(dianders): How to make first mocked call return dir_list and |
+ # subsequent return [] |
+ os.listdir(mox.IsA(basestring)).AndReturn(dir_list) |
+ |
+ # We expect there to be 1 more item than we passed in, since we account |
+ # for 'HOST'. |
+ check_num_items_fn = lambda items: len(items) == (num_specs + 1) |
+ |
+ # Add 1 to menu_return, since 'HOST' is first... |
+ if menu_return is None: |
+ adjusted_menu_return = menu_return |
+ else: |
+ adjusted_menu_return = menu_return + 1 |
+ |
+ # Should be one call to TextMenu, which will return menu_return. |
+ text_menu.TextMenu(mox.And(mox.IsA(list), mox.Func(check_num_items_fn)), |
+ mox.IsA(basestring)).AndReturn(adjusted_menu_return) |
+ |
+ # Run the command and verify proper mocks were called... |
+ self.mox.ReplayAll() |
+ spec_path = chromite._FindSpec(spec_name) |
+ self.mox.VerifyAll() |
+ |
+ if menu_return is None: |
+ self.assertEquals(spec_path, None, |
+ '_FindSpec should have returned None from TextMenu') |
+ else: |
+ expected_result = dir_list[menu_return] |
+ self.assertTrue(re.search('^/.*%s$' % expected_result, spec_path), |
+ '_FindSpec("%s") incorrectly returned "%s".' % |
+ (spec_name, spec_path)) |
+ |
+ def testBlankSpecNameWithQuit(self): |
+ """Test that _FindSpec('') shows menu, mocking quit.""" |
+ self._TestBlankSpecName(None) |
+ |
+ def testBlankSpecNameWithChoice0(self): |
+ """Test that _FindSpec('') shows menu, mocking choice 0.""" |
+ self._TestBlankSpecName(0) |
+ |
+ def testPartialSpecNameWithChoice0(self): |
+ """Test that _FindSpec(non_unique_str) shows menu, mocking choice 0.""" |
+ # We'll search for this spec. |
+ spec_name = 'x87' |
+ |
+ # We'll tell mox to say that these specs exist in the first directory... |
+ dir_list = ['_default', |
+ 'x87-luigi.spec', 'x87-toadstool.SPeC', 'x88-princess.spec'] |
+ |
+ # We expect 2 matches and should get back luigi as choice 0. |
+ num_match = 2 |
+ expected_result = 'x87-luigi.spec' |
+ |
+ # Self-checks for test code... |
+ assert dir_list == sorted(dir_list) |
+ |
+ # This spec doesn't represent any full path. |
+ os.path.isfile(spec_name).AndReturn(False) |
+ |
+ # This spec isn't found in our search path. |
+ os.path.isfile(mox.Regex('^/.*%s.spec$' % spec_name)).MultipleTimes( |
+ ).AndReturn(False) |
+ |
+ # Return our directory listing. |
+ # TODO(dianders): How to make first mocked call return dir_list and |
+ # subsequent return [] |
+ os.listdir(mox.IsA(basestring)).AndReturn(dir_list) |
+ |
+ # Should be one call to TextMenu, which will return 0. |
+ text_menu.TextMenu(mox.And(mox.IsA(list), |
+ mox.Func(lambda items: len(items) == num_match)), |
+ mox.IsA(basestring)).AndReturn(0) |
+ |
+ # Run the command and verify proper mocks were called... |
+ self.mox.ReplayAll() |
+ spec_path = chromite._FindSpec(spec_name) |
+ self.mox.VerifyAll() |
+ |
+ self.assertTrue(re.search('^/.*%s$' % expected_result, spec_path), |
+ '_FindSpec("%s") incorrectly returned "%s".' % |
+ (spec_name, spec_path)) |
+ |
+ |
+if __name__ == '__main__': |
+ doctest.testmod(chromite) |
+ unittest.main() |
+ |