Skip to content

Commit

Permalink
Fix hygiene issues for cqlshlib
Browse files Browse the repository at this point in the history
patch by Brad Schoening; reviewed by Stefan Miklosovic and Berenguer Blasi for CASSANDRA-19450
  • Loading branch information
bschoening authored and smiklosovic committed May 24, 2024
1 parent 7fe30fc commit 67bbbb0
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 86 deletions.
3 changes: 2 additions & 1 deletion pylib/cqlshlib/cqlshmain.py
Expand Up @@ -383,7 +383,8 @@ def check_build_versions(self):
if extra != -1:
baseversion = baseversion[0:extra]
if baseversion != build_version:
print("WARNING: cqlsh was built against {}, but this server is {}. All features may not work!".format(build_version, baseversion))
print("WARNING: cqlsh was built against {}, but this server is {}. All features may not work!"
.format(build_version, baseversion)) # ToDo: use file=sys.stderr)

@property
def batch_mode(self):
Expand Down
10 changes: 3 additions & 7 deletions pylib/cqlshlib/test/run_cqlsh.py
Expand Up @@ -107,10 +107,6 @@ def timing_out(seconds):
signal.setitimer(signal.ITIMER_REAL, 0)


def noop(*a):
pass


class ProcRunner:
def __init__(self, path, tty=True, env=None, args=()):
self.exe_path = path
Expand All @@ -124,7 +120,6 @@ def __init__(self, path, tty=True, env=None, args=()):
self.start_proc()

def start_proc(self):
preexec = noop
stdin = stdout = stderr = None
cqlshlog.info("Spawning %r subprocess with args: %r and env: %r"
% (self.exe_path, self.args, self.env))
Expand All @@ -141,7 +136,6 @@ def start_proc(self):
self.read = self.read_tty
else:
stdin = stdout = subprocess.PIPE
stderr = subprocess.STDOUT
self.proc = subprocess.Popen((self.exe_path,) + tuple(self.args),
env=self.env, stdin=stdin, stdout=stdout,
stderr=stderr, bufsize=0, close_fds=False)
Expand Down Expand Up @@ -178,7 +172,9 @@ def read_pipe(self, blksize, timeout=None):
return buf

def read_until(self, until, blksize=4096, timeout=None,
flags=0, ptty_timeout=None, replace=[]):
flags=0, ptty_timeout=None, replace=None):
if replace is None:
replace = []
if not isinstance(until, Pattern):
until = re.compile(until, flags)

Expand Down
79 changes: 40 additions & 39 deletions pylib/cqlshlib/test/test_authproviderhandling.py
Expand Up @@ -52,6 +52,7 @@ def _assert_auth_provider_matches(actual, klass, expected_props):
assert isinstance(actual, klass)
assert expected_props == vars(actual)


class CustomAuthProviderTest(unittest.TestCase):

def setUp(self):
Expand Down Expand Up @@ -81,18 +82,18 @@ def test_creds_not_checked_for_non_plaintext(self):
def test_partial_property_example(self):
actual = load_auth_provider(construct_config_path('partial_example'))
_assert_auth_provider_matches(
actual,
NoUserNamePlainTextAuthProvider,
{"username": '',
"password": ''})
actual,
NoUserNamePlainTextAuthProvider,
{"username": '',
"password": ''})

def test_full_property_example(self):
actual = load_auth_provider(construct_config_path('full_plain_text_example'))
_assert_auth_provider_matches(
actual,
PlainTextAuthProvider,
{"username": 'user1',
"password": 'pass1'})
actual,
PlainTextAuthProvider,
{"username": 'user1',
"password": 'pass1'})

def test_empty_example(self):
actual = load_auth_provider(construct_config_path('empty_example'))
Expand All @@ -102,10 +103,10 @@ def test_plaintextauth_when_not_defined(self):
creds_file = construct_config_path('plain_text_full_creds')
actual = load_auth_provider(cred_file=creds_file)
_assert_auth_provider_matches(
actual,
PlainTextAuthProvider,
{"username": 'user2',
"password": 'pass2'})
actual,
PlainTextAuthProvider,
{"username": 'user2',
"password": 'pass2'})

def test_no_cqlshrc_file(self):
actual = load_auth_provider()
Expand All @@ -126,65 +127,65 @@ def test_username_password_passed_from_commandline(self):

