Skip to content

Commit dbac809

Browse files
authored
Windows server MSSQL 2022 hammerdb workload (#1162)
1 parent 3b823ee commit dbac809

File tree

77 files changed

+2812
-75
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

77 files changed

+2812
-75
lines changed

MANIFEST.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ include benchmark_runner/common/template_operations/templates/bootstorm/*.yaml
2020
include benchmark_runner/common/template_operations/templates/bootstorm/internal_data/*.yaml
2121
include benchmark_runner/common/template_operations/templates/windows/*.yaml
2222
include benchmark_runner/common/template_operations/templates/windows/internal_data/*.yaml
23+
include benchmark_runner/common/template_operations/templates/winmssql/*.yaml
24+
include benchmark_runner/common/template_operations/templates/winmssql/internal_data/*.yaml
25+
include benchmark_runner/common/template_operations/templates/winmssql/windows_benchmark_runner/*
2326

2427
# ocp resource
2528
include benchmark_runner/common/ocp_resources/lso/template/*.sh

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,12 @@ The following options may be passed via command line flags or set in the environ
6565

6666
Choose one from the following list:
6767

68-
`['stressng_pod', 'stressng_vm', 'stressng_kata', 'uperf_pod', 'uperf_vm', 'uperf_kata', 'hammerdb_pod_mariadb', 'hammerdb_vm_mariadb', 'hammerdb_kata_mariadb', 'hammerdb_pod_mariadb_lso', 'hammerdb_vm_mariadb_lso', 'hammerdb_kata_mariadb_lso', 'hammerdb_pod_postgres', 'hammerdb_vm_postgres', 'hammerdb_kata_postgres', 'hammerdb_pod_postgres_lso', 'hammerdb_vm_postgres_lso', 'hammerdb_kata_postgres_lso', 'hammerdb_pod_mssql', 'hammerdb_vm_mssql', 'hammerdb_kata_mssql', 'hammerdb_pod_mssql_lso', 'hammerdb_vm_mssql_lso', 'hammerdb_kata_mssql_lso', 'vdbench_pod', 'vdbench_kata', 'vdbench_vm', 'clusterbuster', 'bootstorm_vm']`
68+
`['stressng_pod', 'stressng_vm', 'stressng_kata', 'uperf_pod', 'uperf_vm', 'uperf_kata', 'hammerdb_pod_mariadb', 'hammerdb_vm_mariadb', 'hammerdb_kata_mariadb', 'hammerdb_pod_mariadb_lso', 'hammerdb_vm_mariadb_lso', 'hammerdb_kata_mariadb_lso', 'hammerdb_pod_postgres', 'hammerdb_vm_postgres', 'hammerdb_kata_postgres', 'hammerdb_pod_postgres_lso', 'hammerdb_vm_postgres_lso', 'hammerdb_kata_postgres_lso', 'hammerdb_pod_mssql', 'hammerdb_vm_mssql', 'hammerdb_kata_mssql', 'hammerdb_pod_mssql_lso', 'hammerdb_vm_mssql_lso', 'hammerdb_kata_mssql_lso', 'vdbench_pod', 'vdbench_kata', 'vdbench_vm', 'clusterbuster', 'bootstorm_vm', 'windows_vm', 'winmssql_vm' ]`
6969

7070
** clusterbuster workloads: cpusoaker, files, fio, uperf. for more details [see](https://github.com/RobertKrawitz/OpenShift4-tools)
71+
** For windows workloads: need to share windows qcow2 image by nginx
72+
** For hammerdb mssql must run only once [permission](https://github.com/redhat-performance/benchmark-runner/blob/main/benchmark_runner/common/ocp_resources/custom/template/02_mssql_patch_template.sh)
73+
** winmssql_vm: will run hammerdb inside windows server mssql 2022: for more details [see](benchmark_runner/common/template_operations/templates/winmssql/windows_benchmark_runner/readme)
7174

7275
Not mandatory:
7376

@@ -103,6 +106,8 @@ Not mandatory:
103106

104107
**optional:** WORKER_DISK_IDS=$WORKER_DISK_IDS [WORKER_DISK_IDS For ODF/LSO workloads hammerdb/vdbench]
105108

109+
**optional:** WINDOWS_URL=$WINDOWS_URL [WINDOWS_URL for qcow2 image that can be shared by Nginx]
110+
106111
For example:
107112

108113
```sh
@@ -175,3 +180,7 @@ name of the promdb snapshot.
175180
## How to develop in benchmark-runner
176181

177182
see [HOW_TO.md](HOW_TO.md)
183+
184+
## benchmark-runner blog
185+
186+
open [link](https://developers.redhat.com/articles/2025/11/18/how-run-performance-tests-using-benchmark-runner)

benchmark_runner/common/elasticsearch/elasticsearch_exceptions.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,9 @@ class ElasticSearchDataNotUploaded(ElasticSearchError):
1010
def __init__(self):
1111
self.message = f'Data did not upload to elastic search'
1212
super(ElasticSearchDataNotUploaded, self).__init__(self.message)
13+
14+
class ElasticSearchDataNotFound(ElasticSearchError):
15+
"""This exception return elastic search not uploaded error"""
16+
def __init__(self):
17+
self.message = f'Data did not found to elastic search'
18+
super(ElasticSearchDataNotFound, self).__init__(self.message)

benchmark_runner/common/elasticsearch/elasticsearch_operations.py

Lines changed: 103 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
from elasticsearch import Elasticsearch
77
from elasticsearch.connection import create_ssl_context
88
from elasticsearch_dsl import Search
9-
from datetime import datetime, timezone
9+
from datetime import datetime, timezone, timedelta
1010

11-
from benchmark_runner.common.elasticsearch.elasticsearch_exceptions import ElasticSearchDataNotUploaded
11+
from benchmark_runner.common.elasticsearch.elasticsearch_exceptions import ElasticSearchDataNotUploaded, ElasticSearchDataNotFound
1212
from benchmark_runner.common.logger.logger_time_stamp import logger_time_stamp, logger
1313

1414

@@ -154,11 +154,12 @@ def verify_elasticsearch_data_uploaded(self, index: str, uuid: str = '', workloa
154154
raise ElasticSearchDataNotUploaded
155155

156156
@typechecked()
157-
def upload_to_elasticsearch(self, index: str, data: dict, doc_type: str = '_doc', es_add_items: dict = None, **kwargs):
157+
def upload_to_elasticsearch(self, index: str, data: dict, doc_type: str = '_doc', timestamp: datetime = None, es_add_items: dict = None, **kwargs):
158158
"""
159159
This method uploads json data into elasticsearch
160160
:param index: index name to be stored in elasticsearch
161161
:param data: data must be in dictionary i.e. {'key': 'value'}
162+
:param timestamp:
162163
:param doc_type:
163164
:param es_add_items:
164165
:return:
@@ -169,7 +170,10 @@ def upload_to_elasticsearch(self, index: str, data: dict, doc_type: str = '_doc'
169170
data.update(es_add_items)
170171

171172
# utcnow - solve timestamp issue
172-
data['timestamp'] = datetime.now(timezone.utc) # datetime.utcnow() or datetime.now()
173+
if timestamp:
174+
data['timestamp'] = timestamp
175+
else:
176+
data['timestamp'] = datetime.now(timezone.utc) # datetime.utcnow() or datetime.now()
173177

174178
# Uploads data to elasticsearch server
175179
try:
@@ -229,32 +233,48 @@ def delete_elasticsearch_index_by_id(self, index: str, id: str):
229233

230234
@typechecked()
231235
@logger_time_stamp
232-
def get_query_data_between_dates(self, start_datetime: datetime, end_datetime: datetime):
236+
def get_query_data_between_dates(self, start_datetime: datetime, end_datetime: datetime, sort_order: str = "desc") -> dict:
233237
"""
234-
This method returns the query for fetching data between dates
235-
@param start_datetime:
236-
@param end_datetime:
237-
@return:
238+
Returns an Elasticsearch query for fetching data between UTC-aware datetime ranges.
239+
240+
:param start_datetime: datetime, start of the range (UTC-aware)
241+
:param end_datetime: datetime, end of the range (UTC-aware)
242+
:param sort_order: desc or asc
243+
:return: dict, Elasticsearch query
238244
"""
239-
if start_datetime and end_datetime:
240-
if end_datetime < start_datetime:
241-
start_datetime = end_datetime
242-
query = {
243-
"bool": {
244-
"filter": {
245-
"range": {
246-
"timestamp": {
247-
"format": "yyyy-MM-dd HH:mm:ss"
248-
}
245+
if not start_datetime:
246+
raise ValueError('Empty parameters: start_datetime')
247+
if not end_datetime:
248+
raise ValueError('Empty parameters: end_datetime')
249+
250+
# Ensure start_datetime <= end_datetime
251+
if end_datetime < start_datetime:
252+
start_datetime, end_datetime = end_datetime, start_datetime
253+
254+
# Convert to ISO 8601 with Z
255+
start_iso = start_datetime.replace(microsecond=0).isoformat() + "Z"
256+
end_iso = end_datetime.replace(microsecond=0).isoformat() + "Z"
257+
258+
# Build Elasticsearch query
259+
query = {
260+
"query": {
261+
"bool": {
262+
"filter": {
263+
"range": {
264+
"timestamp": {
265+
"gte": start_iso,
266+
"lte": end_iso
249267
}
250268
}
251269
}
252-
}
253-
query['bool']['filter']['range']['timestamp']['lte'] = str(end_datetime.replace(microsecond=0))
254-
query['bool']['filter']['range']['timestamp']['gte'] = str(start_datetime.replace(microsecond=0))
255-
return query
256-
else:
257-
raise Exception('Empty parameters: start_datetime/ end_datetime')
270+
}
271+
},
272+
"sort": [
273+
{"timestamp": {"order": sort_order}}
274+
]
275+
}
276+
277+
return query
258278

259279
@typechecked()
260280
@logger_time_stamp
@@ -271,7 +291,7 @@ def get_index_data_between_dates(self, index: str, start_datetime: datetime = No
271291
if index and start_datetime and end_datetime:
272292
es_data = []
273293
query = self.get_query_data_between_dates(start_datetime, end_datetime)
274-
response = self.__es.search(index=index, query=query, size=number_of_documents, scroll=scroll_duration)
294+
response = self.__es.search(index=index, body=query, size=number_of_documents, scroll=scroll_duration)
275295
scroll_id = response.get('_scroll_id')
276296
if response.get('hits').get('hits'):
277297
es_data.extend(response.get('hits').get('hits'))
@@ -285,6 +305,63 @@ def get_index_data_between_dates(self, index: str, start_datetime: datetime = No
285305
else:
286306
raise Exception('Empty parameters: index/ start_datetime/ end_datetime')
287307

308+
@typechecked()
309+
@logger_time_stamp
310+
def get_latest_resource_with_key(
311+
self,
312+
index: str,
313+
key: str,
314+
start_datetime: datetime = None,
315+
end_datetime: datetime = None
316+
) -> dict:
317+
"""
318+
Returns the _source of the most recent document (latest first)
319+
that contains the given key.
320+
If none found, returns an empty dict.
321+
"""
322+
if not end_datetime:
323+
end_datetime = datetime.now(timezone.utc)
324+
if not start_datetime:
325+
start_datetime = end_datetime - timedelta(minutes=60)
326+
327+
docs = self.get_index_data_between_dates(
328+
index,
329+
start_datetime=start_datetime,
330+
end_datetime=end_datetime
331+
)
332+
333+
if not docs:
334+
return {}
335+
336+
# Latest → oldest
337+
for doc in docs:
338+
source = doc.get('_source', {})
339+
if key in source:
340+
return source
341+
342+
return {}
343+
344+
@typechecked()
345+
@logger_time_stamp
346+
def get_uuid_for_ids(self, index: str, ids: list[str]) -> dict:
347+
"""
348+
Return a mapping of doc_id -> uuid (or None if missing)
349+
"""
350+
if not ids:
351+
# Nothing to fetch, avoid _mget with empty list
352+
return {}
353+
docs = self.__es.mget(
354+
index=index,
355+
body={"ids": ids}
356+
)
357+
result = {}
358+
for doc in docs["docs"]:
359+
if doc.get("found"):
360+
result[doc["_id"]] = doc["_source"].get("uuid")
361+
else:
362+
result[doc["_id"]] = None
363+
return result
364+
288365
@typechecked()
289366
@logger_time_stamp
290367
def get_index_ids_between_dates(self, index: str, start_datetime: datetime = None, end_datetime: datetime = None):

benchmark_runner/common/template_operations/template_operations.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ def __generate_yamls_internal(self, scale: str = None, scale_num: str = None, sc
166166
if os.path.isfile(os.path.join(self.__dir_path, f'namespace_template.yaml')):
167167
answer['namespace.yaml'] = render_yaml_file(dir_path=self.__dir_path, yaml_file='namespace_template.yaml', environment_variable_dict=self.__environment_variables_dict)
168168
# windows workload
169-
if 'windows' in self.__workload_name:
169+
if 'win' in self.__workload_name:
170170
answer['windows_dv.yaml'] = render_yaml_file(dir_path=os.path.join(workload_dir_path, 'internal_data'), yaml_file='windows_dv_template.yaml', environment_variable_dict=render_data)
171171
# vdbench scale
172172
if scale and redis and 'vdbench' in self.__workload_name:

benchmark_runner/common/template_operations/templates/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)