added forced package imports

This commit is contained in:
Nicholas St. Germain 2018-12-02 13:38:37 -06:00
parent 0e2ffdbbb1
commit ef9022c6eb
943 changed files with 125530 additions and 16 deletions

View file

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
"""Define the influxdb08 test package."""

View file

@ -0,0 +1,904 @@
# -*- coding: utf-8 -*-
"""Client unit tests."""
import json
import socket
import sys
import unittest
import random
import warnings
import mock
import requests
import requests.exceptions
import requests_mock
from nose.tools import raises
from mock import patch
from influxdb.influxdb08 import InfluxDBClient
from influxdb.influxdb08.client import session
if sys.version < '3':
import codecs
def u(x):
"""Test codec."""
return codecs.unicode_escape_decode(x)[0]
else:
def u(x):
"""Test codec."""
return x
def _build_response_object(status_code=200, content=""):
resp = requests.Response()
resp.status_code = status_code
resp._content = content.encode("utf8")
return resp
def _mocked_session(method="GET", status_code=200, content=""):
method = method.upper()
def request(*args, **kwargs):
"""Define a request for the _mocked_session."""
c = content
# Check method
assert method == kwargs.get('method', 'GET')
if method == 'POST':
data = kwargs.get('data', None)
if data is not None:
# Data must be a string
assert isinstance(data, str)
# Data must be a JSON string
assert c == json.loads(data, strict=True)
c = data
# Anyway, Content must be a JSON string (or empty string)
if not isinstance(c, str):
c = json.dumps(c)
return _build_response_object(status_code=status_code, content=c)
mocked = patch.object(
session,
'request',
side_effect=request
)
return mocked
class TestInfluxDBClient(unittest.TestCase):
"""Define a TestInfluxDBClient object."""
def setUp(self):
"""Set up a TestInfluxDBClient object."""
# By default, raise exceptions on warnings
warnings.simplefilter('error', FutureWarning)
self.dummy_points = [
{
"points": [
["1", 1, 1.0],
["2", 2, 2.0]
],
"name": "foo",
"columns": ["column_one", "column_two", "column_three"]
}
]
self.dsn_string = 'influxdb://uSr:pWd@host:1886/db'
def test_scheme(self):
"""Test database scheme for TestInfluxDBClient object."""
cli = InfluxDBClient('host', 8086, 'username', 'password', 'database')
self.assertEqual(cli._baseurl, 'http://host:8086')
cli = InfluxDBClient(
'host', 8086, 'username', 'password', 'database', ssl=True
)
self.assertEqual(cli._baseurl, 'https://host:8086')
def test_dsn(self):
"""Test datasource name for TestInfluxDBClient object."""
cli = InfluxDBClient.from_dsn(self.dsn_string)
self.assertEqual('http://host:1886', cli._baseurl)
self.assertEqual('uSr', cli._username)
self.assertEqual('pWd', cli._password)
self.assertEqual('db', cli._database)
self.assertFalse(cli._use_udp)
cli = InfluxDBClient.from_dsn('udp+' + self.dsn_string)
self.assertTrue(cli._use_udp)
cli = InfluxDBClient.from_dsn('https+' + self.dsn_string)
self.assertEqual('https://host:1886', cli._baseurl)
cli = InfluxDBClient.from_dsn('https+' + self.dsn_string,
**{'ssl': False})
self.assertEqual('http://host:1886', cli._baseurl)
def test_switch_database(self):
"""Test switch database for TestInfluxDBClient object."""
cli = InfluxDBClient('host', 8086, 'username', 'password', 'database')
cli.switch_database('another_database')
self.assertEqual(cli._database, 'another_database')
@raises(FutureWarning)
def test_switch_db_deprecated(self):
"""Test deprecated switch database for TestInfluxDBClient object."""
cli = InfluxDBClient('host', 8086, 'username', 'password', 'database')
cli.switch_db('another_database')
self.assertEqual(cli._database, 'another_database')
def test_switch_user(self):
"""Test switch user for TestInfluxDBClient object."""
cli = InfluxDBClient('host', 8086, 'username', 'password', 'database')
cli.switch_user('another_username', 'another_password')
self.assertEqual(cli._username, 'another_username')
self.assertEqual(cli._password, 'another_password')
def test_write(self):
"""Test write to database for TestInfluxDBClient object."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.POST,
"http://localhost:8086/write"
)
cli = InfluxDBClient(database='db')
cli.write(
{"database": "mydb",
"retentionPolicy": "mypolicy",
"points": [{"name": "cpu_load_short",
"tags": {"host": "server01",
"region": "us-west"},
"timestamp": "2009-11-10T23:00:00Z",
"values": {"value": 0.64}}]}
)
self.assertEqual(
json.loads(m.last_request.body),
{"database": "mydb",
"retentionPolicy": "mypolicy",
"points": [{"name": "cpu_load_short",
"tags": {"host": "server01",
"region": "us-west"},
"timestamp": "2009-11-10T23:00:00Z",
"values": {"value": 0.64}}]}
)
def test_write_points(self):
"""Test write points for TestInfluxDBClient object."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.POST,
"http://localhost:8086/db/db/series"
)
cli = InfluxDBClient(database='db')
cli.write_points(
self.dummy_points
)
self.assertListEqual(
json.loads(m.last_request.body),
self.dummy_points
)
def test_write_points_string(self):
"""Test write string points for TestInfluxDBClient object."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.POST,
"http://localhost:8086/db/db/series"
)
cli = InfluxDBClient(database='db')
cli.write_points(
str(json.dumps(self.dummy_points))
)
self.assertListEqual(
json.loads(m.last_request.body),
self.dummy_points
)
def test_write_points_batch(self):
"""Test write batch points for TestInfluxDBClient object."""
with requests_mock.Mocker() as m:
m.register_uri(requests_mock.POST,
"http://localhost:8086/db/db/series")
cli = InfluxDBClient('localhost', 8086,
'username', 'password', 'db')
cli.write_points(data=self.dummy_points, batch_size=2)
self.assertEqual(1, m.call_count)
def test_write_points_batch_invalid_size(self):
"""Test write batch points invalid size for TestInfluxDBClient."""
with requests_mock.Mocker() as m:
m.register_uri(requests_mock.POST,
"http://localhost:8086/db/db/series")
cli = InfluxDBClient('localhost', 8086,
'username', 'password', 'db')
cli.write_points(data=self.dummy_points, batch_size=-2)
self.assertEqual(1, m.call_count)
def test_write_points_batch_multiple_series(self):
"""Test write points batch multiple series."""
dummy_points = [
{"points": [["1", 1, 1.0], ["2", 2, 2.0], ["3", 3, 3.0],
["4", 4, 4.0], ["5", 5, 5.0]],
"name": "foo",
"columns": ["val1", "val2", "val3"]},
{"points": [["1", 1, 1.0], ["2", 2, 2.0], ["3", 3, 3.0],
["4", 4, 4.0], ["5", 5, 5.0], ["6", 6, 6.0],
["7", 7, 7.0], ["8", 8, 8.0]],
"name": "bar",
"columns": ["val1", "val2", "val3"]},
]
expected_last_body = [{'points': [['7', 7, 7.0], ['8', 8, 8.0]],
'name': 'bar',
'columns': ['val1', 'val2', 'val3']}]
with requests_mock.Mocker() as m:
m.register_uri(requests_mock.POST,
"http://localhost:8086/db/db/series")
cli = InfluxDBClient('localhost', 8086,
'username', 'password', 'db')
cli.write_points(data=dummy_points, batch_size=3)
self.assertEqual(m.call_count, 5)
self.assertEqual(expected_last_body, m.request_history[4].json())
def test_write_points_udp(self):
"""Test write points UDP for TestInfluxDBClient object."""
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
port = random.randint(4000, 8000)
s.bind(('0.0.0.0', port))
cli = InfluxDBClient(
'localhost', 8086, 'root', 'root',
'test', use_udp=True, udp_port=port
)
cli.write_points(self.dummy_points)
received_data, addr = s.recvfrom(1024)
self.assertEqual(self.dummy_points,
json.loads(received_data.decode(), strict=True))
def test_write_bad_precision_udp(self):
"""Test write UDP w/bad precision."""
cli = InfluxDBClient(
'localhost', 8086, 'root', 'root',
'test', use_udp=True, udp_port=4444
)
with self.assertRaisesRegexp(
Exception,
"InfluxDB only supports seconds precision for udp writes"
):
cli.write_points(
self.dummy_points,
time_precision='ms'
)
@raises(Exception)
def test_write_points_fails(self):
"""Test failed write points for TestInfluxDBClient object."""
with _mocked_session('post', 500):
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.write_points([])
def test_write_points_with_precision(self):
"""Test write points with precision."""
with _mocked_session('post', 200, self.dummy_points):
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
self.assertTrue(cli.write_points(self.dummy_points))
def test_write_points_bad_precision(self):
"""Test write points with bad precision."""
cli = InfluxDBClient()
with self.assertRaisesRegexp(
Exception,
"Invalid time precision is given. \(use 's', 'm', 'ms' or 'u'\)"
):
cli.write_points(
self.dummy_points,
time_precision='g'
)
@raises(Exception)
def test_write_points_with_precision_fails(self):
"""Test write points where precision fails."""
with _mocked_session('post', 500):
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.write_points_with_precision([])
def test_delete_points(self):
"""Test delete points for TestInfluxDBClient object."""
with _mocked_session('delete', 204) as mocked:
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
self.assertTrue(cli.delete_points("foo"))
self.assertEqual(len(mocked.call_args_list), 1)
args, kwds = mocked.call_args_list[0]
self.assertEqual(kwds['params'],
{'u': 'username', 'p': 'password'})
self.assertEqual(kwds['url'], 'http://host:8086/db/db/series/foo')
@raises(Exception)
def test_delete_points_with_wrong_name(self):
"""Test delete points with wrong name."""
with _mocked_session('delete', 400):
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.delete_points("nonexist")
@raises(NotImplementedError)
def test_create_scheduled_delete(self):
"""Test create scheduled deletes."""
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.create_scheduled_delete([])
@raises(NotImplementedError)
def test_get_list_scheduled_delete(self):
"""Test get schedule list of deletes TestInfluxDBClient."""
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.get_list_scheduled_delete()
@raises(NotImplementedError)
def test_remove_scheduled_delete(self):
"""Test remove scheduled delete TestInfluxDBClient."""
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.remove_scheduled_delete(1)
def test_query(self):
"""Test query for TestInfluxDBClient object."""
data = [
{
"name": "foo",
"columns": ["time", "sequence_number", "column_one"],
"points": [
[1383876043, 16, "2"], [1383876043, 15, "1"],
[1383876035, 14, "2"], [1383876035, 13, "1"]
]
}
]
with _mocked_session('get', 200, data):
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
result = cli.query('select column_one from foo;')
self.assertEqual(len(result[0]['points']), 4)
def test_query_chunked(self):
"""Test chunked query for TestInfluxDBClient object."""
cli = InfluxDBClient(database='db')
example_object = {
'points': [
[1415206250119, 40001, 667],
[1415206244555, 30001, 7],
[1415206228241, 20001, 788],
[1415206212980, 10001, 555],
[1415197271586, 10001, 23]
],
'name': 'foo',
'columns': [
'time',
'sequence_number',
'val'
]
}
example_response = \
json.dumps(example_object) + json.dumps(example_object)
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
"http://localhost:8086/db/db/series",
text=example_response
)
self.assertListEqual(
cli.query('select * from foo', chunked=True),
[example_object, example_object]
)
def test_query_chunked_unicode(self):
"""Test unicode chunked query for TestInfluxDBClient object."""
cli = InfluxDBClient(database='db')
example_object = {
'points': [
[1415206212980, 10001, u('unicode-\xcf\x89')],
[1415197271586, 10001, u('more-unicode-\xcf\x90')]
],
'name': 'foo',
'columns': [
'time',
'sequence_number',
'val'
]
}
example_response = \
json.dumps(example_object) + json.dumps(example_object)
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
"http://localhost:8086/db/db/series",
text=example_response
)
self.assertListEqual(
cli.query('select * from foo', chunked=True),
[example_object, example_object]
)
@raises(Exception)
def test_query_fail(self):
"""Test failed query for TestInfluxDBClient."""
with _mocked_session('get', 401):
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.query('select column_one from foo;')
def test_query_bad_precision(self):
"""Test query with bad precision for TestInfluxDBClient."""
cli = InfluxDBClient()
with self.assertRaisesRegexp(
Exception,
"Invalid time precision is given. \(use 's', 'm', 'ms' or 'u'\)"
):
cli.query('select column_one from foo', time_precision='g')
def test_create_database(self):
"""Test create database for TestInfluxDBClient."""
with _mocked_session('post', 201, {"name": "new_db"}):
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
self.assertTrue(cli.create_database('new_db'))
@raises(Exception)
def test_create_database_fails(self):
"""Test failed create database for TestInfluxDBClient."""
with _mocked_session('post', 401):
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.create_database('new_db')
def test_delete_database(self):
"""Test delete database for TestInfluxDBClient."""
with _mocked_session('delete', 204):
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
self.assertTrue(cli.delete_database('old_db'))
@raises(Exception)
def test_delete_database_fails(self):
"""Test failed delete database for TestInfluxDBClient."""
with _mocked_session('delete', 401):
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.delete_database('old_db')
def test_get_list_database(self):
"""Test get list of databases for TestInfluxDBClient."""
data = [
{"name": "a_db"}
]
with _mocked_session('get', 200, data):
cli = InfluxDBClient('host', 8086, 'username', 'password')
self.assertEqual(len(cli.get_list_database()), 1)
self.assertEqual(cli.get_list_database()[0]['name'], 'a_db')
@raises(Exception)
def test_get_list_database_fails(self):
"""Test failed get list of databases for TestInfluxDBClient."""
with _mocked_session('get', 401):
cli = InfluxDBClient('host', 8086, 'username', 'password')
cli.get_list_database()
@raises(FutureWarning)
def test_get_database_list_deprecated(self):
"""Test deprecated get database list for TestInfluxDBClient."""
data = [
{"name": "a_db"}
]
with _mocked_session('get', 200, data):
cli = InfluxDBClient('host', 8086, 'username', 'password')
self.assertEqual(len(cli.get_database_list()), 1)
self.assertEqual(cli.get_database_list()[0]['name'], 'a_db')
def test_delete_series(self):
"""Test delete series for TestInfluxDBClient."""
with _mocked_session('delete', 204):
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.delete_series('old_series')
@raises(Exception)
def test_delete_series_fails(self):
"""Test failed delete series for TestInfluxDBClient."""
with _mocked_session('delete', 401):
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.delete_series('old_series')
def test_get_series_list(self):
"""Test get list of series for TestInfluxDBClient."""
cli = InfluxDBClient(database='db')
with requests_mock.Mocker() as m:
example_response = \
'[{"name":"list_series_result","columns":' \
'["time","name"],"points":[[0,"foo"],[0,"bar"]]}]'
m.register_uri(
requests_mock.GET,
"http://localhost:8086/db/db/series",
text=example_response
)
self.assertListEqual(
cli.get_list_series(),
['foo', 'bar']
)
def test_get_continuous_queries(self):
"""Test get continuous queries for TestInfluxDBClient."""
cli = InfluxDBClient(database='db')
with requests_mock.Mocker() as m:
# Tip: put this in a json linter!
example_response = '[ { "name": "continuous queries", "columns"' \
': [ "time", "id", "query" ], "points": [ [ ' \
'0, 1, "select foo(bar,95) from \\"foo_bar' \
's\\" group by time(5m) into response_times.' \
'percentiles.5m.95" ], [ 0, 2, "select perce' \
'ntile(value,95) from \\"response_times\\" g' \
'roup by time(5m) into response_times.percen' \
'tiles.5m.95" ] ] } ]'
m.register_uri(
requests_mock.GET,
"http://localhost:8086/db/db/series",
text=example_response
)
self.assertListEqual(
cli.get_list_continuous_queries(),
[
'select foo(bar,95) from "foo_bars" group '
'by time(5m) into response_times.percentiles.5m.95',
'select percentile(value,95) from "response_times" group '
'by time(5m) into response_times.percentiles.5m.95'
]
)
def test_get_list_cluster_admins(self):
"""Test get list of cluster admins, not implemented."""
pass
def test_add_cluster_admin(self):
"""Test add cluster admin for TestInfluxDBClient."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.POST,
"http://localhost:8086/cluster_admins"
)
cli = InfluxDBClient(database='db')
cli.add_cluster_admin(
new_username='paul',
new_password='laup'
)
self.assertDictEqual(
json.loads(m.last_request.body),
{
'name': 'paul',
'password': 'laup'
}
)
def test_update_cluster_admin_password(self):
"""Test update cluster admin pass for TestInfluxDBClient."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.POST,
"http://localhost:8086/cluster_admins/paul"
)
cli = InfluxDBClient(database='db')
cli.update_cluster_admin_password(
username='paul',
new_password='laup'
)
self.assertDictEqual(
json.loads(m.last_request.body),
{'password': 'laup'}
)
def test_delete_cluster_admin(self):
"""Test delete cluster admin for TestInfluxDBClient."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.DELETE,
"http://localhost:8086/cluster_admins/paul",
status_code=200,
)
cli = InfluxDBClient(database='db')
cli.delete_cluster_admin(username='paul')
self.assertIsNone(m.last_request.body)
def test_set_database_admin(self):
"""Test set database admin for TestInfluxDBClient."""
pass
def test_unset_database_admin(self):
"""Test unset database admin for TestInfluxDBClient."""
pass
def test_alter_database_admin(self):
"""Test alter database admin for TestInfluxDBClient."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.POST,
"http://localhost:8086/db/db/users/paul"
)
cli = InfluxDBClient(database='db')
cli.alter_database_admin(
username='paul',
is_admin=False
)
self.assertDictEqual(
json.loads(m.last_request.body),
{
'admin': False
}
)
@raises(NotImplementedError)
def test_get_list_database_admins(self):
"""Test get list of database admins for TestInfluxDBClient."""
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.get_list_database_admins()
@raises(NotImplementedError)
def test_add_database_admin(self):
"""Test add database admins for TestInfluxDBClient."""
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.add_database_admin('admin', 'admin_secret_password')
@raises(NotImplementedError)
def test_update_database_admin_password(self):
"""Test update database admin pass for TestInfluxDBClient."""
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.update_database_admin_password('admin', 'admin_secret_password')
@raises(NotImplementedError)
def test_delete_database_admin(self):
"""Test delete database admin for TestInfluxDBClient."""
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.delete_database_admin('admin')
def test_get_database_users(self):
"""Test get database users for TestInfluxDBClient."""
cli = InfluxDBClient('localhost', 8086, 'username', 'password', 'db')
example_response = \
'[{"name":"paul","isAdmin":false,"writeTo":".*","readFrom":".*"},'\
'{"name":"bobby","isAdmin":false,"writeTo":".*","readFrom":".*"}]'
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.GET,
"http://localhost:8086/db/db/users",
text=example_response
)
users = cli.get_database_users()
self.assertEqual(json.loads(example_response), users)
def test_add_database_user(self):
"""Test add database user for TestInfluxDBClient."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.POST,
"http://localhost:8086/db/db/users"
)
cli = InfluxDBClient(database='db')
cli.add_database_user(
new_username='paul',
new_password='laup',
permissions=('.*', '.*')
)
self.assertDictEqual(
json.loads(m.last_request.body),
{
'writeTo': '.*',
'password': 'laup',
'readFrom': '.*',
'name': 'paul'
}
)
def test_add_database_user_bad_permissions(self):
"""Test add database user with bad perms for TestInfluxDBClient."""
cli = InfluxDBClient()
with self.assertRaisesRegexp(
Exception,
"'permissions' must be \(readFrom, writeTo\) tuple"
):
cli.add_database_user(
new_password='paul',
new_username='paul',
permissions=('hello', 'hello', 'hello')
)
def test_alter_database_user_password(self):
"""Test alter database user pass for TestInfluxDBClient."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.POST,
"http://localhost:8086/db/db/users/paul"
)
cli = InfluxDBClient(database='db')
cli.alter_database_user(
username='paul',
password='n3wp4ss!'
)
self.assertDictEqual(
json.loads(m.last_request.body),
{
'password': 'n3wp4ss!'
}
)
def test_alter_database_user_permissions(self):
"""Test alter database user perms for TestInfluxDBClient."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.POST,
"http://localhost:8086/db/db/users/paul"
)
cli = InfluxDBClient(database='db')
cli.alter_database_user(
username='paul',
permissions=('^$', '.*')
)
self.assertDictEqual(
json.loads(m.last_request.body),
{
'readFrom': '^$',
'writeTo': '.*'
}
)
def test_alter_database_user_password_and_permissions(self):
"""Test alter database user pass and perms for TestInfluxDBClient."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.POST,
"http://localhost:8086/db/db/users/paul"
)
cli = InfluxDBClient(database='db')
cli.alter_database_user(
username='paul',
password='n3wp4ss!',
permissions=('^$', '.*')
)
self.assertDictEqual(
json.loads(m.last_request.body),
{
'password': 'n3wp4ss!',
'readFrom': '^$',
'writeTo': '.*'
}
)
def test_update_database_user_password_current_user(self):
"""Test update database user pass for TestInfluxDBClient."""
cli = InfluxDBClient(
username='root',
password='hello',
database='database'
)
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.POST,
"http://localhost:8086/db/database/users/root"
)
cli.update_database_user_password(
username='root',
new_password='bye'
)
self.assertEqual(cli._password, 'bye')
def test_delete_database_user(self):
"""Test delete database user for TestInfluxDBClient."""
with requests_mock.Mocker() as m:
m.register_uri(
requests_mock.DELETE,
"http://localhost:8086/db/db/users/paul"
)
cli = InfluxDBClient(database='db')
cli.delete_database_user(username='paul')
self.assertIsNone(m.last_request.body)
@raises(NotImplementedError)
def test_update_permission(self):
"""Test update permission for TestInfluxDBClient."""
cli = InfluxDBClient('host', 8086, 'username', 'password', 'db')
cli.update_permission('admin', [])
@mock.patch('requests.Session.request')
def test_request_retry(self, mock_request):
"""Test that two connection errors will be handled."""
class CustomMock(object):
"""Define CustomMock object."""
def __init__(self):
self.i = 0
def connection_error(self, *args, **kwargs):
"""Test connection error in CustomMock."""
self.i += 1
if self.i < 3:
raise requests.exceptions.ConnectionError
else:
r = requests.Response()
r.status_code = 200
return r
mock_request.side_effect = CustomMock().connection_error
cli = InfluxDBClient(database='db')
cli.write_points(
self.dummy_points
)
@mock.patch('requests.Session.request')
def test_request_retry_raises(self, mock_request):
"""Test that three connection errors will not be handled."""
class CustomMock(object):
"""Define CustomMock object."""
def __init__(self):
"""Initialize the object."""
self.i = 0
def connection_error(self, *args, **kwargs):
"""Test the connection error for CustomMock."""
self.i += 1
if self.i < 4:
raise requests.exceptions.ConnectionError
else:
r = requests.Response()
r.status_code = 200
return r
mock_request.side_effect = CustomMock().connection_error
cli = InfluxDBClient(database='db')
with self.assertRaises(requests.exceptions.ConnectionError):
cli.write_points(self.dummy_points)

View file

@ -0,0 +1,331 @@
# -*- coding: utf-8 -*-
"""Unit tests for misc module."""
from datetime import timedelta
import copy
import json
import unittest
import warnings
import requests_mock
from nose.tools import raises
from influxdb.tests import skipIfPYpy, using_pypy
from .client_test import _mocked_session
if not using_pypy:
import pandas as pd
from pandas.util.testing import assert_frame_equal
from influxdb.influxdb08 import DataFrameClient
@skipIfPYpy
class TestDataFrameClient(unittest.TestCase):
"""Define the DataFramClient test object."""
def setUp(self):
"""Set up an instance of TestDataFrameClient object."""
# By default, raise exceptions on warnings
warnings.simplefilter('error', FutureWarning)
def test_write_points_from_dataframe(self):
"""Test write points from dataframe."""
now = pd.Timestamp('1970-01-01 00:00+00:00')
dataframe = pd.DataFrame(data=[["1", 1, 1.0], ["2", 2, 2.0]],
index=[now, now + timedelta(hours=1)],
columns=["column_one", "column_two",
"column_three"])
points = [
{
"points": [
["1", 1, 1.0, 0],
["2", 2, 2.0, 3600]
],
"name": "foo",
"columns": ["column_one", "column_two", "column_three", "time"]
}
]
with requests_mock.Mocker() as m:
m.register_uri(requests_mock.POST,
"http://localhost:8086/db/db/series")
cli = DataFrameClient(database='db')
cli.write_points({"foo": dataframe})
self.assertListEqual(json.loads(m.last_request.body), points)
def test_write_points_from_dataframe_with_float_nan(self):
"""Test write points from dataframe with NaN float."""
now = pd.Timestamp('1970-01-01 00:00+00:00')
dataframe = pd.DataFrame(data=[[1, float("NaN"), 1.0], [2, 2, 2.0]],
index=[now, now + timedelta(hours=1)],
columns=["column_one", "column_two",
"column_three"])
points = [
{
"points": [
[1, None, 1.0, 0],
[2, 2, 2.0, 3600]
],
"name": "foo",
"columns": ["column_one", "column_two", "column_three", "time"]
}
]
with requests_mock.Mocker() as m:
m.register_uri(requests_mock.POST,
"http://localhost:8086/db/db/series")
cli = DataFrameClient(database='db')
cli.write_points({"foo": dataframe})
self.assertListEqual(json.loads(m.last_request.body), points)
def test_write_points_from_dataframe_in_batches(self):
"""Test write points from dataframe in batches."""
now = pd.Timestamp('1970-01-01 00:00+00:00')
dataframe = pd.DataFrame(data=[["1", 1, 1.0], ["2", 2, 2.0]],
index=[now, now + timedelta(hours=1)],
columns=["column_one", "column_two",
"column_three"])
with requests_mock.Mocker() as m:
m.register_uri(requests_mock.POST,
"http://localhost:8086/db/db/series")
cli = DataFrameClient(database='db')
self.assertTrue(cli.write_points({"foo": dataframe}, batch_size=1))
def test_write_points_from_dataframe_with_numeric_column_names(self):
"""Test write points from dataframe with numeric columns."""
now = pd.Timestamp('1970-01-01 00:00+00:00')
# df with numeric column names
dataframe = pd.DataFrame(data=[["1", 1, 1.0], ["2", 2, 2.0]],
index=[now, now + timedelta(hours=1)])
points = [
{
"points": [
["1", 1, 1.0, 0],
["2", 2, 2.0, 3600]
],
"name": "foo",
"columns": ['0', '1', '2', "time"]
}
]
with requests_mock.Mocker() as m:
m.register_uri(requests_mock.POST,
"http://localhost:8086/db/db/series")
cli = DataFrameClient(database='db')
cli.write_points({"foo": dataframe})
self.assertListEqual(json.loads(m.last_request.body), points)
def test_write_points_from_dataframe_with_period_index(self):
"""Test write points from dataframe with period index."""
dataframe = pd.DataFrame(data=[["1", 1, 1.0], ["2", 2, 2.0]],
index=[pd.Period('1970-01-01'),
pd.Period('1970-01-02')],
columns=["column_one", "column_two",
"column_three"])
points = [
{
"points": [
["1", 1, 1.0, 0],
["2", 2, 2.0, 86400]
],
"name": "foo",
"columns": ["column_one", "column_two", "column_three", "time"]
}
]
with requests_mock.Mocker() as m:
m.register_uri(requests_mock.POST,
"http://localhost:8086/db/db/series")
cli = DataFrameClient(database='db')
cli.write_points({"foo": dataframe})
self.assertListEqual(json.loads(m.last_request.body), points)
def test_write_points_from_dataframe_with_time_precision(self):
"""Test write points from dataframe with time precision."""
now = pd.Timestamp('1970-01-01 00:00+00:00')
dataframe = pd.DataFrame(data=[["1", 1, 1.0], ["2", 2, 2.0]],
index=[now, now + timedelta(hours=1)],
columns=["column_one", "column_two",
"column_three"])
points = [
{
"points": [
["1", 1, 1.0, 0],
["2", 2, 2.0, 3600]
],
"name": "foo",
"columns": ["column_one", "column_two", "column_three", "time"]
}
]
points_ms = copy.deepcopy(points)
points_ms[0]["points"][1][-1] = 3600 * 1000
points_us = copy.deepcopy(points)
points_us[0]["points"][1][-1] = 3600 * 1000000
with requests_mock.Mocker() as m:
m.register_uri(requests_mock.POST,
"http://localhost:8086/db/db/series")
cli = DataFrameClient(database='db')
cli.write_points({"foo": dataframe}, time_precision='s')
self.assertListEqual(json.loads(m.last_request.body), points)
cli.write_points({"foo": dataframe}, time_precision='m')
self.assertListEqual(json.loads(m.last_request.body), points_ms)
cli.write_points({"foo": dataframe}, time_precision='u')
self.assertListEqual(json.loads(m.last_request.body), points_us)
@raises(TypeError)
def test_write_points_from_dataframe_fails_without_time_index(self):
"""Test write points from dataframe that fails without time index."""
dataframe = pd.DataFrame(data=[["1", 1, 1.0], ["2", 2, 2.0]],
columns=["column_one", "column_two",
"column_three"])
with requests_mock.Mocker() as m:
m.register_uri(requests_mock.POST,
"http://localhost:8086/db/db/series")
cli = DataFrameClient(database='db')
cli.write_points({"foo": dataframe})
@raises(TypeError)
def test_write_points_from_dataframe_fails_with_series(self):
"""Test failed write points from dataframe with series."""
now = pd.Timestamp('1970-01-01 00:00+00:00')
dataframe = pd.Series(data=[1.0, 2.0],
index=[now, now + timedelta(hours=1)])
with requests_mock.Mocker() as m:
m.register_uri(requests_mock.POST,
"http://localhost:8086/db/db/series")
cli = DataFrameClient(database='db')
cli.write_points({"foo": dataframe})
def test_query_into_dataframe(self):
"""Test query into a dataframe."""
data = [
{
"name": "foo",
"columns": ["time", "sequence_number", "column_one"],
"points": [
[3600, 16, 2], [3600, 15, 1],
[0, 14, 2], [0, 13, 1]
]
}
]
# dataframe sorted ascending by time first, then sequence_number
dataframe = pd.DataFrame(data=[[13, 1], [14, 2], [15, 1], [16, 2]],
index=pd.to_datetime([0, 0,
3600, 3600],
unit='s', utc=True),
columns=['sequence_number', 'column_one'])
with _mocked_session('get', 200, data):
cli = DataFrameClient('host', 8086, 'username', 'password', 'db')
result = cli.query('select column_one from foo;')
assert_frame_equal(dataframe, result)
def test_query_multiple_time_series(self):
"""Test query for multiple time series."""
data = [
{
"name": "series1",
"columns": ["time", "mean", "min", "max", "stddev"],
"points": [[0, 323048, 323048, 323048, 0]]
},
{
"name": "series2",
"columns": ["time", "mean", "min", "max", "stddev"],
"points": [[0, -2.8233, -2.8503, -2.7832, 0.0173]]
},
{
"name": "series3",
"columns": ["time", "mean", "min", "max", "stddev"],
"points": [[0, -0.01220, -0.01220, -0.01220, 0]]
}
]
dataframes = {
'series1': pd.DataFrame(data=[[323048, 323048, 323048, 0]],
index=pd.to_datetime([0], unit='s',
utc=True),
columns=['mean', 'min', 'max', 'stddev']),
'series2': pd.DataFrame(data=[[-2.8233, -2.8503, -2.7832, 0.0173]],
index=pd.to_datetime([0], unit='s',
utc=True),
columns=['mean', 'min', 'max', 'stddev']),
'series3': pd.DataFrame(data=[[-0.01220, -0.01220, -0.01220, 0]],
index=pd.to_datetime([0], unit='s',
utc=True),
columns=['mean', 'min', 'max', 'stddev'])
}
with _mocked_session('get', 200, data):
cli = DataFrameClient('host', 8086, 'username', 'password', 'db')
result = cli.query("""select mean(value), min(value), max(value),
stddev(value) from series1, series2, series3""")
self.assertEqual(dataframes.keys(), result.keys())
for key in dataframes.keys():
assert_frame_equal(dataframes[key], result[key])
def test_query_with_empty_result(self):
"""Test query with empty results."""
with _mocked_session('get', 200, []):
cli = DataFrameClient('host', 8086, 'username', 'password', 'db')
result = cli.query('select column_one from foo;')
self.assertEqual(result, [])
def test_list_series(self):
"""Test list of series for dataframe object."""
response = [
{
'columns': ['time', 'name'],
'name': 'list_series_result',
'points': [[0, 'seriesA'], [0, 'seriesB']]
}
]
with _mocked_session('get', 200, response):
cli = DataFrameClient('host', 8086, 'username', 'password', 'db')
series_list = cli.get_list_series()
self.assertEqual(series_list, ['seriesA', 'seriesB'])
def test_datetime_to_epoch(self):
"""Test convert datetime to epoch."""
timestamp = pd.Timestamp('2013-01-01 00:00:00.000+00:00')
cli = DataFrameClient('host', 8086, 'username', 'password', 'db')
self.assertEqual(
cli._datetime_to_epoch(timestamp),
1356998400.0
)
self.assertEqual(
cli._datetime_to_epoch(timestamp, time_precision='s'),
1356998400.0
)
self.assertEqual(
cli._datetime_to_epoch(timestamp, time_precision='m'),
1356998400000.0
)
self.assertEqual(
cli._datetime_to_epoch(timestamp, time_precision='ms'),
1356998400000.0
)
self.assertEqual(
cli._datetime_to_epoch(timestamp, time_precision='u'),
1356998400000000.0
)

View file

@ -0,0 +1,228 @@
# -*- coding: utf-8 -*-
"""Define set of helper functions for the dataframe."""
import unittest
import warnings
import mock
from influxdb.influxdb08 import SeriesHelper, InfluxDBClient
from requests.exceptions import ConnectionError
class TestSeriesHelper(unittest.TestCase):
"""Define the SeriesHelper for test."""
@classmethod
def setUpClass(cls):
"""Set up an instance of the TestSerisHelper object."""
super(TestSeriesHelper, cls).setUpClass()
TestSeriesHelper.client = InfluxDBClient(
'host',
8086,
'username',
'password',
'database'
)
class MySeriesHelper(SeriesHelper):
"""Define a subset SeriesHelper instance."""
class Meta:
"""Define metadata for the TestSeriesHelper object."""
client = TestSeriesHelper.client
series_name = 'events.stats.{server_name}'
fields = ['time', 'server_name']
bulk_size = 5
autocommit = True
TestSeriesHelper.MySeriesHelper = MySeriesHelper
def test_auto_commit(self):
"""Test that write_points called after the right number of events."""
class AutoCommitTest(SeriesHelper):
"""Define an instance of SeriesHelper for AutoCommit test."""
class Meta:
"""Define metadata AutoCommitTest object."""
series_name = 'events.stats.{server_name}'
fields = ['time', 'server_name']
bulk_size = 5
client = InfluxDBClient()
autocommit = True
fake_write_points = mock.MagicMock()
AutoCommitTest(server_name='us.east-1', time=159)
AutoCommitTest._client.write_points = fake_write_points
AutoCommitTest(server_name='us.east-1', time=158)
AutoCommitTest(server_name='us.east-1', time=157)
AutoCommitTest(server_name='us.east-1', time=156)
self.assertFalse(fake_write_points.called)
AutoCommitTest(server_name='us.east-1', time=3443)
self.assertTrue(fake_write_points.called)
def testSingleSeriesName(self):
"""Test JSON conversion when there is only one series name."""
TestSeriesHelper.MySeriesHelper(server_name='us.east-1', time=159)
TestSeriesHelper.MySeriesHelper(server_name='us.east-1', time=158)
TestSeriesHelper.MySeriesHelper(server_name='us.east-1', time=157)
TestSeriesHelper.MySeriesHelper(server_name='us.east-1', time=156)
expectation = [{'points': [[159, 'us.east-1'],
[158, 'us.east-1'],
[157, 'us.east-1'],
[156, 'us.east-1']],
'name': 'events.stats.us.east-1',
'columns': ['time', 'server_name']}]
rcvd = TestSeriesHelper.MySeriesHelper._json_body_()
self.assertTrue(all([el in expectation for el in rcvd]) and
all([el in rcvd for el in expectation]),
'Invalid JSON body of time series returned from '
'_json_body_ for one series name: {0}.'.format(rcvd))
TestSeriesHelper.MySeriesHelper._reset_()
self.assertEqual(
TestSeriesHelper.MySeriesHelper._json_body_(),
[],
'Resetting helper did not empty datapoints.')
def testSeveralSeriesNames(self):
"""Test JSON conversion when there is only one series name."""
TestSeriesHelper.MySeriesHelper(server_name='us.east-1', time=159)
TestSeriesHelper.MySeriesHelper(server_name='fr.paris-10', time=158)
TestSeriesHelper.MySeriesHelper(server_name='lu.lux', time=157)
TestSeriesHelper.MySeriesHelper(server_name='uk.london', time=156)
expectation = [{'points': [[157, 'lu.lux']],
'name': 'events.stats.lu.lux',
'columns': ['time', 'server_name']},
{'points': [[156, 'uk.london']],
'name': 'events.stats.uk.london',
'columns': ['time', 'server_name']},
{'points': [[158, 'fr.paris-10']],
'name': 'events.stats.fr.paris-10',
'columns': ['time', 'server_name']},
{'points': [[159, 'us.east-1']],
'name': 'events.stats.us.east-1',
'columns': ['time', 'server_name']}]
rcvd = TestSeriesHelper.MySeriesHelper._json_body_()
self.assertTrue(all([el in expectation for el in rcvd]) and
all([el in rcvd for el in expectation]),
'Invalid JSON body of time series returned from '
'_json_body_ for several series names: {0}.'
.format(rcvd))
TestSeriesHelper.MySeriesHelper._reset_()
self.assertEqual(
TestSeriesHelper.MySeriesHelper._json_body_(),
[],
'Resetting helper did not empty datapoints.')
def testInvalidHelpers(self):
"""Test errors in invalid helpers."""
class MissingMeta(SeriesHelper):
"""Define SeriesHelper object for MissingMeta test."""
pass
class MissingClient(SeriesHelper):
"""Define SeriesHelper object for MissingClient test."""
class Meta:
"""Define metadata for MissingClient object."""
series_name = 'events.stats.{server_name}'
fields = ['time', 'server_name']
autocommit = True
class MissingSeriesName(SeriesHelper):
"""Define SeriesHelper object for MissingSeries test."""
class Meta:
"""Define metadata for MissingSeriesName object."""
fields = ['time', 'server_name']
class MissingFields(SeriesHelper):
"""Define SeriesHelper for MissingFields test."""
class Meta:
"""Define metadata for MissingFields object."""
series_name = 'events.stats.{server_name}'
for cls in [MissingMeta, MissingClient, MissingFields,
MissingSeriesName]:
self.assertRaises(
AttributeError, cls, **{'time': 159,
'server_name': 'us.east-1'})
def testWarnBulkSizeZero(self):
"""Test warning for an invalid bulk size."""
class WarnBulkSizeZero(SeriesHelper):
"""Define SeriesHelper for WarnBulkSizeZero test."""
class Meta:
"""Define metadata for WarnBulkSizeZero object."""
client = TestSeriesHelper.client
series_name = 'events.stats.{server_name}'
fields = ['time', 'server_name']
bulk_size = 0
autocommit = True
with warnings.catch_warnings(record=True) as rec_warnings:
warnings.simplefilter("always")
# Server defined in the client is invalid, we're testing
# the warning only.
with self.assertRaises(ConnectionError):
WarnBulkSizeZero(time=159, server_name='us.east-1')
self.assertGreaterEqual(
len(rec_warnings), 1,
'{0} call should have generated one warning.'
'Actual generated warnings: {1}'.format(
WarnBulkSizeZero, '\n'.join(map(str, rec_warnings))))
expected_msg = (
'Definition of bulk_size in WarnBulkSizeZero forced to 1, '
'was less than 1.')
self.assertIn(expected_msg, list(w.message.args[0]
for w in rec_warnings),
'Warning message did not contain "forced to 1".')
def testWarnBulkSizeNoEffect(self):
"""Test warning for a set bulk size but autocommit False."""
class WarnBulkSizeNoEffect(SeriesHelper):
"""Define SeriesHelper for WarnBulkSizeNoEffect object."""
class Meta:
"""Define metadata for WarnBulkSizeNoEffect object."""
series_name = 'events.stats.{server_name}'
fields = ['time', 'server_name']
bulk_size = 5
autocommit = False
with warnings.catch_warnings(record=True) as rec_warnings:
warnings.simplefilter("always")
WarnBulkSizeNoEffect(time=159, server_name='us.east-1')
self.assertGreaterEqual(
len(rec_warnings), 1,
'{0} call should have generated one warning.'
'Actual generated warnings: {1}'.format(
WarnBulkSizeNoEffect, '\n'.join(map(str, rec_warnings))))
expected_msg = (
'Definition of bulk_size in WarnBulkSizeNoEffect has no affect '
'because autocommit is false.')
self.assertIn(expected_msg, list(w.message.args[0]
for w in rec_warnings),
'Warning message did not contain the expected_msg.')
if __name__ == '__main__':
unittest.main()