actual = load_auth_provider(cqlshrc, creds_file, 'user-from-legacy', 'pass-from-legacy')
_assert_auth_provider_matches(
actual,
ComplexTextAuthProvider,
{"username": 'user-from-legacy',
"password": 'pass-from-legacy',
"extra_flag": 'flag2'})
actual,
ComplexTextAuthProvider,
{"username": 'user-from-legacy',
"password": 'pass-from-legacy',
"extra_flag": 'flag2'})

def test_creds_example(self):
creds_file = construct_config_path('complex_auth_provider_creds')
cqlshrc = construct_config_path('complex_auth_provider')

actual = load_auth_provider(cqlshrc, creds_file)
_assert_auth_provider_matches(
actual,
ComplexTextAuthProvider,
{"username": 'user1',
"password": 'pass2',
"extra_flag": 'flag2'})
actual,
ComplexTextAuthProvider,
{"username": 'user1',
"password": 'pass2',
"extra_flag": 'flag2'})

def test_legacy_example_use_passed_username(self):
creds_file = construct_config_path('plain_text_partial_creds')
cqlshrc = construct_config_path('plain_text_partial_example')

actual = load_auth_provider(cqlshrc, creds_file, 'user3')
_assert_auth_provider_matches(
actual,
PlainTextAuthProvider,
{"username": 'user3',
"password": 'pass2'})
actual,
PlainTextAuthProvider,
{"username": 'user3',
"password": 'pass2'})

def test_legacy_example_no_auth_provider_given(self):
cqlshrc = construct_config_path('empty_example')
creds_file = construct_config_path('complex_auth_provider_creds')

actual = load_auth_provider(cqlshrc, creds_file, 'user3', 'pass3')
_assert_auth_provider_matches(
actual,
PlainTextAuthProvider,
{"username": 'user3',
"password": 'pass3'})
actual,
PlainTextAuthProvider,
{"username": 'user3',
"password": 'pass3'})

def test_shouldnt_pass_no_password_when_alt_auth_provider(self):
cqlshrc = construct_config_path('complex_auth_provider')
creds_file = None

actual = load_auth_provider(cqlshrc, creds_file, 'user3')
_assert_auth_provider_matches(
actual,
ComplexTextAuthProvider,
{"username": 'user3',
"password": 'default_pass',
"extra_flag": 'flag1'})
actual,
ComplexTextAuthProvider,
{"username": 'user3',
"password": 'default_pass',
"extra_flag": 'flag1'})

def test_legacy_example_no_password(self):
cqlshrc = construct_config_path('plain_text_partial_example')
creds_file = None

actual = load_auth_provider(cqlshrc, creds_file, 'user3')
_assert_auth_provider_matches(
actual,
PlainTextAuthProvider,
{"username": 'user3',
"password": None})
actual,
PlainTextAuthProvider,
{"username": 'user3',
"password": None})
2 changes: 1 addition & 1 deletion pylib/cqlshlib/test/test_copyutil.py
Expand Up @@ -44,7 +44,7 @@ def setUp(self):
Host('10.0.0.2', SimpleConvictionPolicy, 9000),
Host('10.0.0.3', SimpleConvictionPolicy, 9000),
Host('10.0.0.4', SimpleConvictionPolicy, 9000)
]
]

