Skip to content

Commit cd8a2ce

Browse files
author
aviau
committed
Ensure tests pass without influxdb bin
1 parent 9e40ef2 commit cd8a2ce

File tree

7 files changed

+235
-218
lines changed

7 files changed

+235
-218
lines changed

tests/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# -*- coding: utf-8 -*-
22
import unittest
33
import sys
4+
import os
45

56
using_pypy = hasattr(sys, "pypy_version_info")
67
skipIfPYpy = unittest.skipIf(using_pypy, "Skipping this test on pypy.")
8+
9+
_skip_server_tests = os.environ.get('INFLUXDB_PYTHON_SKIP_SERVER_TESTS', None) == 'True'
10+
skipServerTests = unittest.skipIf(_skip_server_tests, "Skipping server tests...")

tests/influxdb/server_tests/__init__.py

Whitespace-only changes.

tests/influxdb/server_tests/base.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import sys
4+
5+
from tests import using_pypy
6+
from tests.influxdb.server_tests.influxdb_instance import InfluxDbInstance
7+
8+
from influxdb.client import InfluxDBClient
9+
10+
if not using_pypy:
11+
from influxdb.dataframe_client import DataFrameClient
12+
13+
14+
def _setup_influxdb_server(inst):
15+
inst.influxd_inst = InfluxDbInstance(
16+
inst.influxdb_template_conf,
17+
udp_enabled=getattr(inst, 'influxdb_udp_enabled', False),
18+
)
19+
20+
inst.cli = InfluxDBClient('localhost',
21+
inst.influxd_inst.http_port,
22+
'root',
23+
'',
24+
database='db')
25+
if not using_pypy:
26+
inst.cliDF = DataFrameClient('localhost',
27+
inst.influxd_inst.http_port,
28+
'root',
29+
'',
30+
database='db')
31+
32+
33+
def _teardown_influxdb_server(inst):
34+
remove_tree = sys.exc_info() == (None, None, None)
35+
inst.influxd_inst.close(remove_tree=remove_tree)
36+
37+
38+
class SingleTestCaseWithServerMixin(object):
39+
''' A mixin for unittest.TestCase to start an influxdb server instance
40+
in a temporary directory **for each test function/case**
41+
'''
42+
43+
# 'influxdb_template_conf' attribute must be set
44+
# on the TestCase class or instance.
45+
46+
setUp = _setup_influxdb_server
47+
tearDown = _teardown_influxdb_server
48+
49+
50+
class ManyTestCasesWithServerMixin(object):
51+
''' Same than SingleTestCaseWithServerMixin
52+
but creates a single instance for the whole class.
53+
Also pre-creates a fresh database: 'db'.
54+
'''
55+
56+
# 'influxdb_template_conf' attribute must be set on the class itself !
57+
58+
@classmethod
59+
def setUpClass(cls):
60+
_setup_influxdb_server(cls)
61+
62+
def setUp(self):
63+
self.cli.create_database('db')
64+
65+
@classmethod
66+
def tearDownClass(cls):
67+
_teardown_influxdb_server(cls)
68+
69+
def tearDown(self):
70+
self.cli.drop_database('db')

tests/influxdb/client_test_with_server.py renamed to tests/influxdb/server_tests/client_test_with_server.py

