Skip to content

Commit

Permalink
[not4review] test
Browse files Browse the repository at this point in the history
  • Loading branch information
FengPan-Frank committed Oct 31, 2024
1 parent 246f2d2 commit bdceced
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 4 deletions.
2 changes: 1 addition & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[pytest]
addopts = --cov=scripts --cov=host_modules --cov-report html --cov-report term --cov-report xml --ignore=tests/*/test*_vectors.py --junitxml=test-results.xml -vv
addopts = --cov=scripts --cov=host_modules --cov-report html --cov-report term --cov-report xml --ignore=tests/*/test*_vectors.py --junitxml=test-results.xml -vv -s
18 changes: 16 additions & 2 deletions scripts/procdockerstatsd
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ REDIS_HOSTIP = "127.0.0.1"


class ProcDockerStats(daemon_base.DaemonBase):
all_process_obj = {}

def __init__(self, log_identifier):
super(ProcDockerStats, self).__init__(log_identifier)
Expand Down Expand Up @@ -138,10 +139,18 @@ class ProcDockerStats(daemon_base.DaemonBase):

def update_processstats_command(self):
processdata = []
for process in psutil.process_iter(['pid', 'ppid', 'memory_percent', 'cpu_percent', 'create_time', 'cmdline']):
pid_set = set()
for process_obj in psutil.process_iter(['pid', 'ppid', 'memory_percent', 'cpu_percent', 'create_time', 'cmdline']):
try:
pid = process_obj.pid
pid_set.add(pid)
# store process object and reuse for CPU utilization
if pid in self.all_process_obj:
process = self.all_process_obj[pid]
else:
self.all_process_obj[pid] = process_obj
process = process_obj
uid = process.uids()[0]
pid = process.pid
ppid = process.ppid()
mem = process.memory_percent()
cpu = process.cpu_percent()
Expand All @@ -157,6 +166,11 @@ class ProcDockerStats(daemon_base.DaemonBase):
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
pass

# erase dead process
for id in list(self.all_process_obj.keys()):
if id not in pid_set:
del self.all_process_obj[id]

# wipe out all data before updating with new values
self.state_db.delete_all_by_pattern('STATE_DB', 'PROCESS_STATS|*')

Expand Down
136 changes: 136 additions & 0 deletions tests/aatest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
import sys
import os
import psutil
import pytest
import logging
from unittest.mock import call, patch
from swsscommon import swsscommon
from sonic_py_common.general import load_module_from_source
from datetime import datetime, timedelta

from .mock_connector import MockConnector

swsscommon.SonicV2Connector = MockConnector

test_path = os.path.dirname(os.path.abspath(__file__))
modules_path = os.path.dirname(test_path)
scripts_path = os.path.join(modules_path, "scripts")
sys.path.insert(0, modules_path)

# Load the file under test
procdockerstatsd_path = os.path.join(scripts_path, 'procdockerstatsd')
procdockerstatsd = load_module_from_source('procdockerstatsd', procdockerstatsd_path)

class MockProcess:
def __init__(self, uids, pid, ppid, memory_percent, cpu_percent, create_time, cmdline, user_time, system_time):
self._uids = uids
self._pid = pid
self._ppid = ppid
self._memory_percent = memory_percent
self._cpu_percent = cpu_percent
self._create_time = create_time
self._terminal = cmdline
self._cmdline = cmdline
self._user_time = user_time
self._system_time = system_time

def uids(self):
return self._uids

def pid(self):
return self._pid

def ppid(self):
return self._ppid

def memory_percent(self):
return self._memory_percent

def cpu_percent(self):
return self._cpu_percent

def create_time(self):
return self._create_time

def terminal(self):
return self._terminal

def cmdline(self):
return self._cmdline

def cpu_times(self):
class CPUTimes:
def __init__(self, user_time, system_time):
self.user = user_time
self.system = system_time

def __getitem__(self, index):
if index == 0:
return self.user
else:
return self.system

def __iter__(self):
yield self.user
yield self.system

return CPUTimes(self._user_time, self._system_time)


class TestProcDockerStatsDaemon(object):
def test_convert_to_bytes(self):
test_data = [
('1B', 1),
('500B', 500),
('1KB', 1000),
('500KB', 500000),
('1MB', 1000000),
('500MB', 500000000),
('1MiB', 1048576),
('500MiB', 524288000),
('66.41MiB', 69635932),
('333.6MiB', 349804954),
('1GiB', 1073741824),
('500GiB', 536870912000),
('7.751GiB', 8322572878)
]