def mock_shell(self):
"""
Expand Down
56 changes: 28 additions & 28 deletions pylib/cqlshlib/test/test_cqlsh_completion.py
Expand Up @@ -100,7 +100,7 @@ def _get_completions(self, inputstring, split_completed_lines=True):

if split_completed_lines:
completed_lines = list(map(set, (completion_separation_re.split(line.strip())
for line in choice_lines)))
for line in choice_lines)))

if not completed_lines:
return set()
Expand Down Expand Up @@ -493,8 +493,8 @@ def test_complete_in_delete(self):
'TOKEN(a) >= TOKEN(0) IF b CONTAINS '),
choices=['false', 'true', '<pgStringLiteral>',
'-', '<float>', 'TOKEN', '<identifier>',
'<uuid>', '{', '[', 'NULL','<quotedStringLiteral>',
'<blobLiteral>','<wholenumber>', 'KEY'])
'<uuid>', '{', '[', 'NULL', '<quotedStringLiteral>',
'<blobLiteral>', '<wholenumber>', 'KEY'])
self.trycompletions(('DELETE FROM twenty_rows_composite_table USING TIMESTAMP 0 WHERE '
'TOKEN(a) >= TOKEN(0) IF b < 0 '),
choices=['AND', ';'])
Expand All @@ -508,7 +508,7 @@ def test_complete_in_delete(self):
def test_complete_in_begin_batch(self):
self.trycompletions('BEGIN ', choices=['BATCH', 'COUNTER', 'UNLOGGED'])
self.trycompletions('BEGIN BATCH ', choices=['DELETE', 'INSERT', 'UPDATE', 'USING'])
self.trycompletions('BEGIN BATCH INSERT ', immediate='INTO ' )
self.trycompletions('BEGIN BATCH INSERT ', immediate='INTO ')

def test_complete_in_create_keyspace(self):
self.trycompletions('create keyspace ', '', choices=('<identifier>', '<quotedName>', 'IF'))
Expand Down Expand Up @@ -588,18 +588,18 @@ def test_complete_in_create_type(self):
self.trycompletions('CREATE TYPE foo ', choices=['(', '.'])

def test_complete_in_drop_type(self):
self.trycompletions('DROP TYPE ', choices=['IF', 'system_views.', 'system_metrics.',
'tags', 'system_traces.', 'system_distributed.', 'system_cluster_metadata.',
'phone_number', 'quote_udt', 'band_info_type', 'address', 'system.', 'system_schema.',
'system_auth.', 'system_virtual_schema.', self.cqlsh.keyspace + '.'
])
self.trycompletions('DROP TYPE ',
choices=['IF', 'system_views.', 'system_metrics.',
'tags', 'system_traces.', 'system_distributed.', 'system_cluster_metadata.',
'phone_number', 'quote_udt', 'band_info_type', 'address', 'system.', 'system_schema.',
'system_auth.', 'system_virtual_schema.', self.cqlsh.keyspace + '.'])

def test_complete_in_create_trigger(self):
self.trycompletions('CREATE TRIGGER ', choices=['<identifier>', '<quotedName>', 'IF' ])
self.trycompletions('CREATE TRIGGER foo ', immediate='ON ' )
self.trycompletions('CREATE TRIGGER foo ON ', choices=['system.', 'system_auth.',
'system_distributed.', 'system_schema.', 'system_traces.', 'system_views.',
'system_virtual_schema.' ], other_choices_ok=True)
self.trycompletions('CREATE TRIGGER ', choices=['<identifier>', '<quotedName>', 'IF'])
self.trycompletions('CREATE TRIGGER foo ', immediate='ON ')
self.trycompletions('CREATE TRIGGER foo ON ', choices=['system.', 'system_auth.', 'system_distributed.',
'system_schema.', 'system_traces.', 'system_views.',
'system_virtual_schema.'], other_choices_ok=True)

def create_columnfamily_table_template(self, name):
"""Parameterized test for CREATE COLUMNFAMILY and CREATE TABLE. Since
Expand Down Expand Up @@ -768,12 +768,12 @@ def test_complete_in_create_materializedview(self):
self.trycompletions('CREATE MAT', immediate='ERIALIZED VIEW ')
self.trycompletions('CREATE MATERIALIZED VIEW AS ', choices=['AS', 'SELECT'])
self.trycompletions('CREATE MATERIALIZED VIEW AS SELECT * ', immediate='FROM ')
self.trycompletions('CREATE MATERIALIZED VIEW AS SELECT * FROM system.peers ', immediate = 'WHERE ')
self.trycompletions('CREATE MATERIALIZED VIEW AS SELECT * FROM system.peers WHERE host_id ', immediate='IS NOT NULL ' )
self.trycompletions('CREATE MATERIALIZED VIEW AS SELECT * FROM system.peers ', immediate='WHERE ')
self.trycompletions('CREATE MATERIALIZED VIEW AS SELECT * FROM system.peers WHERE host_id ', immediate='IS NOT NULL ')
self.trycompletions('CREATE MATERIALIZED VIEW AS SELECT * FROM system.peers WHERE host_id IS NOT NULL PR', immediate='IMARY KEY ( ')
self.trycompletions('CREATE MATERIALIZED VIEW AS SELECT * FROM system.peers WHERE host_id IS NOT NULL PRIMARY KEY (host_id) ', choices=[';','WITH'])
self.trycompletions('CREATE MATERIALIZED VIEW AS SELECT * FROM system.peers WHERE host_id IS NOT NULL PRIMARY KEY (a, b) ', choices=[';','WITH'])
self.trycompletions('CREATE MATERIALIZED VIEW AS SELECT * FROM system.peers WHERE host_id IS NOT NULL PRIMARY KEY ((a,b), c) ', choices=[';','WITH'])
self.trycompletions('CREATE MATERIALIZED VIEW AS SELECT * FROM system.peers WHERE host_id IS NOT NULL PRIMARY KEY (host_id) ', choices=[';', 'WITH'])
self.trycompletions('CREATE MATERIALIZED VIEW AS SELECT * FROM system.peers WHERE host_id IS NOT NULL PRIMARY KEY (a, b) ', choices=[';', 'WITH'])
self.trycompletions('CREATE MATERIALIZED VIEW AS SELECT * FROM system.peers WHERE host_id IS NOT NULL PRIMARY KEY ((a,b), c) ', choices=[';', 'WITH'])

def test_complete_in_create_table(self):
self.trycompletions('CREATE T', choices=['TRIGGER', 'TABLE', 'TYPE'])
Expand Down Expand Up @@ -896,8 +896,8 @@ def test_complete_in_truncate(self):
def test_complete_in_use(self):
self.trycompletions('US', immediate='E ')
self.trycompletions('USE ', choices=[self.cqlsh.keyspace, 'system', 'system_auth', 'system_metrics',
'system_distributed', 'system_schema', 'system_traces', 'system_views',
'system_virtual_schema', 'system_cluster_metadata' ])
'system_distributed', 'system_schema', 'system_traces', 'system_views',
'system_virtual_schema', 'system_cluster_metadata'])

def test_complete_in_create_index(self):
self.trycompletions('CREATE I', immediate='NDEX ')
Expand Down Expand Up @@ -1033,9 +1033,9 @@ def test_complete_in_alter_user(self):

def test_complete_in_create_role(self):
self.trycompletions('CREATE ROLE ', choices=['<identifier>', 'IF', '<quotedName>'])
self.trycompletions('CREATE ROLE IF ', immediate='NOT EXISTS ');
self.trycompletions('CREATE ROLE IF ', immediate='NOT EXISTS ')
self.trycompletions('CREATE ROLE foo WITH ', choices=['ACCESS', 'HASHED', 'LOGIN', 'OPTIONS', 'PASSWORD', 'SUPERUSER'])
self.trycompletions('CREATE ROLE foo WITH HASHED ', immediate='PASSWORD = ');
self.trycompletions('CREATE ROLE foo WITH HASHED ', immediate='PASSWORD = ')
self.trycompletions('CREATE ROLE foo WITH ACCESS TO ', choices=['ALL', 'DATACENTERS'])
self.trycompletions('CREATE ROLE foo WITH ACCESS TO ALL ', immediate='DATACENTERS ')
self.trycompletions('CREATE ROLE foo WITH ACCESS FROM ', choices=['ALL', 'CIDRS'])
Expand All @@ -1051,19 +1051,19 @@ def test_complete_in_alter_role(self):
def test_complete_in_drop_role(self):
self.trycompletions('DROP ROLE ', choices=['<identifier>', 'IF', '<quotedName>'])


def test_complete_in_list(self):
self.trycompletions('LIST ', choices=['ALL', 'AUTHORIZE', 'DESCRIBE', 'EXECUTE', 'ROLES', 'USERS', 'ALTER', 'CREATE', 'DROP', 'MODIFY', 'SELECT', 'UNMASK', 'SELECT_MASKED', 'SUPERUSERS'])

self.trycompletions('LIST ',
choices=['ALL', 'AUTHORIZE', 'DESCRIBE', 'EXECUTE', 'ROLES', 'USERS', 'ALTER',
'CREATE', 'DROP', 'MODIFY', 'SELECT', 'UNMASK', 'SELECT_MASKED', 'SUPERUSERS'])

# Non-CQL Shell Commands

def test_complete_in_capture(self):
self.trycompletions('CAPTURE ', choices=['OFF', ';', '<enter>'], other_choices_ok=True)

def test_complete_in_paging(self):
self.trycompletions('PAGING ', choices=['ON', 'OFF', ';', '<enter>', '<wholenumber>' ] )
self.trycompletions('PAGING 50 ', choices=[';', '<enter>' ] )
self.trycompletions('PAGING ', choices=['ON', 'OFF', ';', '<enter>', '<wholenumber>'])
self.trycompletions('PAGING 50 ', choices=[';', '<enter>'])

def test_complete_in_serial(self):
self.trycompletions('SERIAL CONSISTENCY ', choices=[';', '<enter>', 'LOCAL_SERIAL', 'SERIAL'])
Expand Down

0 comments on commit 67bbbb0

Please sign in to comment.