xbuddy: Fix linter errors.

Also replace mox

BUG=chromium:403086
TEST=unittests, cros flash

Change-Id: I6052be6b45f1c480732925bf490ff5ecf38e39ca
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/dev-util/+/1822077
Tested-by: Achuith Bhandarkar <achuith@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
diff --git a/xbuddy_unittest.py b/xbuddy_unittest.py
index bcee666..bd39abb 100755
--- a/xbuddy_unittest.py
+++ b/xbuddy_unittest.py
@@ -8,34 +8,33 @@
 
 from __future__ import print_function
 
-import ConfigParser
 import os
 import shutil
 import tempfile
 import time
 import unittest
 
-import mox
+import mock
+from six.moves import configparser
 
 import xbuddy
 
 # Make sure that chromite is available to import.
-import setup_chromite # pylint: disable=unused-import
+import setup_chromite  # pylint: disable=unused-import
 
 try:
   from chromite.lib import gs
 except ImportError as e:
   gs = None
 
-#pylint: disable=W0212
-#pylint: disable=no-value-for-parameter
+# pylint: disable=protected-access
+# pylint: disable=no-value-for-parameter
 
 GS_ALTERNATE_DIR = 'gs://chromeos-alternate-archive/'
 
-class xBuddyTest(mox.MoxTestBase):
+class xBuddyTest(unittest.TestCase):
   """Regression tests for xbuddy."""
   def setUp(self):
-    mox.MoxTestBase.setUp(self)
 
     self.static_image_dir = tempfile.mkdtemp('xbuddy_unittest_static')
 
@@ -61,7 +60,6 @@
 
   def testGetLatestVersionFromGsDir(self):
     """Test that we can get the most recent version from gsutil calls."""
-    self.mox.StubOutWithMock(self.mock_xb, '_LS')
     mock_data1 = """gs://chromeos-releases/stable-channel/parrot/3701.96.0/
     gs://chromeos-releases/stable-channel/parrot/3701.98.0/
     gs://chromeos-releases/stable-channel/parrot/3912.100.0/
@@ -73,134 +71,116 @@
     gs://chromeos-image-archive/parrot-release/R27-3912.101.0
     gs://chromeos-image-archive/parrot-release/R28-3912.101.0"""
 
-    self.mock_xb._LS(mox.IgnoreArg(), list_subdirectory=False).AndReturn(
-        mock_data1.splitlines())
-    self.mock_xb._LS(mox.IgnoreArg(), list_subdirectory=True).AndReturn(
-        mock_data2.splitlines())
-
-    self.mox.ReplayAll()
-    url = ''
-    self.assertEqual(
-        self.mock_xb._GetLatestVersionFromGsDir(url, with_release=False),
-        '3912.101.0')
-    self.assertEqual(
-        self.mock_xb._GetLatestVersionFromGsDir(url, list_subdirectory=True,
-                                                with_release=True),
-        'R28-3912.101.0')
-    self.mox.VerifyAll()
+    with mock.patch.object(
+        self.mock_xb, '_LS',
+        side_effect=[mock_data1.splitlines(),
+                     mock_data2.splitlines()]) as ls_mock:
+      self.assertEqual(
+          self.mock_xb._GetLatestVersionFromGsDir('url1', with_release=False),
+          '3912.101.0')
+      ls_mock.assert_called_with('url1', list_subdirectory=False)
+      self.assertEqual(
+          self.mock_xb._GetLatestVersionFromGsDir(
+              'url2', list_subdirectory=True, with_release=True),
+          'R28-3912.101.0')
+      ls_mock.assert_called_with('url2', list_subdirectory=True)
 
   def testLookupOfficial(self):
     """Basic test of _LookupOfficial. Checks that a given suffix is handled."""
-    self.mox.StubOutWithMock(gs.GSContext, 'Cat')
-    gs.GSContext.Cat(mox.IgnoreArg()).AndReturn('v')
-    expected = 'b-s/v'
-    self.mox.ReplayAll()
-    self.assertEqual(self.mock_xb._LookupOfficial('b', suffix='-s'), expected)
-    self.mox.VerifyAll()
+    with mock.patch.object(gs.GSContext, 'Cat', return_value='v') as cat_mock:
+      self.assertEqual(self.mock_xb._LookupOfficial('b', suffix='-s'), 'b-s/v')
+      cat_mock.assert_called_with(
+          'gs://chromeos-image-archive/b-s/LATEST-master')
 
