class ApiDNSTest(unittest.TestCase): """treadmill.api.dns tests.""" def setUp(self): self.dns = dns.API() def tearDown(self): pass @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.DNS.list', mock.Mock(return_value=[])) def test_list(self): """Dummy test for treadmill.api.cell._list()""" self.dns.list() dns_admin = admin.DNS(None) self.assertTrue(dns_admin.list.called) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.DNS.get', mock.Mock(return_value={"location": "as"})) def test_get(self): """Dummy test for treadmill.api.cell.get()""" dns_admin = admin.DNS(None) self.dns.get('as') dns_admin.get.assert_called_with('as')
class ApiServerTest(unittest.TestCase): """treadmill.api.server tests.""" def setUp(self): self.svr = server.API() def tearDown(self): pass @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Server.list', mock.Mock(return_value=[])) def test_list(self): """Dummy test for treadmill.api.server._list()""" self.svr.list(None, None) svr_admin = admin.Server(None) self.assertTrue(svr_admin.list.called) self.svr.list('some-cell', None) svr_admin.list.assert_called_with({'cell': 'some-cell'}) self.svr.list(partition='xxx') svr_admin.list.assert_called_with({'partition': 'xxx'}) self.svr.list('some-cell', 'xxx') svr_admin.list.assert_called_with({ 'cell': 'some-cell', 'partition': 'xxx' }) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Server.get', mock.Mock(return_value={'_id': 'foo.somewhere.in.xx.com'})) def test_get(self): """Dummy test for treadmill.api.server.get()""" svr_admin = admin.Server(None) self.svr.get('foo.somewhere.in.xx.com') svr_admin.get.assert_called_with('foo.somewhere.in.xx.com') @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Server.get', mock.Mock(return_value={'_id': 'foo.somewhere.in.xx.com'})) @mock.patch('treadmill.admin.Server.create', mock.Mock()) def test_create(self): """Dummy test for treadmill.api.server.create()""" svr_admin = admin.Server(None) self.svr.create('foo.somewhere.in.xx.com', { 'cell': 'ny-999-cell', 'partition': 'xxx' }) svr_admin.get.assert_called_with('foo.somewhere.in.xx.com')
class ApiInstanceTest(unittest.TestCase): """treadmill.api.instance tests.""" def setUp(self): self.instance = instance.API() @unittest.skip('BROKEN: Requires pluging to work') @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.context.ZkContext.conn', mock.Mock()) @mock.patch('treadmill.master.create_apps', mock.Mock()) def test_normalize_run_once(self): """ test missing defaults which cause the app to fail """ doc = """ services: - command: /bin/sleep 1m name: sleep1m restart: limit: 0 memory: 150M cpu: 10% disk: 100M """ master.create_apps.side_effect = _create_apps new_doc = self.instance.create("proid.app", yaml.load(doc)) # Disable E1126: Sequence index is not an int, slice, or instance # pylint: disable=E1126 self.assertEquals(new_doc['services'][0]['restart']['interval'], 60) self.assertTrue(master.create_apps.called) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.context.ZkContext.conn', mock.Mock()) @mock.patch('treadmill.master.create_apps', mock.Mock()) def test_run_once_small_memory(self): """ testing too small memory definition for container """ doc = """ services: - command: /bin/sleep 10 name: sleep1m restart: limit: 0 memory: 10M cpu: 10% disk: 100M """ master.create_apps.side_effect = _create_apps with self.assertRaises(exc.TreadmillError): self.instance.create("proid.app", yaml.load(doc))
class ApiAllocationTest(unittest.TestCase): """treadmill.api.allocation tests.""" @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=None)) def setUp(self): self.alloc = allocation.API() def tearDown(self): pass @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Allocation.list', mock.Mock(return_value=[])) @mock.patch('treadmill.admin.CellAllocation.list', mock.Mock(return_value=[])) def test_list(self): """Dummy test for treadmill.api.allocation._list()""" alloc_admin = admin.Allocation(None) self.alloc.list() alloc_admin.list.assert_called_with({}) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Allocation.create', mock.Mock(return_value={})) @mock.patch('treadmill.admin.Allocation.get', mock.Mock(return_value={'environment': 'prod'})) @mock.patch('treadmill.admin.CellAllocation.create', mock.Mock(return_value={})) @mock.patch('treadmill.admin.CellAllocation.get', mock.Mock(return_value={})) @mock.patch('treadmill.api.allocation._check_capacity', mock.Mock(return_value=True)) def test_reservation(self): """Dummy test for treadmill.api.allocation.create()""" alloc_admin = admin.CellAllocation(None) self.alloc.reservation.create('tenant/alloc/cellname', { 'memory': '1G', 'cpu': '100%', 'disk': '2G', 'partition': None }) alloc_admin.create.assert_called_with( ['cellname', 'tenant/alloc'], { 'disk': '2G', 'partition': None, 'cpu': '100%', 'rank': 100, 'memory': '1G' }, )
def test_schema(self): """Test schema parsing.""" # Disable W0212: Test access protected members of admin module. # pylint: disable=W0212 attrs = [ '{0}( %s NAME x1 DESC \'x x\'' ' ORDERING integerOrderingMatch' ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27' ' )' % (admin._TREADMILL_ATTR_OID_PREFIX + '11'), '{1}( %s NAME x2 DESC \'x x\'' ' SUBSTR caseIgnoreSubstringsMatch' ' EQUALITY caseIgnoreMatch' ' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15' ' )' % (admin._TREADMILL_ATTR_OID_PREFIX + '22'), ] obj_classes = [ '{0}( %s NAME o1 DESC \'x x\'' ' SUP top STRUCTURAL' ' MUST ( xxx ) MAY ( a $ b )' ' )' % (admin._TREADMILL_OBJCLS_OID_PREFIX + '33'), ] admin_obj = admin.Admin(None, None) admin_obj.ldap = ldap3.Connection(ldap3.Server('fake'), client_strategy=ldap3.MOCK_SYNC) admin_obj.ldap.strategy.add_entry( 'cn={1}treadmill,cn=schema,cn=config', { 'olcAttributeTypes': attrs, 'olcObjectClasses': obj_classes }) admin_obj.ldap.bind() self.assertEqual( { 'dn': 'cn={1}treadmill,cn=schema,cn=config', 'objectClasses': { 'o1': { 'idx': 33, 'desc': 'x x', 'must': ['xxx'], 'may': ['a', 'b'], }, }, 'attributeTypes': { 'x1': { 'idx': 11, 'desc': 'x x', 'type': 'int' }, 'x2': { 'idx': 22, 'desc': 'x x', 'type': 'str', 'ignore_case': True }, } }, admin_obj.schema())
class ApiAllocationTest(unittest.TestCase): """treadmill.api.allocation tests.""" @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=None)) def setUp(self): self.alloc = allocation.API() def tearDown(self): pass # pylint: disable=W0212 def test_unpack(self): """Checking _unpack() functionality.""" self.assertEqual(allocation._unpack(['tenant-allocation']), ('tenant-allocation', None)) self.assertEqual(allocation._unpack(['tenant-allocation', 'cell']), ('tenant-allocation', 'cell')) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Allocation.list', mock.Mock(return_value=[])) def test_list(self): """Dummy test for treadmill.api.allocation._list()""" alloc_admin = admin.Allocation(None) self.alloc.list(['*-*']) alloc_admin.list.assert_called_with({'_id': '*-*'}) self.alloc.list(['tenant-*']) alloc_admin.list.assert_called_with({'_id': 'tenant*-*'}) self.alloc.list(['tenant-allocation']) alloc_admin.list.assert_called_with({'_id': 'tenant*-allocation'})
def test_add(self): """Tests add logic.""" admin_obj = admin.Admin(None, 'dc=test,dc=com') admin_obj.write_ldap = ldap3.Connection( ldap3.Server('fake'), client_strategy=ldap3.MOCK_SYNC ) admin_obj.add( 'ou=example,dc=test,dc=com', 'testClass', { 'foo': 1, 'bar': ['z', 'a'], 'lot': 2, 'exp': [3, 4] } ) call = admin_obj.write_ldap.add.call_args_list[0][0] self.assertEqual(call[0], 'ou=example,dc=test,dc=com') self.assertEqual(call[1], 'testClass') self.assertEqual( [attr for attr in six.iteritems(call[2])], [('bar', ['z', 'a']), ('exp', [3, 4]), ('foo', 1), ('lot', 2)] )
def connect(uri, write_uri, ldap_suffix, user, password): """Connect to from parent context parameters.""" _LOGGER.debug('Connecting to LDAP %s, %s', uri, ldap_suffix) conn = admin.Admin(uri, ldap_suffix, write_uri=write_uri, user=user, password=password) conn.connect() return conn
def test_ldap3_sasl_connection(self): """Tests ldap sasl credential.""" admin_obj = admin.Admin("ldap://host:389", None) admin_obj.connect() ldap3.Connection.assert_called_with({}, authentication='SASL', client_strategy='RESTARTABLE', sasl_mechanism='GSSAPI', auto_bind=True)
def _test_replication(self, ldap_suffix, url, other_url): """Check ldap replication {url} -> {other_url}.""" print('Checking %s' % url) time.sleep(2) other_conn = admin.Admin(other_url, ldap_suffix) other_conn.connect() other_admin_app = admin.Application(other_conn) other_admin_app.get(self.name)
class ApiCellTest(unittest.TestCase): """treadmill.api.cell tests.""" def setUp(self): self.cell = cell.API() def tearDown(self): pass @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Cell.list', mock.Mock(return_value=[])) def test_list(self): """Dummy test for treadmill.api.cell._list()""" self.cell.list() cell_admin = admin.Cell(None) self.assertTrue(cell_admin.list.called) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Cell.get', mock.Mock(return_value={'cell': 'ny-999-cell'})) def test_get(self): """Dummy test for treadmill.api.cell.get()""" cell_admin = admin.Cell(None) self.cell.get('some-cell') cell_admin.get.assert_called_with('some-cell') @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Cell.get', mock.Mock(return_value={'cell': 'ny-999-cell'})) @mock.patch('treadmill.admin.Cell.create', mock.Mock()) def test_create(self): """Dummy test for treadmill.api.cell.create()""" cell_admin = admin.Cell(None) self.cell.create('some-cell', { 'location': 'ny', 'treadmillid': 'treadmld', 'version': 'v3' }) cell_admin.get.assert_called_with('some-cell')
def test_init(self): """Tests init logic.""" admin_obj = admin.Admin(None, 'dc=test,dc=com') admin_obj.ldap = ldap3.Connection(ldap3.Server('fake'), client_strategy=ldap3.MOCK_SYNC) admin_obj.init() dn_list = [arg[0][0] for arg in admin_obj.ldap.add.call_args_list] self.assertTrue('dc=test,dc=com' in dn_list) self.assertTrue('ou=treadmill,dc=test,dc=com' in dn_list) self.assertTrue('ou=apps,ou=treadmill,dc=test,dc=com' in dn_list)
def test_ldap3_simple_connection(self): """Tests ldap simple credential.""" admin_obj = admin.Admin("ldap://host:389", None) admin_obj.connect() ldap3.Connection.assert_called_with({}, user="******", password="******", authentication='SIMPLE', client_strategy='RESTARTABLE', sasl_mechanism=None, auto_bind=True)
class ApiTenantTest(unittest.TestCase): """treadmill.api.tenant tests.""" def setUp(self): self.tnt = tenant.API() def tearDown(self): pass @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Tenant.list', mock.Mock(return_value=[])) def test_list(self): """Dummy test for treadmill.api.tenant._list()""" self.tnt.list() tnt_admin = admin.Tenant(None) self.assertTrue(tnt_admin.list.called) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Tenant.get', mock.Mock(return_value={'tenant': '111'})) def test_get(self): """Dummy test for treadmill.api.tenant.get()""" tnt_admin = admin.Tenant(None) self.tnt.get('some_tenant') tnt_admin.get.assert_called_with('some_tenant') @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Tenant.get', mock.Mock(return_value={'tenant': '111'})) @mock.patch('treadmill.admin.Tenant.create', mock.Mock()) def test_create(self): """Dummy test for treadmill.api.tenant.create()""" tnt_admin = admin.Tenant(None) self.tnt.create('some_tenant', {'systems': [1, 2, 3]}) tnt_admin.get.assert_called_with('some_tenant')
def test_update(self): """Tests update logic. """ mock_admin = admin.Admin(None, 'dc=test,dc=com') treadmill.admin.Admin.paged_search.return_value = [ ('cell=xxx,allocation=prod1,...', { 'disk': ['2G'], 'trait': ['a', 'b'], 'priority;tm-alloc-assignment-123': [80], 'pattern;tm-alloc-assignment-123': ['ppp.ttt'], 'priority;tm-alloc-assignment-345': [60], 'pattern;tm-alloc-assignment-345': ['ppp.ddd'], }) ] mock_admin.update( 'cell=xxx,allocation=prod1,...', { 'disk': ['1G'], 'trait': ['a'], 'priority;tm-alloc-assignment-0': [80], 'pattern;tm-alloc-assignment-0': ['ppp.ttt'], 'priority;tm-alloc-assignment-345': [30], 'pattern;tm-alloc-assignment-345': ['ppp.ddd'], }) treadmill.admin.Admin.paged_search.assert_called_once_with( search_base=mock.ANY, search_scope=mock.ANY, search_filter=mock.ANY, attributes=[ 'disk', 'pattern', 'priority', 'trait', ], dirty=False, ) treadmill.admin.Admin.modify.assert_called_once_with( 'cell=xxx,allocation=prod1,...', { 'disk': [('MODIFY_REPLACE', ['1G'])], 'trait': [('MODIFY_REPLACE', ['a'])], 'priority;tm-alloc-assignment-123': [('MODIFY_DELETE', [])], 'pattern;tm-alloc-assignment-123': [('MODIFY_DELETE', [])], 'pattern;tm-alloc-assignment-0': [('MODIFY_ADD', ['ppp.ttt'])], 'priority;tm-alloc-assignment-0': [('MODIFY_ADD', [80])], 'priority;tm-alloc-assignment-345': [('MODIFY_REPLACE', [30])] })
def setUp(self): self.name = '%s.chk.%s.%s' % (sysproid, sysinfo.hostname(), time.time()) manifest = { 'memory': '1G', 'cpu': '10%', 'disk': '1G', 'services': [{ 'name': 'test', 'command': 'test' }] } conn = admin.Admin(url, ldap_suffix) conn.connect() self.admin_app = admin.Application(conn) self.admin_app.create(self.name, manifest)
def conn(self): """Lazily establishes connection to admin LDAP.""" if self._conn is None: if self.search_base is None: raise ContextError('LDAP search base not set.') if self.url is None: if self._resolve: self._resolve() if self.url is None: raise ContextError('LDAP url not set.') _LOGGER.debug('Connecting to LDAP %s, %s', self.url, self.search_base) self._conn = admin.Admin(self.url, self.search_base) self._conn.connect() return self._conn
def _get_repl_urls(url): """Get all the replication servers in config""" ldap_admin = admin.Admin(url, '') ldap_admin.connect() repls = ldap_admin.get_repls() _LOGGER.debug('repls: %r', repls) repl_urls = set() for repl in repls: _rid, url, _rest = repl.split(' ', 2) if url.startswith(_PROVIDER): url = url[len(_PROVIDER):] _LOGGER.debug('url: %r', url) repl_urls.add(url) return list(repl_urls)
class ApiAllocationTest(unittest.TestCase): """treadmill.api.allocation tests.""" @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=None)) def setUp(self): self.alloc = allocation.API() def tearDown(self): pass @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Allocation.list', mock.Mock(return_value=[])) @mock.patch('treadmill.admin.CellAllocation.list', mock.Mock(return_value=[])) def test_list(self): """Dummy test for treadmill.api.allocation._list()""" alloc_admin = admin.Allocation(None) self.alloc.list() alloc_admin.list.assert_called_with({})
def conn(self): """Lazily establishes connection to admin LDAP.""" if self._conn is None: if self.ldap_suffix is None: raise ContextError('LDAP suffix is not set.') if self.url is None: if self._resolve: self._resolve() if self.url is None: raise ContextError('LDAP url not set.') _LOGGER.debug('Connecting to LDAP %s, %s', self.url, self.ldap_suffix) self._conn = admin.Admin(self.url, self.ldap_suffix, user=self.user, password=self.password) self._conn.connect() return self._conn
class ApiInstanceTest(unittest.TestCase): """treadmill.api.instance tests.""" def setUp(self): self.instance = instance.API() @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.context.ZkContext.conn', mock.Mock()) @mock.patch('treadmill.scheduler.masterapi.create_apps', mock.Mock()) @mock.patch('treadmill.api.instance._check_required_attributes', mock.Mock()) def test_normalize_run_once(self): """Test missing defaults which cause the app to fail.""" doc = """ services: - command: /bin/sleep 1m name: sleep1m restart: limit: 0 memory: 150M cpu: 10% disk: 100M """ masterapi.create_apps.side_effect = _create_apps new_doc = self.instance.create('proid.app', yaml.load(doc)) # Disable E1126: Sequence index is not an int, slice, or instance # pylint: disable=E1126 self.assertEqual(new_doc['services'][0]['restart']['interval'], 60) self.assertTrue(masterapi.create_apps.called) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.context.ZkContext.conn', mock.Mock()) @mock.patch('treadmill.scheduler.masterapi.create_apps', mock.Mock()) def test_run_once_small_memory(self): """Testing too small memory definition for container.""" doc = """ services: - command: /bin/sleep 10 name: sleep1m restart: limit: 0 memory: 10M cpu: 10% disk: 100M """ masterapi.create_apps.side_effect = _create_apps with self.assertRaises(exc.TreadmillError): self.instance.create('proid.app', yaml.load(doc)) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.context.ZkContext.conn', mock.Mock()) @mock.patch('treadmill.admin.Application.get', mock.Mock( return_value={ '_id': 'proid.app', 'tickets': ['*****@*****.**'], 'cpu': '10%', 'memory': '100M', 'disk': '100M', 'endpoints': [{ 'name': 'http', 'port': 8888 }], 'services': [{ 'command': 'python -m SimpleHTTPServer 8888', 'name': 'web_server', 'restart': { 'interval': 60, 'limit': 3 } }], 'features': [], 'ephemeral_ports': {}, 'passthrough': [], 'args': [], 'environ': [], 'affinity_limits': {} })) @mock.patch('treadmill.scheduler.masterapi.create_apps') @mock.patch('treadmill.api.instance._check_required_attributes', mock.Mock()) @mock.patch('treadmill.api.instance._set_defaults', mock.Mock()) def test_instance_create_configured(self, create_apps_mock): """Test creating configured instance.""" create_apps_mock.side_effect = _create_apps app = { 'tickets': ['*****@*****.**'], 'cpu': '10%', 'memory': '100M', 'disk': '100M', 'endpoints': [{ 'name': 'http', 'port': 8888 }], 'services': [{ 'command': 'python -m SimpleHTTPServer 8888', 'name': 'web_server', 'restart': { 'interval': 60, 'limit': 3 } }], 'features': [], 'ephemeral_ports': {}, 'passthrough': [], 'args': [], 'environ': [], 'affinity_limits': {}, } self.instance.create('proid.app', {}) create_apps_mock.assert_called_once_with(mock.ANY, 'proid.app', app, 1, None) create_apps_mock.reset_mock() self.instance.create('proid.app', {}, created_by='monitor') create_apps_mock.assert_called_once_with(mock.ANY, 'proid.app', app, 1, 'monitor') create_apps_mock.reset_mock() self.instance.create('proid.app', {}, 2, '*****@*****.**') create_apps_mock.assert_called_once_with(mock.ANY, 'proid.app', app, 2, '*****@*****.**') with six.assertRaisesRegex(self, jsonschema.exceptions.ValidationError, 'u?\'invalid!\' is not valid'): self.instance.create('proid.app', {}, created_by='invalid!') with six.assertRaisesRegex(self, jsonschema.exceptions.ValidationError, '0 is less than the minimum of 1'): self.instance.create('proid.app', {}, count=0) with six.assertRaisesRegex(self, jsonschema.exceptions.ValidationError, '1001 is greater than the maximum of 1000'): self.instance.create('proid.app', {}, count=1001) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.context.ZkContext.conn', mock.Mock()) @mock.patch('treadmill.scheduler.masterapi.delete_apps') def test_instance_delete(self, delete_apps_mock): """Test deleting an instance.""" delete_apps_mock.return_value = None self.instance.delete('proid.app#0000000001') delete_apps_mock.assert_called_once_with(mock.ANY, ['proid.app#0000000001'], None) delete_apps_mock.reset_mock() self.instance.delete('proid.app#0000000002', deleted_by='monitor') delete_apps_mock.assert_called_once_with(mock.ANY, ['proid.app#0000000002'], 'monitor') delete_apps_mock.reset_mock() self.instance.delete('proid.app#0000000003', deleted_by='*****@*****.**') delete_apps_mock.assert_called_once_with(mock.ANY, ['proid.app#0000000003'], '*****@*****.**') with six.assertRaisesRegex(self, jsonschema.exceptions.ValidationError, 'u?\'invalid!\' is not valid'): self.instance.delete('proid.app#0000000001', deleted_by='invalid!') @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.context.ZkContext.conn', mock.Mock()) @mock.patch('treadmill.admin.Application.get', mock.Mock( return_value={ '_id': 'proid.app', 'cpu': '10%', 'memory': '100M', 'disk': '100M', 'image': 'docker://foo', })) @mock.patch('treadmill.scheduler.masterapi.create_apps') @mock.patch('treadmill.api.instance._check_required_attributes', mock.Mock()) @mock.patch('treadmill.api.instance._set_defaults', mock.Mock()) def test_inst_create_cfg_docker(self, create_apps_mock): """Test creating configured docker instance. """ create_apps_mock.side_effect = _create_apps app = { 'cpu': '10%', 'memory': '100M', 'disk': '100M', 'image': 'docker://foo', } self.instance.create('proid.app', {}) create_apps_mock.assert_called_once_with(mock.ANY, 'proid.app', app, 1, None) create_apps_mock.reset_mock() self.instance.create('proid.app', {}, created_by='monitor') create_apps_mock.assert_called_once_with(mock.ANY, 'proid.app', app, 1, 'monitor') create_apps_mock.reset_mock() with six.assertRaisesRegex(self, jsonschema.exceptions.ValidationError, 'u?\'invalid!\' is not valid'): self.instance.create('proid.app', {}, created_by='invalid!') with six.assertRaisesRegex(self, jsonschema.exceptions.ValidationError, '0 is less than the minimum of 1'): self.instance.create('proid.app', {}, count=0) with six.assertRaisesRegex(self, jsonschema.exceptions.ValidationError, '1001 is greater than the maximum of 1000'): self.instance.create('proid.app', {}, count=1001) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.context.ZkContext.conn', mock.Mock()) @mock.patch('treadmill.scheduler.masterapi.create_apps') @mock.patch('treadmill.api.instance._check_required_attributes', mock.Mock()) @mock.patch('treadmill.api.instance._set_defaults', mock.Mock()) def test_inst_create_eph_docker(self, create_apps_mock): """Test creating ephemeral docker instance. """ create_apps_mock.side_effect = _create_apps ephemeral_app = { 'cpu': '10%', 'memory': '100M', 'disk': '100M', 'image': 'docker://foo', } resulting_app = { 'cpu': '10%', 'memory': '100M', 'disk': '100M', 'image': 'docker://foo', 'tickets': [], 'endpoints': [], 'features': [], 'ephemeral_ports': {}, 'passthrough': [], 'args': [], 'environ': [], 'affinity_limits': {}, } self.instance.create('proid.app', ephemeral_app) create_apps_mock.assert_called_once_with(mock.ANY, 'proid.app', resulting_app, 1, None) with six.assertRaisesRegex(self, jsonschema.exceptions.ValidationError, 'u?\'invalid!\' is not valid'): self.instance.create('proid.app', {}, created_by='invalid!') with six.assertRaisesRegex(self, jsonschema.exceptions.ValidationError, '0 is less than the minimum of 1'): self.instance.create('proid.app', {}, count=0) with six.assertRaisesRegex(self, jsonschema.exceptions.ValidationError, '1001 is greater than the maximum of 1000'): self.instance.create('proid.app', {}, count=1001)
class ApiAppTest(unittest.TestCase): """treadmill.api.app tests.""" def setUp(self): self.app = app.API() def tearDown(self): pass @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Application.list', mock.Mock(return_value=[])) def test_list(self): """Dummy test for treadmill.api.cell._list()""" app_admin = admin.Application(None) self.app.list('*') self.assertTrue(app_admin.list.called) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Application.get', mock.Mock(return_value={})) def test_get(self): """Dummy test for treadmill.api.cell.get()""" app_admin = admin.Application(None) self.app.get('proid.name') app_admin.get.assert_called_with('proid.name') @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Application.get', mock.Mock(return_value={})) @mock.patch('treadmill.admin.Application.create', mock.Mock()) def test_create(self): """Dummy test for treadmill.api.cell.create()""" app_admin = admin.Application(None) payload = { 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'tickets': [u'a@realm1', u'b@realm2'], 'features': [], 'services': [ { 'name': 'a', 'command': '/a', 'restart': { 'limit': 3, 'interval': 60, }, }, { 'name': 'b', 'command': '/b', }, ], 'endpoints': [ {'name': 'x', 'port': 1, 'type': 'infra'}, {'name': 'y', 'port': 2, 'type': 'infra'}, ], } self.app.create('proid.name', payload) app_admin.create.assert_called_with('proid.name', payload)
class ApiAllocationTest(unittest.TestCase): """treadmill.api.allocation tests.""" @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=None)) def setUp(self): self.alloc_api = allocation.API() def tearDown(self): pass @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Allocation.list', mock.Mock(return_value=[])) @mock.patch('treadmill.admin.CellAllocation.list', mock.Mock(return_value=[])) def test_list(self): """Dummy test for treadmill.api.allocation._list()""" alloc_admin = admin.Allocation(None) self.alloc_api.list() alloc_admin.list.assert_called_with({}) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Allocation.create', mock.Mock(return_value={})) @mock.patch('treadmill.admin.Allocation.get', mock.Mock(return_value={'environment': 'prod'})) @mock.patch('treadmill.admin.CellAllocation.create', mock.Mock(return_value={})) @mock.patch('treadmill.admin.CellAllocation.get', mock.Mock(return_value={})) @mock.patch('treadmill.api.allocation._check_capacity', mock.Mock(return_value=True)) def test_reservation(self): """Dummy test for treadmill.api.allocation.create()""" alloc_admin = admin.CellAllocation(None) self.alloc_api.reservation.create('tenant/alloc/cellname', { 'memory': '1G', 'cpu': '100%', 'disk': '2G', 'partition': None }) alloc_admin.create.assert_called_with( ['cellname', 'tenant/alloc'], { 'disk': '2G', 'partition': None, 'cpu': '100%', 'rank': 100, 'memory': '1G' }, ) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.CellAllocation.update', mock.Mock(return_value=None)) @mock.patch('treadmill.admin.CellAllocation.get', mock.Mock(return_value={ 'assignments': [{ 'pattern': 'foo.bar*', 'priority': 1 }] })) def test_assignment_update(self): """Test updating assignment, append assignment to existing assignments. """ res = self.alloc_api.assignment.update('test/dev/cell/foo.baz*', {'priority': 1}) self.assertEqual(res, [ { 'pattern': 'foo.bar*', 'priority': 1 }, { 'pattern': 'foo.baz*', 'priority': 1 }, ]) admin.CellAllocation.update.assert_called_once_with( ['cell', 'test/dev'], { 'assignments': [ { 'pattern': 'foo.bar*', 'priority': 1 }, { 'pattern': 'foo.baz*', 'priority': 1 }, ] }) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.CellAllocation.update', mock.Mock(return_value=None)) @mock.patch('treadmill.admin.CellAllocation.get', mock.Mock(return_value={})) def test_assignment_update_empty(self): """Test updating assignment, append assignment to empty cell alloc. """ res = self.alloc_api.assignment.update('test/dev/cell/foo.bar*', {'priority': 1}) self.assertEqual(res, [{'pattern': 'foo.bar*', 'priority': 1}]) admin.CellAllocation.update.assert_called_once_with( ['cell', 'test/dev'], {'assignments': [{ 'pattern': 'foo.bar*', 'priority': 1 }]}) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.CellAllocation.update', mock.Mock(return_value=None)) @mock.patch('treadmill.admin.CellAllocation.get', mock.Mock(return_value={ 'assignments': [{ 'pattern': 'foo.bar*', 'priority': 1 }] })) def test_assignment_update_priority(self): """Test updating assignment, update priority of an existing assignment. """ res = self.alloc_api.assignment.update('test/dev/cell/foo.bar*', {'priority': 100}) self.assertEqual(res, [{'pattern': 'foo.bar*', 'priority': 100}]) admin.CellAllocation.update.assert_called_once_with( ['cell', 'test/dev'], {'assignments': [{ 'pattern': 'foo.bar*', 'priority': 100 }]}) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.CellAllocation.update', mock.Mock(return_value=None)) @mock.patch('treadmill.admin.CellAllocation.get', mock.Mock( return_value={ 'assignments': [ { 'pattern': 'foo.bar*', 'priority': 1 }, { 'pattern': 'foo.baz*', 'priority': 1 }, ] })) def test_assignment_delete(self): """Test deleting assignment. """ self.alloc_api.assignment.delete('test/dev/cell/foo.baz*') admin.CellAllocation.update.assert_called_once_with( ['cell', 'test/dev'], {'assignments': [ { 'pattern': 'foo.bar*', 'priority': 1 }, ]}) # Disable C0103(Invalid method name) # pylint: disable=C0103 @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.CellAllocation.update', mock.Mock(return_value=None)) @mock.patch('treadmill.admin.CellAllocation.get', mock.Mock(return_value={})) def test_assignment_delete_nonexistent(self): """Test deleting nonexistent assignment. """ self.alloc_api.assignment.delete('test/dev/cell/foo.nonexistent*') admin.CellAllocation.update.assert_called_once_with( ['cell', 'test/dev'], {'assignments': []})
def setUp(self): self.alloc = admin.Allocation( admin.Admin(None, 'dc=xx,dc=com'))
def setUp(self): self.part = admin.Partition( admin.Admin(None, 'dc=xx,dc=com'))
def setUp(self): self.tnt = admin.Tenant(admin.Admin(None, 'dc=xx,dc=com'))
class AdminLdapAllocationTest(unittest.TestCase): """Mock test for treadmill.cli.admin.ldap.allocation""" def setUp(self): """Setup common test variables""" self.runner = click.testing.CliRunner() self.alloc_mod = plugin_manager.load('treadmill.cli.admin.ldap', 'allocation') self.alloc_cli = self.alloc_mod.init() @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.CellAllocation.update', mock.Mock(return_value=None)) @mock.patch('treadmill.admin.CellAllocation.get', mock.Mock(return_value={ 'assignments': [{ 'pattern': 'foo.bar*', 'priority': 1 }] })) @mock.patch('treadmill.admin.Allocation.get', mock.Mock(return_value={})) def test_assign_update(self): """Test updating assignment, append assignment to existing assignments. """ res = self.runner.invoke(self.alloc_cli, [ 'assign', 'test/dev', '--cell', 'cell', '--pattern', 'foo.baz*', '--priority', '1', ]) self.assertEqual(res.exit_code, 0) admin.CellAllocation.update.assert_called_once_with( ['cell', 'test/dev'], { 'assignments': [ { 'pattern': 'foo.bar*', 'priority': 1 }, { 'pattern': 'foo.baz*', 'priority': 1 }, ] }) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.CellAllocation.update', mock.Mock(return_value=None)) @mock.patch('treadmill.admin.CellAllocation.get', mock.Mock(return_value={'cell': 'cell'})) @mock.patch('treadmill.admin.Allocation.get', mock.Mock(return_value={})) def test_assign_update_empty(self): """Test updating assignment, append assignment to empty cell alloc. """ res = self.runner.invoke(self.alloc_cli, [ 'assign', 'test/dev', '--cell', 'cell', '--pattern', 'foo.bar*', '--priority', '1', ]) self.assertEqual(res.exit_code, 0) admin.CellAllocation.update.assert_called_once_with( ['cell', 'test/dev'], {'assignments': [{ 'pattern': 'foo.bar*', 'priority': 1 }]}) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.CellAllocation.update', mock.Mock(return_value=None)) @mock.patch('treadmill.admin.CellAllocation.get', mock.Mock(return_value={ 'assignments': [{ 'pattern': 'foo.bar*', 'priority': 1 }] })) @mock.patch('treadmill.admin.Allocation.get', mock.Mock(return_value={})) def test_assign_update_priority(self): """Test updating assignment, update priority of an existing assignment. """ res = self.runner.invoke(self.alloc_cli, [ 'assign', 'test/dev', '--cell', 'cell', '--pattern', 'foo.bar*', '--priority', '100', ]) self.assertEqual(res.exit_code, 0) admin.CellAllocation.update.assert_called_once_with( ['cell', 'test/dev'], {'assignments': [{ 'pattern': 'foo.bar*', 'priority': 100 }]}) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.CellAllocation.update', mock.Mock(return_value=None)) @mock.patch('treadmill.admin.CellAllocation.get', mock.Mock( return_value={ 'assignments': [ { 'pattern': 'foo.bar*', 'priority': 1 }, { 'pattern': 'foo.baz*', 'priority': 1 }, ] })) @mock.patch('treadmill.admin.Allocation.get', mock.Mock(return_value={})) def test_assign_delete(self): """Test deleting assignment. """ res = self.runner.invoke(self.alloc_cli, [ 'assign', 'test/dev', '--cell', 'cell', '--pattern', 'foo.baz*', '--priority', '1', '--delete' ]) self.assertEqual(res.exit_code, 0) admin.CellAllocation.update.assert_called_once_with( ['cell', 'test/dev'], {'assignments': [ { 'pattern': 'foo.bar*', 'priority': 1 }, ]}) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Allocation.get', mock.Mock(return_value={})) @mock.patch('treadmill.admin.CellAllocation.update', mock.Mock(return_value=None)) @mock.patch('treadmill.admin.CellAllocation.get', mock.Mock( return_value={ 'assignments': [ { 'pattern': 'foo.bar*', 'priority': 1 }, { 'pattern': 'foo.baz*', 'priority': 1 }, ] })) def test_assign_delete_nonexistent(self): """Test deleting nonexistent assignment. """ res = self.runner.invoke(self.alloc_cli, [ 'assign', 'test/dev', '--cell', 'cell', '--pattern', 'foo.nonexistent*', '--priority', '1', '--delete' ]) self.assertEqual(res.exit_code, 0) # Assignment should be untouched admin.CellAllocation.update.assert_called_once_with( ['cell', 'test/dev'], { 'assignments': [ { 'pattern': 'foo.bar*', 'priority': 1 }, { 'pattern': 'foo.baz*', 'priority': 1 }, ] }, )
class ApiAppTest(unittest.TestCase): """treadmill.api.app tests.""" def setUp(self): self.app = app.API() def tearDown(self): pass @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Application.list', mock.Mock(return_value=[])) def test_list(self): """Dummy test for treadmill.api.cell._list()""" app_admin = admin.Application(None) self.app.list('*') self.assertTrue(app_admin.list.called) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Application.get', mock.Mock(return_value={})) def test_get(self): """Dummy test for treadmill.api.cell.get()""" app_admin = admin.Application(None) self.app.get('proid.name') app_admin.get.assert_called_with('proid.name') @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Application.get', mock.Mock(return_value={})) @mock.patch('treadmill.admin.Application.create', mock.Mock()) def test_create(self): """Dummy test for treadmill.api.cell.create(). """ app_admin = admin.Application(None) payload = { 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'tickets': ['a@realm1', 'b@realm2'], 'features': [], 'services': [ { 'name': 'a', 'command': '/a', 'restart': { 'limit': 3, 'interval': 60, }, }, { 'name': 'b', 'command': '/b', }, ], 'endpoints': [ {'name': 'x', 'port': 1, 'type': 'infra'}, {'name': 'y', 'port': 2, 'type': 'infra'}, ], } self.app.create('proid.name', payload) app_admin.create.assert_called_with('proid.name', payload) def test_create_fail_null(self): """Test treadmill.api.cell.create() fails with null services. """ payload = { 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'tickets': [u'a@realm1', u'b@realm2'], 'features': [], 'services': None, 'endpoints': [ {'name': 'x', 'port': 1, 'type': 'infra'}, {'name': 'y', 'port': 2, 'type': 'infra'}, ], } with self.assertRaises(jexceptions.ValidationError): self.app.create('proid.name', payload) def test_create_fail_empty(self): """Test treadmill.api.cell.create() fails with empty list services. """ payload = { 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'tickets': [u'a@realm1', u'b@realm2'], 'features': [], 'services': [], 'endpoints': [ {'name': 'x', 'port': 1, 'type': 'infra'}, {'name': 'y', 'port': 2, 'type': 'infra'}, ], } with self.assertRaises(jexceptions.ValidationError): self.app.create('proid.name', payload) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Application.get', mock.Mock(return_value={})) @mock.patch('treadmill.admin.Application.create', mock.Mock()) def test_create_valid_affinity(self): """Test valid affinity name for treadmill.api.cell.create(). """ app_admin = admin.Application(None) payload = { 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'features': [], 'affinity': 'foo.bar', 'services': [ { 'name': 'a', 'command': '/a', }, ], 'endpoints': [ {'name': 'x', 'port': 1, 'type': 'infra'}, ], } self.app.create('proid.name', payload) app_admin.create.assert_called_with('proid.name', payload) def test_create_invalid_affinity(self): """Test invalid affinity name for treadmill.api.cell.create(). """ payload = { 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'features': [], 'affinity': '/foo.bar', 'services': [ { 'name': 'a', 'command': '/a', }, ], 'endpoints': [ {'name': 'x', 'port': 1, 'type': 'infra'}, ], } with self.assertRaises(jexceptions.ValidationError): self.app.create('proid.name', payload) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Application.get', mock.Mock(return_value={})) @mock.patch('treadmill.admin.Application.create', mock.Mock()) def test_create_docker(self): """Dummy test for treadmill.api.cell.create() for docker""" app_admin = admin.Application(None) payload = { 'cpu': '100%', 'memory': '1G', 'disk': '20G', 'image': 'docker://microsoft/windowsservercore', 'endpoints': [ {'name': 'x', 'port': 1, 'type': 'infra'}, {'name': 'y', 'port': 2, 'type': 'infra'}, ] } self.app.create('proid.name', payload) app_admin.create.assert_called_with('proid.name', payload)
def setUp(self): self.cell_alloc = admin.CellAllocation( admin.Admin(None, 'dc=xx,dc=com'))
class ApiAppTest(unittest.TestCase): """treadmill.api.app tests.""" def setUp(self): self.app = app.API() def tearDown(self): pass @mock.patch('treadmill.context.AdminContext.conn') def test_list(self, admin_mock): """Test treadmill.api.app._list()""" apps = [ ('app=foo.app1,ou=apps,ou=treadmill,dc=ms,dc=com', { 'app': ['foo.app1'], 'memory': ['1G'], 'cpu': ['100%'], 'disk': ['1G'], }), ('app=foo.app2,ou=apps,ou=treadmill,dc=ms,dc=com', { 'app': ['foo.app2'], 'memory': ['1G'], 'cpu': ['100%'], 'disk': ['1G'], }), ('app=bar.app1,ou=apps,ou=treadmill,dc=ms,dc=com', { 'app': ['bar.app1'], 'memory': ['1G'], 'cpu': ['100%'], 'disk': ['1G'], }), ] # paged_search returns generator admin_mock.paged_search.return_value = ((dn, entry) for dn, entry in apps) self.assertEqual(self.app.list(match='foo.*'), [ { '_id': 'foo.app1', 'affinity_limits': {}, 'args': [], 'cpu': '100%', 'disk': '1G', 'endpoints': [], 'environ': [], 'ephemeral_ports': {}, 'features': [], 'memory': '1G', 'passthrough': [], 'services': [], 'tickets': [], }, { '_id': 'foo.app2', 'affinity_limits': {}, 'args': [], 'cpu': '100%', 'disk': '1G', 'endpoints': [], 'environ': [], 'ephemeral_ports': {}, 'features': [], 'memory': '1G', 'passthrough': [], 'services': [], 'tickets': [], }, ]) @mock.patch('treadmill.context.AdminContext.conn') def test_list_proid_filtering(self, admin_mock): """Test treadmill.api.app._list() proid filtering""" apps = [ ('app=foo.app1,ou=apps,ou=treadmill,dc=ms,dc=com', { 'app': ['foo.app1'] }), ('app=foo.app2,ou=apps,ou=treadmill,dc=ms,dc=com', { 'app': ['foo.app2'] }), ('app=bar.app1,ou=apps,ou=treadmill,dc=ms,dc=com', { 'app': ['bar.app1'] }), ] admin_mock.paged_search.return_value = apps result = self.app.list() self.assertEqual({item['_id'] for item in result}, {'foo.app1', 'foo.app2', 'bar.app1'}) _args, kwargs = admin_mock.paged_search.call_args self.assertEqual(kwargs['search_filter'], '(objectClass=tmApp)') result = self.app.list(match='*') self.assertEqual({item['_id'] for item in result}, {'foo.app1', 'foo.app2', 'bar.app1'}) _args, kwargs = admin_mock.paged_search.call_args self.assertEqual(kwargs['search_filter'], '(objectClass=tmApp)') result = self.app.list(match='foo.*') self.assertEqual({item['_id'] for item in result}, {'foo.app1', 'foo.app2'}) _args, kwargs = admin_mock.paged_search.call_args self.assertEqual(kwargs['search_filter'], '(&(objectClass=tmApp)(app=foo.*))') result = self.app.list(match='foo.app?') self.assertEqual({item['_id'] for item in result}, {'foo.app1', 'foo.app2'}) _args, kwargs = admin_mock.paged_search.call_args self.assertEqual(kwargs['search_filter'], '(&(objectClass=tmApp)(app=foo.*))') result = self.app.list(match='foo?app*') self.assertEqual({item['_id'] for item in result}, {'foo.app1', 'foo.app2'}) _args, kwargs = admin_mock.paged_search.call_args self.assertEqual(kwargs['search_filter'], '(objectClass=tmApp)') @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Application.get', mock.Mock(return_value={})) def test_get(self): """Dummy test for treadmill.api.cell.get()""" app_admin = admin.Application(None) self.app.get('proid.name') app_admin.get.assert_called_with('proid.name') @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Application.get', mock.Mock(return_value={})) @mock.patch('treadmill.admin.Application.create', mock.Mock()) def test_create(self): """Dummy test for treadmill.api.cell.create(). """ app_admin = admin.Application(None) payload = { 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'tickets': ['a@realm1', 'b@realm2'], 'features': [], 'services': [ { 'name': 'a', 'command': '/a', 'restart': { 'limit': 3, 'interval': 60, }, }, { 'name': 'b', 'command': '/b', }, ], 'endpoints': [ { 'name': 'x', 'port': 1, 'type': 'infra' }, { 'name': 'y', 'port': 2, 'type': 'infra' }, ], } self.app.create('proid.name', payload) app_admin.create.assert_called_with('proid.name', payload) def test_create_fail_null(self): """Test treadmill.api.cell.create() fails with null services. """ payload = { 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'tickets': [u'a@realm1', u'b@realm2'], 'features': [], 'services': None, 'endpoints': [ { 'name': 'x', 'port': 1, 'type': 'infra' }, { 'name': 'y', 'port': 2, 'type': 'infra' }, ], } with self.assertRaises(jexceptions.ValidationError): self.app.create('proid.name', payload) def test_create_fail_empty(self): """Test treadmill.api.cell.create() fails with empty list services. """ payload = { 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'tickets': [u'a@realm1', u'b@realm2'], 'features': [], 'services': [], 'endpoints': [ { 'name': 'x', 'port': 1, 'type': 'infra' }, { 'name': 'y', 'port': 2, 'type': 'infra' }, ], } with self.assertRaises(jexceptions.ValidationError): self.app.create('proid.name', payload) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Application.get', mock.Mock(return_value={})) @mock.patch('treadmill.admin.Application.create', mock.Mock()) def test_create_valid_affinity(self): """Test valid affinity name for treadmill.api.cell.create(). """ app_admin = admin.Application(None) payload = { 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'features': [], 'affinity': 'foo.bar', 'services': [ { 'name': 'a', 'command': '/a', }, ], 'endpoints': [ { 'name': 'x', 'port': 1, 'type': 'infra' }, ], } self.app.create('proid.name', payload) app_admin.create.assert_called_with('proid.name', payload) def test_create_invalid_affinity(self): """Test invalid affinity name for treadmill.api.cell.create(). """ payload = { 'cpu': '100%', 'memory': '1G', 'disk': '1G', 'features': [], 'affinity': '/foo.bar', 'services': [ { 'name': 'a', 'command': '/a', }, ], 'endpoints': [ { 'name': 'x', 'port': 1, 'type': 'infra' }, ], } with self.assertRaises(jexceptions.ValidationError): self.app.create('proid.name', payload) @mock.patch('treadmill.context.AdminContext.conn', mock.Mock(return_value=admin.Admin(None, None))) @mock.patch('treadmill.admin.Application.get', mock.Mock(return_value={})) @mock.patch('treadmill.admin.Application.create', mock.Mock()) def test_create_docker(self): """Dummy test for treadmill.api.cell.create() for docker""" app_admin = admin.Application(None) payload = { 'cpu': '100%', 'memory': '1G', 'disk': '20G', 'image': 'docker://microsoft/windowsservercore', 'endpoints': [ { 'name': 'x', 'port': 1, 'type': 'infra' }, { 'name': 'y', 'port': 2, 'type': 'infra' }, ], 'services': [ { 'name': 'foo', 'image': 'testimage', 'useshell': True, 'command': 'echo', 'restart': { 'limit': 3, 'interval': 30, }, }, { 'name': 'bar', 'image': 'testimage', 'useshell': False, 'command': 'echo', 'restart': { 'limit': 3, 'interval': 30, }, }, ], } self.app.create('proid.name', payload) app_admin.create.assert_called_with('proid.name', payload) @mock.patch('treadmill.context.AdminContext.conn') def test_create_result(self, admin_mock): """Test response for treadmill.api.app.create(). """ admin_mock.dn.return_value = ( 'app=app.foo,ou=apps,ou=treadmill,dc=ms,dc=com') entry = { 'app': ['foo.app'], 'cpu': ['100%'], 'disk': ['1G'], 'memory': ['1G'], 'service-name;tm-service-0': ['test_svc'], 'service-command;tm-service-0': ['test_cmd'], 'service-restart-limit;tm-service-0': ['5'], 'service-restart-interval;tm-service-0': ['60'], } admin_mock.get.return_value = entry result = self.app.create( 'foo.app', { 'cpu': '100%', 'disk': '1G', 'memory': '1G', 'services': [{ 'name': 'test_svc', 'command': 'test_cmd' }], }) entry.update({'objectClass': ['tmApp']}) admin_mock.create.assert_called_once_with( 'app=app.foo,ou=apps,ou=treadmill,dc=ms,dc=com', entry) self.assertEqual( result, { '_id': 'foo.app', 'cpu': '100%', 'disk': '1G', 'memory': '1G', 'services': [{ 'name': 'test_svc', 'command': 'test_cmd', 'restart': { 'limit': 5, 'interval': 60 }, }], 'args': [], 'endpoints': [], 'environ': [], 'features': [], 'passthrough': [], 'tickets': [], 'ephemeral_ports': {}, 'affinity_limits': {}, }) @mock.patch('treadmill.context.AdminContext.conn') def test_update_result(self, admin_mock): """Test response for treadmill.api.app.update(). """ admin_mock.dn.return_value = ( 'app=app.foo,ou=apps,ou=treadmill,dc=ms,dc=com') entry = { 'app': ['foo.app'], 'cpu': ['100%'], 'disk': ['1G'], 'memory': ['1G'], 'service-name;tm-service-0': ['test_svc'], 'service-command;tm-service-0': ['test_cmd'], 'service-restart-limit;tm-service-0': ['5'], 'service-restart-interval;tm-service-0': ['60'], } admin_mock.get.return_value = entry result = self.app.update( 'foo.app', { 'cpu': '100%', 'disk': '1G', 'memory': '1G', 'services': [{ 'name': 'test_svc', 'command': 'test_cmd' }], }) admin_mock.delete.assert_called_once_with( 'app=app.foo,ou=apps,ou=treadmill,dc=ms,dc=com') entry.update({'objectClass': ['tmApp']}) admin_mock.create.assert_called_once_with( 'app=app.foo,ou=apps,ou=treadmill,dc=ms,dc=com', entry) self.assertEqual( result, { '_id': 'foo.app', 'cpu': '100%', 'disk': '1G', 'memory': '1G', 'services': [{ 'name': 'test_svc', 'command': 'test_cmd', 'restart': { 'limit': 5, 'interval': 60 }, }], 'args': [], 'endpoints': [], 'environ': [], 'features': [], 'passthrough': [], 'tickets': [], 'ephemeral_ports': {}, 'affinity_limits': {}, })