
This reverts the fallocate- and punch_hole-related parts of commit c78a5962b5f6c9e75f154cac924a226815236e98. Closes-Bug: #2031035 Related-Change: I3e26f8d4e5de0835212ebc2314cac713950c85d7 Change-Id: I8050296d6982f70bb64a63765b25d287a144cb8d
168 lines
6.4 KiB
Python
168 lines
6.4 KiB
Python
# Copyright (c) 2010-2023 OpenStack Foundation
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
# implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
"""Tests for swift.common.utils.libc"""
|
|
|
|
import ctypes
|
|
import os
|
|
import platform
|
|
import tempfile
|
|
import unittest
|
|
|
|
import mock
|
|
|
|
from swift.common.utils import libc
|
|
|
|
from test.debug_logger import debug_logger
|
|
|
|
|
|
class Test_LibcWrapper(unittest.TestCase):
|
|
def test_available_function(self):
|
|
# This should pretty much always exist
|
|
getpid_wrapper = libc._LibcWrapper('getpid')
|
|
self.assertTrue(getpid_wrapper.available)
|
|
self.assertEqual(getpid_wrapper(), os.getpid())
|
|
|
|
def test_unavailable_function(self):
|
|
# This won't exist
|
|
no_func_wrapper = libc._LibcWrapper('diffractively_protectorship')
|
|
self.assertFalse(no_func_wrapper.available)
|
|
self.assertRaises(NotImplementedError, no_func_wrapper)
|
|
|
|
def test_argument_plumbing(self):
|
|
lseek_wrapper = libc._LibcWrapper('lseek')
|
|
with tempfile.TemporaryFile() as tf:
|
|
tf.write(b"abcdefgh")
|
|
tf.flush()
|
|
lseek_wrapper(tf.fileno(),
|
|
ctypes.c_uint64(3),
|
|
# 0 is SEEK_SET
|
|
0)
|
|
self.assertEqual(tf.read(100), b"defgh")
|
|
|
|
|
|
class TestModifyPriority(unittest.TestCase):
|
|
def test_modify_priority(self):
|
|
pid = os.getpid()
|
|
logger = debug_logger()
|
|
called = {}
|
|
|
|
def _fake_setpriority(*args):
|
|
called['setpriority'] = args
|
|
|
|
def _fake_syscall(*args):
|
|
called['syscall'] = args
|
|
|
|
# Test if current architecture supports changing of priority
|
|
try:
|
|
libc.NR_ioprio_set()
|
|
except OSError as e:
|
|
raise unittest.SkipTest(e)
|
|
|
|
with mock.patch('swift.common.utils.libc._libc_setpriority',
|
|
_fake_setpriority), \
|
|
mock.patch('swift.common.utils.libc._posix_syscall',
|
|
_fake_syscall):
|
|
called = {}
|
|
# not set / default
|
|
libc.modify_priority({}, logger)
|
|
self.assertEqual(called, {})
|
|
called = {}
|
|
# just nice
|
|
libc.modify_priority({'nice_priority': '1'}, logger)
|
|
self.assertEqual(called, {'setpriority': (0, pid, 1)})
|
|
called = {}
|
|
# just ionice class uses default priority 0
|
|
libc.modify_priority({'ionice_class': 'IOPRIO_CLASS_RT'}, logger)
|
|
architecture = os.uname()[4]
|
|
arch_bits = platform.architecture()[0]
|
|
if architecture == 'x86_64' and arch_bits == '64bit':
|
|
self.assertEqual(called, {'syscall': (251, 1, pid, 1 << 13)})
|
|
elif architecture == 'aarch64' and arch_bits == '64bit':
|
|
self.assertEqual(called, {'syscall': (30, 1, pid, 1 << 13)})
|
|
else:
|
|
self.fail("Unexpected call: %r" % called)
|
|
called = {}
|
|
# just ionice priority is ignored
|
|
libc.modify_priority({'ionice_priority': '4'}, logger)
|
|
self.assertEqual(called, {})
|
|
called = {}
|
|
# bad ionice class
|
|
libc.modify_priority({'ionice_class': 'class_foo'}, logger)
|
|
self.assertEqual(called, {})
|
|
called = {}
|
|
# ionice class & priority
|
|
libc.modify_priority({
|
|
'ionice_class': 'IOPRIO_CLASS_BE',
|
|
'ionice_priority': '4',
|
|
}, logger)
|
|
if architecture == 'x86_64' and arch_bits == '64bit':
|
|
self.assertEqual(called, {
|
|
'syscall': (251, 1, pid, 2 << 13 | 4)
|
|
})
|
|
elif architecture == 'aarch64' and arch_bits == '64bit':
|
|
self.assertEqual(called, {
|
|
'syscall': (30, 1, pid, 2 << 13 | 4)
|
|
})
|
|
else:
|
|
self.fail("Unexpected call: %r" % called)
|
|
called = {}
|
|
# all
|
|
libc.modify_priority({
|
|
'nice_priority': '-15',
|
|
'ionice_class': 'IOPRIO_CLASS_IDLE',
|
|
'ionice_priority': '6',
|
|
}, logger)
|
|
if architecture == 'x86_64' and arch_bits == '64bit':
|
|
self.assertEqual(called, {
|
|
'setpriority': (0, pid, -15),
|
|
'syscall': (251, 1, pid, 3 << 13 | 6),
|
|
})
|
|
elif architecture == 'aarch64' and arch_bits == '64bit':
|
|
self.assertEqual(called, {
|
|
'setpriority': (0, pid, -15),
|
|
'syscall': (30, 1, pid, 3 << 13 | 6),
|
|
})
|
|
else:
|
|
self.fail("Unexpected call: %r" % called)
|
|
|
|
def test__NR_ioprio_set(self):
|
|
with mock.patch('os.uname', return_value=('', '', '', '', 'x86_64')), \
|
|
mock.patch('platform.architecture',
|
|
return_value=('64bit', '')):
|
|
self.assertEqual(251, libc.NR_ioprio_set())
|
|
|
|
with mock.patch('os.uname', return_value=('', '', '', '', 'x86_64')), \
|
|
mock.patch('platform.architecture',
|
|
return_value=('32bit', '')):
|
|
self.assertRaises(OSError, libc.NR_ioprio_set)
|
|
|
|
with mock.patch('os.uname',
|
|
return_value=('', '', '', '', 'aarch64')), \
|
|
mock.patch('platform.architecture',
|
|
return_value=('64bit', '')):
|
|
self.assertEqual(30, libc.NR_ioprio_set())
|
|
|
|
with mock.patch('os.uname',
|
|
return_value=('', '', '', '', 'aarch64')), \
|
|
mock.patch('platform.architecture',
|
|
return_value=('32bit', '')):
|
|
self.assertRaises(OSError, libc.NR_ioprio_set)
|
|
|
|
with mock.patch('os.uname', return_value=('', '', '', '', 'alpha')), \
|
|
mock.patch('platform.architecture',
|
|
return_value=('64bit', '')):
|
|
self.assertRaises(OSError, libc.NR_ioprio_set)
|