-  def testLookupChannel(self):
+  @mock.patch('xbuddy.XBuddy._GetLatestVersionFromGsDir',
+              side_effect=['4100.68.0', 'R28-4100.68.0'])
+  def testLookupChannel(self, version_mock):
     """Basic test of _LookupChannel. Checks that a given suffix is handled."""
-    self.mox.StubOutWithMock(self.mock_xb, '_GetLatestVersionFromGsDir')
-    mock_data1 = '4100.68.0'
-    self.mock_xb._GetLatestVersionFromGsDir(
-        mox.IgnoreArg(), with_release=False).AndReturn(mock_data1)
-    mock_data2 = 'R28-4100.68.0'
-    self.mock_xb._GetLatestVersionFromGsDir(
-        mox.IgnoreArg(), list_subdirectory=True).AndReturn(mock_data2)
-    self.mox.ReplayAll()
-    expected = 'b-release/R28-4100.68.0'
     self.assertEqual(self.mock_xb._LookupChannel('b', '-release'),
-                     expected)
-    self.mox.VerifyAll()
+                     'b-release/R28-4100.68.0')
+    version_mock.assert_called_with(
+        'gs://chromeos-image-archive/b-release/R*4100.68.0',
+        list_subdirectory=True)
 
   def testLookupAliasPathRewrite(self):
     """Tests LookupAlias of path rewrite, including keyword substitution."""
-    alias = 'foobar'
     path = 'remote/BOARD/VERSION/test'
-    self.mox.StubOutWithMock(self.mock_xb.config, 'get')
-    self.mock_xb.config.get('LOCATION_SUFFIXES', alias).AndRaise(
-        ConfigParser.Error())
-    self.mock_xb.config.get('PATH_REWRITES', alias).AndReturn(path)
-    self.mox.ReplayAll()
-    self.assertEqual(('remote/parrot/1.2.3/test', '-release'),
-                     self.mock_xb.LookupAlias(alias, board='parrot',
-                                              version='1.2.3'))
+    with mock.patch.object(
+        self.mock_xb.config, 'get',
+        side_effect=[configparser.Error, path]) as get_mock:
+      self.assertEqual(('remote/parrot/1.2.3/test', '-release'),
+                       self.mock_xb.LookupAlias('foobar', board='parrot',
+                                                version='1.2.3'))
+      get_mock.assert_called_with('PATH_REWRITES', 'foobar')
 
   def testLookupAliasSuffix(self):
     """Tests LookupAlias of location suffix."""
-    alias = 'foobar'
-    suffix = '-random'
-    self.mox.StubOutWithMock(self.mock_xb.config, 'get')
-    self.mock_xb.config.get('LOCATION_SUFFIXES', alias).AndReturn(suffix)
-    self.mock_xb.config.get('PATH_REWRITES', alias).AndRaise(
-        ConfigParser.Error())
-    self.mox.ReplayAll()
-    self.assertEqual((alias, suffix),
-                     self.mock_xb.LookupAlias(alias, board='parrot',
-                                              version='1.2.3'))
+    with mock.patch.object(
+        self.mock_xb.config, 'get',
+        side_effect=['-random', configparser.Error]) as get_mock:
+      self.assertEqual(('foobar', '-random'),
+                       self.mock_xb.LookupAlias('foobar', board='parrot',
+                                                version='1.2.3'))
+      get_mock.assert_called_with('PATH_REWRITES', 'foobar')
 
   def testLookupAliasPathRewriteAndSuffix(self):
     """Tests LookupAlias with both path rewrite and suffix."""
-    alias = 'foobar'
     path = 'remote/BOARD/VERSION/test'
-    suffix = '-random'
-    self.mox.StubOutWithMock(self.mock_xb.config, 'get')
-    self.mock_xb.config.get('LOCATION_SUFFIXES', alias).AndReturn(suffix)
-    self.mock_xb.config.get('PATH_REWRITES', alias).AndReturn(path)
-    self.mox.ReplayAll()
-    self.assertEqual(('remote/parrot/1.2.3/test', suffix),
-                     self.mock_xb.LookupAlias(alias, board='parrot',
-                                              version='1.2.3'))
+    with mock.patch.object(
+        self.mock_xb.config, 'get',
+        side_effect=['-random', path]) as get_mock:
+      self.assertEqual(('remote/parrot/1.2.3/test', '-random'),
+                       self.mock_xb.LookupAlias('foobar', board='parrot',
+                                                version='1.2.3'))
+      get_mock.assert_called_with('PATH_REWRITES', 'foobar')
 
