예제 #1
0
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')
예제 #2
0
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')
예제 #3
0
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))
예제 #4
0
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'
            },
        )
예제 #5
0
    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())
예제 #6
0
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'})
예제 #7
0
    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)]
        )
예제 #8
0
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
예제 #9
0
    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)
예제 #10
0
            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)
예제 #11
0
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')
예제 #12
0
    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)
예제 #13
0
    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)
예제 #14
0
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')
예제 #15
0
    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])]
            })
예제 #16
0
        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)
예제 #17
0
    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
예제 #18
0
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)
예제 #19
0
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({})
예제 #20
0
    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
예제 #21
0
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)
예제 #22
0
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)
예제 #23
0
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': []})
예제 #24
0
 def setUp(self):
     self.alloc = admin.Allocation(
         admin.Admin(None, 'dc=xx,dc=com'))
예제 #25
0
 def setUp(self):
     self.part = admin.Partition(
         admin.Admin(None, 'dc=xx,dc=com'))
예제 #26
0
 def setUp(self):
     self.tnt = admin.Tenant(admin.Admin(None, 'dc=xx,dc=com'))
예제 #27
0
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
                    },
                ]
            },
        )
예제 #28
0
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)
예제 #29
0
 def setUp(self):
     self.cell_alloc = admin.CellAllocation(
         admin.Admin(None, 'dc=xx,dc=com'))
예제 #30
0
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': {},
            })