Beispiel #1
0
    def test_main(self, schema_mock, query_mock, create_mock, delete_mock,
                  index_mock, load_mock):
        sys.argv = ['cadc-tap', 'schema']
        main_app()
        calls = [call()]
        schema_mock.assert_has_calls(calls)

        sys.argv = ['cadc-tap', 'query', 'QUERY']
        main_app()
        calls = [call('QUERY', None, 'VOTable', None)]
        query_mock.assert_has_calls(calls)

        sys.argv = ['cadc-tap', 'create', 'tablename', 'path/to/file']
        main_app()
        calls = [call('tablename', 'path/to/file', None)]
        create_mock.assert_has_calls(calls)

        sys.argv = ['cadc-tap', 'index', 'tablename', 'columnName']
        main_app()
        calls = [call('tablename', 'columnName', False)]
        index_mock.assert_has_calls(calls)

        sys.argv = ['cadc-tap', 'load', 'tablename', 'path/to/file']
        main_app()
        calls = [call('tablename', ['path/to/file'], 'tsv')]
        load_mock.assert_has_calls(calls)
Beispiel #2
0
 def test_keyboard_interrupt(self, caps_get_mock, query_mock):
     caps_get_mock.return_value = BASE_URL
     query_mock.reset_mock()
     query_mock.side_effect = KeyboardInterrupt()
     sys.argv = ['cadc-tap', 'query', '-s', 'http://someservice', 'QUERY']
     with patch('sys.stderr', new_callable=StringIO) as stderr_mock:
         try:
             main_app()
         except SystemExit:
             assert stderr_mock.getvalue() == 'KeyboardInterrupt\n'
Beispiel #3
0
def _get_permissions(cert, resource):
    """
    parse permissions from the output of the schema command
    :return: array with permissions elements: owner, others, g-read, g-rwrite
    """
    sys.argv = 'cadc-tap schema --cert {} {} {}'.format(cert, HOST,
                                                        resource).split()
    with patch('sys.stdout', new_callable=StringIO) as stdout_mock:
        main_app()
    return stdout_mock.getvalue().split('\n')[-4].split()
Beispiel #4
0
def _create_table(monkeypatch, owner_cert):
    sys.argv = 'cadc-tap delete --cert {} {} {}'.format(CERT1, HOST,
                                                        TABLE).split()
    try:
        monkeypatch.setattr('cadctap.core.input', lambda x: "yes")
        with patch('cadctap.core.sys.exit'):
            main_app()
        logger.debug('Deleted table {}'.format(TABLE))
    except Exception as e:
        logger.debug('Cannot delete table {}. Reason: {}'.format(
            TABLE, str(e)))

    # create table
    sys.argv = 'cadc-tap create --cert {} {} {} {}'.format(
        owner_cert, HOST, TABLE, TABLE_DEF).split()
    try:
        main_app()
        logger.debug('Created table {}'.format(TABLE))
    except Exception as e:
        logger.debug('Cannot create table {}. Reason: {}'.format(
            TABLE, str(e)))
        raise e
Beispiel #5
0
def _check_read_permissions(table,
                            auth1=False,
                            auth2=False,
                            reg=False,
                            anon=False):
    formats = ['VOTable', 'tsv', 'csv']
    for cert, read_access in [(CERT1, auth1), (CERT2, auth2), (CERTREG, reg),
                              (None, anon)]:
        logger.debug("User cert: {}".format(cert))
        format = formats[random.randrange(0, 3)]
        if format == 'VOTable':
            out_format = BytesIO
        else:
            out_format = StringIO
        cert_opt = '--cert {}'.format(cert) if cert else ''
        sys.argv = \
            'cadc-tap query -f {} {} {}'.format(format, cert_opt, HOST).split()
        sys.argv.append('select * from {}'.format(TABLE))
        if read_access:
            with patch('sys.stdout', new_callable=out_format) as stdout_mock:
                main_app()
            result = stdout_mock.getvalue()
            if out_format == BytesIO:
                assert b'<INFO name="QUERY_STATUS" value="OK" />' in result
            else:
                assert 'rows affected)' in result
        else:
            try:
                with patch('sys.stderr', new_callable=StringIO) as stdout_mock:
                    main_app()
                    assert False,\
                        'Application should have aborted due to access error'
            except SystemExit as e:
                assert e.code == -1
                assert 'is not found in TapSchema. Possible reasons: table ' \
                       'does not exist or permission is denied.' in \
                    stdout_mock.getvalue() or 'permission denied on table' in \
                    stdout_mock.getvalue()
