2017-04-24 13:14:13 +03:00
|
|
|
# -*- coding: utf-8 -*-
|
2017-08-16 23:48:18 +03:00
|
|
|
from __future__ import unicode_literals
|
2017-04-24 13:14:13 +03:00
|
|
|
|
2017-11-06 19:58:10 +03:00
|
|
|
from infi.clickhouse_orm.database import DatabaseException, ServerError
|
2017-04-24 13:14:13 +03:00
|
|
|
from .base_test_with_data import *
|
|
|
|
|
|
|
|
|
|
|
|
class ReadonlyTestCase(TestCaseWithData):
|
|
|
|
|
2017-04-25 08:39:24 +03:00
|
|
|
def _test_readonly_db(self, username):
|
|
|
|
self._insert_and_check(self._sample_data(), len(data))
|
2017-04-24 13:14:13 +03:00
|
|
|
orig_database = self.database
|
2017-04-25 08:39:24 +03:00
|
|
|
try:
|
|
|
|
self.database = Database(orig_database.db_name, username=username, readonly=True)
|
2017-11-06 19:58:10 +03:00
|
|
|
with self.assertRaises(ServerError) as cm:
|
2017-04-25 08:39:24 +03:00
|
|
|
self._insert_and_check(self._sample_data(), len(data))
|
2017-11-06 19:58:10 +03:00
|
|
|
self._check_db_readonly_err(cm.exception)
|
|
|
|
|
2018-08-19 18:22:22 +03:00
|
|
|
self.assertEqual(self.database.count(Person), 100)
|
2017-04-25 08:39:24 +03:00
|
|
|
list(self.database.select('SELECT * from $table', Person))
|
2017-11-06 19:58:10 +03:00
|
|
|
with self.assertRaises(ServerError) as cm:
|
2017-04-25 08:39:24 +03:00
|
|
|
self.database.drop_table(Person)
|
2018-03-14 12:01:41 +03:00
|
|
|
self._check_db_readonly_err(cm.exception, drop_table=True)
|
2017-11-06 19:58:10 +03:00
|
|
|
|
|
|
|
with self.assertRaises(ServerError) as cm:
|
2017-04-25 08:39:24 +03:00
|
|
|
self.database.drop_database()
|
2018-03-14 12:01:41 +03:00
|
|
|
self._check_db_readonly_err(cm.exception, drop_table=True)
|
2017-11-06 19:58:10 +03:00
|
|
|
except ServerError as e:
|
2020-03-16 11:24:02 +03:00
|
|
|
if e.code == 192 and e.message.startswith('Unknown user'): # ClickHouse version < 20.3
|
|
|
|
raise unittest.SkipTest('Database user "%s" is not defined' % username)
|
|
|
|
elif e.code == 516 and e.message.startswith('readonly: Authentication failed'): # ClickHouse version >= 20.3
|
2017-04-25 08:39:24 +03:00
|
|
|
raise unittest.SkipTest('Database user "%s" is not defined' % username)
|
|
|
|
else:
|
|
|
|
raise
|
|
|
|
finally:
|
|
|
|
self.database = orig_database
|
|
|
|
|
2018-03-14 12:01:41 +03:00
|
|
|
def _check_db_readonly_err(self, exc, drop_table=None):
|
2017-11-06 19:58:10 +03:00
|
|
|
self.assertEqual(exc.code, 164)
|
2020-03-16 11:24:02 +03:00
|
|
|
print(exc.message)
|
|
|
|
if self.database.server_version >= (20, 3):
|
2020-03-16 11:41:03 +03:00
|
|
|
self.assertTrue('Cannot execute query in readonly mode' in exc.message)
|
2020-03-16 11:24:02 +03:00
|
|
|
elif drop_table:
|
2019-05-12 10:27:10 +03:00
|
|
|
self.assertTrue(exc.message.startswith('Cannot drop table in readonly mode'))
|
2018-03-14 12:01:41 +03:00
|
|
|
else:
|
2019-05-12 10:27:10 +03:00
|
|
|
self.assertTrue(exc.message.startswith('Cannot insert into table in readonly mode'))
|
2017-11-06 19:58:10 +03:00
|
|
|
|
2017-04-25 08:39:24 +03:00
|
|
|
def test_readonly_db_with_default_user(self):
|
|
|
|
self._test_readonly_db('default')
|
|
|
|
|
|
|
|
def test_readonly_db_with_readonly_user(self):
|
|
|
|
self._test_readonly_db('readonly')
|
2017-04-24 13:14:13 +03:00
|
|
|
|
|
|
|
def test_insert_readonly(self):
|
|
|
|
m = ReadOnlyModel(name='readonly')
|
2018-05-14 14:09:57 +03:00
|
|
|
self.database.create_table(ReadOnlyModel)
|
2017-04-24 13:14:13 +03:00
|
|
|
with self.assertRaises(DatabaseException):
|
|
|
|
self.database.insert([m])
|
|
|
|
|
|
|
|
def test_create_readonly_table(self):
|
2017-09-07 15:44:27 +03:00
|
|
|
self.database.create_table(ReadOnlyModel)
|
2017-04-24 13:14:13 +03:00
|
|
|
|
|
|
|
def test_drop_readonly_table(self):
|
2017-09-07 15:44:27 +03:00
|
|
|
self.database.drop_table(ReadOnlyModel)
|
2017-04-24 13:14:13 +03:00
|
|
|
|
2018-08-19 18:02:37 +03:00
|
|
|
def test_nonexisting_readonly_database(self):
|
|
|
|
with self.assertRaises(DatabaseException) as cm:
|
|
|
|
db = Database('dummy', readonly=True)
|
2018-08-19 18:19:01 +03:00
|
|
|
self.assertEqual(str(cm.exception), 'Database does not exist, and cannot be created under readonly connection')
|
2018-08-19 18:02:37 +03:00
|
|
|
|
2017-04-24 13:14:13 +03:00
|
|
|
|
|
|
|
class ReadOnlyModel(Model):
|
2018-05-14 14:09:57 +03:00
|
|
|
_readonly = True
|
2017-04-24 13:14:13 +03:00
|
|
|
|
|
|
|
name = StringField()
|
2017-09-07 15:44:27 +03:00
|
|
|
date = DateField()
|
|
|
|
engine = MergeTree('date', ('name',))
|