Skip to content

Commit

Permalink
Merge branch 'ad-freiburg:main' into improve_code_for_stop
Browse files Browse the repository at this point in the history
  • Loading branch information
SimonL22 authored Dec 23, 2024
2 parents 3df9c0b + ab46d69 commit acedc2c
Show file tree
Hide file tree
Showing 2 changed files with 267 additions and 0 deletions.
214 changes: 214 additions & 0 deletions test/qlever/commands/test_cache_stats_execute.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
from __future__ import annotations

import unittest
from unittest.mock import MagicMock, patch

from qlever.commands.cache_stats import CacheStatsCommand


class TestCacheStatsCommand(unittest.TestCase):
def setUp(self):
self.command = CacheStatsCommand()

@patch("qlever.commands.cache_stats.subprocess.check_output")
@patch("qlever.commands.cache_stats.json.loads")
@patch("qlever.commands.cache_stats.log")
# Test execute of cache stats command for basic case with successful
# execution
def test_execute_successful_basic_cache_stats(
self, mock_log, mock_json_loads, mock_check_output
):
# Mock arguments for basic cache stats
args = MagicMock()
args.server_url = None
args.port = 1234
args.show = False
args.detailed = False

# Mock `subprocess.check_output` and `json.loads` as encoded bytes
mock_check_output.side_effect = [
# Mock cache_stats
b'{"pinned-size": 1e9, "non-pinned-size": 3e9}',
# Mock cache_settings
b'{"cache-max-size": "10 GB"}',
]
# mock cache_stats_dict and cache_settings_dict as a dictionary
mock_json_loads.side_effect = [
{"pinned-size": 1e9, "non-pinned-size": 3e9},
{"cache-max-size": "10 GB"},
]

# Execute the command
result = self.command.execute(args)

# Assertions
expected_stats_call = (
f"curl -s localhost:{args.port} "
f'--data-urlencode "cmd=cache-stats"'
)
expected_settings_call = (
f"curl -s localhost:{args.port} "
f'--data-urlencode "cmd=get-settings"'
)

mock_check_output.assert_any_call(expected_stats_call, shell=True)
mock_check_output.assert_any_call(expected_settings_call, shell=True)

# Verify the correct information logs
mock_log.info.assert_any_call(
"Pinned queries : 1.0 GB of 10.0 GB [10.0%]"
)
mock_log.info.assert_any_call(
"Non-pinned queries : 3.0 GB of 10.0 GB [30.0%]"
)
mock_log.info.assert_any_call(
"FREE : 6.0 GB of 10.0 GB [60.0%]"
)

self.assertTrue(result)

@patch("qlever.commands.cache_stats.subprocess.check_output")
@patch("qlever.commands.cache_stats.json.loads")
@patch("qlever.commands.cache_stats.log")
# Test for show_dict_as_table function. Reached if 'args.detailed = True'.
def test_execute_detailed_cache_stats(
self, mock_log, mock_json_loads, mock_check_output
):
# Mock arguments for detailed cache stats
args = MagicMock()
args.server_url = "http://testlocalhost:1234"
args.show = False
args.detailed = True

# Mock the responses from `subprocess.check_output` and `json.loads`
mock_check_output.side_effect = [
b'{"pinned-size": 2e9, "non-pinned-size": 1e9, "test-stat": 500}',
b'{"cache-max-size": "10 GB", "test-setting": 1000}',
]
# CAREFUL: if value is float you will get an error in re.match
mock_json_loads.side_effect = [
{
"pinned-size": int(2e9),
"non-pinned-size": int(1e9),
"test-stat": 500,
},
{"cache-max-size": "10 GB", "test-setting": 1000},
]

# Execute the command
result = self.command.execute(args)

# Assertions
expected_stats_call = (
f"curl -s {args.server_url} " f'--data-urlencode "cmd=cache-stats"'
)
expected_settings_call = (
f"curl -s {args.server_url} "
f'--data-urlencode "cmd=get-settings"'
)

mock_check_output.assert_any_call(expected_stats_call, shell=True)
mock_check_output.assert_any_call(expected_settings_call, shell=True)

# Verify that detailed stats and settings were logged as a table
mock_log.info.assert_any_call("pinned-size : 2,000,000,000")
mock_log.info.assert_any_call("non-pinned-size : 1,000,000,000")
mock_log.info.assert_any_call("test-stat : 500")
mock_log.info.assert_any_call("cache-max-size : 10 GB")
mock_log.info.assert_any_call("test-setting : 1,000")

