Skip to content

Commit 5e40743

Browse files
authored
Merge pull request #430 from tableau/dev-tdvt
TDVT 2.1.4
2 parents 3f53e9d + 0a61d34 commit 5e40743

12 files changed

Lines changed: 441 additions & 109 deletions

File tree

.gitignore

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# Byte-compiled / optimized / DLL files
2+
__pycache__/
3+
*.py[cod]
4+
*$py.class
5+
6+
# C extensions
7+
*.so
8+
9+
# Distribution / packaging
10+
.Python
11+
build/
12+
develop-eggs/
13+
dist/
14+
downloads/
15+
eggs/
16+
.eggs/
17+
lib/
18+
lib64/
19+
parts/
20+
sdist/
21+
var/
22+
wheels/
23+
pip-wheel-metadata/
24+
share/python-wheels/
25+
*.egg-info/
26+
.installed.cfg
27+
*.egg
28+
MANIFEST
29+
30+
# PyInstaller
31+
# Usually these files are written by a python script from a template
32+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
33+
*.manifest
34+
*.spec
35+
36+
# Installer logs
37+
pip-log.txt
38+
pip-delete-this-directory.txt
39+
40+
# Unit test / coverage reports
41+
htmlcov/
42+
.tox/
43+
.nox/
44+
.coverage
45+
.coverage.*
46+
.cache
47+
nosetests.xml
48+
coverage.xml
49+
*.cover
50+
*.py,cover
51+
.hypothesis/
52+
.pytest_cache/
53+
54+
# Translations
55+
*.mo
56+
*.pot
57+
58+
# Django stuff:
59+
*.log
60+
local_settings.py
61+
db.sqlite3
62+
db.sqlite3-journal
63+
64+
# Flask stuff:
65+
instance/
66+
.webassets-cache
67+
68+
# Scrapy stuff:
69+
.scrapy
70+
71+
# Sphinx documentation
72+
docs/_build/
73+
74+
# PyBuilder
75+
target/
76+
77+
# Jupyter Notebook
78+
.ipynb_checkpoints
79+
80+
# IPython
81+
profile_default/
82+
ipython_config.py
83+
84+
# pyenv
85+
.python-version
86+
87+
# pipenv
88+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
90+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
91+
# install all needed dependencies.
92+
#Pipfile.lock
93+
94+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
95+
__pypackages__/
96+
97+
# Celery stuff
98+
celerybeat-schedule
99+
celerybeat.pid
100+
101+
# SageMath parsed files
102+
*.sage.py
103+
104+
# Environments
105+
.env
106+
.venv
107+
env/
108+
venv/
109+
ENV/
110+
env.bak/
111+
venv.bak/
112+
113+
# Spyder project settings
114+
.spyderproject
115+
.spyproject
116+
117+
# Rope project settings
118+
.ropeproject
119+
120+
# mkdocs documentation
121+
/site
122+
123+
# mypy
124+
.mypy_cache/
125+
.dmypy.json
126+
dmypy.json
127+
128+
# Pyre type checker
129+
.pyre/
130+
131+
# VS Code files
132+
.vscode/
133+
134+
# PyCharm
135+
.idea/
136+
137+
# Connector Packager logs
138+
packager_tests_logs.txt
139+
packaging_logs.txt
140+
141+
# TDVT logs
142+
tabquery_logs.zip
143+
tdvt_actuals_combined.zip
144+
tdvt_log_combined.txt
145+
tdvt_output_combined_failed.json
146+
tdvt_output_combined.json
147+
test_results_combined.csv

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This project consists of documentation, example files, the Tableau Datasource Ve
77
| Tool | Latest Version |
88
|--------------------------------------------------|--------------------|
99
| Connector Packager SDK (Beta) for Tableau 2019.3 | 12-11-2019 |
10-
| TDVT | 2.1.3 (12-30-2019) |
10+
| TDVT | 2.1.4 (02-02-2020) |
1111
| Connector Packager | 0.0.1 (10-03-2019) |
1212