Beispiel #6
0
    def test_help(self):
        """ Tests the helper displays for commands and subcommands in main"""
        self.maxDiff = None

        # help
        with open(os.path.join(TESTDATA_DIR, 'help.txt'), 'r') as myfile:
            usage = myfile.read()

        with patch('sys.stdout', new_callable=StringIO) as stdout_mock:
            sys.argv = ['cadc-tap', '--help']
            with self.assertRaises(MyExitError):
                main_app()
            self.assertEqual(usage, stdout_mock.getvalue())

        usage = ('usage: cadc-tap [-h] [-V] [-s SERVICE]\n'
                 '                {schema,query,create,delete,index,load} ...'
                 '\ncadc-tap: error: too few arguments\n')

        with patch('sys.stdout', new_callable=StringIO) as stdout_mock:
            with patch('sys.stderr', new_callable=StringIO) as stderr_mock:
                sys.argv = ['cadc-tap']
                with self.assertRaises(MyExitError):
                    main_app()
                self.assertEqual(usage, stderr_mock.getvalue())

        # schema -h
        with open(os.path.join(TESTDATA_DIR,
                               'help_schema.txt'), 'r') as myfile:
            usage = myfile.read()

        with patch('sys.stdout', new_callable=StringIO) as stdout_mock:
            sys.argv = ['cadc-tap', 'schema', '--help']
            with self.assertRaises(MyExitError):
                main_app()
            self.assertEqual(usage, stdout_mock.getvalue())

        # query -h
        with open(os.path.join(TESTDATA_DIR,
                               'help_query.txt'), 'r') as myfile:
            usage = myfile.read()

        with patch('sys.stdout', new_callable=StringIO) as stdout_mock:
            sys.argv = ['cadc-tap', 'query', '--help']
            with self.assertRaises(MyExitError):
                main_app()
            self.assertEqual(usage, stdout_mock.getvalue())

        # create -h
        with open(os.path.join(TESTDATA_DIR,
                               'help_create.txt'), 'r') as myfile:
            usage = myfile.read()

        with patch('sys.stdout', new_callable=StringIO) as stdout_mock:
            sys.argv = ['cadc-tap', 'create', '--help']
            with self.assertRaises(MyExitError):
                main_app()
            self.assertEqual(usage, stdout_mock.getvalue())

        # delete -h
        with open(os.path.join(TESTDATA_DIR,
                               'help_delete.txt'), 'r') as myfile:
            usage = myfile.read()

        with patch('sys.stdout', new_callable=StringIO) as stdout_mock:
            sys.argv = ['cadc-tap', 'delete', '--help']
            with self.assertRaises(MyExitError):
                main_app()
            self.assertEqual(usage, stdout_mock.getvalue())

        # index -h
        with open(os.path.join(TESTDATA_DIR,
                               'help_index.txt'), 'r') as myfile:
            usage = myfile.read()

        with patch('sys.stdout', new_callable=StringIO) as stdout_mock:
            sys.argv = ['cadc-tap', 'index', '--help']
            with self.assertRaises(MyExitError):
                main_app()
            self.assertEqual(usage, stdout_mock.getvalue())

        # load -h
        with open(os.path.join(TESTDATA_DIR,
                               'help_load.txt'), 'r') as myfile:
            usage = myfile.read()

        with patch('sys.stdout', new_callable=StringIO) as stdout_mock:
            sys.argv = ['cadc-tap', 'load', '--help']
            with self.assertRaises(MyExitError):
                main_app()
            self.assertEqual(usage, stdout_mock.getvalue())
Beispiel #7
0
def test_commands(monkeypatch):
    # test cadc TAP service with anonymous access
    sys.argv = ['cadc-tap', 'query', '-s', 'ivo://cadc.nrc.ca/tap',
                'select observationID FROM caom2.Observation '
                'where observationID=\'dao_c122_2018_003262\'']
    with patch('sys.stdout', new_callable=StringIO) as stdout_mock:
        main_app()
    assert '<INFO name="QUERY_STATUS" value="OK" />' in stdout_mock.getvalue()
    assert '<TD>dao_c122_2018_003262</TD>' in stdout_mock.getvalue()

    # monkeypatch required for the "user interaction"
    sys.argv = 'cadc-tap delete --cert {} {}'.format(CERT, TABLE).split()
    try:
        monkeypatch.setattr('cadctap.core.input', lambda x: "yes")
        main_app()
        logger.debug('Deleted table {}'.format(TABLE))
    except Exception as e:
        logger.debug(
            'Cannot delete table {}. Reason: {}'.format(TABLE, str(e)))

    # create table
    sys.argv = 'cadc-tap create --cert {} {} {}'.format(
        CERT, TABLE, TABLE_DEF).split()
    try:
        main_app()
        logger.debug('Created table {}'.format(TABLE))
    except Exception as e:
        logger.debug(
            'Cannot create table {}. Reason: {}'.format(TABLE, str(e)))
        raise e

    sys.argv = 'cadc-tap query --cert {}'.format(CERT).split()
    sys.argv.append('select * from {}'.format(TABLE))
    with patch('sys.stdout', new_callable=StringIO) as stdout_mock:
        main_app()
    assert '<INFO name="QUERY_STATUS" value="OK" />' in stdout_mock.getvalue()
    assert '<TABLEDATA />' in stdout_mock.getvalue()

    # create index
    sys.argv = 'cadc-tap index --cert {} {} article'.format(
        CERT, TABLE).split()
    try:
        main_app()
        logger.debug('Create index on {}.article'.format(TABLE))
    except Exception as e:
        logger.debug(
            'Cannot create index {}.article. Reason: {}'.format(TABLE, str(e)))
        raise e

    # load data csv format
    sys.argv = 'cadc-tap load -f csv --cert {} {} {}'.format(
        CERT, TABLE, os.path.join(TESTDATA_DIR, 'loadTable_csv.txt')).split()
    try:
        main_app()
        logger.debug('Load table {} (csv)'.format(TABLE))
    except Exception as e:
        logger.debug(
            'Cannot load table csv {}. Reason: {}'.format(TABLE, str(e)))
        raise e

    sys.argv = 'cadc-tap query --cert {}'.format(CERT).split()
    sys.argv.append('select * from {}'.format(TABLE))
    with patch('sys.stdout', new_callable=StringIO) as stdout_mock:
        main_app()
    result = stdout_mock.getvalue()
    assert '<INFO name="QUERY_STATUS" value="OK" />' in result
    # 3 rows
    assert 3 == result.count('<TD>art')
    for i in range(1, 3):
        assert '<TD>art{}</TD>'.format(i) in result
        assert '<TD>{}</TD>'.format(i) in result

    # load data tsv format
    sys.argv = 'cadc-tap load --cert {} {} {}'.format(
        CERT, TABLE, os.path.join(TESTDATA_DIR, 'loadTable_tsv.txt')).split()
    try:
        main_app()
        logger.debug('Load table {} (tsv)'.format(TABLE))
    except Exception as e:
        logger.debug(
            'Cannot load tsv table {}. Reason: {}'.format(TABLE, str(e)))
        raise e

    sys.argv = 'cadc-tap query --cert {}'.format(CERT).split()
    sys.argv.append('select * from {}'.format(TABLE))
    with patch('sys.stdout', new_callable=StringIO) as stdout_mock:
        main_app()
    result = stdout_mock.getvalue()
    assert '<INFO name="QUERY_STATUS" value="OK" />' in result
    # 6 rows
    assert 6 == result.count('<TD>art')
    for i in range(1, 6):
        assert '<TD>art{}</TD>'.format(i) in result
        assert '<TD>{}</TD>'.format(i) in result

    # load data BINTABLE format
    hdu0 = fits.PrimaryHDU()
    hdu0.header['COMMENT'] = 'Sample BINTABLE'

    c1 = fits.Column(name='article', array=np.array(['art6', 'art7', 'art8']),
                     format='5A')
    c2 = fits.Column(name='count', array=np.array([6, 7, 8]), format='K')
    hdu1 = fits.BinTableHDU.from_columns([c1, c2])
    new_hdul = fits.HDUList([hdu0, hdu1])

    tempdir = tempfile.mkdtemp()
    bintb_file = os.path.join(tempdir, 'bintable.fits')
    new_hdul.writeto(bintb_file)

    sys.argv = 'cadc-tap load -f FITSTable --cert {} {} {}'.format(
        CERT, TABLE, bintb_file).split()
    try:
        main_app()
        logger.debug('Load table {} (bintable)'.format(TABLE))
    except Exception as e:
        logger.debug(
            'Cannot load table bintable {}. Reason: {}'.format(TABLE, str(e)))
        raise e

    sys.argv = 'cadc-tap query --cert {}'.format(CERT).split()
    sys.argv.append('select * from {}'.format(TABLE))
    with patch('sys.stdout', new_callable=StringIO) as stdout_mock:
        main_app()
    result = stdout_mock.getvalue()
    assert '<INFO name="QUERY_STATUS" value="OK" />' in result
    # 9 rows
    assert 9 == result.count('<TD>art')
    for i in range(1, 9):
        assert '<TD>art{}</TD>'.format(i) in result
        assert '<TD>{}</TD>'.format(i) in result

    #TODO query with temporary table

    # cleanup
    sys.argv = 'cadc-tap delete --cert {} {}'.format(CERT, TABLE).split()
    try:
        monkeypatch.setattr('cadctap.core.input', lambda x: "yes")
        main_app()
        logger.debug('Deleted table {}'.format(TABLE))
    except Exception as e:
        logger.debug(
            'Cannot delete table {}. Reason: {}'.format(TABLE, str(e)))
        raise e
Beispiel #8
0
    def test_main(self, schema_mock, query_mock, create_mock,
                  delete_mock, index_mock, load_mock, permissions_mock):
        sys.argv = ['cadc-tap', 'schema']
        main_app()
        calls = [call(None)]
        schema_mock.assert_has_calls(calls)

        sys.argv = ['cadc-tap', 'schema', 'mytable']
        main_app()
        calls = [call('mytable')]
        schema_mock.assert_has_calls(calls)

        sys.argv = ['cadc-tap', 'create', '-d', 'tablename', 'path/to/file']
        main_app()
        calls = [call('tablename', 'path/to/file', 'VOSITable')]
        create_mock.assert_has_calls(calls)

        sys.argv = ['cadc-tap', 'index', '-v', 'tablename', 'columnName']
        main_app()
        calls = [call('tablename', 'columnName', False)]
        index_mock.assert_has_calls(calls)

        sys.argv = ['cadc-tap', 'load', 'tablename', 'path/to/file']
        main_app()
        calls = [call('tablename', ['path/to/file'], 'tsv')]
        load_mock.assert_has_calls(calls)

        sys.argv = ['cadc-tap', 'query', '-s', 'http://someservice', 'QUERY']
        main_app()
        calls = [call('QUERY', None, 'tsv', None, data_only=False, timeout=2)]
        query_mock.assert_has_calls(calls)

        query_mock.reset_mock()
        sys.argv = ['cadc-tap', 'query', '-q', '-s', 'http://someservice',
                    'QUERY']
        main_app()
        calls = [call('QUERY', None, 'tsv', None, data_only=True, timeout=2)]
        query_mock.assert_has_calls(calls)

        query_mock.reset_mock()
        sys.argv = ['cadc-tap', 'query', '-s', 'http://someservice',
                    '--timeout', '7', 'QUERY']
        main_app()
        calls = [call('QUERY', None, 'tsv', None, data_only=False, timeout=7)]
        query_mock.assert_has_calls(calls)

        query_mock.reset_mock()
        query_file = os.path.join(TESTDATA_DIR, 'example_query.sql')
        sys.argv = ['cadc-tap', 'query', '-i', query_file, '-s', 'tap']
        main_app()
        calls = [call('SELECT TOP 10 target_name FROM caom2.Observation', None,
                      'tsv', None, data_only=False, timeout=2)]
        query_mock.assert_has_calls(calls)

        sys.argv = ['cadc-tap', 'permission', 'o+r', 'table']
        main_app()
        calls = [call('table', read_anon=True, read_only=None,
                      read_write=None)]
        permissions_mock.assert_has_calls(calls)

        permissions_mock.reset_mock()
        sys.argv = ['cadc-tap', 'permission', 'g+rw', 'table', 'CADC1',
                    'CADC2']
        main_app()
        calls = [call('table', read_anon=None,
                      read_only='ivo://cadc.nrc.ca/gms?CADC1',
                      read_write='ivo://cadc.nrc.ca/gms?CADC2')]
        permissions_mock.assert_has_calls(calls)

        permissions_mock.reset_mock()
        sys.argv = ['cadc-tap', 'permission', 'og-r', 'table']
        main_app()
        calls = [call('table', read_anon=False, read_only='',
                      read_write=None)]
        permissions_mock.assert_has_calls(calls)
Beispiel #9
0
def test_write_delete_permissions(monkeypatch):
    # monkeypatch required for the "user interaction"

    # set schema permissions
    sys.argv = 'cadc-tap permission --cert {} {} og-rw {}'.format(
        CERT1, HOST, DB_SCHEMA_NAME).split()
    main_app()
    sys.argv = 'cadc-tap permission --cert {} {} og+r {} {}'.format(
        CERT1, HOST, DB_SCHEMA_NAME, GROUP).split()
    main_app()
    sys.argv = 'cadc-tap schema --cert {} {} {}'.format(
        CERT1, HOST, DB_SCHEMA_NAME).split()
    with patch('sys.stdout', new_callable=StringIO) as stdout_mock:
        main_app()
    result = stdout_mock.getvalue()

    # create table with no credentials (Fail)
    sys.argv = 'cadc-tap create {} {} {}'.format(HOST, TABLE,
                                                 TABLE_DEF).split()
    try:
        with patch('sys.stderr', new_callable=StringIO) as stdout_mock:
            main_app()
            assert False, 'Application should have aborted due to access error'
    except SystemExit as e:
        assert e.code == -1
        assert 'permission denied' in stdout_mock.getvalue()

    # create table with no write permission in schema (Fail)
    for cert in [CERT2, CERTREG]:
        sys.argv = 'cadc-tap create --cert {} {} {} {}'.format(
            cert, HOST, TABLE, TABLE_DEF).split()
        try:
            with patch('sys.stderr', new_callable=StringIO) as stdout_mock:
                main_app()
                assert False,\
                    'Application should have aborted due to access error'
        except SystemExit as e:
            assert e.code == -1
            assert 'permission denied' in stdout_mock.getvalue()

    _create_table(monkeypatch, CERT1)

    # -------------------- test write access ---------------
    hdu0 = fits.PrimaryHDU()
    hdu0.header['COMMENT'] = 'Sample BINTABLE'

    c1 = fits.Column(name='article', array=np.array(['art1']), format='5A')
    c2 = fits.Column(name='count', array=np.array([1]), format='K')
    hdu1 = fits.BinTableHDU.from_columns([c1, c2])
    new_hdul = fits.HDUList([hdu0, hdu1])

    tempdir = tempfile.mkdtemp()
    bintb_file = os.path.join(tempdir, 'bintable.fits')
    new_hdul.writeto(bintb_file)

    sys.argv = 'cadc-tap load -f FITSTable --cert {} {} {} {}'.format(
        CERT2, HOST, TABLE, bintb_file).split()
    try:
        with patch('sys.stderr', new_callable=StringIO) as stdout_mock:
            main_app()
            assert False, 'Application should have aborted due to access error'
    except SystemExit as e:
        assert e.code == -1
        assert 'permission denied' in stdout_mock.getvalue()

    # give write access and try again
    sys.argv = 'cadc-tap permission --cert {} {} g+w {} {}'.format(
        CERT1, HOST, TABLE, GROUP).split()
    main_app()

    sys.argv = 'cadc-tap load -f FITSTable --cert {} {} {} {}'.format(
        CERT2, HOST, TABLE, bintb_file).split()
    try:
        main_app()
        logger.debug('Load table {} (bintable)'.format(TABLE))
    except Exception as e:
        logger.debug('Cannot load table bintable {}. Reason: {}'.format(
            TABLE, str(e)))
        raise e

    sys.argv = 'cadc-tap query -f VOTable --cert {} {}'.format(CERT1,
                                                               HOST).split()
    sys.argv.append('select * from {}'.format(TABLE))
    with patch('sys.stdout', new_callable=BytesIO) as stdout_mock:
        main_app()
    result = stdout_mock.getvalue()
    assert b'<INFO name="QUERY_STATUS" value="OK" />' in result
    # 1 row
    assert 1 == result.count(b'<TD>art')
    for i in range(1, 1):
        assert '<TD>art{}</TD>'.format(i).encode('utf-8') in result
        assert '<TD>{}</TD>'.format(i).encode('utf-8') in result

    # REG user still failing
    sys.argv = 'cadc-tap load -f FITSTable --cert {} {} {} {}'.format(
        CERTREG, HOST, TABLE, bintb_file).split()

    try:
        with patch('sys.stderr', new_callable=StringIO) as stdout_mock:
            main_app()
            assert False, 'Application should have aborted due to access error'
    except SystemExit as e:
        assert e.code == -1
        assert 'permission denied' in stdout_mock.getvalue()

    # test remove with anon user
    sys.argv = 'cadc-tap delete {} {}'.format(HOST, TABLE).split()
    try:
        with patch('sys.stderr', new_callable=StringIO) as stdout_mock:
            monkeypatch.setattr('cadctap.core.input', lambda x: "yes")
            main_app()
            assert False, 'Application should have aborted due to access error'
    except SystemExit as e:
        assert e.code == -1
        assert 'permission denied' in stdout_mock.getvalue()

    # same thing with user in no groups or in write group
    for cert in [CERT2, CERTREG]:
        sys.argv = 'cadc-tap delete --cert {} {} {}'.format(
            CERTREG, HOST, TABLE).split()
        try:
            with patch('sys.stderr', new_callable=StringIO) as stdout_mock:
                monkeypatch.setattr('cadctap.core.input', lambda x: "yes")
                main_app()
                assert False, 'Application should have aborted due to access error'
        except SystemExit as e:
            assert e.code == -1
            assert 'permission denied' in stdout_mock.getvalue()

    # success if user is the owner
    sys.argv = 'cadc-tap delete --cert {} {} {}'.format(CERT1, HOST,
                                                        TABLE).split()
    try:
        monkeypatch.setattr('cadctap.core.input', lambda x: "yes")
        main_app()
        logger.debug('Deleted table {}'.format(TABLE))
    except Exception as e:
        logger.debug('Cannot delete table {}. Reason: {}'.format(
            TABLE, str(e)))
        raise e
Beispiel #10
0
def test_permission_settings(monkeypatch):
    sys.argv = 'cadc-tap permission --cert {} {} og-rw {}'.format(
        CERT1, HOST, DB_SCHEMA_NAME).split()
    main_app()
    # create a table
    _create_table(monkeypatch, CERT1)

    # schema permissions at the minimum - overrides table permissions
    assert [DN1, 'false', '-', '-'] == _get_permissions(CERT1, DB_SCHEMA_NAME)
    _check_read_permissions(TABLE, True, False, False, False)

    sys.argv = 'cadc-tap permission --cert {} {} g+r {} {}'.format(
        CERT1, HOST, TABLE, GROUP).split()
    main_app()
    assert [DN1, 'false', GROUP, '-'] == _get_permissions(CERT1, TABLE)
    _check_read_permissions(TABLE, True, False, False, False)

    sys.argv = 'cadc-tap permission --cert {} {} g+w {} {}'.format(
        CERT1, HOST, TABLE, GROUP).split()
    main_app()
    assert [DN1, 'false', GROUP, GROUP] == \
           _get_permissions(CERT1, TABLE)
    _check_read_permissions(TABLE, True, False, False, False)

    sys.argv = 'cadc-tap permission --cert {} {} o+r {}'.format(
        CERT1, HOST, TABLE).split()
    main_app()
    assert [DN1, 'true', GROUP, GROUP] == \
           _get_permissions(CERT1, TABLE)
    _check_read_permissions(TABLE, True, False, False, False)

    # change the schema permissions - table has all permissions
    sys.argv = 'cadc-tap permission --cert {} {} g+r {} {}'.format(
        CERT1, HOST, DB_SCHEMA_NAME, GROUP).split()
    main_app()
    assert [DN1, 'false', GROUP, '-'] == \
           _get_permissions(CERT1, DB_SCHEMA_NAME)
    _check_read_permissions(TABLE, True, True, False, False)

    sys.argv = 'cadc-tap permission --cert {} {} g+w {} {}'.format(
        CERT1, HOST, DB_SCHEMA_NAME, GROUP).split()
    main_app()
    assert [DN1, 'false', GROUP, GROUP] == \
           _get_permissions(CERT1, DB_SCHEMA_NAME)
    _check_read_permissions(TABLE, True, True, False, False)

    sys.argv = 'cadc-tap permission --cert {} {} o+r {}'.format(
        CERT1, HOST, DB_SCHEMA_NAME).split()
    main_app()
    assert [DN1, 'true', GROUP, GROUP] == \
           _get_permissions(CERT1, DB_SCHEMA_NAME)
    _check_read_permissions(TABLE, True, True, True, True)

    # remove table and create a new one owned by CERT2 user
    _create_table(monkeypatch, CERT2)
    _check_read_permissions(TABLE, False, True, False, False)

    sys.argv = 'cadc-tap permission --cert {} {} g+r {} {}'.format(
        CERT2, HOST, TABLE, GROUP).split()
    main_app()
    assert [DN2, 'false', GROUP, '-'] == \
           _get_permissions(CERT2, TABLE)
    _check_read_permissions(TABLE, True, True, False, False)

    sys.argv = 'cadc-tap permission --cert {} {} o+r {}'.format(
        CERT2, HOST, TABLE).split()
    main_app()
    assert [DN2, 'true', GROUP, '-'] == \
           _get_permissions(CERT2, TABLE)
    _check_read_permissions(TABLE, True, True, True, True)

    sys.argv = 'cadc-tap permission --cert {} {} og-r {}'.format(
        CERT2, HOST, TABLE).split()
    main_app()
    assert [DN2, 'false', '-', '-'] == \
           _get_permissions(CERT2, TABLE)
    # try to delete as CERT1
    _create_table(monkeypatch, CERT1)