Commit 17583c8b authored by Mark Beierl's avatar Mark Beierl
Browse files

Merge branch 'master' into 'master'

Update squid charm

See merge request !105
parents e2197769 9c012576
Pipeline #143 passed with stage
in 1 minute and 34 seconds
# Copyright 2020 Canonical Ltd.
#
# 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.
import io
import itertools
import os
import re
import subprocess
import sys
import tempfile
import unittest
from unittest.mock import patch
import autopep8
from flake8.api.legacy import get_style_guide
def get_python_filepaths():
"""Helper to retrieve paths of Python files."""
python_paths = ['setup.py']
for root in ['ops', 'test']:
for dirpath, dirnames, filenames in os.walk(root):
for filename in filenames:
if filename.endswith(".py"):
python_paths.append(os.path.join(dirpath, filename))
return python_paths
class InfrastructureTests(unittest.TestCase):
def test_pep8(self):
# verify all files are nicely styled
python_filepaths = get_python_filepaths()
style_guide = get_style_guide()
fake_stdout = io.StringIO()
with patch('sys.stdout', fake_stdout):
report = style_guide.check_files(python_filepaths)
# if flake8 didnt' report anything, we're done
if report.total_errors == 0:
return
# grab on which files we have issues
flake8_issues = fake_stdout.getvalue().split('\n')
broken_filepaths = {item.split(':')[0] for item in flake8_issues if item}
# give hints to the developer on how files' style could be improved
options = autopep8.parse_args([''])
options.aggressive = 1
options.diff = True
options.max_line_length = 99
issues = []
for filepath in broken_filepaths:
diff = autopep8.fix_file(filepath, options=options)
if diff:
issues.append(diff)
report = ["Please fix files as suggested by autopep8:"] + issues
report += ["\n-- Original flake8 reports:"] + flake8_issues
self.fail("\n".join(report))
def test_quote_backslashes(self):
# ensure we're not using unneeded backslash to escape strings
issues = []
for filepath in get_python_filepaths():
with open(filepath, "rt", encoding="utf8") as fh:
for idx, line in enumerate(fh, 1):
if (r'\"' in line or r"\'" in line) and "NOQA" not in line:
issues.append((filepath, idx, line.rstrip()))
if issues:
msgs = ["{}:{:d}:{}".format(*issue) for issue in issues]
self.fail("Spurious backslashes found, please fix these quotings:\n" + "\n".join(msgs))
def test_ensure_copyright(self):
# all non-empty Python files must have a proper copyright somewhere in the first 5 lines
issues = []
regex = re.compile(r"# Copyright \d\d\d\d(-\d\d\d\d)? Canonical Ltd.\n")
for filepath in get_python_filepaths():
if os.stat(filepath).st_size == 0:
continue
with open(filepath, "rt", encoding="utf8") as fh:
for line in itertools.islice(fh, 5):
if regex.match(line):
break
else:
issues.append(filepath)
if issues:
self.fail("Please add copyright headers to the following files:\n" + "\n".join(issues))
class ImportersTestCase(unittest.TestCase):
template = "from ops import {module_name}"
def test_imports(self):
mod_names = [
'charm',
'framework',
'main',
'model',
'testing',
]
for name in mod_names:
with self.subTest(name=name):
self.check(name)
def check(self, name):
"""Helper function to run the test."""
_, testfile = tempfile.mkstemp()
self.addCleanup(os.unlink, testfile)
with open(testfile, 'wt', encoding='utf8') as fh:
fh.write(self.template.format(module_name=name))
proc = subprocess.run([sys.executable, testfile], env={'PYTHONPATH': os.getcwd()})
self.assertEqual(proc.returncode, 0)
#!/usr/bin/env python3
# Copyright 2019 Canonical Ltd.
#
# 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.
import unittest
from ops.jujuversion import JujuVersion
class TestJujuVersion(unittest.TestCase):
def test_parsing(self):
test_cases = [
("0.0.0", 0, 0, '', 0, 0),
("0.0.2", 0, 0, '', 2, 0),
("0.1.0", 0, 1, '', 0, 0),
("0.2.3", 0, 2, '', 3, 0),
("10.234.3456", 10, 234, '', 3456, 0),
("10.234.3456.1", 10, 234, '', 3456, 1),
("1.21-alpha12", 1, 21, 'alpha', 12, 0),
("1.21-alpha1.34", 1, 21, 'alpha', 1, 34),
("2.7", 2, 7, '', 0, 0)
]
for vs, major, minor, tag, patch, build in test_cases:
v = JujuVersion(vs)
self.assertEqual(v.major, major)
self.assertEqual(v.minor, minor)
self.assertEqual(v.tag, tag)
self.assertEqual(v.patch, patch)
self.assertEqual(v.build, build)
def test_parsing_errors(self):
invalid_versions = [
"xyz",
"foo.bar",
"foo.bar.baz",
"dead.beef.ca.fe",
"1234567890.2.1", # The major version is too long.
"0.2..1", # Two periods next to each other.
"1.21.alpha1", # Tag comes after period.
"1.21-alpha", # No patch number but a tag is present.
"1.21-alpha1beta", # Non-numeric string after the patch number.
"1.21-alpha-dev", # Tag duplication.
"1.21-alpha_dev3", # Underscore in a tag.
"1.21-alpha123dev3", # Non-numeric string after the patch number.
]
for v in invalid_versions:
with self.assertRaises(RuntimeError):
JujuVersion(v)
def test_equality(self):
test_cases = [
("1.0.0", "1.0.0", True),
("01.0.0", "1.0.0", True),
("10.0.0", "9.0.0", False),
("1.0.0", "1.0.1", False),
("1.0.1", "1.0.0", False),
("1.0.0", "1.1.0", False),
("1.1.0", "1.0.0", False),
("1.0.0", "2.0.0", False),
("1.2-alpha1", "1.2.0", False),
("1.2-alpha2", "1.2-alpha1", False),
("1.2-alpha2.1", "1.2-alpha2", False),
("1.2-alpha2.2", "1.2-alpha2.1", False),
("1.2-beta1", "1.2-alpha1", False),
("1.2-beta1", "1.2-alpha2.1", False),
("1.2-beta1", "1.2.0", False),
("1.2.1", "1.2.0", False),
("2.0.0", "1.0.0", False),
("2.0.0.0", "2.0.0", True),
("2.0.0.0", "2.0.0.0", True),
("2.0.0.1", "2.0.0.0", False),
("2.0.1.10", "2.0.0.0", False),
]
for a, b, expected in test_cases:
self.assertEqual(JujuVersion(a) == JujuVersion(b), expected)
self.assertEqual(JujuVersion(a) == b, expected)
def test_comparison(self):
test_cases = [
("1.0.0", "1.0.0", False, True),
("01.0.0", "1.0.0", False, True),
("10.0.0", "9.0.0", False, False),
("1.0.0", "1.0.1", True, True),
("1.0.1", "1.0.0", False, False),
("1.0.0", "1.1.0", True, True),
("1.1.0", "1.0.0", False, False),
("1.0.0", "2.0.0", True, True),
("1.2-alpha1", "1.2.0", True, True),
("1.2-alpha2", "1.2-alpha1", False, False),
("1.2-alpha2.1", "1.2-alpha2", False, False),
("1.2-alpha2.2", "1.2-alpha2.1", False, False),
("1.2-beta1", "1.2-alpha1", False, False),
("1.2-beta1", "1.2-alpha2.1", False, False),
("1.2-beta1", "1.2.0", True, True),
("1.2.1", "1.2.0", False, False),
("2.0.0", "1.0.0", False, False),
("2.0.0.0", "2.0.0", False, True),
("2.0.0.0", "2.0.0.0", False, True),
("2.0.0.1", "2.0.0.0", False, False),
("2.0.1.10", "2.0.0.0", False, False),
]
for a, b, expected_strict, expected_weak in test_cases:
self.assertEqual(JujuVersion(a) < JujuVersion(b), expected_strict)
self.assertEqual(JujuVersion(a) <= JujuVersion(b), expected_weak)
self.assertEqual(JujuVersion(b) > JujuVersion(a), expected_strict)
self.assertEqual(JujuVersion(b) >= JujuVersion(a), expected_weak)
# Implicit conversion.
self.assertEqual(JujuVersion(a) < b, expected_strict)
self.assertEqual(JujuVersion(a) <= b, expected_weak)
self.assertEqual(b > JujuVersion(a), expected_strict)
self.assertEqual(b >= JujuVersion(a), expected_weak)
if __name__ == "__main__":
unittest.main()
#!/usr/bin/python3
# Copyright 2020 Canonical Ltd.
#
# 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.
import io
import unittest
from unittest.mock import patch
import importlib
import logging
import ops.log
class FakeModelBackend:
def __init__(self):
self._calls = []
def calls(self, clear=False):
calls = self._calls
if clear:
self._calls = []
return calls
def juju_log(self, message, level):
self._calls.append((message, level))
def reset_logging():
logging.shutdown()
importlib.reload(logging)
class TestLogging(unittest.TestCase):
def setUp(self):
self.backend = FakeModelBackend()
reset_logging()
self.addCleanup(reset_logging)
def test_default_logging(self):
ops.log.setup_root_logging(self.backend)
logger = logging.getLogger()
self.assertEqual(logger.level, logging.DEBUG)
self.assertIsInstance(logger.handlers[0], ops.log.JujuLogHandler)
test_cases = [(
lambda: logger.critical('critical'), [('CRITICAL', 'critical')]
), (
lambda: logger.error('error'), [('ERROR', 'error')]
), (
lambda: logger.warning('warning'), [('WARNING', 'warning')]
), (
lambda: logger.info('info'), [('INFO', 'info')]
), (
lambda: logger.debug('debug'), [('DEBUG', 'debug')]
)]
for do, res in test_cases:
do()
calls = self.backend.calls(clear=True)
self.assertEqual(calls, res)
def test_handler_filtering(self):
logger = logging.getLogger()
logger.setLevel(logging.INFO)
logger.addHandler(ops.log.JujuLogHandler(self.backend, logging.WARNING))
logger.info('foo')
self.assertEqual(self.backend.calls(), [])
logger.warning('bar')
self.assertEqual(self.backend.calls(), [('WARNING', 'bar')])
def test_no_stderr_without_debug(self):
buffer = io.StringIO()
with patch('sys.stderr', buffer):
ops.log.setup_root_logging(self.backend, debug=False)
logger = logging.getLogger()
logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.critical('critical message')
self.assertEqual(
self.backend.calls(),
[('DEBUG', 'debug message'),
('INFO', 'info message'),
('WARNING', 'warning message'),
('CRITICAL', 'critical message'),
])
self.assertEqual(buffer.getvalue(), "")
def test_debug_logging(self):
buffer = io.StringIO()
with patch('sys.stderr', buffer):
ops.log.setup_root_logging(self.backend, debug=True)
logger = logging.getLogger()
logger.debug('debug message')
logger.info('info message')
logger.warning('warning message')
logger.critical('critical message')
self.assertEqual(
self.backend.calls(),
[('DEBUG', 'debug message'),
('INFO', 'info message'),
('WARNING', 'warning message'),
('CRITICAL', 'critical message'),
])
self.assertRegex(
buffer.getvalue(),
r"\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d,\d\d\d DEBUG debug message\n"
r"\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d,\d\d\d INFO info message\n"
r"\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d,\d\d\d WARNING warning message\n"
r"\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d,\d\d\d CRITICAL critical message\n"
)
def test_reduced_logging(self):
ops.log.setup_root_logging(self.backend)
logger = logging.getLogger()
logger.setLevel(logging.WARNING)
logger.debug('debug')
logger.info('info')
logger.warning('warning')
self.assertEqual(self.backend.calls(), [('WARNING', 'warning')])
if __name__ == '__main__':
unittest.main()
ops
jinja2
git+https://github.com/juju-solutions/resource-oci-image/@c5778285d332edf3d9a538f9d0c06154b7ec1b0b#egg=oci-image
This diff is collapsed.
This diff is collapsed.
Wheel-Version: 1.0
Generator: bdist_wheel (0.34.2)
Root-Is-Purelib: true
Tag: py2-none-any
Tag: py3-none-any
[babel.extractors]
jinja2 = jinja2.ext:babel_extract [i18n]
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment