Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TDVT quarterly release #1208

Merged
merged 4 commits into from
Dec 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions tdvt/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,61 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


## [2.13.4] - 2023-12-20
- Some nits from making the release PR.

## [2.13.3] - 2023-12-04
- Change ARM tabquery path logic, falling back to regular Mac path if no arm-specific one is found.

## [2.13.2] - 2023-12-04
- Add expecteds with tolerance tags.

## [2.13.1] - 2023-12-01
- Fix bug in Mac ARM path logic.

## [2.13.0] - 2023-11-28
- Add support for Apple Silicon-specific tabquery path in tdvt.ini

## [2.12.0] - 2023-11-14
- Add support for tolerance, changing how test actuals and expecteds are compared to use `math.isclose()` if a tolerance value is included in expected file.

## [2.11.3] - 2023-10-15
- Escape column names in expression tests. Contributed by @wnob via [PR 1194](https://github.com/tableau/connector-plugin-sdk/pull/1194).

## [2.11.2] - 2023-10-09
- Fixed error produced by zip log deletion attempts.
- Added unit testing around BatchQueueWork do_work().

## [2.11.1] - 2023-09-29
- Changed verbiage and added newline to failed test run commands to test results.

## [2.11.0] - 2023-09-27
- Added failed test run commands to test results.

## [2.10.0] - 2023-09-19
- Update logging so `tdvt_log_combined.txt` is less verbose by default, but can have the current output using the `--verbose` flag.
- Update various logging calls to use the appropriate logging level throughout TDVT.
- Fix a bug that kept `tdvt_log_combined.txt` from being created but not being appended.

## [2.9.8] - 2023-09-13
- Add more REGEXP test cases

## [2.9.7] - 2023-08-28
- Added formatting for generated expected files.

## [2.9.6] - 2023-08-28
- Address Spark SQL test issue

## [2.9.5] - 2023-08-28
- Add regex/tds mangling tests.

## [2.9.4] - 2023-08-09
- Add more `dateadd` tests.

## [2.9.3] - 2023-07-26
- PR 1151 from the monolith, add missing metadata argument.

## [2.7.6]. - 2023-10-11
- Use quoting for column references in the expression tests.

Expand Down
2 changes: 2 additions & 0 deletions tdvt/tdvt/config/registry/mac_arm.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[DatasourceRegistry]
all = *
119 changes: 73 additions & 46 deletions tdvt/tdvt/config_gen/datasource_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ def print_configurations(ds_reg, dsname, verbose):
print_ds(ds, ds_reg)



def get_password_file(config):
return config.get('PasswordFile', '')

Expand Down Expand Up @@ -183,11 +182,12 @@ def load_test(config, test_dir=get_root_dir()):
run_time_config.set_tabquery_paths(
dsconfig.get('TabQueryPathLinux', ''),
dsconfig.get('TabQueryPathMac', ''),
dsconfig.get('TabQueryPathMacArm', ''),
dsconfig.get('TabQueryPathx64', '')
)
test_config = TestConfig(config_name, dsconfig['LogicalQueryFormat'], run_time_config)


logging.info("Loading test config for datasource: " + config_name)
# Add the standard test suites.
if standard_tests in config.sections():
try:
Expand All @@ -207,8 +207,9 @@ def load_test(config, test_dir=get_root_dir()):
get_expression_test_dir_path(standard, 'exprtests/standard/'),
test_dir, get_password_file(standard), get_expected_message(standard),
get_is_smoke_test(standard), get_is_test_enabled(standard), False)
logging.info("\tAdded standard tests.")
except KeyError as e:
logging.debug(e)
logging.error(e)
pass

# Add the optional LOD tests.
Expand All @@ -224,74 +225,83 @@ def load_test(config, test_dir=get_root_dir()):
get_expression_test_dir_path(lod, 'exprtests/lodcalcs/'), test_dir,
get_password_file(lod), get_expected_message(lod), get_is_smoke_test(lod),
get_is_test_enabled(lod), False)
logging.info("\tAdded LOD tests.")
except KeyError as e:
logging.debug(e)
logging.error(e)
pass

# Add the optional Staples data check test.
if staples_data_test in config.sections():
try:
staples_data = config[staples_data_test]
all_ini_sections.remove(staples_data_test)
test_config.add_expression_test('expression.staples.', STAPLES_TDS, '',
get_expression_test_dir_path(staples_data, 'exprtests/staples/'),
test_dir, get_password_file(staples_data),
get_expected_message(staples_data), get_is_smoke_test(staples_data),
get_is_test_enabled(staples_data), False)
test_config.add_expression_test(
'expression.staples.', STAPLES_TDS, '', get_expression_test_dir_path(staples_data, 'exprtests/staples/'),
test_dir, get_password_file(staples_data), get_expected_message(staples_data),
get_is_smoke_test(staples_data), get_is_test_enabled(staples_data), False
)
logging.info("\tAdded Staples data check test.")
except KeyError as e:
logging.debug(e)
logging.error(e)
pass

# Add the optional Union test.
if union_test in config.sections():
try:
union = config[union_test]
all_ini_sections.remove(union_test)
test_config.add_logical_test('logical.union.', CALCS_TDS, '',
test_config.get_logical_test_path('logicaltests/setup/union/setup.*.'),
test_dir, get_password_file(union), get_expected_message(union),
get_is_smoke_test(union), get_is_test_enabled(union), False)
test_config.add_logical_test(
'logical.union.', CALCS_TDS, '',
test_config.get_logical_test_path('logicaltests/setup/union/setup.*.'), test_dir,
get_password_file(union), get_expected_message(union), get_is_smoke_test(union),
get_is_test_enabled(union), False
)
logging.info("\tAdded Union tests.")
except KeyError as e:
logging.debug(e)
logging.error(e)
pass

# Add the optional Regex test.
if regex_test in config.sections():
try:
regex = config[regex_test]
all_ini_sections.remove(regex_test)
test_config.add_expression_test('expression.regex.', CALCS_TDS, regex.get(KEY_EXCLUSIONS, ''),
get_expression_test_dir_path(regex, 'exprtests/regexcalcs/'), test_dir,
get_password_file(regex), get_expected_message(regex),
get_is_smoke_test(regex), get_is_test_enabled(regex), False)
test_config.add_expression_test(
'expression.regex.', CALCS_TDS, regex.get(KEY_EXCLUSIONS, ''),
get_expression_test_dir_path(regex, 'exprtests/regexcalcs/'), test_dir, get_password_file(regex),
get_expected_message(regex), get_is_smoke_test(regex), get_is_test_enabled(regex), False)
logging.info("\tAdded Regex tests.")
except KeyError as e:
logging.debug(e)
logging.error(e)
pass

# Add the optional Median test.
if median_test in config.sections():
try:
median = config[median_test]
all_ini_sections.remove(median_test)
test_config.add_expression_test('expression.median.', CALCS_TDS, median.get(KEY_EXCLUSIONS, ''),
get_expression_test_dir_path(median, 'exprtests/median/'), test_dir,
get_password_file(median), get_expected_message(median),
get_is_smoke_test(median), get_is_test_enabled(median), False)
test_config.add_expression_test(
'expression.median.', CALCS_TDS, median.get(KEY_EXCLUSIONS, ''),
get_expression_test_dir_path(median, 'exprtests/median/'), test_dir,
get_password_file(median), get_expected_message(median),
get_is_smoke_test(median), get_is_test_enabled(median), False)
logging.info("\tAdded Median tests.")
except KeyError as e:
logging.debug(e)
logging.error(e)
pass

# Add the optional Percentile test.
if percentile_test in config.sections():
try:
percentile = config[percentile_test]
all_ini_sections.remove(percentile_test)
test_config.add_expression_test('expression.percentile.', CALCS_TDS, percentile.get(KEY_EXCLUSIONS, ''),
'exprtests/percentile', test_dir, get_password_file(percentile),
get_expected_message(percentile), get_is_smoke_test(percentile),
get_is_test_enabled(percentile), False)
test_config.add_expression_test(
'expression.percentile.', CALCS_TDS, percentile.get(KEY_EXCLUSIONS, ''),
'exprtests/percentile', test_dir, get_password_file(percentile), get_expected_message(percentile),
get_is_smoke_test(percentile), get_is_test_enabled(percentile), False)
logging.info("\tAdded Percentile tests.")
except KeyError as e:
logging.debug(e)
logging.error(e)
pass

# Optional logical config settings.
Expand All @@ -308,8 +318,9 @@ def load_test(config, test_dir=get_root_dir()):
else:
cfg_data[name][k] = cfg[k]
test_config.add_logical_config(cfg_data)
logging.info("\tAdded logical config settings.")
except KeyError as e:
logging.debug(e)
logging.error(e)
pass

# This is for custom tables with custom schema
Expand All @@ -336,12 +347,13 @@ def load_test(config, test_dir=get_root_dir()):
if new_expression_test in section or sect.get('Type', '') == 'expression':
try:
all_ini_sections.remove(section)
test_config.add_expression_test(sect.get('Name', ''), tds_name, sect.get(KEY_EXCLUSIONS, ''),
sect.get('TestPath', ''), test_dir, get_password_file(sect),
get_expected_message(sect), get_is_smoke_test(sect),
get_is_test_enabled(sect), False)
test_config.add_expression_test(
sect.get('Name', ''), tds_name, sect.get(KEY_EXCLUSIONS, ''), sect.get('TestPath', ''), test_dir,
get_password_file(sect), get_expected_message(sect), get_is_smoke_test(sect),
get_is_test_enabled(sect), False)
logging.info("\tAdded extra expression test: " + sect.get('Name', ''))
except KeyError as e:
logging.debug(e)
logging.error(e)
pass

# Add any extra logical tests.
Expand All @@ -352,29 +364,34 @@ def load_test(config, test_dir=get_root_dir()):
sect.get('TestPath', ''), test_dir, get_password_file(sect),
get_expected_message(sect), get_is_smoke_test(sect),
get_is_test_enabled(sect), False)
logging.info("\tAdded extra logical test: " + sect.get('Name', ''))
except KeyError as e:
logging.debug(e)
logging.error(e)
pass
# Add smoke tests
elif connection_test in section:
try:
all_ini_sections.remove(section)
test_config.add_logical_test('StaplesConnectionTest', STAPLES_TDS, sect.get(KEY_EXCLUSIONS, ''),
test_config.get_logical_test_path('logicaltests/setup/connection_test/setup.staples.*.'), # noqa: E501
test_config.get_logical_test_path(
'logicaltests/setup/connection_test/setup.staples.*.'), # noqa: E501
test_dir, get_password_file(sect), get_expected_message(sect), True,
get_is_test_enabled(sect, 'StaplesTestEnabled'), False)
test_config.add_expression_test('CastCalcsConnectionTest', CALCS_TDS, sect.get(KEY_EXCLUSIONS, ''),
get_expression_test_dir_path(sect, 'exprtests/pretest/connection_tests/calcs/'), # noqa: E501
get_expression_test_dir_path(sect,
'exprtests/pretest/connection_tests/calcs/'),
# noqa: E501
test_dir, get_password_file(sect), get_expected_message(sect), True,
get_is_test_enabled(sect, 'CastCalcsTestEnabled'), False)
logging.info("\tAdded connection tests.")
except KeyError as e:
logging.debug(e)
logging.error(e)
pass

if all_ini_sections:
logging.debug("Found unparsed sections in the ini file.")
logging.error("Found unparsed sections in the ini file.")
for section in all_ini_sections:
logging.debug("Unparsed section: {0}".format(section))
logging.error("Unparsed section: {0}".format(section))

logging.debug(test_config)
return test_config
Expand All @@ -390,14 +407,14 @@ def __init__(self, ini_file):
# Read all the datasource ini files and load the test configuration.
ini_files = get_all_ini_files_local_first('config')
for f in ini_files:
logging.debug("Reading ini file [{}]".format(f))
logging.info("Reading ini file [{}]".format(f))
config = configparser.ConfigParser()
# Preserve the case of elements.
config.optionxform = str
try:
config.read(f)
except configparser.ParsingError as e:
logging.debug(e)
logging.error(e)
continue

self.add_test(load_test(config))
Expand All @@ -407,7 +424,7 @@ def __init__(self, ini_file):
def load_ini_file(self, ini_file):
# Create the test suites (groups of datasources to test)
registry_ini_file = get_ini_path_local_first('config/registry', ini_file)
logging.debug("Reading registry ini file [{}]".format(registry_ini_file))
logging.info("Reading registry ini file [{}]".format(registry_ini_file))
self.load_registry(registry_ini_file)

def load_registry(self, registry_ini_file):
Expand All @@ -417,7 +434,10 @@ def load_registry(self, registry_ini_file):
ds = config['DatasourceRegistry']

for suite_name in ds:
self.suite_map[suite_name] = [x.strip() for x in self.interpret_ds_list(ds[suite_name], False).split(',')]
self.suite_map[suite_name] = [
x.strip() for x in
self.interpret_ds_list(ds[suite_name], False).split(',')
]

except KeyError:
# Create a simple default.
Expand Down Expand Up @@ -466,6 +486,13 @@ def __init__(self):
super(MacRegistry, self).__init__('mac')


class MacArmRegistry(TestRegistry):
"""Mac ARM specific test suites."""

def __init__(self):
super(MacArmRegistry, self).__init__('mac_arm')


class LinuxRegistry(TestRegistry):
"""Linux specific test suites."""

Expand Down
15 changes: 6 additions & 9 deletions tdvt/tdvt/config_gen/gentests.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@
import os
import re
import shutil

from string import Template
from typing import Dict, List, Tuple

from .templates import template_attributes
from ..constants import CALCS_FIELDS, STAPLES_FIELDS


debug = False


def get_logical_config_templates(ds_registry):
all_templates = template_attributes.copy()

Expand Down Expand Up @@ -129,22 +127,21 @@ def get_modified_line(line, attrs, fields, field_name_map):
new_line = new_line.replace('$Staples$', staples_table_name)
return new_line



def process_test_file(filename, ds_registry, output_dir, col_names: List[List[str]]):
if debug:
print("Processing " + filename)
logging.debug("Processing " + filename)

input_file = open(filename, 'r', encoding='utf-8')
base_name = os.path.basename(filename)
if debug:
print("base_name " + base_name)
logging.debug("base_name " + base_name)
match = re.search('setup\.(.*)\.xml', base_name)
if match:
test_name = match.group(1)
else:
test_name = os.path.splitext(base_name)[0]

if debug:
print("Test " + test_name)
logging.debug("Test " + test_name)

fields = []
for table in col_names:
Expand Down
Loading
Loading