Lines changed: 7 additions & 218 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,11 @@
1111
"""
1212

1313
from __future__ import print_function
14-
import datetime
15-
import distutils.spawn
14+
1615
from functools import partial
1716
import os
18-
import shutil
19-
import subprocess
20-
import sys
21-
import tempfile
2217
import time
2318
import unittest
24-
2519
import warnings
2620

2721
# By default, raise exceptions on warnings
@@ -30,50 +24,17 @@
3024
from influxdb import InfluxDBClient
3125
from influxdb.exceptions import InfluxDBClientError
3226

33-
from tests.influxdb.misc import get_free_port, is_port_open
34-
from tests import skipIfPYpy, using_pypy
27+
from tests import skipIfPYpy, using_pypy, skipServerTests
28+
from tests.influxdb.server_tests.base import ManyTestCasesWithServerMixin
29+
from tests.influxdb.server_tests.base import SingleTestCaseWithServerMixin
3530

3631
if not using_pypy:
3732
import pandas as pd
3833
from pandas.util.testing import assert_frame_equal
39-
from influxdb import DataFrameClient
4034

4135

4236
THIS_DIR = os.path.abspath(os.path.dirname(__file__))
4337

44-
#############################################################################
45-
# try to find where the 'influxd' binary is located:
46-
# You can define 'InfluxDbPythonClientTest_SERVER_BIN_PATH'
47-
# env var to force it :
48-
influxdb_bin_path = influxdb_forced_bin = os.environ.get(
49-
'InfluxDbPythonClientTest_SERVER_BIN_PATH', '')
50-
if not influxdb_bin_path:
51-
try:
52-
influxdb_bin_path = distutils.spawn.find_executable('influxd')
53-
if not influxdb_bin_path:
54-
raise Exception('not found via distutils')
55-
except Exception as err:
56-
try:
57-
influxdb_bin_path = subprocess.check_output(
58-
['which', 'influxdb']).strip()
59-
except subprocess.CalledProcessError as err:
60-
# fallback on :
61-
influxdb_bin_path = '/opt/influxdb/influxd'
62-
63-
is_influxdb_bin_ok = (
64-
# if the env var is set then consider the influxdb_bin as OK..
65-
influxdb_forced_bin
66-
or (os.path.isfile(influxdb_bin_path)
67-
and os.access(influxdb_bin_path, os.X_OK))
68-
)
69-
70-
if is_influxdb_bin_ok:
71-
# read version :
72-
version = subprocess.check_output([influxdb_bin_path, 'version'])
73-
print(version, file=sys.stderr)
74-
75-
76-
#############################################################################
7738

7839
def point(serie_name, timestamp=None, tags=None, **fields):
7940
res = {'measurement': serie_name}
@@ -152,174 +113,7 @@ def point(serie_name, timestamp=None, tags=None, **fields):
152113
}
153114
]
154115

155-
#############################################################################
156-
157-
158-
class InfluxDbInstance(object):
159-
''' A class to launch of fresh influxdb server instance
160-
in a temporary place, using a config file template.
161-
'''
162-
163-
def __init__(self, conf_template, udp_enabled=False):
164-
# create a temporary dir to store all needed files
165-
# for the influxdb server instance :
166-
self.temp_dir_base = tempfile.mkdtemp()
167-
# "temp_dir_base" will be used for conf file and logs,
168-
# while "temp_dir_influxdb" is for the databases files/dirs :
169-
tempdir = self.temp_dir_influxdb = tempfile.mkdtemp(
170-
dir=self.temp_dir_base)
171-
# we need some "free" ports :
172-
173-
ports = dict(
174-
http_port=get_free_port(),
175-
admin_port=get_free_port(),
176-
meta_port=get_free_port(),
177-
udp_port=get_free_port() if udp_enabled else -1,
178-
)
179-
180-
conf_data = dict(
181-
meta_dir=os.path.join(tempdir, 'meta'),
182-
data_dir=os.path.join(tempdir, 'data'),
183-
cluster_dir=os.path.join(tempdir, 'state'),
184-
handoff_dir=os.path.join(tempdir, 'handoff'),
185-
logs_file=os.path.join(self.temp_dir_base, 'logs.txt'),
186-
udp_enabled='true' if udp_enabled else 'false',
187-
)
188-
conf_data.update(ports)
189-
self.__dict__.update(conf_data)
190-
191-
conf_file = os.path.join(self.temp_dir_base, 'influxdb.conf')
192-
with open(conf_file, "w") as fh:
193-
with open(conf_template) as fh_template:
194-
fh.write(fh_template.read().format(**conf_data))
195-
196-
# now start the server instance:
197-
proc = self.proc = subprocess.Popen(
198-
[influxdb_bin_path, '-config', conf_file],
199-
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
200-
201-
print("%s > Started influxdb bin in %r with ports %s and %s.." % (
202-
datetime.datetime.now(),
203-
self.temp_dir_base,
204-
self.admin_port, self.http_port))
205-
206-
# wait for it to listen on the broker and admin ports:
207-
# usually a fresh instance is ready in less than 1 sec ..
208-
timeout = time.time() + 10 # so 10 secs should be enough,
209-
# otherwise either your system load is high,
210-
# or you run a 286 @ 1Mhz ?
211-
try:
212-
while time.time() < timeout:
213-
if (is_port_open(self.http_port)
214-
and is_port_open(self.admin_port)):
215-
# it's hard to check if a UDP port is open..
216-
if udp_enabled:
217-
# so let's just sleep 0.5 sec in this case
218-
# to be sure that the server has open the port
219-
time.sleep(0.5)
220-
break
221-
time.sleep(0.5)
222-
if proc.poll() is not None:
223-
raise RuntimeError('influxdb prematurely exited')
224-
else:
225-
proc.terminate()
226-
proc.wait()
227-
raise RuntimeError('Timeout waiting for influxdb to listen'
228-
' on its ports (%s)' % ports)
229-
except RuntimeError as err:
230-
data = self.get_logs_and_output()
231-
data['reason'] = str(err)
232-
data['now'] = datetime.datetime.now()
233-
raise RuntimeError("%(now)s > %(reason)s. RC=%(rc)s\n"
234-
"stdout=%(out)s\nstderr=%(err)s\nlogs=%(logs)r"
235-
% data)
236-
237-
def get_logs_and_output(self):
238-
proc = self.proc
239-
try:
240-
with open(self.logs_file) as fh:
241-
logs = fh.read()
242-
except IOError as err:
243-
logs = "Couldn't read logs: %s" % err
244-
return {
245-
'rc': proc.returncode,
246-
'out': proc.stdout.read(),
247-
'err': proc.stderr.read(),
248-
'logs': logs
249-
}
250-
251-
def close(self, remove_tree=True):
252-
self.proc.terminate()
253-
self.proc.wait()
254-
if remove_tree:
255-
shutil.rmtree(self.temp_dir_base)
256-
257-
############################################################################
258-
259-
260-
def _setup_influxdb_server(inst):
261-
inst.influxd_inst = InfluxDbInstance(
262-
inst.influxdb_template_conf,
263-
udp_enabled=getattr(inst, 'influxdb_udp_enabled', False))
264-
265-
inst.cli = InfluxDBClient('localhost',
266-
inst.influxd_inst.http_port,
267-
'root',
268-
'',
269-
database='db')
270-
if not using_pypy:
271-
inst.cliDF = DataFrameClient('localhost',
272-
inst.influxd_inst.http_port,
273-
'root',
274-
'',
275-
database='db')
276-
277-
278-
def _unsetup_influxdb_server(inst):
279-
remove_tree = sys.exc_info() == (None, None, None)
280-
inst.influxd_inst.close(remove_tree=remove_tree)
281-
282-
############################################################################
283-
284-
285-
class SingleTestCaseWithServerMixin(object):
286-
''' A mixin for unittest.TestCase to start an influxdb server instance
287-
in a temporary directory **for each test function/case**
288-
'''
289-
290-
# 'influxdb_template_conf' attribute must be set
291-
# on the TestCase class or instance.
292-
293-
setUp = _setup_influxdb_server
294-
tearDown = _unsetup_influxdb_server
295-
296-
297-
class ManyTestCasesWithServerMixin(object):
298-
''' Same than SingleTestCaseWithServerMixin
299-
but creates a single instance for the whole class.
300-
Also pre-creates a fresh database: 'db'.
301-
'''
302-
303-
# 'influxdb_template_conf' attribute must be set on the class itself !
304-
305-
@classmethod
306-
def setUpClass(cls):
307-
_setup_influxdb_server(cls)
308-
309-
def setUp(self):
310-
self.cli.create_database('db')
311-
312-
@classmethod
313-
def tearDownClass(cls):
314-
_unsetup_influxdb_server(cls)
315-
316-
def tearDown(self):
317-
self.cli.drop_database('db')
318-
319-
############################################################################
320-
321-
322-
@unittest.skipIf(not is_influxdb_bin_ok, "could not find influxd binary")
116+
@skipServerTests
323117
class SimpleTests(SingleTestCaseWithServerMixin,
324118
unittest.TestCase):
325119

@@ -492,10 +286,7 @@ def test_revoke_privilege_invalid(self):
492286
ctx.exception.content)
493287

494288

495-
############################################################################
496-
497-
498-
@unittest.skipIf(not is_influxdb_bin_ok, "could not find influxd binary")
289+
@skipServerTests
499290
class CommonTests(ManyTestCasesWithServerMixin,
500291
unittest.TestCase):
501292

@@ -858,9 +649,7 @@ def test_query_multiple_series(self):
858649
self.cli.write_points(pts)
859650

860651

861-
############################################################################
862-
863-
@unittest.skipIf(not is_influxdb_bin_ok, "could not find influxd binary")
652+
@skipServerTests
864653
class UdpTests(ManyTestCasesWithServerMixin,
865654
unittest.TestCase):
866655

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy