cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mish...@apache.org
Subject [1/2] Switch cqlsh from cassandra-dbapi2 to python-driver patch by Mikhail Stepura for CASSANDRA-6307; reviewed by Aleksey Yeschenko and Tyler Hobbs
Date Wed, 12 Mar 2014 22:06:17 GMT
Repository: cassandra
Updated Branches:
  refs/heads/cassandra-2.1 773dda7d5 -> caf609cf6


http://git-wip-us.apache.org/repos/asf/cassandra/blob/caf609cf/pylib/cqlshlib/sslhandling.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/sslhandling.py b/pylib/cqlshlib/sslhandling.py
new file mode 100644
index 0000000..70dd759
--- /dev/null
+++ b/pylib/cqlshlib/sslhandling.py
@@ -0,0 +1,78 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import sys
+import ConfigParser
+import ssl
+
+def ssl_settings(host, config_file, env=os.environ):
+    """
+    Function wcich generates SSL setting for cassandra.Cluster
+
+    Params:
+    * host .........: hostname of Cassandra node.
+    * env ..........: environment variables. SSL factory will use, if passed,
+                      SSL_CERTFILE and SSL_VALIDATE variables.
+    * config_file ..: path to cqlsh config file (usually ~/.cqlshrc).
+                      SSL factory will use, if set, certfile and validate
+                      options in [ssl] section, as well as host to certfile
+                      mapping in [certfiles] section.
+
+    [certfiles] section is optional, 'validate' setting in [ssl] section is
+    optional too. If validation is enabled then SSL certfile must be provided
+    either in the config file or as an environment variable.
+    Environment variables override any options set in cqlsh config file.
+    """
+    configs = ConfigParser.SafeConfigParser()
+    configs.read(config_file)
+
+    def get_option(section, option):
+        try:
+            return configs.get(section, option)
+        except ConfigParser.Error:
+            return None
+
+    ssl_validate = env.get('SSL_VALIDATE')
+    if ssl_validate is None:
+        ssl_validate = get_option('ssl', 'validate')
+    ssl_validate = ssl_validate is None or ssl_validate.lower() != 'false'
+
+    ssl_certfile = env.get('SSL_CERTFILE')
+    if ssl_certfile is None:
+        ssl_certfile = get_option('certfiles', host)
+    if ssl_certfile is None:
+        ssl_certfile = get_option('ssl', 'certfile')
+    if ssl_validate and ssl_certfile is None:
+        sys.exit("Validation is enabled; SSL transport factory requires a valid certfile
"
+                 "to be specified. Please provide path to the certfile in [ssl] section "
+                 "as 'certfile' option in %s (or use [certfiles] section) or set SSL_CERTFILE
"
+                 "environment variable." % (config_file,))
+    if not ssl_certfile is None:
+        ssl_certfile = os.path.expanduser(ssl_certfile)
+
+    userkey = get_option('ssl', 'userkey')
+    if userkey:
+        userkey = os.path.expanduser(userkey)
+    usercert = get_option('ssl', 'usercert')
+    if usercert:
+        usercert = os.path.expanduser(usercert)
+
+    return dict(ca_certs=ssl_certfile,
+                cert_reqs=ssl.CERT_REQUIRED if ssl_validate else ssl.CERT_NONE,
+                ssl_version=ssl.PROTOCOL_TLSv1,
+                keyfile=userkey, certfile=usercert)
+

http://git-wip-us.apache.org/repos/asf/cassandra/blob/caf609cf/pylib/cqlshlib/test/basecase.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/test/basecase.py b/pylib/cqlshlib/test/basecase.py
index efc2555..5600f1a 100644
--- a/pylib/cqlshlib/test/basecase.py
+++ b/pylib/cqlshlib/test/basecase.py
@@ -44,10 +44,10 @@ os.symlink(path_to_cqlsh, modulepath)
 
 sys.path.append(rundir)
 import cqlsh
-cql = cqlsh.cql
+cql = cqlsh.cassandra.cluster.Cluster
 
-TEST_HOST = os.environ.get('CQL_TEST_HOST', 'localhost')
-TEST_PORT = int(os.environ.get('CQL_TEST_PORT', 9160))
+TEST_HOST = os.environ.get('CQL_TEST_HOST', '127.0.0.1')
+TEST_PORT = int(os.environ.get('CQL_TEST_PORT', 9042))
 
 class BaseTestCase(unittest.TestCase):
     def assertNicelyFormattedTableHeader(self, line, msg=None):

http://git-wip-us.apache.org/repos/asf/cassandra/blob/caf609cf/pylib/cqlshlib/test/cassconnect.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/test/cassconnect.py b/pylib/cqlshlib/test/cassconnect.py
index 63d8c10..bf62c2f 100644
--- a/pylib/cqlshlib/test/cassconnect.py
+++ b/pylib/cqlshlib/test/cassconnect.py
@@ -26,8 +26,8 @@ test_keyspace_init = os.path.join(rundir, 'test_keyspace_init.cql')
 
 def get_cassandra_connection(cql_version=None):
     if cql_version is None:
-        cql_version = '3.1.0'
-    conn = cql.connect(TEST_HOST, TEST_PORT, cql_version=cql_version)
+        cql_version = '3.1.5'
+    conn = cql((TEST_HOST,), TEST_PORT, cql_version=cql_version)
     # until the cql lib does this for us
     conn.cql_version = cql_version
     return conn
@@ -46,17 +46,17 @@ def make_test_ks_name():
 
 def create_test_keyspace(cursor):
     ksname = make_test_ks_name()
-    qksname = quote_name(cursor, ksname)
+    qksname = quote_name(ksname)
     cursor.execute('''
         CREATE KEYSPACE %s WITH replication =
             {'class': 'SimpleStrategy', 'replication_factor': 1};
-    ''' % quote_name(cursor, ksname))
+    ''' % quote_name(ksname))
     cursor.execute('USE %s;' % qksname)
     TEST_KEYSPACES_CREATED.append(ksname)
     return ksname
 
-def split_cql_commands(source, cqlver='3.1.0'):
-    ruleset = cql_rule_set(cqlver)
+def split_cql_commands(source):
+    ruleset = cql_rule_set()
     statements, in_batch = ruleset.cql_split_statements(source)
     if in_batch:
         raise ValueError("CQL source ends unexpectedly")
@@ -64,7 +64,7 @@ def split_cql_commands(source, cqlver='3.1.0'):
     return [ruleset.cql_extract_orig(toks, source) for toks in statements if toks]
 
 def execute_cql_commands(cursor, source, logprefix='INIT: '):
-    for cql in split_cql_commands(source, cqlver=cursor._connection.cql_version):
+    for cql in split_cql_commands(source):
         cqlshlog.debug(logprefix + cql)
         cursor.execute(cql)
 
@@ -73,14 +73,14 @@ def execute_cql_file(cursor, fname):
         return execute_cql_commands(cursor, f.read())
 
 def create_test_db():
-    with cassandra_cursor(ks=None, cql_version='3.1.0') as c:
+    with cassandra_cursor(ks=None, cql_version='3.1.5') as c:
         k = create_test_keyspace(c)
         execute_cql_file(c, test_keyspace_init)
     return k
 
 def remove_test_db():
     with cassandra_cursor(ks=None) as c:
-        c.execute('DROP KEYSPACE %s' % quote_name(c, TEST_KEYSPACES_CREATED.pop(-1)))
+        c.execute('DROP KEYSPACE %s' % quote_name(TEST_KEYSPACES_CREATED.pop(-1)))
 
 @contextlib.contextmanager
 def cassandra_connection(cql_version=None):
@@ -115,22 +115,18 @@ def cassandra_cursor(cql_version=None, ks=''):
         ks = get_test_keyspace()
     conn = get_cassandra_connection(cql_version=cql_version)
     try:
-        c = conn.cursor()
-        if ks is not None:
-            c.execute('USE %s;' % quote_name(c, ks))
+        c = conn.connect(ks)
+        # if ks is not None:
+        #     c.execute('USE %s;' % quote_name(c, ks))
         yield c
     finally:
-        conn.close()
+        conn.shutdown()
 
-def cql_rule_set(cqlver):
+def cql_rule_set():
     return cqlsh.cql3handling.CqlRuleSet
 
-def quote_name(cqlver, name):
-    if isinstance(cqlver, cql.cursor.Cursor):
-        cqlver = cqlver._connection
-    if isinstance(cqlver, cql.connection.Connection):
-        cqlver = cqlver.cql_version
-    return cql_rule_set(cqlver).maybe_escape_name(name)
+def quote_name(name):
+    return cql_rule_set().maybe_escape_name(name)
 
 class DEFAULTVAL: pass
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/caf609cf/pylib/cqlshlib/test/run_cqlsh.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/test/run_cqlsh.py b/pylib/cqlshlib/test/run_cqlsh.py
index 929849c..6ae295c 100644
--- a/pylib/cqlshlib/test/run_cqlsh.py
+++ b/pylib/cqlshlib/test/run_cqlsh.py
@@ -246,6 +246,7 @@ class CqlshRunner(ProcRunner):
         # readline trying to be friendly- remove these artifacts
         output = output.replace(' \r', '')
         output = output.replace('\r', '')
+        output = output.replace(' \b', '')
         if self.tty:
             echo, output = output.split('\n', 1)
             assert echo == cmd, "unexpected echo %r instead of %r" % (echo, cmd)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/caf609cf/pylib/cqlshlib/test/test_cqlsh_completion.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/test/test_cqlsh_completion.py b/pylib/cqlshlib/test/test_cqlsh_completion.py
index 63296fa..0ccfe43 100644
--- a/pylib/cqlshlib/test/test_cqlsh_completion.py
+++ b/pylib/cqlshlib/test/test_cqlsh_completion.py
@@ -33,7 +33,7 @@ TAB = '\t'
 # isn't coming
 COMPLETION_RESPONSE_TIME = 0.5
 
-completion_separation_re = re.compile(r'\s\s+')
+completion_separation_re = re.compile(r'\s+')
 
 class CqlshCompletionCase(BaseTestCase):
     def setUp(self):
@@ -56,6 +56,7 @@ class CqlshCompletionCase(BaseTestCase):
         self.cqlsh.send(inputstring)
         self.cqlsh.send(TAB)
         completed = self.cqlsh.read_up_to_timeout(COMPLETION_RESPONSE_TIME)
+        completed = completed.replace(' \b', '')
         self.assertEqual(completed[:len(inputstring)], inputstring)
         completed = completed[len(inputstring):]
         completed = completed.replace(BEL, '')
@@ -91,7 +92,7 @@ class CqlshCompletionCase(BaseTestCase):
         return self.module.CqlRuleSet.replication_strategies
 
 class TestCqlshCompletion(CqlshCompletionCase):
-    cqlver = '3.1.0'
+    cqlver = '3.1.5'
     module = cqlsh.cql3handling
 
     def test_complete_on_empty_string(self):

http://git-wip-us.apache.org/repos/asf/cassandra/blob/caf609cf/pylib/cqlshlib/test/test_cqlsh_output.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/test/test_cqlsh_output.py b/pylib/cqlshlib/test/test_cqlsh_output.py
index a8c1158..f3e9b57 100644
--- a/pylib/cqlshlib/test/test_cqlsh_output.py
+++ b/pylib/cqlshlib/test/test_cqlsh_output.py
@@ -200,7 +200,7 @@ class TestCqlshOutput(BaseTestCase):
             (1 rows)
             nnnnnnnn
             """),
-        ), cqlver=3)
+        ), cqlver="3.1.5")
 
         q = 'select COUNT(*) FROM twenty_rows_composite_table limit 1000000;'
         self.assertQueriesGiveColoredOutput((
@@ -216,7 +216,7 @@ class TestCqlshOutput(BaseTestCase):
             (1 rows)
             nnnnnnnn
             """),
-        ), cqlver=3)
+        ), cqlver="3.1.5")
 
     def test_static_cf_output(self):
         self.assertCqlverQueriesGiveColoredOutput((
@@ -236,7 +236,7 @@ class TestCqlshOutput(BaseTestCase):
             (3 rows)
             nnnnnnnn
             """),
-        ), cqlver=3)
+        ), cqlver="3.1.5")
 
         self.assertQueriesGiveColoredOutput((
             ('select * from dynamic_columns;', """
@@ -259,14 +259,14 @@ class TestCqlshOutput(BaseTestCase):
             (5 rows)
             nnnnnnnn
             """),
-        ), cqlver=3)
+        ), cqlver="3.1.5")
 
     def test_empty_cf_output(self):
         self.assertCqlverQueriesGiveColoredOutput((
             ('select * from empty_table;', """
             (0 rows)
             """),
-        ), cqlver=3)
+        ), cqlver="3.1.5")
 
         q = 'select * from has_all_types where num = 999;'
 
@@ -275,7 +275,7 @@ class TestCqlshOutput(BaseTestCase):
             (q, """
             (0 rows)
             """),
-        ), cqlver=3)
+        ), cqlver="3.1.5")
 
     def test_columnless_key_output(self):
         q = "select a from twenty_rows_table where a in ('1', '2', '-9192');"
@@ -295,7 +295,7 @@ class TestCqlshOutput(BaseTestCase):
             (2 rows)
             nnnnnnnn
             """),
-        ), cqlver=3)
+        ), cqlver="3.1.5")
 
     def test_numeric_output(self):
         self.assertCqlverQueriesGiveColoredOutput((
@@ -344,7 +344,7 @@ class TestCqlshOutput(BaseTestCase):
             (5 rows)
             nnnnnnnn
             """),
-        ), cqlver=3)
+        ), cqlver="3.1.5")
 
     def test_timestamp_output(self):
         self.assertQueriesGiveColoredOutput((
@@ -397,7 +397,7 @@ class TestCqlshOutput(BaseTestCase):
             (4 rows)
             nnnnnnnn
             """),
-        ), cqlver=3)
+        ), cqlver="3.1.5")
 
     def test_null_output(self):
         # column with metainfo but no values
@@ -416,7 +416,7 @@ class TestCqlshOutput(BaseTestCase):
             (2 rows)
             nnnnnnnn
             """),
-        ), cqlver=3)
+        ), cqlver="3.1.5")
 
         # all-columns, including a metainfo column has no values (cql3)
         self.assertQueriesGiveColoredOutput((
@@ -434,7 +434,7 @@ class TestCqlshOutput(BaseTestCase):
             (2 rows)
             nnnnnnnn
             """),
-        ), cqlver=3)
+        ), cqlver="3.1.5")
 
     def test_string_output_ascii(self):
         self.assertCqlverQueriesGiveColoredOutput((
@@ -458,7 +458,7 @@ class TestCqlshOutput(BaseTestCase):
             (5 rows)
             nnnnnnnn
             """),
-        ), cqlver=3)
+        ), cqlver="3.1.5")
 
     def test_string_output_utf8(self):
         # many of these won't line up visually here, to keep the source code
@@ -492,7 +492,7 @@ class TestCqlshOutput(BaseTestCase):
             (7 rows)
             nnnnnnnn
             """.encode('utf-8')),
-        ), cqlver=3, env={'LANG': 'en_US.UTF-8'})
+        ), cqlver="3.1.5", env={'LANG': 'en_US.UTF-8'})
 
     def test_blob_output(self):
         self.assertCqlverQueriesGiveColoredOutput((
@@ -514,7 +514,7 @@ class TestCqlshOutput(BaseTestCase):
             (4 rows)
             nnnnnnnn
             """),
-        ), cqlver=3)
+        ), cqlver="3.1.5")
 
     def test_colname_decoding_errors(self):
         # not clear how to achieve this situation in the first place. the
@@ -543,7 +543,7 @@ class TestCqlshOutput(BaseTestCase):
             Failed to decode value '\x00\xff\x00\xff' (for column 'utf8col') as text: 'utf8'
codec can't decode byte 0xff in position 1: invalid start byte
             RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
             """),
-        ), cqlver=3)
+        ), cqlver="3.1.5")
 
     def test_key_decoding_errors(self):
         self.assertCqlverQueriesGiveColoredOutput((
@@ -563,10 +563,10 @@ class TestCqlshOutput(BaseTestCase):
             Failed to decode value '\x00\xff\x02\x8f' (for column 'pkey') as text: 'utf8'
codec can't decode byte 0xff in position 1: invalid start byte
             RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
             """),
-        ), cqlver=3)
+        ), cqlver="3.1.5")
 
     def test_prompt(self):
-        with testrun_cqlsh(tty=True, keyspace=None, cqlver=3) as c:
+        with testrun_cqlsh(tty=True, keyspace=None, cqlver="3.1.5") as c:
             self.assertEqual(c.output_header.splitlines()[-1], 'cqlsh> ')
 
             c.send('\n')
@@ -589,15 +589,15 @@ class TestCqlshOutput(BaseTestCase):
             self.assertEqual(outputlines[2], 'cqlsh:system> ')
             midline = ColoredText(outputlines[1])
             self.assertEqual(midline.plain(),
-                             "Bad Request: Keyspace 'nonexistentkeyspace' does not exist")
+                             'code=2200 [Invalid query] message="Keyspace \'nonexistentkeyspace\'
does not exist"')
             self.assertColorFromTags(midline,
                              "RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR")
 
     def test_describe_keyspace_output(self):
-        fullcqlver = '3.1.0'
+        fullcqlver = '3.1.5'
         with testrun_cqlsh(tty=True, cqlver=fullcqlver) as c:
             ks = get_test_keyspace()
-            qks = quote_name(fullcqlver, ks)
+            qks = quote_name(ks)
             for cmd in ('describe keyspace', 'desc keyspace'):
                 for givename in ('system', '', qks):
                     for semicolon in ('', ';'):
@@ -609,7 +609,7 @@ class TestCqlshOutput(BaseTestCase):
             # new keyspace name
             new_ks_name = 'COPY_OF_' + ks
             copy_desc = desc.replace(ks, new_ks_name)
-            statements = split_cql_commands(copy_desc, cqlver=fullcqlver)
+            statements = split_cql_commands(copy_desc)
             do_drop = True
 
             with cassandra_cursor(cql_version=fullcqlver) as curs:
@@ -620,13 +620,12 @@ class TestCqlshOutput(BaseTestCase):
                 finally:
                     curs.execute('use system')
                     if do_drop:
-                        curs.execute('drop keyspace %s' % quote_name(fullcqlver, new_ks_name))
+                        curs.execute('drop keyspace %s' % quote_name(new_ks_name))
 
     def check_describe_keyspace_output(self, output, qksname, fullcqlver):
         expected_bits = [r'(?im)^CREATE KEYSPACE %s WITH\b' % re.escape(qksname),
-                         r'(?im)^USE \S+;$',
                          r';\s*$',
-                         r'\breplication = {\n  \'class\':']
+                         r'\breplication = {\'class\':']
         for expr in expected_bits:
             self.assertRegexpMatches(output, expr)
 
@@ -637,41 +636,39 @@ class TestCqlshOutput(BaseTestCase):
         # note columns are now comparator-ordered instead of original-order.
         table_desc3 = dedent("""
 
-            CREATE TABLE has_all_types (
-              num int,
-              asciicol ascii,
-              bigintcol bigint,
-              blobcol blob,
-              booleancol boolean,
-              decimalcol decimal,
-              doublecol double,
-              floatcol float,
-              intcol int,
-              textcol text,
-              timestampcol timestamp,
-              uuidcol uuid,
-              varcharcol text,
-              varintcol varint,
-              PRIMARY KEY (num)
-            ) WITH
-              bloom_filter_fp_chance=0.010000 AND
-              caching='KEYS_ONLY' AND
-              comment='' AND
-              dclocal_read_repair_chance=0.000000 AND
-              gc_grace_seconds=864000 AND
-              min_index_interval=128 AND
-              max_index_interval=2048 AND
-              read_repair_chance=0.100000 AND
-              populate_io_cache_on_flush='false' AND
-              default_time_to_live=0 AND
-              speculative_retry='NONE' AND
-              memtable_flush_period_in_ms=0 AND
-              compaction={'class': 'SizeTieredCompactionStrategy'} AND
-              compression={'sstable_compression': 'LZ4Compressor'};
-
-        """)
-
-        with testrun_cqlsh(tty=True, cqlver='3.0.0') as c:
+            CREATE TABLE %s.has_all_types (
+                num int PRIMARY KEY,
+                asciicol ascii,
+                bigintcol bigint,
+                blobcol blob,
+                booleancol boolean,
+                decimalcol decimal,
+                doublecol double,
+                floatcol float,
+                intcol int,
+                textcol text,
+                timestampcol timestamp,
+                uuidcol uuid,
+                varcharcol text,
+                varintcol varint
+            ) WITH bloom_filter_fp_chance = 0.01
+                AND caching = 'KEYS_ONLY'
+                AND comment = ''
+                AND compaction = {'min_threshold': '4', 'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy',
'max_threshold': '32'}
+                AND compression = {'sstable_compression': 'org.apache.cassandra.io.compress.LZ4Compressor'}
+                AND default_time_to_live = 0
+                AND gc_grace_seconds = 864000
+                AND max_index_interval = 2048
+                AND memtable_flush_period_in_ms = 0
+                AND min_index_interval = 128
+                AND populate_io_cache_on_flush = false
+                AND read_repair_chance = 0.1
+                AND rows_per_partition_to_cache = '100'
+                AND speculative_retry = '99.0PERCENTILE';
+
+        """ % quote_name(get_test_keyspace()))
+
+        with testrun_cqlsh(tty=True, cqlver='3.1.5') as c:
             for cmdword in ('describe table', 'desc columnfamily'):
                 for semicolon in (';', ''):
                     output = c.cmd_and_response('%s has_all_types%s' % (cmdword, semicolon))
@@ -689,7 +686,7 @@ class TestCqlshOutput(BaseTestCase):
 
         ks = get_test_keyspace()
 
-        with testrun_cqlsh(tty=True, keyspace=None, cqlver=3) as c:
+        with testrun_cqlsh(tty=True, keyspace=None, cqlver="3.1.5") as c:
 
             # when not in a keyspace
             for cmdword in ('DESCRIBE COLUMNFAMILIES', 'desc tables'):
@@ -708,10 +705,10 @@ class TestCqlshOutput(BaseTestCase):
                             self.assertIn('ascii_with_invalid_and_special_chars', cfnames)
 
                     self.assertIn('system', ksnames)
-                    self.assertIn(quote_name('3.0.0', ks), ksnames)
+                    self.assertIn(quote_name(ks), ksnames)
 
             # when in a keyspace
-            c.send('USE %s;\n' % quote_name('3.0.0', ks))
+            c.send('USE %s;\n' % quote_name(ks))
             c.read_to_next_prompt()
 
             for cmdword in ('DESCRIBE COLUMNFAMILIES', 'desc tables'):
@@ -720,7 +717,7 @@ class TestCqlshOutput(BaseTestCase):
                     self.assertNoHasColors(output)
                     self.assertEqual(output[0], '\n')
                     self.assertEqual(output[-1], '\n')
-                    self.assertNotIn('Keyspace %s' % quote_name('3.0.0', ks), output)
+                    self.assertNotIn('Keyspace %s' % quote_name(ks), output)
                     self.assertIn('has_value_encoding_errors', output)
                     self.assertIn('undefined_values_table', output)
 
@@ -730,7 +727,6 @@ class TestCqlshOutput(BaseTestCase):
             \n
             Cluster: [ ] (?P<clustername> .* ) \n
             Partitioner: [ ] (?P<partitionername> .* ) \n
-            Snitch: [ ] (?P<snitchname> .* ) \n
             \n
         '''
 
@@ -742,7 +738,7 @@ class TestCqlshOutput(BaseTestCase):
             \n
         '''
 
-        with testrun_cqlsh(tty=True, keyspace=None, cqlver=3) as c:
+        with testrun_cqlsh(tty=True, keyspace=None, cqlver="3.1.5") as c:
 
             # not in a keyspace
             for semicolon in ('', ';'):
@@ -750,7 +746,7 @@ class TestCqlshOutput(BaseTestCase):
                 self.assertNoHasColors(output)
                 self.assertRegexpMatches(output, output_re + '$')
 
-            c.send('USE %s;\n' % quote_name('3.0.0', get_test_keyspace()))
+            c.send('USE %s;\n' % quote_name(get_test_keyspace()))
             c.read_to_next_prompt()
 
             for semicolon in ('', ';'):
@@ -764,7 +760,7 @@ class TestCqlshOutput(BaseTestCase):
                 output = c.cmd_and_response('desc full schema' + semicolon)
                 self.assertNoHasColors(output)
                 self.assertRegexpMatches(output, '^\nCREATE KEYSPACE')
-                self.assertIn("\nCREATE KEYSPACE system WITH replication = {\n  'class':
'LocalStrategy'\n};\n",
+                self.assertIn("\nCREATE KEYSPACE system WITH replication = {'class': 'LocalStrategy'}
 AND durable_writes = true;\n",
                               output)
                 self.assertRegexpMatches(output, ';\s*$')
 
@@ -772,7 +768,7 @@ class TestCqlshOutput(BaseTestCase):
         with testrun_cqlsh(tty=True) as c:
             output = c.cmd_and_response('show version;')
             self.assertRegexpMatches(output,
-                    '^\[cqlsh \S+ \| Cassandra \S+ \| CQL spec \S+ \| Thrift protocol \S+\]$')
+                    '^\[cqlsh \S+ \| Cassandra \S+ \| CQL spec \S+ \| Native protocol \S+\]$')
 
             output = c.cmd_and_response('show host;')
             self.assertHasColors(output)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/caf609cf/pylib/cqlshlib/test/test_keyspace_init.cql
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/test/test_keyspace_init.cql b/pylib/cqlshlib/test/test_keyspace_init.cql
index e92d5d0..8079cd5 100644
--- a/pylib/cqlshlib/test/test_keyspace_init.cql
+++ b/pylib/cqlshlib/test/test_keyspace_init.cql
@@ -54,11 +54,10 @@ VALUES (4, blobAsInt(0x), '', blobAsBigint(0x), 0x, blobAsBoolean(0x),
blobAsDec
 
 CREATE TABLE has_value_encoding_errors (
     pkey ascii PRIMARY KEY,
-    utf8col blob
+    utf8col text
 );
 
-INSERT INTO has_value_encoding_errors (pkey, utf8col) VALUES ('A', 0x00ff00ff);
-ALTER TABLE has_value_encoding_errors ALTER utf8col TYPE text;
+INSERT INTO has_value_encoding_errors (pkey, utf8col) VALUES ('A', blobAsText(0x00ff00ff));
 
 CREATE TABLE has_key_encoding_errors (
     pkey blob PRIMARY KEY,
@@ -66,8 +65,6 @@ CREATE TABLE has_key_encoding_errors (
 );
 
 INSERT INTO has_key_encoding_errors (pkey, col) VALUES (0x00ff028f, 'whatever');
-ALTER TABLE has_key_encoding_errors ALTER pkey TYPE text;
-
 
 
 CREATE TABLE empty_table (
@@ -132,21 +129,19 @@ INSERT INTO undefined_values_table (k, c) VALUES ('k2', 'c2');
 
 CREATE TABLE ascii_with_invalid_and_special_chars (
     k int PRIMARY KEY,
-    val blob
+    val ascii
 );
 
 -- "newline:\n"
-INSERT INTO ascii_with_invalid_and_special_chars (k, val) VALUES (0, 0x6e65776c696e653a0a);
+INSERT INTO ascii_with_invalid_and_special_chars (k, val) VALUES (0, blobAsAscii(0x6e65776c696e653a0a));
 -- "return\rand null\0!"
-INSERT INTO ascii_with_invalid_and_special_chars (k, val) VALUES (1, 0x72657475726e0d616e64206e756c6c0021);
+INSERT INTO ascii_with_invalid_and_special_chars (k, val) VALUES (1, blobAsAscii(0x72657475726e0d616e64206e756c6c0021));
 -- "\x00\x01\x02\x03\x04\x05control chars\x06\x07"
-INSERT INTO ascii_with_invalid_and_special_chars (k, val) VALUES (2, 0x000102030405636f6e74726f6c2063686172730607);
+INSERT INTO ascii_with_invalid_and_special_chars (k, val) VALUES (2, blobAsAscii(0x000102030405636f6e74726f6c2063686172730607));
 -- "\xfe\xffbyte order mark"
-INSERT INTO ascii_with_invalid_and_special_chars (k, val) VALUES (3, 0xfeff62797465206f72646572206d61726b);
+INSERT INTO ascii_with_invalid_and_special_chars (k, val) VALUES (3, blobAsAscii(0xfeff62797465206f72646572206d61726b));
 -- "fake special chars\\x00\\n"
-INSERT INTO ascii_with_invalid_and_special_chars (k, val) VALUES (4, 0x66616b65207370656369616c2063686172735c7830305c6e);
-
-ALTER TABLE ascii_with_invalid_and_special_chars ALTER val TYPE ascii;
+INSERT INTO ascii_with_invalid_and_special_chars (k, val) VALUES (4, blobAsAscii(0x66616b65207370656369616c2063686172735c7830305c6e));
 
 
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/caf609cf/pylib/cqlshlib/tfactory.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/tfactory.py b/pylib/cqlshlib/tfactory.py
deleted file mode 100644
index cc02e88..0000000
--- a/pylib/cqlshlib/tfactory.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from thrift.transport import TSocket, TTransport
-
-def regular_transport_factory(host, port, env, config_file):
-    """
-    Basic unencrypted Thrift transport factory function.
-    Returns instantiated Thrift transport for use with cql.Connection.
-
-    Params:
-    * host .........: hostname of Cassandra node.
-    * port .........: port number to connect to.
-    * env ..........: environment variables (os.environ) - not used by this implementation.
-    * config_file ..: path to cqlsh config file - not used by this implementation.
-    """
-    tsocket = TSocket.TSocket(host, port)
-    return TTransport.TFramedTransport(tsocket)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/caf609cf/pylib/cqlshlib/tracing.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/tracing.py b/pylib/cqlshlib/tracing.py
index fe0f71e..456ea31 100644
--- a/pylib/cqlshlib/tracing.py
+++ b/pylib/cqlshlib/tracing.py
@@ -14,24 +14,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import time
-from cql.cqltypes import UTF8Type, InetAddressType, Int32Type
 from cqlshlib.displaying import MAGENTA
+from datetime import datetime
+import time
+from cassandra.query import QueryTrace
 
-TRACING_KS = 'system_traces'
-SESSIONS_CF = 'sessions'
-EVENTS_CF = 'events'
 
-def print_trace_session(shell, cursor, session_id):
-    rows  = fetch_trace_session(cursor, session_id)
+def print_trace_session(shell, session, session_id):
+    trace = QueryTrace(session_id, session)
+    rows = fetch_trace_session(trace)
     if not rows:
         shell.printerr("Session %s wasn't found." % session_id)
         return
     names = ['activity', 'timestamp', 'source', 'source_elapsed']
-    types = [UTF8Type, UTF8Type, InetAddressType, Int32Type]
 
-    formatted_names = [shell.myformat_colname(name, UTF8Type) for name in names]
-    formatted_values = [map(shell.myformat_value, row, types) for row in rows]
+    formatted_names = map(shell.myformat_colname, names)
+    formatted_values = [map(shell.myformat_value, row) for row in rows]
 
     shell.writeresult('')
     shell.writeresult('Tracing session: ', color=MAGENTA, newline=False)
@@ -40,43 +38,33 @@ def print_trace_session(shell, cursor, session_id):
     shell.print_formatted_result(formatted_names, formatted_values)
     shell.writeresult('')
 
-def fetch_trace_session(cursor, session_id):
-    cursor.execute("SELECT request, coordinator, started_at, duration "
-                   "FROM %s.%s "
-                   "WHERE session_id = %s" % (TRACING_KS, SESSIONS_CF, session_id),
-                   consistency_level='ONE')
-    session = cursor.fetchone()
-    if not session:
+
+def fetch_trace_session(trace):
+    trace.populate()
+    if not trace.events:
         return []
-    (request, coordinator, started_at, duration) = session
-    cursor.execute("SELECT activity, event_id, source, source_elapsed "
-                   "FROM %s.%s "
-                   "WHERE session_id = %s" % (TRACING_KS, EVENTS_CF, session_id),
-                   consistency_level='ONE')
-    events = cursor.fetchall()
 
-    rows = []
-    # append header row (from sessions table).
-    rows.append([request, format_timestamp(started_at), coordinator, 0])
+    rows = [[trace.request_type, str(datetime_from_utc_to_local(trace.started_at)), trace.coordinator,
0]]
+
     # append main rows (from events table).
-    for activity, event_id, source, source_elapsed in events:
-        rows.append([activity, format_timeuuid(event_id), source, source_elapsed])
+    for event in trace.events:
+        rows.append(["%s [%s]" % (event.description, event.thread_name),
+                     str(datetime_from_utc_to_local(event.datetime)),
+                     event.source,
+                     event.source_elapsed.microseconds])
     # append footer row (from sessions table).
-    if duration:
-        finished_at = format_timestamp(started_at + (duration / 1000000.))
+    if trace.duration:
+        finished_at = (datetime_from_utc_to_local(trace.started_at) + trace.duration)
     else:
-        finished_at = duration = "--"
+        finished_at = trace.duration = "--"
 
-    rows.append(['Request complete', finished_at, coordinator, duration])
+    rows.append(['Request complete', str(finished_at), trace.coordinator, trace.duration.microseconds])
 
     return rows
 
-def format_timestamp(value):
-    return format_time(int(value * 1000))
 
-def format_timeuuid(value):
-    return format_time((value.get_time() - 0x01b21dd213814000) / 10000)
+def datetime_from_utc_to_local(utc_datetime):
+    now_timestamp = time.time()
+    offset = datetime.fromtimestamp(now_timestamp) - datetime.utcfromtimestamp(now_timestamp)
+    return utc_datetime + offset
 
-def format_time(millis):
-    s, ms = divmod(millis, 1000)
-    return time.strftime('%H:%M:%S', time.localtime(s)) + ',' + str(ms).rjust(3, '0')

http://git-wip-us.apache.org/repos/asf/cassandra/blob/caf609cf/pylib/cqlshlib/usertypes.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/usertypes.py b/pylib/cqlshlib/usertypes.py
index 4438913..1ca9b11 100644
--- a/pylib/cqlshlib/usertypes.py
+++ b/pylib/cqlshlib/usertypes.py
@@ -14,26 +14,18 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from cql.marshal import uint16_unpack
-from cql.cqltypes import CompositeType
+from cassandra.marshal import uint16_unpack
+from cassandra.cqltypes import CompositeType
+import collections
 from formatting import formatter_for, format_value_utype
 
-
-def get_field_names(ks_name, ut_name):
-    """
-    UserTypes will use this function to get its fields names from Shell's utypes_dict
-    """
-    raise NotImplementedError("this function shall be overloaded by Shell")
-
-
 class UserType(CompositeType):
-    typename = 'UserType'
+    typename = "'org.apache.cassandra.db.marshal.UserType'"
 
     @classmethod
-    def apply_parameters(cls, *subtypes):
-        ksname = subtypes[0].cassname
+    def apply_parameters(cls, subtypes, names):
         newname = subtypes[1].cassname.decode("hex")
-        field_names = get_field_names(ksname, newname)
+        field_names = [encoded_name.decode("hex") for encoded_name in names[2:]]
         assert len(field_names) == len(subtypes[2:])
         formatter_for(newname)(format_value_utype)
         return type(newname, (cls,), {'subtypes': subtypes[2:],
@@ -46,18 +38,23 @@ class UserType(CompositeType):
     @classmethod
     def deserialize_safe(cls, byts):
         p = 0
+        Result = collections.namedtuple(cls.typename, cls.fieldnames)
         result = []
-        for col_name, col_type in zip(cls.fieldnames, cls.subtypes):
+        for col_type in cls.subtypes:
             if p == len(byts):
                 break
             itemlen = uint16_unpack(byts[p:p + 2])
             p += 2
             item = byts[p:p + itemlen]
             p += itemlen
-            result.append((str(col_name), col_type.from_binary(item)))
+            result.append(col_type.from_binary(item))
             p += 1
 
-        return tuple(result)
+        if len(result) < len(cls.subtypes):
+            nones = [None] * (len(cls.subtypes) - len(result))
+            result = result + nones
+
+        return Result(*result)
 
 
 


Mime
View raw message