pdstatsd = procdockerstatsd.ProcDockerStats(procdockerstatsd.SYSLOG_IDENTIFIER)

for test_input, expected_output in test_data:
res = pdstatsd.convert_to_bytes(test_input)
assert res == expected_output

def test_run_command(self):
pdstatsd = procdockerstatsd.ProcDockerStats(procdockerstatsd.SYSLOG_IDENTIFIER)
output = pdstatsd.run_command(['echo', 'pdstatsd'])
assert output == 'pdstatsd\n'

output = pdstatsd.run_command([sys.executable, "-c", "import sys; sys.exit(6)"])
assert output is None

def test_update_processstats_command(self):
pdstatsd = procdockerstatsd.ProcDockerStats(procdockerstatsd.SYSLOG_IDENTIFIER)
current_time = datetime.now()
valid_create_time1 = int((current_time - timedelta(days=1)).timestamp())
valid_create_time2 = int((current_time - timedelta(days=2)).timestamp())
# Create a list of mocked processes
mocked_processes = [
MockProcess(pid=1234, ppid=0, memory_percent=10.5, cpu_percent=20.5, create_time=valid_create_time1, cmdline=['python', 'script.py'], user_time=1.5, system_time=2.0),
MockProcess(pid=5678, ppid=0, memory_percent=5.5, cpu_percent=15.5, create_time=valid_create_time2, cmdline=['bash', 'script.sh'], user_time=3.5, system_time=4.0)
]

with patch("procdockerstatsd.psutil.process_iter", return_value=mocked_processes) as mock_process_iter:
pdstatsd.all_process_obj = {1234: psutil.Process(pid=1234, ppid=0, memory_percent=5.5, cpu_percent=99, create_time=valid_create_time2, cmdline=['bash', 'script.py'], user_time=3.5, system_time=4.0),
6666: psutil.Process(pid=6666, ppid=0, memory_percent=5.5, cpu_percent=15.5, create_time=valid_create_time2, cmdline=['bash', 'script.sh'], user_time=3.5, system_time=4.0)}
pdstatsd.update_processstats_command()
mock_process_iter.assert_called_once()
print(pdstatsd.all_process_obj)
assert(len(pdstatsd.all_process_obj)== 2)

@patch('procdockerstatsd.getstatusoutput_noshell_pipe', return_value=([0, 0], ''))
def test_update_fipsstats_command(self, mock_cmd):
pdstatsd = procdockerstatsd.ProcDockerStats(procdockerstatsd.SYSLOG_IDENTIFIER)
pdstatsd.update_fipsstats_command()
assert pdstatsd.state_db.get('STATE_DB', 'FIPS_STATS|state', 'enforced') == "False"
assert pdstatsd.state_db.get('STATE_DB', 'FIPS_STATS|state', 'enabled') == "True"
7 changes: 6 additions & 1 deletion tests/procdockerstatsd_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os
import psutil
import pytest
import logging
from unittest.mock import call, patch
from swsscommon import swsscommon
from sonic_py_common.general import load_module_from_source
Expand Down Expand Up @@ -115,13 +116,17 @@ def test_update_processstats_command(self):
valid_create_time2 = int((current_time - timedelta(days=2)).timestamp())
# Create a list of mocked processes
mocked_processes = [
MockProcess(uids=[1000], pid=1234, ppid=5678, memory_percent=10.5, cpu_percent=20.5, create_time=valid_create_time1, cmdline=['python', 'script.py'], user_time=1.5, system_time=2.0),
MockProcess(uids=[1000], pid=1234, ppid=0, memory_percent=10.5, cpu_percent=20.5, create_time=valid_create_time1, cmdline=['python', 'script.py'], user_time=1.5, system_time=2.0),
MockProcess(uids=[1000], pid=5678, ppid=0, memory_percent=5.5, cpu_percent=15.5, create_time=valid_create_time2, cmdline=['bash', 'script.sh'], user_time=3.5, system_time=4.0)
]

with patch("procdockerstatsd.psutil.process_iter", return_value=mocked_processes) as mock_process_iter:
pdstatsd.all_process_obj = {1234: psutil.Process(pid=1234),
6666: psutil.Process(pid=6666)}
pdstatsd.update_processstats_command()
mock_process_iter.assert_called_once()
print(pdstatsd.all_process_obj)
assert(len(pdstatsd.all_process_obj)== 2)

@patch('procdockerstatsd.getstatusoutput_noshell_pipe', return_value=([0, 0], ''))
def test_update_fipsstats_command(self, mock_cmd):
Expand Down

0 comments on commit bdceced

Please sign in to comment.