1313
* [Why Connectors?](#why-connectors)

tdvt/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## Unreleased
88

9+
## [2.1.4] - 2020-02-02
10+
- Update smoke tests to count skipped & disabled tests as "pass". Also update the command line results from a TDVT run with more details.
11+
- Refactor list command. list is used with suites and list-logical-configs is just for logical configs.
12+
- Fixes test rerun bug.
13+
914
## [2.1.3] - 2019-12-30
1015
- Add tests specific to Snowflake.
1116

@@ -18,3 +23,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1823
- Compress the log file zip archive. This relies on the zlib module which seems to usually be installed by default.
1924
- More logging about test exclusions.
2025
- Update handling of args.run_file to use Path
26+
- Update TDVT to add `expected_message` to JSON output of failed tests.

tdvt/tdvt/config_gen/datasource_list.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ def print_ds(ds, ds_reg):
2424
for x in test_config.get_logical_tests():
2525
print("\t" * 2 + str(x))
2626
root_directory = get_root_dir()
27-
tests = x.generate_test_file_list_from_config()
27+
tests = x.generate_test_file_list()
2828
for test in tests:
2929
print("\t" * 3 + test.test_path)
3030

3131
print("\tExpression tests:")
3232
for x in test_config.get_expression_tests():
3333
print("\t" * 2 + str(x))
3434
root_directory = get_root_dir()
35-
tests = x.generate_test_file_list_from_config()
35+
tests = x.generate_test_file_list()
3636
for test in tests:
3737
print("\t" * 3 + test.test_path)
3838

tdvt/tdvt/config_gen/test_config.py

Lines changed: 14 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import glob
77
import re
88
from ..resources import *
9+
from ..tabquery_path import TabQueryPath
910

1011
class TestFile(object):
1112
"""
@@ -26,7 +27,8 @@ class TestSet(object):
2627
Represents everything needed to run a set of tests. This includes a path to the test files, which tds etc.
2728
"""
2829
def __init__(self, ds_name, root_dir, config_name, tds_name, exclusions, test_pattern, is_logical, suite_name, password_file,
29-
expected_message, smoke_test=False, test_is_enabled=True, test_is_skipped=False):
30+
expected_message: str = '', smoke_test: bool = False, test_is_enabled: bool = True,
31+
test_is_skipped: bool = False):
3032
self.ds_name = ds_name
3133
self.suite_name = suite_name
3234
self.config_name = config_name
@@ -40,6 +42,8 @@ def __init__(self, ds_name, root_dir, config_name, tds_name, exclusions, test_pa
4042
self.smoke_test = smoke_test
4143
self.test_is_enabled = test_is_enabled
4244
self.test_is_skipped = test_is_skipped
45+
self.test_list_cached = None
46+
self.test_list_checked = False
4347

4448

4549
def is_logical_test(self):
@@ -62,24 +66,20 @@ def generate_test_file_list(self):
6266
Return the sorted list of tests.
6367
6468
"""
65-
final_test_list = self.generate_test_file_list_from_config()
69+
if self.test_list_checked:
70+
return self.test_list_cached
6671

67-
logging.debug("Found final list of " + str(len(final_test_list)) + " tests to run.")
68-
if len(final_test_list) == 0:
69-
logging.warning("Did not find any tests to run.")
70-
print("Did not find any tests to run.")
71-
return final_test_list
72+
final_test_list = self.__generate_test_file_list()
7273

73-
for x in final_test_list:
74-
logging.debug("final test path " + x.test_path)
75-
76-
return final_test_list
74+
self.test_list_cached = final_test_list
75+
self.test_list_checked = True
76+
return self.test_list_cached
7777

7878
def get_test_dirs(self):
7979
return (self.root_dir, get_local_test_dir())
8080

81-
def generate_test_file_list_from_config(self):
82-
"""Read the config file and generate a list of tests."""
81+
def __generate_test_file_list(self):
82+
"""Private function to generate the list of tests."""
8383
allowed_tests = []
8484
exclude_tests = self.get_exclusions()
8585
exclude_tests.append('expected.')
@@ -181,7 +181,7 @@ def get_actual_and_base_file_path(self, test_file, output_dir):
181181
def append_test_file(self, file_path):
182182
self.test_paths.append(file_path)
183183

184-
def generate_test_file_list_from_config(self):
184+
def generate_test_file_list(self):
185185
tests_to_run = []
186186
for test_file in self.test_paths:
187187
added_test = False
@@ -249,30 +249,6 @@ def build_config_name(prefix, dsname):
249249
def build_tds_name(prefix, dsname):
250250
return prefix + dsname + '.tds'
251251

252-
class TabQueryPath(object):
253-
def __init__(self, linux_path, mac_path, windows_path):
254-
self.linux_path = linux_path
255-
self.mac_path = mac_path
256-
self.windows_path = windows_path
257-
258-
@staticmethod
259-
def from_array(paths):
260-
if len(paths) != 3:
261-
raise IndexError
262-
t = TabQueryPath(paths[0], paths[1], paths[2])
263-
return t
264-
265-
def to_array(self):
266-
return [self.linux_path, self.mac_path, self.windows_path]
267-
268-
def get_path(self, os):
269-
if os.startswith("darwin"):
270-
return self.mac_path
271-
elif os.startswith("linux"):
272-
return self.linux_path
273-
else:
274-
return self.windows_path
275-
276252
class RunTimeTestConfig(object):
277253
"""
278254
Tracks specifics about how a group of tests were run.

tdvt/tdvt/tabquery.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
import sys
33

44
from .resources import *
5+
from .tabquery_path import TabQueryPath
6+
57
tab_cli_exe = ''
68

79
def configure_tabquery_path():
@@ -88,8 +90,14 @@ def build_tabquery_command_line(self, work):
8890
work.test_config.command_line = cmdline
8991
return cmdline
9092

91-
def tabquerycli_exists():
93+
def tabquerycli_exists(tabquery_cli_path: TabQueryPath = None):
9294
global tab_cli_exe
95+
if tabquery_cli_path:
96+
resolved_path = tabquery_cli_path.get_path(sys.platform)
97+
if os.path.isfile(resolved_path):
98+
logging.debug("Found tabquery at [{0}]".format(resolved_path))
99+
return True
100+
93101
if os.path.isfile(tab_cli_exe):
94102
logging.debug("Found tabquery at [{0}]".format(tab_cli_exe))
95103
return True

tdvt/tdvt/tabquery_path.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class TabQueryPath(object):
2+
def __init__(self, linux_path, mac_path, windows_path):
3+
self.linux_path = linux_path
4+
self.mac_path = mac_path
5+
self.windows_path = windows_path
6+
7+
@staticmethod
8+
def from_array(paths):
9+
if len(paths) != 3:
10+
raise IndexError
11+
t = TabQueryPath(paths[0], paths[1], paths[2])
12+
return t
13+
14+
def to_array(self):
15+
return [self.linux_path, self.mac_path, self.windows_path]
16+
17+
def get_path(self, os):
18+
if os.startswith("darwin"):
19+
return self.mac_path
20+
elif os.startswith("linux"):
21+
return self.linux_path
22+
else:
23+
return self.windows_path

0 commit comments

Comments
 (0)