-  def testResolveVersionToBuildIdAndChannel_Official(self):
+  @mock.patch('xbuddy.XBuddy._LookupOfficial')
+  def testResolveVersionToBuildIdAndChannel_Official(self, lookup_mock):
     """Check _ResolveVersionToBuildIdAndChannel support for official build."""
-    board = 'b'
+    board = 'chell'
     suffix = '-s'
 
-    # aliases that should be redirected to LookupOfficial
-
-    self.mox.StubOutWithMock(self.mock_xb, '_LookupOfficial')
-    self.mock_xb._LookupOfficial(board, suffix, image_dir=None)
-    self.mock_xb._LookupOfficial(board, suffix,
-                                 image_dir=GS_ALTERNATE_DIR)
-    self.mock_xb._LookupOfficial(board, 'paladin', image_dir=None)
-    self.mock_xb._LookupOfficial(board, 'paladin',
-                                 image_dir=GS_ALTERNATE_DIR)
-
-    self.mox.ReplayAll()
     version = 'latest-official'
     self.mock_xb._ResolveVersionToBuildIdAndChannel(board, suffix, version)
+    lookup_mock.assert_called_with('chell', '-s', image_dir=None)
+
     self.mock_xb._ResolveVersionToBuildIdAndChannel(board, suffix, version,
                                                     image_dir=GS_ALTERNATE_DIR)
+    lookup_mock.assert_called_with('chell', '-s',
+                                   image_dir='gs://chromeos-alternate-archive/')
+
     version = 'latest-official-paladin'
     self.mock_xb._ResolveVersionToBuildIdAndChannel(board, suffix, version)
+    lookup_mock.assert_called_with('chell', 'paladin', image_dir=None)
+
     self.mock_xb._ResolveVersionToBuildIdAndChannel(board, suffix, version,
                                                     image_dir=GS_ALTERNATE_DIR)
-    self.mox.VerifyAll()
+    lookup_mock.assert_called_with('chell', 'paladin',
+                                   image_dir='gs://chromeos-alternate-archive/')
 
-  def testResolveVersionToBuildIdAndChannel_Channel(self):
+  @mock.patch('xbuddy.XBuddy._LookupChannel')
+  def testResolveVersionToBuildIdAndChannel_Channel(self, lookup_mock):
     """Check _ResolveVersionToBuildIdAndChannel support for channels."""
-    board = 'b'
+    board = 'chell'
     suffix = '-s'
 
-    # aliases that should be redirected to LookupChannel
-    self.mox.StubOutWithMock(self.mock_xb, '_LookupChannel')
-    self.mock_xb._LookupChannel(board, suffix, image_dir=None)
-    self.mock_xb._LookupChannel(board, suffix, image_dir=GS_ALTERNATE_DIR)
-    self.mock_xb._LookupChannel(board, suffix, channel='dev', image_dir=None)
-    self.mock_xb._LookupChannel(board, suffix, channel='dev',
-                                image_dir=GS_ALTERNATE_DIR)
-
-    self.mox.ReplayAll()
     version = 'latest'
     self.mock_xb._ResolveVersionToBuildIdAndChannel(board, suffix, version)
+    lookup_mock.assert_called_with('chell', '-s', image_dir=None)
+
     self.mock_xb._ResolveVersionToBuildIdAndChannel(board, suffix, version,
                                                     image_dir=GS_ALTERNATE_DIR)
+    lookup_mock.assert_called_with('chell', '-s',
+                                   image_dir='gs://chromeos-alternate-archive/')
+
     version = 'latest-dev'
     self.mock_xb._ResolveVersionToBuildIdAndChannel(board, suffix, version)
+    lookup_mock.assert_called_with('chell', '-s', channel='dev', image_dir=None)
+
     self.mock_xb._ResolveVersionToBuildIdAndChannel(board, suffix, version,
                                                     image_dir=GS_ALTERNATE_DIR)
