blob: 3b99687c1158c4dfe228a3bd09dcd63597666665 [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.
#
"""Unittest for testing utilities,"""
# pytype: skip-file
import importlib
import logging
import os
import sys
import tempfile
import unittest
import mock
from apache_beam.io.filesystem import BeamIOError
from apache_beam.io.filesystems import FileSystems
from apache_beam.testing import test_utils as utils
class TestUtilsTest(unittest.TestCase):
def setUp(self):
utils.patch_retry(self, utils)
self.tmpdir = tempfile.mkdtemp()
def test_delete_files_succeeds(self):
path = os.path.join(self.tmpdir, 'f1')
with open(path, 'a') as f:
f.write('test')
assert FileSystems.exists(path)
utils.delete_files([path])
assert not FileSystems.exists(path)
def test_delete_files_fails_with_io_error(self):
path = os.path.join(self.tmpdir, 'f2')
with self.assertRaises(BeamIOError) as error:
utils.delete_files([path])
self.assertTrue(
error.exception.args[0].startswith('Delete operation failed'))
self.assertEqual(list(error.exception.exception_details.keys()), [path])
def test_delete_files_fails_with_invalid_arg(self):
with self.assertRaises(RuntimeError):
utils.delete_files([])
def test_temp_dir_removes_files(self):
with utils.TempDir() as tempdir:
dir_path = tempdir.get_path()
file_path = tempdir.create_temp_file()
self.assertTrue(os.path.exists(dir_path))
self.assertTrue(os.path.exists(file_path))
self.assertFalse(os.path.exists(dir_path))
self.assertFalse(os.path.exists(file_path))
def test_temp_file_field_correct(self):
with utils.TempDir() as tempdir:
filename = tempdir.create_temp_file(
suffix='.txt', lines=[b'line1\n', b'line2\n', b'line3\n'])
self.assertTrue(filename.endswith('.txt'))
with open(filename, 'rb') as f:
self.assertEqual(f.readline(), b'line1\n')
self.assertEqual(f.readline(), b'line2\n')
self.assertEqual(f.readline(), b'line3\n')
def test_cleanup_subscriptions(self):
sub_client = mock.Mock()
sub = mock.Mock()
sub.name = 'test_sub'
utils.cleanup_subscriptions(sub_client, [sub])
sub_client.delete_subscription.assert_called_with(subscription=sub.name)
def test_cleanup_topics(self):
pub_client = mock.Mock()
topic = mock.Mock()
topic.name = 'test_topic'
utils.cleanup_topics(pub_client, [topic])
pub_client.delete_topic.assert_called_with(topic=topic.name)
class BlockImportsTest(unittest.TestCase):
def test_block_imports_blocks_and_records_imports(self):
with utils.block_imports('colorsys') as attempted_imports:
with self.assertRaises(ImportError):
importlib.import_module('colorsys')
self.assertEqual(attempted_imports, ['colorsys'])
# The module can be imported again after exiting the context.
importlib.import_module('colorsys')
def test_block_imports_hides_and_restores_imported_modules(self):
wsgiref_util = importlib.import_module('wsgiref.util')
wsgiref = sys.modules['wsgiref']
with utils.block_imports('wsgiref') as attempted_imports:
self.assertNotIn('wsgiref', sys.modules)
self.assertNotIn('wsgiref.util', sys.modules)
with self.assertRaises(ImportError):
importlib.import_module('wsgiref.util')
# Importing a submodule first imports its parent package.
self.assertEqual(attempted_imports, ['wsgiref'])
self.assertIs(sys.modules['wsgiref'], wsgiref)
self.assertIs(sys.modules['wsgiref.util'], wsgiref_util)
def test_block_imports_only_blocks_given_packages(self):
with utils.block_imports('wsgi', 'colorsys.foo') as attempted_imports:
importlib.import_module('wsgiref')
importlib.import_module('colorsys')
self.assertEqual(attempted_imports, [])
class RequireLinuxDockerTest(unittest.TestCase):
def _fake_docker(self, os_type=None, error=None):
fake_docker = mock.MagicMock()
client = fake_docker.from_env.return_value
if error:
client.info.side_effect = error
else:
client.info.return_value = {'OSType': os_type}
return fake_docker, client
def test_linux_docker_does_not_skip(self):
fake_docker, client = self._fake_docker(os_type='linux')
with mock.patch.dict(sys.modules, {'docker': fake_docker}):
utils.require_linux_docker()
client.close.assert_called_once()
def test_windows_docker_skips(self):
fake_docker, client = self._fake_docker(os_type='windows')
with mock.patch.dict(sys.modules, {'docker': fake_docker}):
with self.assertRaisesRegex(unittest.SkipTest, 'windows containers'):
utils.require_linux_docker()
client.close.assert_called_once()
def test_unreachable_docker_skips(self):
fake_docker, client = self._fake_docker(
error=ConnectionError('no such file'))
with mock.patch.dict(sys.modules, {'docker': fake_docker}):
with self.assertRaisesRegex(unittest.SkipTest, 'Docker is not available'):
utils.require_linux_docker()
client.close.assert_called_once()
def test_missing_docker_sdk_skips(self):
with utils.block_imports('docker'):
with self.assertRaisesRegex(unittest.SkipTest, 'Docker is not available'):
utils.require_linux_docker()
class LCGeneratorTest(unittest.TestCase):
Generator = utils.LCGenerator
def test_generator_seed_results(self):
generator = self.Generator()
generator.seed(0)
self.assertEqual(generator.next_int(), 4232237)
generator.seed(1)
self.assertEqual(generator.next_int(), -1151252339)
self.assertEqual(generator.next_uint(), 3745583449)
self.assertAlmostEqual(generator.random_sample(), 0.375548, delta=1e-6)
self.assertEqual(generator.randbytes(10), b'\xa6\x8fW\xcb\xb1\xa88]dP')
def test_generator_seed_jdk_results(self):
generator = self.Generator()
generator.seed_jdk(0)
self.assertEqual(generator.next_int(), -1155484576)
generator.seed_jdk(1)
# the first next_int after seed_jdk(1) is close to seed_jdk(0)
self.assertEqual(generator.next_int(), -1155869325)
self.assertEqual(generator.next_uint(), 431529176)
self.assertAlmostEqual(generator.random_sample(), 0.410081, delta=1e-6)
self.assertEqual(generator.randbytes(10), b'\x92\xf9Mh\xfc\xcc,5\xf0\xb8')
try:
# pylint: disable=wrong-import-position
from .fast_test_utils import LCGenerator as FastLCGenerator
class FastLCGeneratorTest(LCGeneratorTest):
Generator = FastLCGenerator
except ImportError:
pass
if __name__ == '__main__':
logging.getLogger().setLevel(logging.INFO)
unittest.main()