Skip to content

Commit 68c7305

Browse files
committed
Add script for logrotate test
Add test for logrotate test PR #9504 [rsyslog]Setting log file size to 16Mb
1 parent 6c7ac4d commit 68c7305

1 file changed

Lines changed: 215 additions & 0 deletions

File tree

tests/syslog/test_logrotate.py

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
import logging
2+
import pytest
3+
import allure
4+
5+
from tests.common.plugins.loganalyzer.loganalyzer import DisableLogrotateCronContext
6+
from tests.common import config_reload
7+
8+
logger = logging.getLogger(__name__)
9+
10+
pytestmark = [
11+
pytest.mark.topology("any"),
12+
pytest.mark.disable_loganalyzer
13+
]
14+
15+
LOG_FOLDER = '/var/log'
16+
ROTATE_THRESHOLD_LARGE = '16M'
17+
ROTATE_THRESHOLD_SMALL = '1024K'
18+
SMALL_VAR_LOG_PARTITION_SIZE = '100M'
19+
20+
21+
@pytest.fixture(scope='module', autouse=True)
22+
def disable_logrotate_cron_job(rand_selected_dut):
23+
with DisableLogrotateCronContext(rand_selected_dut):
24+
yield
25+
26+
27+
@pytest.fixture(scope='module', autouse=True)
28+
def backup_syslog(rand_selected_dut):
29+
"""
30+
Back up current syslog file
31+
:param rand_selected_dut: The fixture returns a randomly selected DUT
32+
"""
33+
duthost = rand_selected_dut
34+
logger.info('Backup syslog file to syslog_bk')
35+
duthost.shell('sudo cp -f /var/log/syslog /var/log/syslog_bk')
36+
37+
yield
38+
39+
logger.info('Recover syslog file to syslog')
40+
duthost.shell('sudo mv /var/log/syslog_bk /var/log/syslog')
41+
42+
logger.info('Remove temp file /var/log/syslog.1')
43+
duthost.shell('sudo rm -f /var/log/syslog.1')
44+
45+
logger.info('Restart rsyslog service')
46+
duthost.shell('sudo service rsyslog restart')
47+
48+
49+
@pytest.fixture(scope='function')
50+
def simulate_small_var_log_partition(rand_selected_dut, localhost):
51+
"""
52+
Simulate a small var log partition
53+
:param rand_selected_dut: The fixture returns a randomly selected DUT
54+
"""
55+
duthost = rand_selected_dut
56+
with allure.step('Create a small var log partition with size of {}'.format(SMALL_VAR_LOG_PARTITION_SIZE)):
57+
logger.info('Create a small var log partition with size of {}'.format(SMALL_VAR_LOG_PARTITION_SIZE))
58+
duthost.shell('sudo fallocate -l {} log-new-partition'.format(SMALL_VAR_LOG_PARTITION_SIZE))
59+
duthost.shell('sudo losetup -P /dev/loop2 log-new-partition')
60+
duthost.shell('sudo mkfs.ext4 /dev/loop2')
61+
duthost.shell('sudo mount /dev/loop2 /var/log')
62+
63+
config_reload(duthost, safe_reload=True)
64+
65+
logger.info('Start logrotate-config service')
66+
duthost.shell('sudo service logrotate-config start')
67+
68+
yield
69+
70+
with allure.step('Recovery var log'):
71+
logger.info('Umount and unload the small var log partition')
72+
duthost.shell('sudo umount -l /dev/loop2')
73+
duthost.shell('sudo losetup -d /dev/loop2')
74+
75+
logger.info('Remove the small var log partition')
76+
duthost.shell('sudo rm -f log-new-partition')
77+
78+
config_reload(duthost, safe_reload=True)
79+
80+
logger.info('Restart logrotate-config service')
81+
duthost.shell('sudo service logrotate-config restart')
82+
83+
84+
def get_var_log_size(duthost):
85+
"""
86+
Check the size of /var/log folder
87+
:param duthost: DUT host object
88+
:return: size value
89+
"""
90+
size = duthost.shell("sudo df -k /var/log | sed -n 2p | awk '{ print $2 }'")['stdout']
91+
return int(size)
92+
93+
94+
def get_syslog_file_count(duthost):
95+
"""
96+
Check the rotated syslog file number
97+
:param duthost: DUT host object
98+
:return: file number value
99+
"""
100+
logger.info('Check rotated syslog file number')
101+
num = duthost.shell('sudo ls -l /var/log | grep -Ec "syslog\\.[0-9]{1,4}[\\.gz]{0,1}"')['stdout']
102+
logger.debug('There are {} rotated syslog files'.format(num))
103+
return int(num)
104+
105+
106+
def create_temp_syslog_file(duthost, size):
107+
"""
108+
Create a temp syslog file with specific size and
109+
:param duthost: DUT host object
110+
:param size: file size with unit, such as 16M or 1024K, the unit could be M or K
111+
"""
112+
logger.info('Create a temp syslog file as {}'.format(size))
113+
duthost.shell('sudo fallocate -l {} /var/log/syslog'.format(size))
114+
115+
116+
def run_logrotate(duthost, force=False):
117+
"""
118+
Run logrotate command
119+
:param duthost: DUT host object
120+
:param force: force logrotate run immediately even the syslog size is very small, value is True or False
121+
"""
122+
if force:
123+
logger.debug('Make sure there is no big /var/log/syslog exist by forcing execute logrotate')
124+
cmd = 'sudo /usr/sbin/logrotate -f /etc/logrotate.conf > /dev/null 2>&1'
125+
else:
126+
cmd = 'sudo /usr/sbin/logrotate /etc/logrotate.conf > /dev/null 2>&1'
127+
logger.info('Run logrotate command: {}'.format(cmd))
128+
duthost.shell(cmd)
129+
130+
131+
def multiply_with_unit(logrotate_threshold, num):
132+
"""
133+
Multiply logrotate_threshold with number, and return the value
134+
Such as '1024K' * 0.5, return '512K'
135+
:param logrotate_threshold: string type threshold value with unit, such as '1024K'
136+
:param num: the number need to multiply with
137+
:return: value with unit, such as '512K'
138+
"""
139+
return str(int(logrotate_threshold[:-1]) * num) + logrotate_threshold[-1]
140+
141+
142+
def validate_logrotate_function(duthost, logrotate_threshold):
143+
"""
144+
Validate logrotate function
145+
:param duthost: DUT host object
146+
:param logrotate_threshold: logrotate threshold, such as 16M or 1024K
147+
"""
148+
with allure.step('Run logrotate with force option to prepare clean syslog environment'):
149+
run_logrotate(duthost, force=True)
150+
151+
with allure.step('There should be no logrotate process when rsyslog size is smaller than threshold {}'.format(
152+
logrotate_threshold)):
153+
syslog_number_origin = get_syslog_file_count(duthost)
154+
logger.info('There are {} syslog gz files'.format(syslog_number_origin))
155+
create_temp_syslog_file(duthost, multiply_with_unit(logrotate_threshold, 0.9))
156+
run_logrotate(duthost)
157+
syslog_number_no_rotate = get_syslog_file_count(duthost)
158+
logger.info('There are {} syslog gz files after running logrotate'.format(syslog_number_no_rotate))
159+
assert syslog_number_origin == syslog_number_no_rotate, \
160+
'Unexpected logrotate happens, there should be no logrotate executed'
161+
162+
with allure.step('There will be logrotate process when rsyslog size is larger than threshold {}'.format(
163+
logrotate_threshold)):
164+
create_temp_syslog_file(duthost, multiply_with_unit(logrotate_threshold, 1.1))
165+
run_logrotate(duthost)
166+
syslog_number_with_rotate = get_syslog_file_count(duthost)
167+
logger.info('There are {} syslog gz files after running logrotate'.format(syslog_number_with_rotate))
168+
assert syslog_number_origin + 1 == syslog_number_with_rotate, \
169+
'No logrotate happens, there should be one time logrotate executed'
170+
171+
172+
@pytest.mark.disable_loganalyzer
173+
def test_logrotate_normal_size(rand_selected_dut):
174+
"""
175+
Test case of logrotate under normal size /var/log, test steps are listed
176+
177+
Stop logrotate cron job, make sure no logrotate executes during this test
178+
Back up current syslog file, name the backup file as 'syslog_bk'
179+
Check current /var/log is lower than 200MB, else skip this test
180+
Check current syslog.x file number and save it
181+
Create a temp file with size of rotate_size * 90% , and rename it as 'syslog', run logrotate command
182+
There would be no logrotate happens - by checking the 'syslog.x' file number not increased
183+
Create a temp file with size of rotate_size * 110%, and rename it as 'syslog', run logrotate command
184+
There would be logrotate happens - by checking the 'syslog.x' file number increased by 1
185+
Remove the temp 'syslog' file and recover the 'syslog_bk' to 'syslog'
186+
187+
:param rand_selected_dut: The fixture returns a randomly selected DUT
188+
"""
189+
duthost = rand_selected_dut
190+
with allure.step('Check whether the DUT is a small flash DUT'):
191+
if get_var_log_size(duthost) < 200 * 1024:
192+
pytest.skip('{} size is lower than 200MB, skip this test'.format(LOG_FOLDER))
193+
validate_logrotate_function(duthost, ROTATE_THRESHOLD_LARGE)
194+
195+
196+
@pytest.mark.disable_loganalyzer
197+
def test_logrotate_small_size(rand_selected_dut, simulate_small_var_log_partition):
198+
"""
199+
Test case of logrotate under a simulated small size /var/log, test steps are listed
200+
201+
Create a temp device which is around 100MB large, then mount it to /var/log
202+
Execute config reload to active the mount
203+
Stop logrotate cron job, make sure no logrotate executes during this test
204+
Check current syslog.x file number and save it
205+
Create a temp file with size of rotate_size * 90%, and rename it as 'syslog', run logrotate command
206+
There would be no logrotate happens - by checking the 'syslog.x' file number not increased
207+
Create a temp file with size of rotate_size * 110%, and rename it as 'syslog', run logrotate command
208+
There would be logrotate happens - by checking the 'syslog.x' file number increased by 1
209+
Reboot the dut to recover original /var/log mount
210+
211+
:param rand_selected_dut: The fixture returns a randomly selected DUT
212+
:param simulate_small_var_log_partition: The fixture simulates a small var log partition
213+
"""
214+
duthost = rand_selected_dut
215+
validate_logrotate_function(duthost, ROTATE_THRESHOLD_SMALL)

0 commit comments

Comments
 (0)