blob: 3fa592d8953a23273a4c4303a361c2fe7e8aaf15 [file]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
"""Unit tests for transfer idle timeout (no image server / nbd dependency)."""
import unittest
from unittest.mock import patch
from imageserver.config import (
TransferRegistry,
parse_idle_timeout_seconds,
validate_transfer_config,
)
from imageserver.constants import DEFAULT_IDLE_TIMEOUT_SECONDS
class TestParseIdleTimeout(unittest.TestCase):
def test_default_600(self):
self.assertEqual(parse_idle_timeout_seconds({}), DEFAULT_IDLE_TIMEOUT_SECONDS)
def test_explicit(self):
self.assertEqual(
parse_idle_timeout_seconds({"idle_timeout_seconds": 30}), 30
)
def test_zero_timeout(self):
self.assertEqual(
parse_idle_timeout_seconds({"idle_timeout_seconds": 0}), 86400
)
class TestValidateTransferConfig(unittest.TestCase):
def test_file_merges_idle(self):
c = validate_transfer_config(
{"backend": "file", "file": "/tmp/x", "idle_timeout_seconds": 3}
)
self.assertEqual(c["idle_timeout_seconds"], 3)
self.assertEqual(c["backend"], "file")
class TestRegistryIdleSweep(unittest.TestCase):
def test_sweep_unregisters_after_idle(self):
clock = [0.0]
def mono():
return clock[0]
with patch("imageserver.config.time.monotonic", mono):
r = TransferRegistry()
r.register(
"t1",
validate_transfer_config(
{"backend": "file", "file": "/x", "idle_timeout_seconds": 2}
),
)
clock[0] = 5.0
r.sweep_expired_transfers()
self.assertIsNone(r.get("t1"))
def test_inflight_prevents_sweep_until_request_ends(self):
clock = [0.0]
def mono():
return clock[0]
with patch("imageserver.config.time.monotonic", mono):
r = TransferRegistry()
r.register(
"t1",
validate_transfer_config(
{"backend": "file", "file": "/x", "idle_timeout_seconds": 2}
),
)
clock[0] = 1.0
ctx = r.request_lifecycle("t1")
ctx.__enter__()
clock[0] = 100.0
r.sweep_expired_transfers()
self.assertIsNotNone(r.get("t1"))
ctx.__exit__(None, None, None)
clock[0] = 103.0
r.sweep_expired_transfers()
self.assertIsNone(r.get("t1"))
if __name__ == "__main__":
unittest.main()