self.assertTrue(result)

@patch("qlever.commands.cache_stats.subprocess.check_output")
@patch("qlever.commands.cache_stats.log")
# Checking if correct error message is given for unsuccessful try/except
# block.
def test_execute_failed_cache_stats(self, mock_log, mock_check_output):
# Mock arguments for basic cache stats
args = MagicMock()
args.server_url = "http://testlocalhost:1234"
args.show = False
args.detailed = False

# Simulate a command execution failure
mock_check_output.side_effect = Exception("Mocked command failure")

# Execute the command
result = self.command.execute(args)

# Assertions to verify that error was logged
mock_log.error.assert_called_once_with(
"Failed to get cache stats and settings: Mocked command failure"
)

self.assertFalse(result)

@patch("qlever.commands.cache_stats.subprocess.check_output")
@patch("qlever.commands.cache_stats.json.loads")
@patch("qlever.commands.cache_stats.log")
# Checking if correct error message is given for invalid cache_size
def test_execute_invalid_cache_size_format(
self, mock_log, mock_json_loads, mock_check_output
):
# Mock arguments for basic cache stats
args = MagicMock()
args.server_url = None
args.port = 1234
args.show = False
args.detailed = False

# Mock the responses with invalid cache size format
mock_check_output.side_effect = [
b'{"pinned-size": 2e9, "non-pinned-size": 1e9}',
# Mock cache stats with invalid cache settings
b'{"cache-max-size": "1000 MB"}',
]
mock_json_loads.side_effect = [
{"pinned-size": 2e9, "non-pinned-size": 1e9},
{"cache-max-size": "1000 MB"},
]

# Execute the command
result = self.command.execute(args)

# Assertions to verify that error was logged
mock_log.error.assert_called_once_with(
"Cache size 1000 MB is not in GB, QLever should return "
"bytes instead"
)

self.assertFalse(result)

@patch("qlever.commands.cache_stats.subprocess.check_output")
@patch("qlever.commands.cache_stats.json.loads")
@patch("qlever.commands.cache_stats.log")
# Checking if correct log message is given for empty cache_size
def test_execute_empty_cache_size(
self, mock_log, mock_json_loads, mock_check_output
):
# Mock arguments for basic cache stats
args = MagicMock()
args.server_url = None
args.port = 1234
args.show = False
args.detailed = False

# Mock the responses with empty cache size
mock_check_output.side_effect = [
b'{"pinned-size": 0, "non-pinned-size": 0}',
b'{"cache-max-size": "10 GB"}',
]
mock_json_loads.side_effect = [
{"pinned-size": 0, "non-pinned-size": 0},
{"cache-max-size": "10 GB"},
]

# Execute the command
result = self.command.execute(args)

# Assertions to verify that log.info was called correctly
mock_log.info.assert_called_once_with(
"Cache is empty, all 10.0 GB available"
)

self.assertTrue(result)
53 changes: 53 additions & 0 deletions test/qlever/commands/test_cache_stats_other_methods.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import argparse
import unittest

from qlever.commands.cache_stats import CacheStatsCommand


class TestStartCommand(unittest.TestCase):
def test_description(self):
self.assertEqual(
"Show how much of the cache is currently being " "used",
CacheStatsCommand().description(),
)

def test_should_have_qleverfile(self):
assert not CacheStatsCommand().should_have_qleverfile()

def test_relevant_qleverfile_arguments(self):
testdict = {"server": ["host_name", "port"]}
self.assertEqual(
testdict, CacheStatsCommand().relevant_qleverfile_arguments()
)

def test_additional_arguments(self):
# Create an instance of CacheStatsCommand
csc = CacheStatsCommand()

# Create a parser and a subparser
parser = argparse.ArgumentParser()
subparser = parser.add_argument_group("test")
# Call the method
csc.additional_arguments(subparser)
# Parse an empty argument list to see the default
args = parser.parse_args([])

# Test that the default value for server-url is set correctly
"""Why is there no default="localhost:{port}"? """
self.assertEqual(args.server_url, None)

# Test that the help text for server-url is correctly set
argument_help = subparser._group_actions[-2].help
self.assertEqual(
"URL of the QLever server, default is " "localhost:{port}",
argument_help,
)

# Test that the default value for --detailed is set correctly
self.assertEqual(False, args.detailed)

# Test that the help text for --detailed is correctly set
argument_help = subparser._group_actions[-1].help
self.assertEqual(
"Show detailed statistics and settings", argument_help
)

0 comments on commit acedc2c

Please sign in to comment.