• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# Copyright 2014 The Chromium 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.
5"""
6Unit tests for the contents of mock_calls.py.
7"""
8
9import logging
10import os
11import unittest
12
13from devil import devil_env
14from devil.android.sdk import version_codes
15from devil.utils import mock_calls
16
17with devil_env.SysPath(devil_env.PYMOCK_PATH):
18  import mock  # pylint: disable=import-error
19
20
21class _DummyAdb(object):
22  def __str__(self):
23    return '0123456789abcdef'
24
25  def Push(self, host_path, device_path):
26    logging.debug('(device %s) pushing %r to %r', self, host_path, device_path)
27
28  def IsOnline(self):
29    logging.debug('(device %s) checking device online', self)
30    return True
31
32  def Shell(self, cmd):
33    logging.debug('(device %s) running command %r', self, cmd)
34    return "nice output\n"
35
36  def Reboot(self):
37    logging.debug('(device %s) rebooted!', self)
38
39  @property
40  def build_version_sdk(self):
41    logging.debug('(device %s) getting build_version_sdk', self)
42    return version_codes.LOLLIPOP
43
44
45class TestCaseWithAssertCallsTest(mock_calls.TestCase):
46  def setUp(self):
47    self.adb = _DummyAdb()
48
49  def ShellError(self):
50    def action(cmd):
51      raise ValueError('(device %s) command %r is not nice' % (self.adb, cmd))
52
53    return action
54
55  def get_answer(self):
56    logging.debug("called 'get_answer' of %r object", self)
57    return 42
58
59  def echo(self, thing):
60    logging.debug("called 'echo' of %r object", self)
61    return thing
62
63  def testCallTarget_succeds(self):
64    self.assertEquals(self.adb.Shell, self.call_target(self.call.adb.Shell))
65
66  def testCallTarget_failsExternal(self):
67    with self.assertRaises(ValueError):
68      self.call_target(mock.call.sys.getcwd)
69
70  def testCallTarget_failsUnknownAttribute(self):
71    with self.assertRaises(AttributeError):
72      self.call_target(self.call.adb.Run)
73
74  def testCallTarget_failsIntermediateCalls(self):
75    with self.assertRaises(AttributeError):
76      self.call_target(self.call.adb.RunShell('cmd').append)
77
78  def testPatchCall_method(self):
79    self.assertEquals(42, self.get_answer())
80    with self.patch_call(self.call.get_answer, return_value=123):
81      self.assertEquals(123, self.get_answer())
82    self.assertEquals(42, self.get_answer())
83
84  def testPatchCall_attribute_method(self):
85    with self.patch_call(self.call.adb.Shell, return_value='hello'):
86      self.assertEquals('hello', self.adb.Shell('echo hello'))
87
88  def testPatchCall_global(self):
89    with self.patch_call(mock.call.os.getcwd, return_value='/some/path'):
90      self.assertEquals('/some/path', os.getcwd())
91
92  def testPatchCall_withSideEffect(self):
93    with self.patch_call(self.call.adb.Shell, side_effect=ValueError):
94      with self.assertRaises(ValueError):
95        self.adb.Shell('echo hello')
96
97  def testPatchCall_property(self):
98    self.assertEquals(version_codes.LOLLIPOP, self.adb.build_version_sdk)
99    with self.patch_call(
100        self.call.adb.build_version_sdk, return_value=version_codes.KITKAT):
101      self.assertEquals(version_codes.KITKAT, self.adb.build_version_sdk)
102    self.assertEquals(version_codes.LOLLIPOP, self.adb.build_version_sdk)
103
104  def testAssertCalls_succeeds_simple(self):
105    self.assertEquals(42, self.get_answer())
106    with self.assertCall(self.call.get_answer(), 123):
107      self.assertEquals(123, self.get_answer())
108    self.assertEquals(42, self.get_answer())
109
110  def testAssertCalls_succeeds_multiple(self):
111    with self.assertCalls(
112        (mock.call.os.getcwd(), '/some/path'),
113        (self.call.echo('hello'), 'hello'), (self.call.get_answer(), 11),
114        self.call.adb.Push('this_file',
115                           'that_file'), (self.call.get_answer(), 12)):
116      self.assertEquals(os.getcwd(), '/some/path')
117      self.assertEquals('hello', self.echo('hello'))
118      self.assertEquals(11, self.get_answer())
119      self.adb.Push('this_file', 'that_file')
120      self.assertEquals(12, self.get_answer())
121
122  def testAsserCalls_succeeds_withAction(self):
123    with self.assertCall(self.call.adb.Shell('echo hello'), self.ShellError()):
124      with self.assertRaises(ValueError):
125        self.adb.Shell('echo hello')
126
127  def testAssertCalls_fails_tooManyCalls(self):
128    with self.assertRaises(AssertionError):
129      with self.assertCalls(self.call.adb.IsOnline()):
130        self.adb.IsOnline()
131        self.adb.IsOnline()
132
133  def testAssertCalls_fails_tooFewCalls(self):
134    with self.assertRaises(AssertionError):
135      with self.assertCalls(self.call.adb.IsOnline()):
136        pass
137
138  def testAssertCalls_succeeds_extraCalls(self):
139    # we are not watching Reboot, so the assertion succeeds
140    with self.assertCalls(self.call.adb.IsOnline()):
141      self.adb.IsOnline()
142      self.adb.Reboot()
143
144  def testAssertCalls_fails_extraCalls(self):
145    self.watchCalls([self.call.adb.Reboot])
146    # this time we are also watching Reboot, so the assertion fails
147    with self.assertRaises(AssertionError):
148      with self.assertCalls(self.call.adb.IsOnline()):
149        self.adb.IsOnline()
150        self.adb.Reboot()
151
152  def testAssertCalls_succeeds_NoCalls(self):
153    self.watchMethodCalls(self.call.adb)  # we are watching all adb methods
154    with self.assertCalls():
155      pass
156
157  def testAssertCalls_fails_NoCalls(self):
158    self.watchMethodCalls(self.call.adb)
159    with self.assertRaises(AssertionError):
160      with self.assertCalls():
161        self.adb.IsOnline()
162
163
164if __name__ == '__main__':
165  logging.getLogger().setLevel(logging.DEBUG)
166  unittest.main(verbosity=2)
167