-    self.mox.VerifyAll()
+    lookup_mock.assert_called_with('chell', '-s', channel='dev',
+                                   image_dir='gs://chromeos-alternate-archive/')
 
   # TODO(dgarrett): Re-enable when crbug.com/585914 is fixed.
   # def testResolveVersionToBuildId_BaseVersion(self):
@@ -329,56 +309,57 @@
     result = self.mock_xb._ListBuildTimes()
     self.assertEqual(len(result), 4)
 
-  ############### Public Methods
   def testXBuddyCaching(self):
     """Caching & replacement of timestamp files."""
-    path_a = ('remote', 'a', 'R0', 'test')
-    path_b = ('remote', 'b', 'R0', 'test')
-    self.mox.StubOutWithMock(gs.GSContext, 'LS')
-    self.mox.StubOutWithMock(self.mock_xb, '_Download')
-    for _ in range(8):
-      self.mock_xb._Download(mox.IsA(str), mox.In(mox.IsA(str)), mox.IsA(str))
 
-    # All non-release urls are invalid so we can meet expectations.
-    gs.GSContext.LS(
-        mox.Not(mox.StrContains('-release'))).MultipleTimes().AndRaise(
-            gs.GSContextException('bad url'))
-    gs.GSContext.LS(mox.StrContains('-release')).MultipleTimes()
+    def _ReleaseOnly(name):
+      # All non-release URLs are invalid so we can meet expectations.
+      if name.find('-release') == -1:
+        raise gs.GSContextException('bad URL')
+      return name
 
-    self.mox.ReplayAll()
+    with mock.patch.object(
+        gs.GSContext, 'LS', side_effect=_ReleaseOnly) as ls_mock:
+      with mock.patch.object(
+          self.mock_xb, '_Download') as download_mock:
+        version = '%s-release/R0'
 
-    # requires default capacity
-    self.assertEqual(self.mock_xb.Capacity(), '5')
+        def _Download(image):
+          gs_image = 'gs://chromeos-image-archive/' + version
+          self.mock_xb.Get(('remote', image, 'R0', 'test'))
+          ls_mock.assert_called_with(gs_image % image)
+          download_mock.assert_called_with(gs_image % image, ['test_image'],
+                                           version % image)
+          time.sleep(0.05)
 
-    # Get 6 different images: a,b,c,d,e,f
-    images = ['a', 'b', 'c', 'd', 'e', 'f']
-    for c in images:
-      self.mock_xb.Get(('remote', c, 'R0', 'test'))
-      time.sleep(0.05)
+        # Requires default capacity.
+        self.assertEqual(self.mock_xb.Capacity(), '5')
 
-    # check that b,c,d,e,f are still stored
-    result = self.mock_xb._ListBuildTimes()
-    self.assertEqual(len(result), 5)
+        # Get 6 different images: a,b,c,d,e,f.
+        images = ['a', 'b', 'c', 'd', 'e', 'f']
+        for image in images:
+          _Download(image)
 
-    # Flip the list to get reverse chronological order
-    images.reverse()
-    for i in range(5):
-      self.assertEqual(result[i][0], '%s-release/R0' % images[i])
+        # Check that b,c,d,e,f are still stored.
+        result = self.mock_xb._ListBuildTimes()
+        self.assertEqual(len(result), 5)
 
-    # Get b,a
-    self.mock_xb.Get(path_b)
-    time.sleep(0.05)
-    self.mock_xb.Get(path_a)
-    time.sleep(0.05)
+        # Flip the list to get reverse chronological order
+        images.reverse()
+        for i in range(5):
+          self.assertEqual(result[i][0], version % images[i])
 
-    # check that d,e,f,b,a are still stored
-    result = self.mock_xb._ListBuildTimes()
-    self.assertEqual(len(result), 5)
-    images_expected = ['a', 'b', 'f', 'e', 'd']
-    for i in range(5):
-      self.assertEqual(result[i][0], '%s-release/R0' % images_expected[i])
+        # Get b,a.
+        images = ['b', 'a']
+        for image in images:
+          _Download(image)
 
-    self.mox.VerifyAll()
+        # Check that d,e,f,b,a are still stored.
+        result = self.mock_xb._ListBuildTimes()
+        self.assertEqual(len(result), 5)
+        images_expected = ['a', 'b', 'f', 'e', 'd']
+        for i in range(5):
+          self.assertEqual(result[i][0], '%s-release/R0' % images_expected[i])
 
 
 if __name__ == '__main__':