blob: 649cf4df72a34390773efb28239400b675eeae86 [file] [log] [blame]
# Copyright (C) 2022 The Android Open Source Project
#
# Licensed 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 unittest
ROOT_DIR = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
sys.path.append(os.path.join(ROOT_DIR))
from python.generators.stdlib_docs.parse import parse_file_to_dict
DESC = """--
-- First line.
-- Second line."""
COLS_STR = """--
-- @column slice_id Id of slice.
-- @column slice_name Name of slice."""
COLS_SQL_STR = "slice_id INT, slice_name STRING"
ARGS_STR = """--
-- @arg utid INT Utid of thread.
-- @arg name STRING String name."""
ARGS_SQL_STR = "utid INT, name STRING"
RET_STR = """--
-- @ret BOOL Exists."""
RET_SQL_STR = "BOOL"
SQL_STR = "SELECT * FROM slice"
class TestStdlib(unittest.TestCase):
def test_valid_table(self):
res = parse_file_to_dict(
'foo/bar.sql', f'''
{DESC}
{COLS_STR}
CREATE TABLE foo_table AS
{SQL_STR};
'''.strip())
assert isinstance(res, dict)
table = res['imports'][0]
self.assertEqual(table['name'], 'foo_table')
self.assertEqual(table['desc'], 'First line. Second line.')
self.assertEqual(table['type'], 'TABLE')
self.assertEqual(table['cols'], {
'slice_id': 'Id of slice.',
'slice_name': 'Name of slice.'
})
def test_valid_function(self):
res = parse_file_to_dict(
'foo/bar.sql', f'''
{DESC}
{ARGS_STR}
{RET_STR}
CREATE PERFETTO FUNCTION FOO_FN({ARGS_SQL_STR})
RETURNS {RET_SQL_STR}
AS
{SQL_STR};
'''.strip())
assert isinstance(res, dict)
fn = res['functions'][0]
self.assertEqual(fn['name'], 'FOO_FN')
self.assertEqual(fn['desc'], 'First line. Second line.')
self.assertEqual(
fn['args'], {
'utid': {
'type': 'INT',
'desc': 'Utid of thread.',
},
'name': {
'type': 'STRING',
'desc': 'String name.',
},
})
self.assertEqual(fn['return_type'], 'BOOL')
self.assertEqual(fn['return_desc'], 'Exists.')
def test_valid_view_function(self):
res = parse_file_to_dict(
'foo/bar.sql', f'''
{DESC}
{ARGS_STR}
{COLS_STR}
SELECT CREATE_VIEW_FUNCTION(
'FOO_VIEW_FN({ARGS_SQL_STR})',
'{COLS_SQL_STR}',
'{SQL_STR}'
);
'''.strip())
assert isinstance(res, dict)
fn = res['view_functions'][0]
self.assertEqual(fn['name'], 'FOO_VIEW_FN')
self.assertEqual(fn['desc'], 'First line. Second line.')
self.assertEqual(
fn['args'], {
'utid': {
'type': 'INT',
'desc': 'Utid of thread.',
},
'name': {
'type': 'STRING',
'desc': 'String name.',
},
})
self.assertEqual(fn['cols'], {
'slice_id': 'Id of slice.',
'slice_name': 'Name of slice.'
})
def test_missing_module_name(self):
res = parse_file_to_dict(
'foo/bar.sql', f'''
{DESC}
{COLS_STR}
CREATE TABLE bar_table AS
{SQL_STR};
'''.strip())
assert isinstance(res, list)
def test_common_does_not_include_module_name(self):
res = parse_file_to_dict(
'common/bar.sql', f'''
{DESC}
{COLS_STR}
CREATE TABLE common_table AS
{SQL_STR};
'''.strip())
assert isinstance(res, list)
def test_cols_typo(self):
res = parse_file_to_dict(
'foo/bar.sql', f'''
{DESC}
--
-- @column slice_id2 Foo.
-- @column slice_name Bar.
CREATE TABLE bar_table AS
{SQL_STR};
'''.strip())
assert isinstance(res, list)
def test_cols_no_desc(self):
res = parse_file_to_dict(
'foo/bar.sql', f'''
{DESC}
--
-- @column slice_id
-- @column slice_name Bar.
CREATE TABLE bar_table AS
{SQL_STR};
'''.strip())
assert isinstance(res, list)
def test_args_typo(self):
res = parse_file_to_dict(
'foo/bar.sql', f'''
{DESC}
--
-- @arg utid2 INT Uint.
-- @arg name STRING String name.
{RET_STR}
CREATE PERFETTO FUNCTION FOO_FN({ARGS_SQL_STR})
RETURNS {RET_SQL_STR}
AS
{SQL_STR};
'''.strip())
assert isinstance(res, list)
def test_args_no_desc(self):
res = parse_file_to_dict(
'foo/bar.sql', f'''
{DESC}
--
-- @arg utid INT
-- @arg name STRING String name.
{RET_STR}
CREATE PERFETTO FUNCTION FOO_FN({ARGS_SQL_STR})
RETURNS {RET_SQL_STR}
AS
{SQL_STR};
'''.strip())
assert isinstance(res, list)
def test_ret_no_desc(self):
res = parse_file_to_dict(
'foo/bar.sql', f'''
{DESC}
{ARGS_STR}
--
-- @ret BOOL
CREATE PERFETTO FUNCTION FOO_FN({ARGS_SQL_STR})
RETURNS {RET_SQL_STR}
AS
{SQL_STR};
'''.strip())
assert isinstance(res, list)
def test_multiline_desc(self):
res = parse_file_to_dict(
'foo/bar.sql', f'''
-- This
-- is
--
-- a
-- very
--
-- long
--
-- description.
{ARGS_STR}
{RET_STR}
CREATE PERFETTO FUNCTION FOO_FN({ARGS_SQL_STR})
RETURNS {RET_SQL_STR}
AS
{SQL_STR};
'''.strip())
assert isinstance(res, dict)
fn = res['functions'][0]
self.assertEqual(fn['desc'], 'This is a very long description.')
def test_multiline_arg_desc(self):
res = parse_file_to_dict(
'foo/bar.sql', f'''
{DESC}
--
-- @arg utid INT Uint
-- spread
--
-- across lines.
-- @arg name STRING String name
-- which spans across multiple lines
-- inconsistently.
{RET_STR}
CREATE PERFETTO FUNCTION FOO_FN({ARGS_SQL_STR})
RETURNS {RET_SQL_STR}
AS
{SQL_STR};
'''.strip())
assert isinstance(res, dict)
fn = res['functions'][0]
self.assertEqual(
fn['args'], {
'utid': {
'type': 'INT',
'desc': 'Uint spread across lines.',
},
'name': {
'type': 'STRING',
'desc': 'String name which spans across multiple lines '
'inconsistently.',
},
})