Skip to content

Commit

Permalink
Extract and refactored functionalities for performance testing into e…
Browse files Browse the repository at this point in the history
…xatest
  • Loading branch information
tkilias committed Jul 3, 2020
1 parent df470b2 commit 1dcc358
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 10 deletions.
110 changes: 110 additions & 0 deletions tests/lib/performance/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import time
from scipy import stats
import numpy as np

class MetricMeasurements:
def __init__(self,metric_name, measurements):
self._metric_name = metric_name
self._measurements = measurements
print("measurements:",self._measurements)
array=np.array(self._measurements)
self._stats = stats.describe(array)
self._bayes_mvs = stats.bayes_mvs(array)

@property
def metric_name(self):
return self._metric_name

@property
def mean(self):
return self._stats.mean

@property
def maximum(self):
return self._stats.minmax[1]

@property
def minimum(self):
return self._stats.minmax[0]

@property
def variance(self):
return self._stats.variance

@property
def skewness(self):
return self._stats.skewness

@property
def kurtosis(self):
return self._stats.kurtosis

def __repr__(self):
return \
(
'MetricMeasurements('
'metric_name: {metric_name}\n'
'mean: {mean}\n'
'max: {maximum}\n'
'min: {minimum}\n'
'variance: {variance}\n'
'skewness: {skewness}\n'
'kurtosis: {kurtosis}\n'
'bayes_mvs: {bayes_mvs}\n'
')'
).format(
metric_name=self._metric_name,
mean=self.mean,
maximum=self.maximum,
minimum=self.minimum,
variance=self.variance,
skewness=self.skewness,
kurtosis=self.kurtosis,
bayes_mvs=self._bayes_mvs
)


class PerformanceMeasurementResults:
def __init__(self, measurement_name, elapsed_times):
self._measurement_name = measurement_name
self._elapsed_time_measurements = MetricMeasurements("elapsed_time",elapsed_times)

@property
def measurement_name(self):
return self._measurement_name

def __repr__(self):
elapsed_time_measurements=str(self._elapsed_time_measurements)
return \
(
'MetricMeasurements('
'measurement_name: {measurement_name}\n'
'metrics: (\n'
'{elapsed_time_measurements}\n'
')\n'
')'
).format(
measurement_name=self._measurement_name,
elapsed_time_measurements=elapsed_time_measurements
)

def measure_query(conn, query):
start = time.time()
rows = conn.query(query)
end = time.time()
return end-start


def measure_query_repeated(connection, measurement_name, nb_of_runs, query):
measurements = []
for i in range(nb_of_runs):
measurements.append(measure_query(connection, query))
results = PerformanceMeasurementResults(measurement_name,measurements)
return results


def run_performance_measurements(connection, test_name, runs, warmup, query):
connection.query("alter session set query_cache='off'")
warmup_results=measure_query_repeated(connection,test_name+"_WARMUP", warmup, query)
measurement_results=measure_query_repeated(connection,test_name+"_MEASUREMENT", runs, query)
return warmup_results, measurement_results
89 changes: 79 additions & 10 deletions tests/lib/udf/__init__.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@

from datetime import date
from datetime import datetime
from decimal import Decimal
import math
import functools
import logging
import os
import re
import subprocess
import threading
import sys
import unittest
import subprocess

import pyodbc
from decimal import Decimal
from datetime import date
from datetime import datetime

import tempfile
import csv

import exatest
from exatest import *

from exatest.clients.odbc import ODBCClient, getScriptLanguagesFromArgs
import pyodbc

capabilities = []
opts = None
Expand Down Expand Up @@ -242,8 +243,8 @@ def import_via_exaplus(self, table_name, table_generator, prepare_sql):
os.mkfifo(fifo_filename)
write_trhead = threading.Thread(target=self._write_into_fifo, args=(fifo_filename, table_generator))
write_trhead.start()
sql=prepare_sql+"\n"+create_table_sql+"\n"+import_table_sql+"\n"+"commit;"
out,err=self.query_via_exaplus(schema,sql)
sql=prepare_sql+"\n"+import_table_sql+"\n"+"commit;"
out,err=self.query_via_exaplus(sql)
print(out)
print(err)
write_trhead.join()
Expand Down Expand Up @@ -301,5 +302,73 @@ def _convert_insert_value(self, value):
else:
raise TypeError("Type %s of value %s is not supported" % (type(value), value))


def create_table_by_amplifying_data_linear(
self,
source_table_name, destination_table_name,
multiplier, max_unions=10):
self.query("CREATE OR REPLACE TABLE {destination_table_name} like {source_table_name}"\
.format(
destination_table_name=destination_table_name,
source_table_name=source_table_name))
for i in range(int(math.floor(multiplier/max_unions))):
self.generate_insert_via_union(
source_table_name, destination_table_name,max_unions)
if multiplier % max_unions > 0:
self.generate_insert_via_union(
source_table_name, destination_table_name,multiplier % max_unions)

def generate_insert_via_union(self, source_table_name, destination_table_name, multiplier):
select_queries = ['''select * from {soruce_table_name}'''\
.format(soruce_table_name=source_table_name)
for i in range(multiplier)]
union_query = " union all ".join(select_queries)
self.query('''INSERT INTO {destination_table_name} {union_query};'''\
.format(
destination_table_name=destination_table_name,
union_query=union_query))


def create_table_by_amplifying_data_exponential(
self,
source_table_name, destination_table_name,
exponent, base=10):
"""Amplifies the data in source_table_name by count(source_table)*base**exponent"""
self.query(fixindent(
"""
CREATE OR REPLACE TABLE {destination_table_name} as
SELECT * from {source_table_name}
"""\
.format(
destination_table_name=destination_table_name,
source_table_name=source_table_name
)))
select_queries = ['''select * from {destination_table_name}'''\
.format(destination_table_name=destination_table_name)
for i in range(base)]
union_query = " union all ".join(select_queries)
for i in range(exponent):
self.query('''INSERT INTO {destination_table_name} {union_query};'''\
.format(
destination_table_name=destination_table_name,
union_query=union_query))

# def compare_performance_against_standard_container(
# self, runs, warmup, max_deviation, query):
# connection = self.getConnection(self.user,self.password)
# under_test_mean_elapsed_time,under_test_variance_elapsed_time,\
# under_test_max_elapsed_time,under_test_min_elapsed_time=\
# self.run_queries(connection,"under_test", runs, warmup, query)
# connection.close()

# connection = self.getConnection(self.user,self.password)
# connection.query("ALTER SESSION SET script_languages='PYTHON=builtin_python PYTHON3=builtin_python3 JAVA=builtin_java R=builtin_r'")
# builtin_mean_elapsed_time,builtin_variance_elapsed_time,\
# builtin_max_elapsed_time,builtin_min_elapsed_time=\
# self.run_queries(connection,"builtin_python", runs, warmup, query)
# connection.close()

# deviation = 100-builtin_mean_elapsed_time/under_test_mean_elapsed_time*100

# vim: ts=4:sts=4:sw=4:et:fdm=indent

1 change: 1 addition & 0 deletions tests/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ pyodbc<=4.0.24
pytz
lxml
docker
scipy

0 comments on commit 1dcc358

Please sign in to comment.