1#!/usr/bin/env python3
2
3"""Test there is a valid Python environment available.
4
5This is a standalone file that doesn't need any other CHART code and is used to test
6interpreter installation."""
7
8import sys
9import subprocess
10from pathlib import Path
11import warnings
12
13# disable matplotlib warnings about collections
14# (this doesn't work)
15# warnings.simplefilter('ignore')
16# (this also doesn't work)
17# warnings.filterwarnings('ignore', category=DeprecationWarning)
18
19def warn(*args, **kwargs):
20 """Messy but functional way to disable pointless depreciation warnings from matplotlib."""
21 pass
22
23warnings.warn = warn
24
25target = sys.stdout
26
27
28def shell(command):
29 """Run a command in a shell."""
30 # print('>', command)
31 subprocess.run(command.split(' '))
32
33
34def test_interpreter():
35 """Check for a recent Python interpreter."""
36 import platform
37 assert platform.python_version_tuple()[0] >= '3' and platform.python_version_tuple()[1] >= '6'
38
39# def prereq(package, version):
40 # target.write('Found {package} {version}\n'.format(package=package, version=version))
41# ;
42
43# def test_prereq():
44 # """Test suitable prerequisites can be found.
45
46 # This list may not be definitive and the exact requirements depend on the project.
47 # But it's useful to have some kind of standard list.
48
49 # Some of these are only needed for development."""
50 # target.write('Searching for prerequisites...\n')
51
52 # import platform
53 # prereq('python interpreter', platform.python_version())
54
55def test_prereq_expat():
56 import xml.parsers.expat
57 # prereq('expat', xml.parsers.expat.EXPAT_VERSION)
58
59
60def test_prereq_pillow():
61 import PIL
62 # prereq('pillow', PIL.__version__)
63
64
65def test_prereq_numpy():
66 import numpy
67 # prereq('numpy', numpy.version.version)
68
69
70def test_prereq_matplotlib():
71 import matplotlib
72 # prereq('matplotlib', matplotlib.__version__)
73
74
75def test_prereq_lxml():
76 import lxml
77 import lxml.etree
78 # prereq('lxml', lxml.etree.__version__)
79
80
81def test_prereq_django():
82 import django
83 import unslashed
84 # prereq('django', django.__version__)
85 # prereq('django_unslashed', unslashed.__version__)
86
87
88def test_prereq_mysql():
89 # Our code can use either
90 try:
91 import MySQLdb
92 except ImportError:
93 try:
94 import pymysql
95
96 except ImportError:
97 import mysql.connector
98 # prereq('pymysql', pymysql.__version__)
99
100
101def test_prereq_oracle():
102 import cx_Oracle
103 cx_Oracle.clientversion()
104 # prereq('cx_oracle', cx_Oracle.__version__)
105
106
107def test_prereq_supervisor():
108 shell('supervisord')
109 # import supervisor.options
110 # prereq('supervisord', supervisor.options.VERSION)
111
112
113def test_prereq_gunicorn():
114 # import gunicorn
115 # prereq('gunicorn', gunicorn.__version__)
116 shell('gunicorn')
117
118
119def test_prereq_docutils():
120 import docutils
121 # prereq('docutils', docutils.__version__)
122
123
124def test_prereq_pygments():
125 import pygments
126 # prereq('pygments', pygments.__version__)
127
128
129def test_prereq_slimit():
130 # import slimit
131 # prereq('slimit', 'unknown')
132 shell('slimit')
133
134
135def test_prereq_pytest():
136 try:
137 shell('pytest --version')
138 except FileNotFoundError:
139 # Ubuntu packages the python 3 pytest executable as pytest-3
140 shell('pytest --version')
141 # shell('pytest-3 --version')
142 # shell('pytest-3.6 --version')
143
144 import pytest
145 # prereq('pytest', pytest.__version__)
146
147
148def test_prereq_fabulous():
149 import fabulous
150 # prereq('fabulous', fabulous.__version__)
151
152
153def test_prereq_astor():
154 """This replaces codegen. Do not install or check for codegen.
155
156 The settings tool needs this."""
157 import astor
158 # prereq('astor', astor.__version__)
159
160
161def test_prereq_paramiko():
162 import paramiko
163 # prereq('paramiko', docutils.__version__)
164
165
166def test_prereq_xlrd():
167 """Excel library used by chartmsg."""
168 import xlrd
169 # prereq('xlrd', xlrd.__VERSION__)
170
171
172def test_prereq_matplotlib():
173 import matplotlib
174
175
176def test_prereq_fonts():
177 import matplotlib.font_manager
178 dejavu = [Path(i).name for i in matplotlib.font_manager.findSystemFonts(
179 fontpaths=None, fontext='ttf') if 'DejaVu' in i]
180 sans = [Path(i).name for i in matplotlib.font_manager.findSystemFonts(
181 fontpaths=None, fontext='ttf') if 'Sans' in i]
182 assert len(dejavu) > 0 or len(sans) > 0
183 # prereq('devavu fonts', len(dejavu))
184
185
186def test_prereq_cartopy():
187 try:
188 import cartopy
189
190 except ImportError:
191 from mpl_toolkits import basemap
192
193
194# def test_prereq_ucmclient():
195 # import ucmclient
196 # prereq('ucmclient', 'unknown')
197
198
199# aspell removed because it was only ever used to detect French text in CHART-EPS
200# parameter descriptions in order to auto-translate them, but that feature hasn't worked for a
201# long time and everyone is used to the original text by now anyway
202# def test_prereq_aspell():
203 # """Check installation of aspell."""
204 # aspell = subprocess.run(['aspell', '--version'], capture_output=True).stdout.decode(
205 # 'latin-1').strip()
206 # prereq('aspell', aspell)
207 # aspell_en = [i for i in subprocess.run(['aspell', '--help'], capture_output=True).stdout.decode(
208 # 'latin-1').split('\n') if i == ' en']
209 # prereq('aspell-en', len(aspell_en))
210 # shell('aspell')
211
212
213def test_prereq_trang():
214 # trang = subprocess.run(['trang'], capture_output=True).stdout.decode('latin-1').strip()
215 # prereq('trang', trang)
216 shell('trang')
217
218
219def test_prereq_rlwrap():
220 # rlwrap = subprocess.run(['rlwrap', '-v'], capture_output=True).stdout.decode('latin-1').strip()
221 # prereq('rlwrap', rlwrap)
222 shell('rlwrap')
223
224
225def test_prereq_postgres_psycopg2():
226 import psycopg2
227
228
229def test_prereq_postgres_psql():
230 shell('psql')
231
232
233def test_prereq_bugs():
234 """Over time we've hit various bugs in the compiler and libraries."""
235
236 # we once had an interpreter that returned "3155327:0000.0"
237 # due to some weird over-ambitious gcc optimisations
238 assert str(315532800000-0.0) == '315532800000.0'
239
240 # some versions of numpy compiled on older gcc versions cannot detect NaN values
241 import numpy
242 assert numpy.isnan(numpy.nan)
243
244 # struct decoding error that happened (gcc optimisation again I think)
245 import struct
246 assert struct.unpack('>f', b'\x00\x00\x00\x04')[0] == 5.605193857299268e-45
247
248 # struct decoding error after importing all of lxml (just a bad release of lxml)
249 from lxml import etree
250 assert struct.unpack('>f', b'\x00\x00\x00\x01')[0] == 1.401298464324817e-45
251
252 # Here, we could try to validate the build environment
253 # import sysconfig
254 # sysconfig.get_config_vars()['CFLAGS']
255 # sysconfig.get_config_vars()['CONFIGURE_CFLAGS']
256 # sysconfig.get_config_vars()['PY_CFLAGS']
257 # sysconfig.get_config_vars()['PY_CORE_CFLAGS']
258 # sysconfig.get_config_vars()['CONFIG_ARGS']
259 # sysconfig.get_config_vars()['OPT']
260
261
262if __name__ == '__main__':
263 here = __file__
264 test_interpreter()
265 try:
266 shell('pytest --version')
267 except FileNotFoundError:
268 # Ubuntu packages the python 3 pytest executable as pytest-3
269 # shell('pytest-3 --version')
270 shell('pytest --version')
271 # shell('pytest-3.6 --version')
272
273 import pytest
274 print('\nBasic test succeeded. Now run "pytest -v {here}" to run the full test'.format(here=here))