You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ma...@apache.org on 2013/02/04 03:24:02 UTC
svn commit: r1442010 [9/29] - in /incubator/ambari/branches/branch-1.2: ./
ambari-agent/ ambari-agent/conf/unix/ ambari-agent/src/examples/
ambari-agent/src/main/puppet/modules/hdp-ganglia/files/
ambari-agent/src/main/puppet/modules/hdp-ganglia/manifes...
Added: incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tests/testpatch.py
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tests/testpatch.py?rev=1442010&view=auto
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tests/testpatch.py (added)
+++ incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tests/testpatch.py Mon Feb 4 02:23:55 2013
@@ -0,0 +1,1815 @@
+# Copyright (C) 2007-2012 Michael Foord & the mock team
+# E-mail: fuzzyman AT voidspace DOT org DOT uk
+# http://www.voidspace.org.uk/python/mock/
+
+import os
+import sys
+
+from tests import support
+from tests.support import unittest2, inPy3k, SomeClass, is_instance, callable
+
+from mock import (
+ NonCallableMock, CallableMixin, patch, sentinel,
+ MagicMock, Mock, NonCallableMagicMock, patch, _patch,
+ DEFAULT, call, _get_target
+)
+
+builtin_string = '__builtin__'
+if inPy3k:
+ builtin_string = 'builtins'
+ unicode = str
+
+PTModule = sys.modules[__name__]
+MODNAME = '%s.PTModule' % __name__
+
+
+def _get_proxy(obj, get_only=True):
+ class Proxy(object):
+ def __getattr__(self, name):
+ return getattr(obj, name)
+ if not get_only:
+ def __setattr__(self, name, value):
+ setattr(obj, name, value)
+ def __delattr__(self, name):
+ delattr(obj, name)
+ Proxy.__setattr__ = __setattr__
+ Proxy.__delattr__ = __delattr__
+ return Proxy()
+
+
+# for use in the test
+something = sentinel.Something
+something_else = sentinel.SomethingElse
+
+
+class Foo(object):
+ def __init__(self, a):
+ pass
+ def f(self, a):
+ pass
+ def g(self):
+ pass
+ foo = 'bar'
+
+ class Bar(object):
+ def a(self):
+ pass
+
+foo_name = '%s.Foo' % __name__
+
+
+def function(a, b=Foo):
+ pass
+
+
+class Container(object):
+ def __init__(self):
+ self.values = {}
+
+ def __getitem__(self, name):
+ return self.values[name]
+
+ def __setitem__(self, name, value):
+ self.values[name] = value
+
+ def __delitem__(self, name):
+ del self.values[name]
+
+ def __iter__(self):
+ return iter(self.values)
+
+
+
+class PatchTest(unittest2.TestCase):
+
+ def assertNotCallable(self, obj, magic=True):
+ MockClass = NonCallableMagicMock
+ if not magic:
+ MockClass = NonCallableMock
+
+ self.assertRaises(TypeError, obj)
+ self.assertTrue(is_instance(obj, MockClass))
+ self.assertFalse(is_instance(obj, CallableMixin))
+
+
+ def test_single_patchobject(self):
+ class Something(object):
+ attribute = sentinel.Original
+
+ @patch.object(Something, 'attribute', sentinel.Patched)
+ def test():
+ self.assertEqual(Something.attribute, sentinel.Patched, "unpatched")
+
+ test()
+ self.assertEqual(Something.attribute, sentinel.Original,
+ "patch not restored")
+
+
+ def test_patchobject_with_none(self):
+ class Something(object):
+ attribute = sentinel.Original
+
+ @patch.object(Something, 'attribute', None)
+ def test():
+ self.assertIsNone(Something.attribute, "unpatched")
+
+ test()
+ self.assertEqual(Something.attribute, sentinel.Original,
+ "patch not restored")
+
+
+ def test_multiple_patchobject(self):
+ class Something(object):
+ attribute = sentinel.Original
+ next_attribute = sentinel.Original2
+
+ @patch.object(Something, 'attribute', sentinel.Patched)
+ @patch.object(Something, 'next_attribute', sentinel.Patched2)
+ def test():
+ self.assertEqual(Something.attribute, sentinel.Patched,
+ "unpatched")
+ self.assertEqual(Something.next_attribute, sentinel.Patched2,
+ "unpatched")
+
+ test()
+ self.assertEqual(Something.attribute, sentinel.Original,
+ "patch not restored")
+ self.assertEqual(Something.next_attribute, sentinel.Original2,
+ "patch not restored")
+
+
+ def test_object_lookup_is_quite_lazy(self):
+ global something
+ original = something
+ @patch('%s.something' % __name__, sentinel.Something2)
+ def test():
+ pass
+
+ try:
+ something = sentinel.replacement_value
+ test()
+ self.assertEqual(something, sentinel.replacement_value)
+ finally:
+ something = original
+
+
+ def test_patch(self):
+ @patch('%s.something' % __name__, sentinel.Something2)
+ def test():
+ self.assertEqual(PTModule.something, sentinel.Something2,
+ "unpatched")
+
+ test()
+ self.assertEqual(PTModule.something, sentinel.Something,
+ "patch not restored")
+
+ @patch('%s.something' % __name__, sentinel.Something2)
+ @patch('%s.something_else' % __name__, sentinel.SomethingElse)
+ def test():
+ self.assertEqual(PTModule.something, sentinel.Something2,
+ "unpatched")
+ self.assertEqual(PTModule.something_else, sentinel.SomethingElse,
+ "unpatched")
+
+ self.assertEqual(PTModule.something, sentinel.Something,
+ "patch not restored")
+ self.assertEqual(PTModule.something_else, sentinel.SomethingElse,
+ "patch not restored")
+
+ # Test the patching and restoring works a second time
+ test()
+
+ self.assertEqual(PTModule.something, sentinel.Something,
+ "patch not restored")
+ self.assertEqual(PTModule.something_else, sentinel.SomethingElse,
+ "patch not restored")
+
+ mock = Mock()
+ mock.return_value = sentinel.Handle
+ @patch('%s.open' % builtin_string, mock)
+ def test():
+ self.assertEqual(open('filename', 'r'), sentinel.Handle,
+ "open not patched")
+ test()
+ test()
+
+ self.assertNotEqual(open, mock, "patch not restored")
+
+
+ def test_patch_class_attribute(self):
+ @patch('%s.SomeClass.class_attribute' % __name__,
+ sentinel.ClassAttribute)
+ def test():
+ self.assertEqual(PTModule.SomeClass.class_attribute,
+ sentinel.ClassAttribute, "unpatched")
+ test()
+
+ self.assertIsNone(PTModule.SomeClass.class_attribute,
+ "patch not restored")
+
+
+ def test_patchobject_with_default_mock(self):
+ class Test(object):
+ something = sentinel.Original
+ something2 = sentinel.Original2
+
+ @patch.object(Test, 'something')
+ def test(mock):
+ self.assertEqual(mock, Test.something,
+ "Mock not passed into test function")
+ self.assertIsInstance(mock, MagicMock,
+ "patch with two arguments did not create a mock")
+
+ test()
+
+ @patch.object(Test, 'something')
+ @patch.object(Test, 'something2')
+ def test(this1, this2, mock1, mock2):
+ self.assertEqual(this1, sentinel.this1,
+ "Patched function didn't receive initial argument")
+ self.assertEqual(this2, sentinel.this2,
+ "Patched function didn't receive second argument")
+ self.assertEqual(mock1, Test.something2,
+ "Mock not passed into test function")
+ self.assertEqual(mock2, Test.something,
+ "Second Mock not passed into test function")
+ self.assertIsInstance(mock2, MagicMock,
+ "patch with two arguments did not create a mock")
+ self.assertIsInstance(mock2, MagicMock,
+ "patch with two arguments did not create a mock")
+
+ # A hack to test that new mocks are passed the second time
+ self.assertNotEqual(outerMock1, mock1, "unexpected value for mock1")
+ self.assertNotEqual(outerMock2, mock2, "unexpected value for mock1")
+ return mock1, mock2
+
+ outerMock1 = outerMock2 = None
+ outerMock1, outerMock2 = test(sentinel.this1, sentinel.this2)
+
+ # Test that executing a second time creates new mocks
+ test(sentinel.this1, sentinel.this2)
+
+
+ def test_patch_with_spec(self):
+ @patch('%s.SomeClass' % __name__, spec=SomeClass)
+ def test(MockSomeClass):
+ self.assertEqual(SomeClass, MockSomeClass)
+ self.assertTrue(is_instance(SomeClass.wibble, MagicMock))
+ self.assertRaises(AttributeError, lambda: SomeClass.not_wibble)
+
+ test()
+
+
+ def test_patchobject_with_spec(self):
+ @patch.object(SomeClass, 'class_attribute', spec=SomeClass)
+ def test(MockAttribute):
+ self.assertEqual(SomeClass.class_attribute, MockAttribute)
+ self.assertTrue(is_instance(SomeClass.class_attribute.wibble,
+ MagicMock))
+ self.assertRaises(AttributeError,
+ lambda: SomeClass.class_attribute.not_wibble)
+
+ test()
+
+
+ def test_patch_with_spec_as_list(self):
+ @patch('%s.SomeClass' % __name__, spec=['wibble'])
+ def test(MockSomeClass):
+ self.assertEqual(SomeClass, MockSomeClass)
+ self.assertTrue(is_instance(SomeClass.wibble, MagicMock))
+ self.assertRaises(AttributeError, lambda: SomeClass.not_wibble)
+
+ test()
+
+
+ def test_patchobject_with_spec_as_list(self):
+ @patch.object(SomeClass, 'class_attribute', spec=['wibble'])
+ def test(MockAttribute):
+ self.assertEqual(SomeClass.class_attribute, MockAttribute)
+ self.assertTrue(is_instance(SomeClass.class_attribute.wibble,
+ MagicMock))
+ self.assertRaises(AttributeError,
+ lambda: SomeClass.class_attribute.not_wibble)
+
+ test()
+
+
+ def test_nested_patch_with_spec_as_list(self):
+ # regression test for nested decorators
+ @patch('%s.open' % builtin_string)
+ @patch('%s.SomeClass' % __name__, spec=['wibble'])
+ def test(MockSomeClass, MockOpen):
+ self.assertEqual(SomeClass, MockSomeClass)
+ self.assertTrue(is_instance(SomeClass.wibble, MagicMock))
+ self.assertRaises(AttributeError, lambda: SomeClass.not_wibble)
+ test()
+
+
+ def test_patch_with_spec_as_boolean(self):
+ @patch('%s.SomeClass' % __name__, spec=True)
+ def test(MockSomeClass):
+ self.assertEqual(SomeClass, MockSomeClass)
+ # Should not raise attribute error
+ MockSomeClass.wibble
+
+ self.assertRaises(AttributeError, lambda: MockSomeClass.not_wibble)
+
+ test()
+
+
+ def test_patch_object_with_spec_as_boolean(self):
+ @patch.object(PTModule, 'SomeClass', spec=True)
+ def test(MockSomeClass):
+ self.assertEqual(SomeClass, MockSomeClass)
+ # Should not raise attribute error
+ MockSomeClass.wibble
+
+ self.assertRaises(AttributeError, lambda: MockSomeClass.not_wibble)
+
+ test()
+
+
+ def test_patch_class_acts_with_spec_is_inherited(self):
+ @patch('%s.SomeClass' % __name__, spec=True)
+ def test(MockSomeClass):
+ self.assertTrue(is_instance(MockSomeClass, MagicMock))
+ instance = MockSomeClass()
+ self.assertNotCallable(instance)
+ # Should not raise attribute error
+ instance.wibble
+
+ self.assertRaises(AttributeError, lambda: instance.not_wibble)
+
+ test()
+
+
+ def test_patch_with_create_mocks_non_existent_attributes(self):
+ @patch('%s.frooble' % builtin_string, sentinel.Frooble, create=True)
+ def test():
+ self.assertEqual(frooble, sentinel.Frooble)
+
+ test()
+ self.assertRaises(NameError, lambda: frooble)
+
+
+ def test_patchobject_with_create_mocks_non_existent_attributes(self):
+ @patch.object(SomeClass, 'frooble', sentinel.Frooble, create=True)
+ def test():
+ self.assertEqual(SomeClass.frooble, sentinel.Frooble)
+
+ test()
+ self.assertFalse(hasattr(SomeClass, 'frooble'))
+
+
+ def test_patch_wont_create_by_default(self):
+ try:
+ @patch('%s.frooble' % builtin_string, sentinel.Frooble)
+ def test():
+ self.assertEqual(frooble, sentinel.Frooble)
+
+ test()
+ except AttributeError:
+ pass
+ else:
+ self.fail('Patching non existent attributes should fail')
+
+ self.assertRaises(NameError, lambda: frooble)
+
+
+ def test_patchobject_wont_create_by_default(self):
+ try:
+ @patch.object(SomeClass, 'frooble', sentinel.Frooble)
+ def test():
+ self.fail('Patching non existent attributes should fail')
+
+ test()
+ except AttributeError:
+ pass
+ else:
+ self.fail('Patching non existent attributes should fail')
+ self.assertFalse(hasattr(SomeClass, 'frooble'))
+
+
+ def test_patch_with_static_methods(self):
+ class Foo(object):
+ @staticmethod
+ def woot():
+ return sentinel.Static
+
+ @patch.object(Foo, 'woot', staticmethod(lambda: sentinel.Patched))
+ def anonymous():
+ self.assertEqual(Foo.woot(), sentinel.Patched)
+ anonymous()
+
+ self.assertEqual(Foo.woot(), sentinel.Static)
+
+
+ def test_patch_local(self):
+ foo = sentinel.Foo
+ @patch.object(sentinel, 'Foo', 'Foo')
+ def anonymous():
+ self.assertEqual(sentinel.Foo, 'Foo')
+ anonymous()
+
+ self.assertEqual(sentinel.Foo, foo)
+
+
+ def test_patch_slots(self):
+ class Foo(object):
+ __slots__ = ('Foo',)
+
+ foo = Foo()
+ foo.Foo = sentinel.Foo
+
+ @patch.object(foo, 'Foo', 'Foo')
+ def anonymous():
+ self.assertEqual(foo.Foo, 'Foo')
+ anonymous()
+
+ self.assertEqual(foo.Foo, sentinel.Foo)
+
+
+ def test_patchobject_class_decorator(self):
+ class Something(object):
+ attribute = sentinel.Original
+
+ class Foo(object):
+ def test_method(other_self):
+ self.assertEqual(Something.attribute, sentinel.Patched,
+ "unpatched")
+ def not_test_method(other_self):
+ self.assertEqual(Something.attribute, sentinel.Original,
+ "non-test method patched")
+
+ Foo = patch.object(Something, 'attribute', sentinel.Patched)(Foo)
+
+ f = Foo()
+ f.test_method()
+ f.not_test_method()
+
+ self.assertEqual(Something.attribute, sentinel.Original,
+ "patch not restored")
+
+
+ def test_patch_class_decorator(self):
+ class Something(object):
+ attribute = sentinel.Original
+
+ class Foo(object):
+ def test_method(other_self, mock_something):
+ self.assertEqual(PTModule.something, mock_something,
+ "unpatched")
+ def not_test_method(other_self):
+ self.assertEqual(PTModule.something, sentinel.Something,
+ "non-test method patched")
+ Foo = patch('%s.something' % __name__)(Foo)
+
+ f = Foo()
+ f.test_method()
+ f.not_test_method()
+
+ self.assertEqual(Something.attribute, sentinel.Original,
+ "patch not restored")
+ self.assertEqual(PTModule.something, sentinel.Something,
+ "patch not restored")
+
+
+ def test_patchobject_twice(self):
+ class Something(object):
+ attribute = sentinel.Original
+ next_attribute = sentinel.Original2
+
+ @patch.object(Something, 'attribute', sentinel.Patched)
+ @patch.object(Something, 'attribute', sentinel.Patched)
+ def test():
+ self.assertEqual(Something.attribute, sentinel.Patched, "unpatched")
+
+ test()
+
+ self.assertEqual(Something.attribute, sentinel.Original,
+ "patch not restored")
+
+
+ def test_patch_dict(self):
+ foo = {'initial': object(), 'other': 'something'}
+ original = foo.copy()
+
+ @patch.dict(foo)
+ def test():
+ foo['a'] = 3
+ del foo['initial']
+ foo['other'] = 'something else'
+
+ test()
+
+ self.assertEqual(foo, original)
+
+ @patch.dict(foo, {'a': 'b'})
+ def test():
+ self.assertEqual(len(foo), 3)
+ self.assertEqual(foo['a'], 'b')
+
+ test()
+
+ self.assertEqual(foo, original)
+
+ @patch.dict(foo, [('a', 'b')])
+ def test():
+ self.assertEqual(len(foo), 3)
+ self.assertEqual(foo['a'], 'b')
+
+ test()
+
+ self.assertEqual(foo, original)
+
+
+ def test_patch_dict_with_container_object(self):
+ foo = Container()
+ foo['initial'] = object()
+ foo['other'] = 'something'
+
+ original = foo.values.copy()
+
+ @patch.dict(foo)
+ def test():
+ foo['a'] = 3
+ del foo['initial']
+ foo['other'] = 'something else'
+
+ test()
+
+ self.assertEqual(foo.values, original)
+
+ @patch.dict(foo, {'a': 'b'})
+ def test():
+ self.assertEqual(len(foo.values), 3)
+ self.assertEqual(foo['a'], 'b')
+
+ test()
+
+ self.assertEqual(foo.values, original)
+
+
+ def test_patch_dict_with_clear(self):
+ foo = {'initial': object(), 'other': 'something'}
+ original = foo.copy()
+
+ @patch.dict(foo, clear=True)
+ def test():
+ self.assertEqual(foo, {})
+ foo['a'] = 3
+ foo['other'] = 'something else'
+
+ test()
+
+ self.assertEqual(foo, original)
+
+ @patch.dict(foo, {'a': 'b'}, clear=True)
+ def test():
+ self.assertEqual(foo, {'a': 'b'})
+
+ test()
+
+ self.assertEqual(foo, original)
+
+ @patch.dict(foo, [('a', 'b')], clear=True)
+ def test():
+ self.assertEqual(foo, {'a': 'b'})
+
+ test()
+
+ self.assertEqual(foo, original)
+
+
+ def test_patch_dict_with_container_object_and_clear(self):
+ foo = Container()
+ foo['initial'] = object()
+ foo['other'] = 'something'
+
+ original = foo.values.copy()
+
+ @patch.dict(foo, clear=True)
+ def test():
+ self.assertEqual(foo.values, {})
+ foo['a'] = 3
+ foo['other'] = 'something else'
+
+ test()
+
+ self.assertEqual(foo.values, original)
+
+ @patch.dict(foo, {'a': 'b'}, clear=True)
+ def test():
+ self.assertEqual(foo.values, {'a': 'b'})
+
+ test()
+
+ self.assertEqual(foo.values, original)
+
+
+ def test_name_preserved(self):
+ foo = {}
+
+ @patch('%s.SomeClass' % __name__, object())
+ @patch('%s.SomeClass' % __name__, object(), autospec=True)
+ @patch.object(SomeClass, object())
+ @patch.dict(foo)
+ def some_name():
+ pass
+
+ self.assertEqual(some_name.__name__, 'some_name')
+
+
+ def test_patch_with_exception(self):
+ foo = {}
+
+ @patch.dict(foo, {'a': 'b'})
+ def test():
+ raise NameError('Konrad')
+ try:
+ test()
+ except NameError:
+ pass
+ else:
+ self.fail('NameError not raised by test')
+
+ self.assertEqual(foo, {})
+
+
+ def test_patch_dict_with_string(self):
+ @patch.dict('os.environ', {'konrad_delong': 'some value'})
+ def test():
+ self.assertIn('konrad_delong', os.environ)
+
+ test()
+
+
+ @unittest2.expectedFailure
+ def test_patch_descriptor(self):
+ # would be some effort to fix this - we could special case the
+ # builtin descriptors: classmethod, property, staticmethod
+ class Nothing(object):
+ foo = None
+
+ class Something(object):
+ foo = {}
+
+ @patch.object(Nothing, 'foo', 2)
+ @classmethod
+ def klass(cls):
+ self.assertIs(cls, Something)
+
+ @patch.object(Nothing, 'foo', 2)
+ @staticmethod
+ def static(arg):
+ return arg
+
+ @patch.dict(foo)
+ @classmethod
+ def klass_dict(cls):
+ self.assertIs(cls, Something)
+
+ @patch.dict(foo)
+ @staticmethod
+ def static_dict(arg):
+ return arg
+
+ # these will raise exceptions if patching descriptors is broken
+ self.assertEqual(Something.static('f00'), 'f00')
+ Something.klass()
+ self.assertEqual(Something.static_dict('f00'), 'f00')
+ Something.klass_dict()
+
+ something = Something()
+ self.assertEqual(something.static('f00'), 'f00')
+ something.klass()
+ self.assertEqual(something.static_dict('f00'), 'f00')
+ something.klass_dict()
+
+
+ def test_patch_spec_set(self):
+ @patch('%s.SomeClass' % __name__, spec_set=SomeClass)
+ def test(MockClass):
+ MockClass.z = 'foo'
+
+ self.assertRaises(AttributeError, test)
+
+ @patch.object(support, 'SomeClass', spec_set=SomeClass)
+ def test(MockClass):
+ MockClass.z = 'foo'
+
+ self.assertRaises(AttributeError, test)
+ @patch('%s.SomeClass' % __name__, spec_set=True)
+ def test(MockClass):
+ MockClass.z = 'foo'
+
+ self.assertRaises(AttributeError, test)
+
+ @patch.object(support, 'SomeClass', spec_set=True)
+ def test(MockClass):
+ MockClass.z = 'foo'
+
+ self.assertRaises(AttributeError, test)
+
+
+ def test_spec_set_inherit(self):
+ @patch('%s.SomeClass' % __name__, spec_set=True)
+ def test(MockClass):
+ instance = MockClass()
+ instance.z = 'foo'
+
+ self.assertRaises(AttributeError, test)
+
+
+ def test_patch_start_stop(self):
+ original = something
+ patcher = patch('%s.something' % __name__)
+ self.assertIs(something, original)
+ mock = patcher.start()
+ try:
+ self.assertIsNot(mock, original)
+ self.assertIs(something, mock)
+ finally:
+ patcher.stop()
+ self.assertIs(something, original)
+
+
+ def test_stop_without_start(self):
+ patcher = patch(foo_name, 'bar', 3)
+
+ # calling stop without start used to produce a very obscure error
+ self.assertRaises(RuntimeError, patcher.stop)
+
+
+ def test_patchobject_start_stop(self):
+ original = something
+ patcher = patch.object(PTModule, 'something', 'foo')
+ self.assertIs(something, original)
+ replaced = patcher.start()
+ try:
+ self.assertEqual(replaced, 'foo')
+ self.assertIs(something, replaced)
+ finally:
+ patcher.stop()
+ self.assertIs(something, original)
+
+
+ def test_patch_dict_start_stop(self):
+ d = {'foo': 'bar'}
+ original = d.copy()
+ patcher = patch.dict(d, [('spam', 'eggs')], clear=True)
+ self.assertEqual(d, original)
+
+ patcher.start()
+ try:
+ self.assertEqual(d, {'spam': 'eggs'})
+ finally:
+ patcher.stop()
+ self.assertEqual(d, original)
+
+
+ def test_patch_dict_class_decorator(self):
+ this = self
+ d = {'spam': 'eggs'}
+ original = d.copy()
+
+ class Test(object):
+ def test_first(self):
+ this.assertEqual(d, {'foo': 'bar'})
+ def test_second(self):
+ this.assertEqual(d, {'foo': 'bar'})
+
+ Test = patch.dict(d, {'foo': 'bar'}, clear=True)(Test)
+ self.assertEqual(d, original)
+
+ test = Test()
+
+ test.test_first()
+ self.assertEqual(d, original)
+
+ test.test_second()
+ self.assertEqual(d, original)
+
+ test = Test()
+
+ test.test_first()
+ self.assertEqual(d, original)
+
+ test.test_second()
+ self.assertEqual(d, original)
+
+
+ def test_get_only_proxy(self):
+ class Something(object):
+ foo = 'foo'
+ class SomethingElse:
+ foo = 'foo'
+
+ for thing in Something, SomethingElse, Something(), SomethingElse:
+ proxy = _get_proxy(thing)
+
+ @patch.object(proxy, 'foo', 'bar')
+ def test():
+ self.assertEqual(proxy.foo, 'bar')
+ test()
+ self.assertEqual(proxy.foo, 'foo')
+ self.assertEqual(thing.foo, 'foo')
+ self.assertNotIn('foo', proxy.__dict__)
+
+
+ def test_get_set_delete_proxy(self):
+ class Something(object):
+ foo = 'foo'
+ class SomethingElse:
+ foo = 'foo'
+
+ for thing in Something, SomethingElse, Something(), SomethingElse:
+ proxy = _get_proxy(Something, get_only=False)
+
+ @patch.object(proxy, 'foo', 'bar')
+ def test():
+ self.assertEqual(proxy.foo, 'bar')
+ test()
+ self.assertEqual(proxy.foo, 'foo')
+ self.assertEqual(thing.foo, 'foo')
+ self.assertNotIn('foo', proxy.__dict__)
+
+
+ def test_patch_keyword_args(self):
+ kwargs = {'side_effect': KeyError, 'foo.bar.return_value': 33,
+ 'foo': MagicMock()}
+
+ patcher = patch(foo_name, **kwargs)
+ mock = patcher.start()
+ patcher.stop()
+
+ self.assertRaises(KeyError, mock)
+ self.assertEqual(mock.foo.bar(), 33)
+ self.assertIsInstance(mock.foo, MagicMock)
+
+
+ def test_patch_object_keyword_args(self):
+ kwargs = {'side_effect': KeyError, 'foo.bar.return_value': 33,
+ 'foo': MagicMock()}
+
+ patcher = patch.object(Foo, 'f', **kwargs)
+ mock = patcher.start()
+ patcher.stop()
+
+ self.assertRaises(KeyError, mock)
+ self.assertEqual(mock.foo.bar(), 33)
+ self.assertIsInstance(mock.foo, MagicMock)
+
+
+ def test_patch_dict_keyword_args(self):
+ original = {'foo': 'bar'}
+ copy = original.copy()
+
+ patcher = patch.dict(original, foo=3, bar=4, baz=5)
+ patcher.start()
+
+ try:
+ self.assertEqual(original, dict(foo=3, bar=4, baz=5))
+ finally:
+ patcher.stop()
+
+ self.assertEqual(original, copy)
+
+
+ def test_autospec(self):
+ class Boo(object):
+ def __init__(self, a):
+ pass
+ def f(self, a):
+ pass
+ def g(self):
+ pass
+ foo = 'bar'
+
+ class Bar(object):
+ def a(self):
+ pass
+
+ def _test(mock):
+ mock(1)
+ mock.assert_called_with(1)
+ self.assertRaises(TypeError, mock)
+
+ def _test2(mock):
+ mock.f(1)
+ mock.f.assert_called_with(1)
+ self.assertRaises(TypeError, mock.f)
+
+ mock.g()
+ mock.g.assert_called_with()
+ self.assertRaises(TypeError, mock.g, 1)
+
+ self.assertRaises(AttributeError, getattr, mock, 'h')
+
+ mock.foo.lower()
+ mock.foo.lower.assert_called_with()
+ self.assertRaises(AttributeError, getattr, mock.foo, 'bar')
+
+ mock.Bar()
+ mock.Bar.assert_called_with()
+
+ mock.Bar.a()
+ mock.Bar.a.assert_called_with()
+ self.assertRaises(TypeError, mock.Bar.a, 1)
+
+ mock.Bar().a()
+ mock.Bar().a.assert_called_with()
+ self.assertRaises(TypeError, mock.Bar().a, 1)
+
+ self.assertRaises(AttributeError, getattr, mock.Bar, 'b')
+ self.assertRaises(AttributeError, getattr, mock.Bar(), 'b')
+
+ def function(mock):
+ _test(mock)
+ _test2(mock)
+ _test2(mock(1))
+ self.assertIs(mock, Foo)
+ return mock
+
+ test = patch(foo_name, autospec=True)(function)
+
+ mock = test()
+ self.assertIsNot(Foo, mock)
+ # test patching a second time works
+ test()
+
+ module = sys.modules[__name__]
+ test = patch.object(module, 'Foo', autospec=True)(function)
+
+ mock = test()
+ self.assertIsNot(Foo, mock)
+ # test patching a second time works
+ test()
+
+
+ def test_autospec_function(self):
+ @patch('%s.function' % __name__, autospec=True)
+ def test(mock):
+ function(1)
+ function.assert_called_with(1)
+ function(2, 3)
+ function.assert_called_with(2, 3)
+
+ self.assertRaises(TypeError, function)
+ self.assertRaises(AttributeError, getattr, function, 'foo')
+
+ test()
+
+
+ def test_autospec_keywords(self):
+ @patch('%s.function' % __name__, autospec=True,
+ return_value=3)
+ def test(mock_function):
+ #self.assertEqual(function.abc, 'foo')
+ return function(1, 2)
+
+ result = test()
+ self.assertEqual(result, 3)
+
+
+ def test_autospec_with_new(self):
+ patcher = patch('%s.function' % __name__, new=3, autospec=True)
+ self.assertRaises(TypeError, patcher.start)
+
+ module = sys.modules[__name__]
+ patcher = patch.object(module, 'function', new=3, autospec=True)
+ self.assertRaises(TypeError, patcher.start)
+
+
+ def test_autospec_with_object(self):
+ class Bar(Foo):
+ extra = []
+
+ patcher = patch(foo_name, autospec=Bar)
+ mock = patcher.start()
+ try:
+ self.assertIsInstance(mock, Bar)
+ self.assertIsInstance(mock.extra, list)
+ finally:
+ patcher.stop()
+
+
+ def test_autospec_inherits(self):
+ FooClass = Foo
+ patcher = patch(foo_name, autospec=True)
+ mock = patcher.start()
+ try:
+ self.assertIsInstance(mock, FooClass)
+ self.assertIsInstance(mock(3), FooClass)
+ finally:
+ patcher.stop()
+
+
+ def test_autospec_name(self):
+ patcher = patch(foo_name, autospec=True)
+ mock = patcher.start()
+
+ try:
+ self.assertIn(" name='Foo'", repr(mock))
+ self.assertIn(" name='Foo.f'", repr(mock.f))
+ self.assertIn(" name='Foo()'", repr(mock(None)))
+ self.assertIn(" name='Foo().f'", repr(mock(None).f))
+ finally:
+ patcher.stop()
+
+
+ def test_tracebacks(self):
+ @patch.object(Foo, 'f', object())
+ def test():
+ raise AssertionError
+ try:
+ test()
+ except:
+ err = sys.exc_info()
+
+ result = unittest2.TextTestResult(None, None, 0)
+ traceback = result._exc_info_to_string(err, self)
+ self.assertIn('raise AssertionError', traceback)
+
+
+ def test_new_callable_patch(self):
+ patcher = patch(foo_name, new_callable=NonCallableMagicMock)
+
+ m1 = patcher.start()
+ patcher.stop()
+ m2 = patcher.start()
+ patcher.stop()
+
+ self.assertIsNot(m1, m2)
+ for mock in m1, m2:
+ self.assertNotCallable(m1)
+
+
+ def test_new_callable_patch_object(self):
+ patcher = patch.object(Foo, 'f', new_callable=NonCallableMagicMock)
+
+ m1 = patcher.start()
+ patcher.stop()
+ m2 = patcher.start()
+ patcher.stop()
+
+ self.assertIsNot(m1, m2)
+ for mock in m1, m2:
+ self.assertNotCallable(m1)
+
+
+ def test_new_callable_keyword_arguments(self):
+ class Bar(object):
+ kwargs = None
+ def __init__(self, **kwargs):
+ Bar.kwargs = kwargs
+
+ patcher = patch(foo_name, new_callable=Bar, arg1=1, arg2=2)
+ m = patcher.start()
+ try:
+ self.assertIs(type(m), Bar)
+ self.assertEqual(Bar.kwargs, dict(arg1=1, arg2=2))
+ finally:
+ patcher.stop()
+
+
+ def test_new_callable_spec(self):
+ class Bar(object):
+ kwargs = None
+ def __init__(self, **kwargs):
+ Bar.kwargs = kwargs
+
+ patcher = patch(foo_name, new_callable=Bar, spec=Bar)
+ patcher.start()
+ try:
+ self.assertEqual(Bar.kwargs, dict(spec=Bar))
+ finally:
+ patcher.stop()
+
+ patcher = patch(foo_name, new_callable=Bar, spec_set=Bar)
+ patcher.start()
+ try:
+ self.assertEqual(Bar.kwargs, dict(spec_set=Bar))
+ finally:
+ patcher.stop()
+
+
+ def test_new_callable_create(self):
+ non_existent_attr = '%s.weeeee' % foo_name
+ p = patch(non_existent_attr, new_callable=NonCallableMock)
+ self.assertRaises(AttributeError, p.start)
+
+ p = patch(non_existent_attr, new_callable=NonCallableMock,
+ create=True)
+ m = p.start()
+ try:
+ self.assertNotCallable(m, magic=False)
+ finally:
+ p.stop()
+
+
+ def test_new_callable_incompatible_with_new(self):
+ self.assertRaises(
+ ValueError, patch, foo_name, new=object(), new_callable=MagicMock
+ )
+ self.assertRaises(
+ ValueError, patch.object, Foo, 'f', new=object(),
+ new_callable=MagicMock
+ )
+
+
+ def test_new_callable_incompatible_with_autospec(self):
+ self.assertRaises(
+ ValueError, patch, foo_name, new_callable=MagicMock,
+ autospec=True
+ )
+ self.assertRaises(
+ ValueError, patch.object, Foo, 'f', new_callable=MagicMock,
+ autospec=True
+ )
+
+
+ def test_new_callable_inherit_for_mocks(self):
+ class MockSub(Mock):
+ pass
+
+ MockClasses = (
+ NonCallableMock, NonCallableMagicMock, MagicMock, Mock, MockSub
+ )
+ for Klass in MockClasses:
+ for arg in 'spec', 'spec_set':
+ kwargs = {arg: True}
+ p = patch(foo_name, new_callable=Klass, **kwargs)
+ m = p.start()
+ try:
+ instance = m.return_value
+ self.assertRaises(AttributeError, getattr, instance, 'x')
+ finally:
+ p.stop()
+
+
+ def test_new_callable_inherit_non_mock(self):
+ class NotAMock(object):
+ def __init__(self, spec):
+ self.spec = spec
+
+ p = patch(foo_name, new_callable=NotAMock, spec=True)
+ m = p.start()
+ try:
+ self.assertTrue(is_instance(m, NotAMock))
+ self.assertRaises(AttributeError, getattr, m, 'return_value')
+ finally:
+ p.stop()
+
+ self.assertEqual(m.spec, Foo)
+
+
+ def test_new_callable_class_decorating(self):
+ test = self
+ original = Foo
+ class SomeTest(object):
+
+ def _test(self, mock_foo):
+ test.assertIsNot(Foo, original)
+ test.assertIs(Foo, mock_foo)
+ test.assertIsInstance(Foo, SomeClass)
+
+ def test_two(self, mock_foo):
+ self._test(mock_foo)
+ def test_one(self, mock_foo):
+ self._test(mock_foo)
+
+ SomeTest = patch(foo_name, new_callable=SomeClass)(SomeTest)
+ SomeTest().test_one()
+ SomeTest().test_two()
+ self.assertIs(Foo, original)
+
+
+ def test_patch_multiple(self):
+ original_foo = Foo
+ original_f = Foo.f
+ original_g = Foo.g
+
+ patcher1 = patch.multiple(foo_name, f=1, g=2)
+ patcher2 = patch.multiple(Foo, f=1, g=2)
+
+ for patcher in patcher1, patcher2:
+ patcher.start()
+ try:
+ self.assertIs(Foo, original_foo)
+ self.assertEqual(Foo.f, 1)
+ self.assertEqual(Foo.g, 2)
+ finally:
+ patcher.stop()
+
+ self.assertIs(Foo, original_foo)
+ self.assertEqual(Foo.f, original_f)
+ self.assertEqual(Foo.g, original_g)
+
+
+ @patch.multiple(foo_name, f=3, g=4)
+ def test():
+ self.assertIs(Foo, original_foo)
+ self.assertEqual(Foo.f, 3)
+ self.assertEqual(Foo.g, 4)
+
+ test()
+
+
+ def test_patch_multiple_no_kwargs(self):
+ self.assertRaises(ValueError, patch.multiple, foo_name)
+ self.assertRaises(ValueError, patch.multiple, Foo)
+
+
+ def test_patch_multiple_create_mocks(self):
+ original_foo = Foo
+ original_f = Foo.f
+ original_g = Foo.g
+
+ @patch.multiple(foo_name, f=DEFAULT, g=3, foo=DEFAULT)
+ def test(f, foo):
+ self.assertIs(Foo, original_foo)
+ self.assertIs(Foo.f, f)
+ self.assertEqual(Foo.g, 3)
+ self.assertIs(Foo.foo, foo)
+ self.assertTrue(is_instance(f, MagicMock))
+ self.assertTrue(is_instance(foo, MagicMock))
+
+ test()
+ self.assertEqual(Foo.f, original_f)
+ self.assertEqual(Foo.g, original_g)
+
+
+ def test_patch_multiple_create_mocks_different_order(self):
+ # bug revealed by Jython!
+ original_f = Foo.f
+ original_g = Foo.g
+
+ patcher = patch.object(Foo, 'f', 3)
+ patcher.attribute_name = 'f'
+
+ other = patch.object(Foo, 'g', DEFAULT)
+ other.attribute_name = 'g'
+ patcher.additional_patchers = [other]
+
+ @patcher
+ def test(g):
+ self.assertIs(Foo.g, g)
+ self.assertEqual(Foo.f, 3)
+
+ test()
+ self.assertEqual(Foo.f, original_f)
+ self.assertEqual(Foo.g, original_g)
+
+
+ def test_patch_multiple_stacked_decorators(self):
+ original_foo = Foo
+ original_f = Foo.f
+ original_g = Foo.g
+
+ @patch.multiple(foo_name, f=DEFAULT)
+ @patch.multiple(foo_name, foo=DEFAULT)
+ @patch(foo_name + '.g')
+ def test1(g, **kwargs):
+ _test(g, **kwargs)
+
+ @patch.multiple(foo_name, f=DEFAULT)
+ @patch(foo_name + '.g')
+ @patch.multiple(foo_name, foo=DEFAULT)
+ def test2(g, **kwargs):
+ _test(g, **kwargs)
+
+ @patch(foo_name + '.g')
+ @patch.multiple(foo_name, f=DEFAULT)
+ @patch.multiple(foo_name, foo=DEFAULT)
+ def test3(g, **kwargs):
+ _test(g, **kwargs)
+
+ def _test(g, **kwargs):
+ f = kwargs.pop('f')
+ foo = kwargs.pop('foo')
+ self.assertFalse(kwargs)
+
+ self.assertIs(Foo, original_foo)
+ self.assertIs(Foo.f, f)
+ self.assertIs(Foo.g, g)
+ self.assertIs(Foo.foo, foo)
+ self.assertTrue(is_instance(f, MagicMock))
+ self.assertTrue(is_instance(g, MagicMock))
+ self.assertTrue(is_instance(foo, MagicMock))
+
+ test1()
+ test2()
+ test3()
+ self.assertEqual(Foo.f, original_f)
+ self.assertEqual(Foo.g, original_g)
+
+
+ def test_patch_multiple_create_mocks_patcher(self):
+ original_foo = Foo
+ original_f = Foo.f
+ original_g = Foo.g
+
+ patcher = patch.multiple(foo_name, f=DEFAULT, g=3, foo=DEFAULT)
+
+ result = patcher.start()
+ try:
+ f = result['f']
+ foo = result['foo']
+ self.assertEqual(set(result), set(['f', 'foo']))
+
+ self.assertIs(Foo, original_foo)
+ self.assertIs(Foo.f, f)
+ self.assertIs(Foo.foo, foo)
+ self.assertTrue(is_instance(f, MagicMock))
+ self.assertTrue(is_instance(foo, MagicMock))
+ finally:
+ patcher.stop()
+
+ self.assertEqual(Foo.f, original_f)
+ self.assertEqual(Foo.g, original_g)
+
+
+ def test_patch_multiple_decorating_class(self):
+ test = self
+ original_foo = Foo
+ original_f = Foo.f
+ original_g = Foo.g
+
+ class SomeTest(object):
+
+ def _test(self, f, foo):
+ test.assertIs(Foo, original_foo)
+ test.assertIs(Foo.f, f)
+ test.assertEqual(Foo.g, 3)
+ test.assertIs(Foo.foo, foo)
+ test.assertTrue(is_instance(f, MagicMock))
+ test.assertTrue(is_instance(foo, MagicMock))
+
+ def test_two(self, f, foo):
+ self._test(f, foo)
+ def test_one(self, f, foo):
+ self._test(f, foo)
+
+ SomeTest = patch.multiple(
+ foo_name, f=DEFAULT, g=3, foo=DEFAULT
+ )(SomeTest)
+
+ thing = SomeTest()
+ thing.test_one()
+ thing.test_two()
+
+ self.assertEqual(Foo.f, original_f)
+ self.assertEqual(Foo.g, original_g)
+
+
+ def test_patch_multiple_create(self):
+ patcher = patch.multiple(Foo, blam='blam')
+ self.assertRaises(AttributeError, patcher.start)
+
+ patcher = patch.multiple(Foo, blam='blam', create=True)
+ patcher.start()
+ try:
+ self.assertEqual(Foo.blam, 'blam')
+ finally:
+ patcher.stop()
+
+ self.assertFalse(hasattr(Foo, 'blam'))
+
+
+ def test_patch_multiple_spec_set(self):
+ # if spec_set works then we can assume that spec and autospec also
+ # work as the underlying machinery is the same
+ patcher = patch.multiple(Foo, foo=DEFAULT, spec_set=['a', 'b'])
+ result = patcher.start()
+ try:
+ self.assertEqual(Foo.foo, result['foo'])
+ Foo.foo.a(1)
+ Foo.foo.b(2)
+ Foo.foo.a.assert_called_with(1)
+ Foo.foo.b.assert_called_with(2)
+ self.assertRaises(AttributeError, setattr, Foo.foo, 'c', None)
+ finally:
+ patcher.stop()
+
+
+ def test_patch_multiple_new_callable(self):
+ class Thing(object):
+ pass
+
+ patcher = patch.multiple(
+ Foo, f=DEFAULT, g=DEFAULT, new_callable=Thing
+ )
+ result = patcher.start()
+ try:
+ self.assertIs(Foo.f, result['f'])
+ self.assertIs(Foo.g, result['g'])
+ self.assertIsInstance(Foo.f, Thing)
+ self.assertIsInstance(Foo.g, Thing)
+ self.assertIsNot(Foo.f, Foo.g)
+ finally:
+ patcher.stop()
+
+
+ def test_nested_patch_failure(self):
+ original_f = Foo.f
+ original_g = Foo.g
+
+ @patch.object(Foo, 'g', 1)
+ @patch.object(Foo, 'missing', 1)
+ @patch.object(Foo, 'f', 1)
+ def thing1():
+ pass
+
+ @patch.object(Foo, 'missing', 1)
+ @patch.object(Foo, 'g', 1)
+ @patch.object(Foo, 'f', 1)
+ def thing2():
+ pass
+
+ @patch.object(Foo, 'g', 1)
+ @patch.object(Foo, 'f', 1)
+ @patch.object(Foo, 'missing', 1)
+ def thing3():
+ pass
+
+ for func in thing1, thing2, thing3:
+ self.assertRaises(AttributeError, func)
+ self.assertEqual(Foo.f, original_f)
+ self.assertEqual(Foo.g, original_g)
+
+
+ def test_new_callable_failure(self):
+ original_f = Foo.f
+ original_g = Foo.g
+ original_foo = Foo.foo
+
+ def crasher():
+ raise NameError('crasher')
+
+ @patch.object(Foo, 'g', 1)
+ @patch.object(Foo, 'foo', new_callable=crasher)
+ @patch.object(Foo, 'f', 1)
+ def thing1():
+ pass
+
+ @patch.object(Foo, 'foo', new_callable=crasher)
+ @patch.object(Foo, 'g', 1)
+ @patch.object(Foo, 'f', 1)
+ def thing2():
+ pass
+
+ @patch.object(Foo, 'g', 1)
+ @patch.object(Foo, 'f', 1)
+ @patch.object(Foo, 'foo', new_callable=crasher)
+ def thing3():
+ pass
+
+ for func in thing1, thing2, thing3:
+ self.assertRaises(NameError, func)
+ self.assertEqual(Foo.f, original_f)
+ self.assertEqual(Foo.g, original_g)
+ self.assertEqual(Foo.foo, original_foo)
+
+
+ def test_patch_multiple_failure(self):
+ original_f = Foo.f
+ original_g = Foo.g
+
+ patcher = patch.object(Foo, 'f', 1)
+ patcher.attribute_name = 'f'
+
+ good = patch.object(Foo, 'g', 1)
+ good.attribute_name = 'g'
+
+ bad = patch.object(Foo, 'missing', 1)
+ bad.attribute_name = 'missing'
+
+ for additionals in [good, bad], [bad, good]:
+ patcher.additional_patchers = additionals
+
+ @patcher
+ def func():
+ pass
+
+ self.assertRaises(AttributeError, func)
+ self.assertEqual(Foo.f, original_f)
+ self.assertEqual(Foo.g, original_g)
+
+
+ def test_patch_multiple_new_callable_failure(self):
+ original_f = Foo.f
+ original_g = Foo.g
+ original_foo = Foo.foo
+
+ def crasher():
+ raise NameError('crasher')
+
+ patcher = patch.object(Foo, 'f', 1)
+ patcher.attribute_name = 'f'
+
+ good = patch.object(Foo, 'g', 1)
+ good.attribute_name = 'g'
+
+ bad = patch.object(Foo, 'foo', new_callable=crasher)
+ bad.attribute_name = 'foo'
+
+ for additionals in [good, bad], [bad, good]:
+ patcher.additional_patchers = additionals
+
+ @patcher
+ def func():
+ pass
+
+ self.assertRaises(NameError, func)
+ self.assertEqual(Foo.f, original_f)
+ self.assertEqual(Foo.g, original_g)
+ self.assertEqual(Foo.foo, original_foo)
+
+
+ def test_patch_multiple_string_subclasses(self):
+ for base in (str, unicode):
+ Foo = type('Foo', (base,), {'fish': 'tasty'})
+ foo = Foo()
+ @patch.multiple(foo, fish='nearly gone')
+ def test():
+ self.assertEqual(foo.fish, 'nearly gone')
+
+ test()
+ self.assertEqual(foo.fish, 'tasty')
+
+
+ @patch('mock.patch.TEST_PREFIX', 'foo')
+ def test_patch_test_prefix(self):
+ class Foo(object):
+ thing = 'original'
+
+ def foo_one(self):
+ return self.thing
+ def foo_two(self):
+ return self.thing
+ def test_one(self):
+ return self.thing
+ def test_two(self):
+ return self.thing
+
+ Foo = patch.object(Foo, 'thing', 'changed')(Foo)
+
+ foo = Foo()
+ self.assertEqual(foo.foo_one(), 'changed')
+ self.assertEqual(foo.foo_two(), 'changed')
+ self.assertEqual(foo.test_one(), 'original')
+ self.assertEqual(foo.test_two(), 'original')
+
+
+ @patch('mock.patch.TEST_PREFIX', 'bar')
+ def test_patch_dict_test_prefix(self):
+ class Foo(object):
+ def bar_one(self):
+ return dict(the_dict)
+ def bar_two(self):
+ return dict(the_dict)
+ def test_one(self):
+ return dict(the_dict)
+ def test_two(self):
+ return dict(the_dict)
+
+ the_dict = {'key': 'original'}
+ Foo = patch.dict(the_dict, key='changed')(Foo)
+
+ foo =Foo()
+ self.assertEqual(foo.bar_one(), {'key': 'changed'})
+ self.assertEqual(foo.bar_two(), {'key': 'changed'})
+ self.assertEqual(foo.test_one(), {'key': 'original'})
+ self.assertEqual(foo.test_two(), {'key': 'original'})
+
+
+ def test_patch_with_spec_mock_repr(self):
+ for arg in ('spec', 'autospec', 'spec_set'):
+ p = patch('%s.SomeClass' % __name__, **{arg: True})
+ m = p.start()
+ try:
+ self.assertIn(" name='SomeClass'", repr(m))
+ self.assertIn(" name='SomeClass.class_attribute'",
+ repr(m.class_attribute))
+ self.assertIn(" name='SomeClass()'", repr(m()))
+ self.assertIn(" name='SomeClass().class_attribute'",
+ repr(m().class_attribute))
+ finally:
+ p.stop()
+
+
+ def test_patch_nested_autospec_repr(self):
+ p = patch('tests.support', autospec=True)
+ m = p.start()
+ try:
+ self.assertIn(" name='support.SomeClass.wibble()'",
+ repr(m.SomeClass.wibble()))
+ self.assertIn(" name='support.SomeClass().wibble()'",
+ repr(m.SomeClass().wibble()))
+ finally:
+ p.stop()
+
+
+ def test_mock_calls_with_patch(self):
+ for arg in ('spec', 'autospec', 'spec_set'):
+ p = patch('%s.SomeClass' % __name__, **{arg: True})
+ m = p.start()
+ try:
+ m.wibble()
+
+ kalls = [call.wibble()]
+ self.assertEqual(m.mock_calls, kalls)
+ self.assertEqual(m.method_calls, kalls)
+ self.assertEqual(m.wibble.mock_calls, [call()])
+
+ result = m()
+ kalls.append(call())
+ self.assertEqual(m.mock_calls, kalls)
+
+ result.wibble()
+ kalls.append(call().wibble())
+ self.assertEqual(m.mock_calls, kalls)
+
+ self.assertEqual(result.mock_calls, [call.wibble()])
+ self.assertEqual(result.wibble.mock_calls, [call()])
+ self.assertEqual(result.method_calls, [call.wibble()])
+ finally:
+ p.stop()
+
+
+ def test_patch_imports_lazily(self):
+ sys.modules.pop('squizz', None)
+
+ p1 = patch('squizz.squozz')
+ self.assertRaises(ImportError, p1.start)
+
+ squizz = Mock()
+ squizz.squozz = 6
+ sys.modules['squizz'] = squizz
+ p1 = patch('squizz.squozz')
+ squizz.squozz = 3
+ p1.start()
+ p1.stop()
+ self.assertEqual(squizz.squozz, 3)
+
+
+ def test_patch_propogrates_exc_on_exit(self):
+ class holder:
+ exc_info = None, None, None
+
+ class custom_patch(_patch):
+ def __exit__(self, etype=None, val=None, tb=None):
+ _patch.__exit__(self, etype, val, tb)
+ holder.exc_info = etype, val, tb
+ stop = __exit__
+
+ def with_custom_patch(target):
+ getter, attribute = _get_target(target)
+ return custom_patch(
+ getter, attribute, DEFAULT, None, False, None,
+ None, None, {}
+ )
+
+ @with_custom_patch('squizz.squozz')
+ def test(mock):
+ raise RuntimeError
+
+ self.assertRaises(RuntimeError, test)
+ self.assertIs(holder.exc_info[0], RuntimeError)
+ self.assertIsNotNone(holder.exc_info[1],
+ 'exception value not propgated')
+ self.assertIsNotNone(holder.exc_info[2],
+ 'exception traceback not propgated')
+
+
+ def test_create_and_specs(self):
+ for kwarg in ('spec', 'spec_set', 'autospec'):
+ p = patch('%s.doesnotexist' % __name__, create=True,
+ **{kwarg: True})
+ self.assertRaises(TypeError, p.start)
+ self.assertRaises(NameError, lambda: doesnotexist)
+
+ # check that spec with create is innocuous if the original exists
+ p = patch(MODNAME, create=True, **{kwarg: True})
+ p.start()
+ p.stop()
+
+
+ def test_multiple_specs(self):
+ original = PTModule
+ for kwarg in ('spec', 'spec_set'):
+ p = patch(MODNAME, autospec=0, **{kwarg: 0})
+ self.assertRaises(TypeError, p.start)
+ self.assertIs(PTModule, original)
+
+ for kwarg in ('spec', 'autospec'):
+ p = patch(MODNAME, spec_set=0, **{kwarg: 0})
+ self.assertRaises(TypeError, p.start)
+ self.assertIs(PTModule, original)
+
+ for kwarg in ('spec_set', 'autospec'):
+ p = patch(MODNAME, spec=0, **{kwarg: 0})
+ self.assertRaises(TypeError, p.start)
+ self.assertIs(PTModule, original)
+
+
+ def test_specs_false_instead_of_none(self):
+ p = patch(MODNAME, spec=False, spec_set=False, autospec=False)
+ mock = p.start()
+ try:
+ # no spec should have been set, so attribute access should not fail
+ mock.does_not_exist
+ mock.does_not_exist = 3
+ finally:
+ p.stop()
+
+
+ def test_falsey_spec(self):
+ for kwarg in ('spec', 'autospec', 'spec_set'):
+ p = patch(MODNAME, **{kwarg: 0})
+ m = p.start()
+ try:
+ self.assertRaises(AttributeError, getattr, m, 'doesnotexit')
+ finally:
+ p.stop()
+
+
+ def test_spec_set_true(self):
+ for kwarg in ('spec', 'autospec'):
+ p = patch(MODNAME, spec_set=True, **{kwarg: True})
+ m = p.start()
+ try:
+ self.assertRaises(AttributeError, setattr, m,
+ 'doesnotexist', 'something')
+ self.assertRaises(AttributeError, getattr, m, 'doesnotexist')
+ finally:
+ p.stop()
+
+
+ def test_callable_spec_as_list(self):
+ spec = ('__call__',)
+ p = patch(MODNAME, spec=spec)
+ m = p.start()
+ try:
+ self.assertTrue(callable(m))
+ finally:
+ p.stop()
+
+
+ def test_not_callable_spec_as_list(self):
+ spec = ('foo', 'bar')
+ p = patch(MODNAME, spec=spec)
+ m = p.start()
+ try:
+ self.assertFalse(callable(m))
+ finally:
+ p.stop()
+
+
+ def test_patch_stopall(self):
+ unlink = os.unlink
+ chdir = os.chdir
+ path = os.path
+ patch('os.unlink', something).start()
+ patch('os.chdir', something_else).start()
+
+ @patch('os.path')
+ def patched(mock_path):
+ patch.stopall()
+ self.assertIs(os.path, mock_path)
+ self.assertIs(os.unlink, unlink)
+ self.assertIs(os.chdir, chdir)
+
+ patched()
+ self.assertIs(os.path, path)
+
+
+ def test_wrapped_patch(self):
+ decorated = patch('sys.modules')(function)
+ self.assertIs(decorated.__wrapped__, function)
+
+
+ def test_wrapped_several_times_patch(self):
+ decorated = patch('sys.modules')(function)
+ decorated = patch('sys.modules')(decorated)
+ self.assertIs(decorated.__wrapped__, function)
+
+
+ def test_wrapped_patch_object(self):
+ decorated = patch.object(sys, 'modules')(function)
+ self.assertIs(decorated.__wrapped__, function)
+
+
+ def test_wrapped_patch_dict(self):
+ decorated = patch.dict('sys.modules')(function)
+ self.assertIs(decorated.__wrapped__, function)
+
+
+ def test_wrapped_patch_multiple(self):
+ decorated = patch.multiple('sys', modules={})(function)
+ self.assertIs(decorated.__wrapped__, function)
+
+
+if __name__ == '__main__':
+ unittest2.main()
Added: incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tests/testsentinel.py
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tests/testsentinel.py?rev=1442010&view=auto
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tests/testsentinel.py (added)
+++ incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tests/testsentinel.py Mon Feb 4 02:23:55 2013
@@ -0,0 +1,33 @@
+# Copyright (C) 2007-2012 Michael Foord & the mock team
+# E-mail: fuzzyman AT voidspace DOT org DOT uk
+# http://www.voidspace.org.uk/python/mock/
+
+from tests.support import unittest2
+
+from mock import sentinel, DEFAULT
+
+
+class SentinelTest(unittest2.TestCase):
+
+ def testSentinels(self):
+ self.assertEqual(sentinel.whatever, sentinel.whatever,
+ 'sentinel not stored')
+ self.assertNotEqual(sentinel.whatever, sentinel.whateverelse,
+ 'sentinel should be unique')
+
+
+ def testSentinelName(self):
+ self.assertEqual(str(sentinel.whatever), 'sentinel.whatever',
+ 'sentinel name incorrect')
+
+
+ def testDEFAULT(self):
+ self.assertTrue(DEFAULT is sentinel.DEFAULT)
+
+ def testBases(self):
+ # If this doesn't raise an AttributeError then help(mock) is broken
+ self.assertRaises(AttributeError, lambda: sentinel.__bases__)
+
+
+if __name__ == '__main__':
+ unittest2.main()
Added: incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tests/testwith.py
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tests/testwith.py?rev=1442010&view=auto
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tests/testwith.py (added)
+++ incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tests/testwith.py Mon Feb 4 02:23:55 2013
@@ -0,0 +1,16 @@
+import sys
+
+if sys.version_info[:2] >= (2, 5):
+ from tests._testwith import *
+else:
+ from tests.support import unittest2
+
+ class TestWith(unittest2.TestCase):
+
+ @unittest2.skip('tests using with statement skipped on Python 2.4')
+ def testWith(self):
+ pass
+
+
+if __name__ == '__main__':
+ unittest2.main()
Added: incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tox.ini
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tox.ini?rev=1442010&view=auto
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tox.ini (added)
+++ incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/tox.ini Mon Feb 4 02:23:55 2013
@@ -0,0 +1,40 @@
+[tox]
+envlist = py25,py26,py27,py31,pypy,py32,py33,jython
+
+[testenv]
+deps=unittest2
+commands={envbindir}/unit2 discover []
+
+[testenv:py26]
+commands=
+ {envbindir}/unit2 discover []
+ {envbindir}/sphinx-build -E -b doctest docs html
+ {envbindir}/sphinx-build -E docs html
+deps =
+ unittest2
+ sphinx
+
+[testenv:py27]
+commands=
+ {envbindir}/unit2 discover []
+ {envbindir}/sphinx-build -E -b doctest docs html
+deps =
+ unittest2
+ sphinx
+
+[testenv:py31]
+deps =
+ unittest2py3k
+
+[testenv:py32]
+commands=
+ {envbindir}/python -m unittest discover []
+deps =
+
+[testenv:py33]
+commands=
+ {envbindir}/python -m unittest discover []
+deps =
+
+# note for jython. Execute in tests directory:
+# rm `find . -name '*$py.class'`
\ No newline at end of file
Added: incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/unittest.cfg
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/unittest.cfg?rev=1442010&view=auto
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/unittest.cfg (added)
+++ incubator/ambari/branches/branch-1.2/ambari-common/src/test/python/mock/unittest.cfg Mon Feb 4 02:23:55 2013
@@ -0,0 +1,95 @@
+
+[unittest]
+plugins =
+ unittest2.plugins.debugger
+ unittest2.plugins.checker
+ unittest2.plugins.doctestloader
+ unittest2.plugins.matchregexp
+ unittest2.plugins.moduleloading
+ unittest2.plugins.testcoverage
+ unittest2.plugins.growl
+ unittest2.plugins.filtertests
+ unittest2.plugins.junitxml
+ unittest2.plugins.timed
+ unittest2.plugins.counttests
+ unittest2.plugins.logchannels
+
+excluded-plugins =
+
+# 0, 1 or 2 (default is 1)
+# quiet, normal or verbose
+# can be overriden at command line
+verbosity = normal
+
+# true or false
+# even if false can be switched on at command line
+catch =
+buffer =
+failfast =
+
+
+[matchregexp]
+always-on = False
+full-path = True
+
+[debugger]
+always-on = False
+errors-only = True
+
+[coverage]
+always-on = False
+config =
+report-html = False
+# only used if report-html is false
+annotate = False
+# defaults to './htmlcov/'
+html-directory =
+# if unset will output to console
+text-file =
+branch = False
+timid = False
+cover-pylib = False
+exclude-lines =
+ # Have to re-enable the standard pragma
+ pragma: no cover
+
+ # Don't complain about missing debug-only code:
+ def __repr__
+ if self\.debug
+
+ # Don't complain if tests don't hit defensive assertion code:
+ raise AssertionError
+ raise NotImplementedError
+
+ # Don't complain if non-runnable code isn't run:
+ if 0:
+ if __name__ == .__main__.
+
+ignore-errors = False
+modules =
+
+[growl]
+always-on = False
+
+[doctest]
+always-on = False
+
+[module-loading]
+always-on = False
+
+[checker]
+always-on = False
+pep8 = False
+pyflakes = True
+
+[junit-xml]
+always-on = False
+path = junit.xml
+
+[timed]
+always-on = True
+threshold = 0.01
+
+[count]
+always-on = True
+enhanced = False
Modified: incubator/ambari/branches/branch-1.2/ambari-project/pom.xml
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-project/pom.xml?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-project/pom.xml (original)
+++ incubator/ambari/branches/branch-1.2/ambari-project/pom.xml Mon Feb 4 02:23:55 2013
@@ -17,11 +17,11 @@
<parent>
<groupId>org.apache.ambari</groupId>
<artifactId>ambari</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.2.1-SNAPSHOT</version>
</parent>
<groupId>org.apache.ambari</groupId>
<artifactId>ambari-project</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.2.1-SNAPSHOT</version>
<description>Apache Ambari Project POM</description>
<name>Apache Ambari Project POM</name>
<packaging>pom</packaging>
Added: incubator/ambari/branches/branch-1.2/ambari-server/pass.txt
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-server/pass.txt?rev=1442010&view=auto
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-server/pass.txt (added)
+++ incubator/ambari/branches/branch-1.2/ambari-server/pass.txt Mon Feb 4 02:23:55 2013
@@ -0,0 +1 @@
+k0n9LEBvrNOBzCw4drmUBSnCykzL0ZVzt5cZyLXvJtlsQZpUNq
\ No newline at end of file
Modified: incubator/ambari/branches/branch-1.2/ambari-server/pom.xml
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-server/pom.xml?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-server/pom.xml (original)
+++ incubator/ambari/branches/branch-1.2/ambari-server/pom.xml Mon Feb 4 02:23:55 2013
@@ -16,7 +16,7 @@
<parent>
<groupId>org.apache.ambari</groupId>
<artifactId>ambari-project</artifactId>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.2.1-SNAPSHOT</version>
<relativePath>../ambari-project</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
@@ -24,7 +24,7 @@
<artifactId>ambari-server</artifactId>
<packaging>jar</packaging>
<name>Ambari Server</name>
- <version>1.2.0-SNAPSHOT</version>
+ <version>1.2.1-SNAPSHOT</version>
<description>Ambari Server</description>
<properties>
<python.ver>python >= 2.6</python.ver>
@@ -64,6 +64,9 @@
<!--gitignore content-->
<exclude>src/main/resources/db/newcerts/**</exclude>
+
+ <!--test samples-->
+ <exclude>src/test/resources/TestAmbaryServer.samples/**</exclude>
</excludes>
</configuration>
</plugin>
@@ -96,6 +99,9 @@
<require>openssl</require>
<require>${python.ver}</require>
</requires>
+ <preremoveScriptlet>
+ <script>mv /etc/ambari-server/conf /etc/ambari-server/conf.save</script>
+ </preremoveScriptlet>
<mappings>
<mapping>
<directory>/usr/lib/ambari-server</directory>
@@ -227,6 +233,23 @@
</sources>
</mapping>
<mapping>
+ <directory>/var/lib/ambari-server/resources/upgrade</directory>
+ <filemode>755</filemode>
+ <username>root</username>
+ <groupname>root</groupname>
+ </mapping>
+ <mapping>
+ <directory>/var/lib/ambari-server/resources/upgrade/ddl</directory>
+ <filemode>755</filemode>
+ <username>root</username>
+ <groupname>root</groupname>
+ <sources>
+ <source>
+ <location>src/main/resources/upgrade/ddl/Ambari-DDL-Postgres-UPGRADE-1.2.1.sql</location>
+ </source>
+ </sources>
+ </mapping>
+ <mapping>
<directory>/var/lib/ambari-server/resources/stacks</directory>
<filemode>755</filemode>
<username>root</username>
@@ -276,6 +299,31 @@
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>exec-maven-plugin</artifactId>
+ <version>1.2</version>
+ <executions>
+ <execution>
+ <configuration>
+ <executable>python2.6</executable>
+ <workingDirectory>src/test/python</workingDirectory>
+ <arguments>
+ <argument>unitTests.py</argument>
+ </arguments>
+ <environmentVariables>
+ <PYTHONPATH>${project.basedir}/../ambari-common/src/test/python:${project.basedir}/src/main/python:${project.basedir}/src/main/python/ambari-server-state:${project.basedir}/src/test/python:$PYTHONPATH</PYTHONPATH>
+ </environmentVariables>
+ <skip>${skipTests}</skip>
+ </configuration>
+ <id>python-test</id>
+ <phase>test</phase>
+ <goals>
+ <goal>exec</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
</plugins>
</build>
<profiles>
@@ -500,7 +548,7 @@
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
- <version>8.3-603.jdbc4</version>
+ <version>9.1-901.jdbc4</version>
</dependency>
</dependencies>
<!--<reporting>
Modified: incubator/ambari/branches/branch-1.2/ambari-server/sbin/ambari-server
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-server/sbin/ambari-server?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-server/sbin/ambari-server (original)
+++ incubator/ambari/branches/branch-1.2/ambari-server/sbin/ambari-server Mon Feb 4 02:23:55 2013
@@ -73,6 +73,10 @@ case "$1" in
$0 stop
$0 start
;;
+ upgrade)
+ echo -e "Upgrading ambari-server"
+ $PYTHON /usr/sbin/ambari-server.py $@
+ ;;
setup)
echo -e "Run postgresql initdb"
initdb_res=`/sbin/service postgresql initdb`
@@ -85,7 +89,7 @@ case "$1" in
$PYTHON /usr/sbin/ambari-server.py $@
;;
*)
- echo "Usage: /usr/sbin/ambari-server {start|stop|restart|setup} [options]"
+ echo "Usage: /usr/sbin/ambari-server {start|stop|restart|setup|upgrade} [options]"
exit 1
esac
Modified: incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/eventdb/db/PostgresConnector.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/eventdb/db/PostgresConnector.java?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/eventdb/db/PostgresConnector.java (original)
+++ incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/eventdb/db/PostgresConnector.java Mon Feb 4 02:23:55 2013
@@ -245,6 +245,13 @@ public class PostgresConnector implement
DataTable table = new DataTable();
table.setiTotalRecords(total);
table.setiTotalDisplayRecords(summary.getNumRows());
+ if (workflows.isEmpty()) {
+ table.setStartIndex(-1);
+ table.setEndIndex(-1);
+ } else {
+ table.setStartIndex(offset);
+ table.setEndIndex(offset + workflows.size() - 1);
+ }
table.setAaData(workflows);
table.setsEcho(echo);
table.setSummary(summary);
@@ -440,7 +447,7 @@ public class PostgresConnector implement
return field.toString() + " >= " + s;
}
- private static final String WHERE = " where";
+ private static final String WHERE = " where ";
private static String buildSearchClause(String searchTerm, String searchWorkflowId, String searchWorkflowName, String searchWorkflowType,
String searchUserName, int minJobs, int maxJobs, long minInputBytes, long maxInputBytes, long minOutputBytes, long maxOutputBytes, long minDuration,
@@ -448,7 +455,7 @@ public class PostgresConnector implement
StringBuilder sb = new StringBuilder();
sb.append(WHERE);
if (searchTerm != null && searchTerm.length() > 0) {
- sb.append(" (");
+ sb.append("(");
sb.append(like(WorkflowFields.WORKFLOWID, searchTerm));
sb.append(" or ");
sb.append(like(WorkflowFields.WORKFLOWNAME, searchTerm));
Modified: incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/eventdb/model/DataTable.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/eventdb/model/DataTable.java?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/eventdb/model/DataTable.java (original)
+++ incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/eventdb/model/DataTable.java Mon Feb 4 02:23:55 2013
@@ -33,6 +33,8 @@ public class DataTable {
int sEcho;
int iTotalRecords;
int iTotalDisplayRecords;
+ int startIndex;
+ int endIndex;
List<WorkflowDBEntry> aaData;
Summary summary;
@@ -206,6 +208,22 @@ public class DataTable {
this.iTotalDisplayRecords = iTotalDisplayRecords;
}
+ public int getStartIndex() {
+ return startIndex;
+ }
+
+ public void setStartIndex(int startIndex) {
+ this.startIndex = startIndex;
+ }
+
+ public int getEndIndex() {
+ return endIndex;
+ }
+
+ public void setEndIndex(int endIndex) {
+ this.endIndex = endIndex;
+ }
+
public List<WorkflowDBEntry> getAaData() {
return aaData;
}
Modified: incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionManager.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionManager.java?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionManager.java (original)
+++ incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionManager.java Mon Feb 4 02:23:55 2013
@@ -24,6 +24,7 @@ import java.util.concurrent.atomic.Atomi
import org.apache.ambari.server.agent.ActionQueue;
import org.apache.ambari.server.agent.CommandReport;
+import org.apache.ambari.server.controller.HostsMap;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.utils.StageUtils;
import org.slf4j.Logger;
@@ -42,17 +43,19 @@ public class ActionManager {
private final ActionScheduler scheduler;
private final ActionDBAccessor db;
private final ActionQueue actionQueue;
+ private final HostsMap hostsMap;
private static Logger LOG = LoggerFactory.getLogger(ActionManager.class);
private final AtomicLong requestCounter;
@Inject
public ActionManager(@Named("schedulerSleeptime") long schedulerSleepTime,
@Named("actionTimeout") long actionTimeout,
- ActionQueue aq, Clusters fsm, ActionDBAccessor db) {
+ ActionQueue aq, Clusters fsm, ActionDBAccessor db, HostsMap hostsMap) {
this.actionQueue = aq;
this.db = db;
+ this.hostsMap = hostsMap;
scheduler = new ActionScheduler(schedulerSleepTime, actionTimeout, db,
- actionQueue, fsm, 2);
+ actionQueue, fsm, 2, hostsMap);
requestCounter = new AtomicLong(
db.getLastPersistedRequestIdWhenInitialized());
}
Modified: incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java (original)
+++ incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/actionmanager/ActionScheduler.java Mon Feb 4 02:23:55 2013
@@ -28,6 +28,7 @@ import org.apache.ambari.server.Role;
import org.apache.ambari.server.ServiceComponentNotFoundException;
import org.apache.ambari.server.agent.ActionQueue;
import org.apache.ambari.server.agent.ExecutionCommand;
+import org.apache.ambari.server.controller.HostsMap;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.Service;
@@ -54,11 +55,13 @@ class ActionScheduler implements Runnabl
private final ActionQueue actionQueue;
private final Clusters fsmObject;
private boolean taskTimeoutAdjustment = true;
+ private final HostsMap hostsMap;
public ActionScheduler(long sleepTimeMilliSec, long actionTimeoutMilliSec,
ActionDBAccessor db, ActionQueue actionQueue, Clusters fsmObject,
- int maxAttempts) {
+ int maxAttempts, HostsMap hostsMap) {
this.sleepTime = sleepTimeMilliSec;
+ this.hostsMap = hostsMap;
this.actionTimeout = actionTimeoutMilliSec;
this.db = db;
this.actionQueue = actionQueue;
@@ -283,6 +286,8 @@ class ActionScheduler implements Runnabl
s.setLastAttemptTime(hostname, roleStr, now);
s.incrementAttemptCount(hostname, roleStr);
LOG.info("Scheduling command: "+cmd.toString()+" for host: "+hostname);
+ /** change the hostname in the command for the host itself **/
+ cmd.setHostname(hostsMap.getHostMap(hostname));
actionQueue.enqueue(hostname, cmd);
db.hostRoleScheduled(s, hostname, roleStr);
}
Added: incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/AgentEnv.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/AgentEnv.java?rev=1442010&view=auto
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/AgentEnv.java (added)
+++ incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/AgentEnv.java Mon Feb 4 02:23:55 2013
@@ -0,0 +1,242 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.agent;
+
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
+
+/**
+ * Agent environment data.
+ */
+public class AgentEnv {
+
+ /**
+ * Various directories, configurable in <code>ambari-agent.ini</code>
+ */
+ private Directory[] paths = new Directory[0];
+
+ /**
+ * Java processes running on the system. Default empty array.
+ */
+ private JavaProc[] javaProcs = new JavaProc[0];
+
+ /**
+ * Various RPM package versions.
+ */
+ private Rpm[] rpms = new Rpm[0];
+
+ /**
+ * Number of pid files found in <code>/var/run/hadoop</code>
+ */
+ private int varRunHadoopPidCount = 0;
+
+ /**
+ * Number of log files found in <code>/var/log/hadoop</code>
+ */
+ private int varLogHadoopLogCount = 0;
+
+ /**
+ * Directories that match name <code>/etc/alternatives/*conf</code>
+ */
+ private Alternative[] etcAlternativesConf = new Alternative[0];
+
+ /**
+ * Output for repo listing. Command to do this varies, but for RHEL it is
+ * <code>yum -C repolist</code>
+ */
+ private String repoInfo;
+
+
+ public Directory[] getPaths() {
+ return paths;
+ }
+
+ public void setPaths(Directory[] dirs) {
+ paths = dirs;
+ }
+
+ public void setVarRunHadoopPidCount(int count) {
+ varRunHadoopPidCount = count;
+ }
+
+ public int getVarRunHadoopPidCount() {
+ return varRunHadoopPidCount;
+ }
+
+ public void setVarLogHadoopLogCount(int count) {
+ varLogHadoopLogCount = count;
+ }
+
+ public int getVarLogHadoopLogCount() {
+ return varLogHadoopLogCount;
+ }
+
+ public void setJavaProcs(JavaProc[] procs) {
+ javaProcs = procs;
+ }
+
+ public JavaProc[] getJavaProcs() {
+ return javaProcs;
+ }
+
+ public void setRpms(Rpm[] rpm) {
+ rpms = rpm;
+ }
+
+ public Rpm[] getRpms() {
+ return rpms;
+ }
+
+ public void setEtcAlternativesConf(Alternative[] dirs) {
+ etcAlternativesConf = dirs;
+ }
+
+ public Alternative[] getEtcAlternativesConf() {
+ return etcAlternativesConf;
+ }
+
+ public void setRepoInfo(String info) {
+ repoInfo = info;
+ }
+
+ public String getRepoInfo() {
+ return repoInfo;
+ }
+
+ /**
+ * Represents information about rpm-installed packages
+ */
+ public static class Rpm {
+ private String rpmName;
+ private boolean rpmInstalled = false;
+ private String rpmVersion;
+
+ public void setName(String name) {
+ rpmName = name;
+ }
+
+ public String getName() {
+ return rpmName;
+ }
+
+ public void setInstalled(boolean installed) {
+ rpmInstalled = installed;
+ }
+
+ public boolean isInstalled() {
+ return rpmInstalled;
+ }
+
+ public void setVersion(String version) {
+ rpmVersion = version;
+ }
+
+ @JsonSerialize(include=Inclusion.NON_NULL)
+ public String getVersion() {
+ return rpmVersion;
+ }
+ }
+
+ /**
+ * Represents information about a directory of interest.
+ */
+ public static class Directory {
+ private String dirName;
+ private String dirType;
+
+ public void setName(String name) {
+ dirName = name;
+ }
+
+ public String getName() {
+ return dirName;
+ }
+
+ public void setType(String type) {
+ dirType = type;
+ }
+
+ public String getType() {
+ return dirType;
+ }
+ }
+
+ /**
+ * Represents information about running java processes.
+ */
+ public static class JavaProc {
+ private String user;
+ private int pid = 0;
+ private boolean is_hadoop = false;
+ private String command;
+
+ public void setUser(String user) {
+ this.user = user;
+ }
+
+ public String getUser() {
+ return user;
+ }
+
+ public void setPid(int pid) {
+ this.pid = pid;
+ }
+
+ public int getPid() {
+ return pid;
+ }
+
+ public void setHadoop(boolean hadoop) {
+ is_hadoop = hadoop;
+ }
+
+ public boolean isHadoop() {
+ return is_hadoop;
+ }
+
+ public void setCommand(String cmd) {
+ command = cmd;
+ }
+
+ public String getCommand() {
+ return command;
+ }
+ }
+
+ public static class Alternative {
+ private String altName;
+ private String altTarget;
+
+ public void setName(String name) {
+ altName = name;
+ }
+
+ public String getName() {
+ return altName;
+ }
+
+ public void setTarget(String target) {
+ altTarget = target;
+ }
+
+ public String getTarget() {
+ return altTarget;
+ }
+ }
+
+}
Modified: incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeat.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeat.java?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeat.java (original)
+++ incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeat.java Mon Feb 4 02:23:55 2013
@@ -37,6 +37,7 @@ public class HeartBeat {
List<CommandReport> reports = new ArrayList<CommandReport>();
List<ComponentStatus> componentStatus = new ArrayList<ComponentStatus>();
HostStatus nodeStatus;
+ private AgentEnv agentEnv = null;
public long getResponseId() {
return responseId;
@@ -79,6 +80,14 @@ public class HeartBeat {
public void setNodeStatus(HostStatus nodeStatus) {
this.nodeStatus = nodeStatus;
}
+
+ public AgentEnv getAgentEnv() {
+ return agentEnv;
+ }
+
+ public void setAgentEnv(AgentEnv env) {
+ agentEnv = env;
+ }
@JsonProperty("componentStatus")
public List<ComponentStatus> getComponentStatus() {
Modified: incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java (original)
+++ incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartBeatHandler.java Mon Feb 4 02:23:55 2013
@@ -151,9 +151,9 @@ public class HeartBeatHandler {
}
try {
- if (heartbeat.getNodeStatus().getStatus()
- .equals(HostStatus.Status.HEALTHY)) {
- hostObject.handleEvent(new HostHealthyHeartbeatEvent(hostname, now));
+ if (heartbeat.getNodeStatus().getStatus().equals(HostStatus.Status.HEALTHY)) {
+ hostObject.handleEvent(new HostHealthyHeartbeatEvent(hostname, now,
+ heartbeat.getAgentEnv()));
} else {
hostObject.handleEvent(new HostUnhealthyHeartbeatEvent(hostname, now,
null));
@@ -224,6 +224,12 @@ public class HeartBeatHandler {
|| prevState.equals(State.START_FAILED)
|| prevState.equals(State.STARTED)
|| prevState.equals(State.STOP_FAILED)) {
+ if (prevState == State.START_FAILED
+ && liveState == State.INSTALLED) {
+ LOG.info("Ignoring INSTALLED state update for " +
+ "START_FAILED component");
+ continue;
+ }
scHost.setState(liveState);
if (!prevState.equals(liveState)) {
LOG.info("State of service component " + componentName
@@ -349,7 +355,7 @@ public class HeartBeatHandler {
hostObject.handleEvent(new HostRegistrationRequestEvent(hostname,
null != register.getPublicHostname() ? register.getPublicHostname() : hostname,
- new AgentVersion("v1"), now, register.getHardwareProfile()));
+ new AgentVersion("v1"), now, register.getHardwareProfile(), register.getAgentEnv()));
RegistrationResponse response = new RegistrationResponse();
if (cmds.isEmpty()) {
//No status commands needed let the fsm know that status step is done
Modified: incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java
URL: http://svn.apache.org/viewvc/incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java?rev=1442010&r1=1442009&r2=1442010&view=diff
==============================================================================
--- incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java (original)
+++ incubator/ambari/branches/branch-1.2/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatMonitor.java Mon Feb 4 02:23:55 2013
@@ -19,13 +19,19 @@ package org.apache.ambari.server.agent;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.actionmanager.ActionManager;
-import org.apache.ambari.server.state.*;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.HostState;
+import org.apache.ambari.server.state.ServiceComponentHost;
import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
import org.apache.ambari.server.state.host.HostHeartbeatLostEvent;
-import org.apache.ambari.server.state.host.HostStatusUpdatesReceivedEvent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -145,10 +151,23 @@ public class HeartbeatMonitor implements
LOG.debug("Live status will include status of service " + serviceName +
" of cluster " + cl.getClusterName());
}
+
+ Map<String, Config> configs = sch.getDesiredConfigs();
+
+ Map<String, Map<String, String>> configurations =
+ new TreeMap<String, Map<String, String>>();
+
+ for (Config config : configs.values()) {
+ if (config.getType().equals("global"))
+ configurations.put(config.getType(),
+ config.getProperties());
+ }
+
StatusCommand statusCmd = new StatusCommand();
statusCmd.setClusterName(cl.getClusterName());
statusCmd.setServiceName(serviceName);
statusCmd.setComponentName(sch.getServiceComponentName());
+ statusCmd.setConfigurations(configurations);
cmds.add(statusCmd);
}
}