367 lines
11 KiB
Python
367 lines
11 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test flake8 compliance for deb-bootc-image-builder.
|
|
|
|
This module tests code style compliance using flake8,
|
|
including:
|
|
- PEP 8 compliance
|
|
- Code style validation
|
|
- Debian-specific style standards
|
|
"""
|
|
|
|
import pytest
|
|
import os
|
|
import tempfile
|
|
import shutil
|
|
import subprocess
|
|
import logging
|
|
|
|
# Configure logging
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class TestFlake8Compliance:
|
|
"""Test cases for flake8 compliance."""
|
|
|
|
def test_flake8_installation(self, work_dir):
|
|
"""Test that flake8 is available."""
|
|
try:
|
|
result = subprocess.run(
|
|
["flake8", "--version"],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=10
|
|
)
|
|
assert result.returncode == 0, "flake8 is not properly installed"
|
|
logger.info("flake8 is available")
|
|
except FileNotFoundError:
|
|
pytest.skip("flake8 not installed")
|
|
|
|
def test_flake8_basic_usage(self, work_dir):
|
|
"""Test basic flake8 functionality."""
|
|
# Create a simple test file
|
|
test_file = os.path.join(work_dir, "test_flake8.py")
|
|
with open(test_file, 'w') as f:
|
|
f.write('''#!/usr/bin/env python3
|
|
"""
|
|
Test file for flake8 validation.
|
|
"""
|
|
|
|
def test_function():
|
|
"""Test function for flake8."""
|
|
return "test"
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print(test_function())
|
|
''')
|
|
|
|
# Run flake8 on the test file
|
|
try:
|
|
result = subprocess.run(
|
|
["flake8", test_file],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=30
|
|
)
|
|
|
|
# flake8 should run without errors
|
|
assert result.returncode == 0, f"flake8 found issues: {result.stdout}"
|
|
logger.info("flake8 basic functionality test passed")
|
|
|
|
except subprocess.TimeoutExpired:
|
|
pytest.fail("flake8 test timed out")
|
|
except Exception as e:
|
|
pytest.fail(f"flake8 test failed: {e}")
|
|
|
|
def test_pep8_compliance(self, work_dir):
|
|
"""Test PEP 8 compliance."""
|
|
# Create a test file with various PEP 8 issues
|
|
test_file = os.path.join(work_dir, "pep8_test.py")
|
|
with open(test_file, 'w') as f:
|
|
f.write('''#!/usr/bin/env python3
|
|
"""
|
|
Test file for PEP 8 compliance.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
|
|
# This line is too long and should trigger E501
|
|
very_long_line_that_exceeds_the_maximum_line_length_and_should_trigger_a_flake8_error = "test"
|
|
|
|
def test_function_with_bad_spacing( x,y ):
|
|
"""Function with bad spacing."""
|
|
if x==y:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
class BadClass:
|
|
def __init__(self):
|
|
pass
|
|
|
|
def method_with_bad_indentation(self):
|
|
return "bad indentation"
|
|
|
|
# Missing blank line at end of file
|
|
''')
|
|
|
|
# Run flake8 and check for expected errors
|
|
try:
|
|
result = subprocess.run(
|
|
["flake8", test_file],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=30
|
|
)
|
|
|
|
# Should find PEP 8 violations
|
|
assert result.returncode != 0, "flake8 should find PEP 8 violations"
|
|
|
|
output = result.stdout + result.stderr
|
|
|
|
# Check for specific error codes
|
|
expected_errors = ["E501", "E201", "E202", "E225", "E111", "W292"]
|
|
found_errors = []
|
|
|
|
for error_code in expected_errors:
|
|
if error_code in output:
|
|
found_errors.append(error_code)
|
|
|
|
assert len(found_errors) > 0, f"No expected PEP 8 errors found. Output: {output}"
|
|
logger.info(f"Found PEP 8 violations: {found_errors}")
|
|
|
|
except subprocess.TimeoutExpired:
|
|
pytest.fail("flake8 PEP 8 test timed out")
|
|
except Exception as e:
|
|
pytest.fail(f"flake8 PEP 8 test failed: {e}")
|
|
|
|
def test_debian_specific_style_standards(self, work_dir):
|
|
"""Test Debian-specific style standards."""
|
|
# Create a test file following Debian style standards
|
|
test_file = os.path.join(work_dir, "debian_style_test.py")
|
|
with open(test_file, 'w') as f:
|
|
f.write('''#!/usr/bin/env python3
|
|
"""
|
|
Debian-specific test file for flake8 validation.
|
|
"""
|
|
|
|
import os
|
|
import subprocess
|
|
import logging
|
|
from typing import Dict, List, Any, Optional
|
|
|
|
# Configure logging
|
|
logging.basicConfig(level=logging.INFO)
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class DebianBootcBuilder:
|
|
"""Debian bootc image builder class."""
|
|
|
|
def __init__(self, work_dir: str):
|
|
"""Initialize the builder."""
|
|
self.work_dir = work_dir
|
|
self.packages: List[str] = []
|
|
self.release = "trixie"
|
|
self.arch = "amd64"
|
|
|
|
def add_package(self, package: str) -> None:
|
|
"""Add a package to the installation list."""
|
|
if package not in self.packages:
|
|
self.packages.append(package)
|
|
logger.info(f"Added package: {package}")
|
|
|
|
def set_release(self, release: str) -> None:
|
|
"""Set the Debian release."""
|
|
valid_releases = ["trixie", "bookworm", "bullseye"]
|
|
if release in valid_releases:
|
|
self.release = release
|
|
logger.info(f"Set release to: {release}")
|
|
else:
|
|
raise ValueError(f"Invalid release: {release}")
|
|
|
|
def build_image(self) -> Dict[str, Any]:
|
|
"""Build the Debian image."""
|
|
logger.info("Starting Debian image build")
|
|
|
|
# Validate configuration
|
|
if not self.packages:
|
|
raise ValueError("No packages specified")
|
|
|
|
# Build process would go here
|
|
result = {
|
|
"status": "success",
|
|
"packages": self.packages,
|
|
"release": self.release,
|
|
"arch": self.arch
|
|
}
|
|
|
|
logger.info("Debian image build completed")
|
|
return result
|
|
|
|
|
|
def main() -> None:
|
|
"""Main function."""
|
|
builder = DebianBootcBuilder("/tmp/test")
|
|
builder.add_package("linux-image-amd64")
|
|
builder.add_package("systemd")
|
|
builder.set_release("trixie")
|
|
|
|
try:
|
|
result = builder.build_image()
|
|
print(f"Build result: {result}")
|
|
except Exception as e:
|
|
logger.error(f"Build failed: {e}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|
|
''')
|
|
|
|
# Run flake8 on the Debian style file
|
|
try:
|
|
result = subprocess.run(
|
|
["flake8", test_file],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=30
|
|
)
|
|
|
|
# Should pass flake8 validation
|
|
assert result.returncode == 0, f"flake8 found issues in Debian style file: {result.stdout}"
|
|
logger.info("Debian-specific style standards test passed")
|
|
|
|
except subprocess.TimeoutExpired:
|
|
pytest.fail("flake8 Debian style test timed out")
|
|
except Exception as e:
|
|
pytest.fail(f"flake8 Debian style test failed: {e}")
|
|
|
|
def test_flake8_configuration(self, work_dir):
|
|
"""Test flake8 configuration and custom rules."""
|
|
# Create a flake8 configuration file
|
|
setup_cfg = os.path.join(work_dir, "setup.cfg")
|
|
with open(setup_cfg, 'w') as f:
|
|
f.write('''[flake8]
|
|
# Maximum line length
|
|
max-line-length = 120
|
|
|
|
# Ignore specific error codes
|
|
ignore = E203, W503
|
|
|
|
# Exclude directories
|
|
exclude = .git,__pycache__,.venv
|
|
|
|
# Maximum complexity
|
|
max-complexity = 10
|
|
''')
|
|
|
|
# Create a test file that would normally trigger ignored errors
|
|
test_file = os.path.join(work_dir, "config_test.py")
|
|
with open(test_file, 'w') as f:
|
|
f.write('''#!/usr/bin/env python3
|
|
"""
|
|
Test file for flake8 configuration.
|
|
"""
|
|
|
|
def test_function():
|
|
"""Test function for flake8 config."""
|
|
# This line is long but should be allowed by config
|
|
very_long_line_that_exceeds_normal_pep8_but_is_allowed_by_our_config = "test"
|
|
return very_long_line_that_exceeds_normal_pep8_but_is_allowed_by_our_config
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print(test_function())
|
|
|
|
''')
|
|
|
|
# Run flake8 with custom configuration
|
|
try:
|
|
result = subprocess.run(
|
|
["flake8", "--config", setup_cfg, test_file],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=30
|
|
)
|
|
|
|
# Should pass with custom configuration
|
|
assert result.returncode == 0, f"flake8 with custom config failed: {result.stdout}"
|
|
logger.info("flake8 configuration test passed")
|
|
|
|
except subprocess.TimeoutExpired:
|
|
pytest.fail("flake8 configuration test timed out")
|
|
except Exception as e:
|
|
pytest.fail(f"flake8 configuration test failed: {e}")
|
|
|
|
def test_flake8_error_codes(self, work_dir):
|
|
"""Test specific flake8 error codes."""
|
|
# Create a test file with specific error types
|
|
test_file = os.path.join(work_dir, "error_codes_test.py")
|
|
with open(test_file, 'w') as f:
|
|
f.write('''#!/usr/bin/env python3
|
|
"""
|
|
Test file for specific flake8 error codes.
|
|
"""
|
|
|
|
# E501: Line too long
|
|
very_long_line_that_exceeds_the_maximum_line_length_and_should_trigger_a_flake8_error = "test"
|
|
|
|
# E201: Whitespace after '('
|
|
def function_with_bad_spacing( x ):
|
|
return x
|
|
|
|
# E202: Whitespace before ')'
|
|
def another_bad_function( y ):
|
|
return y
|
|
|
|
# E225: Missing whitespace around operator
|
|
x=1
|
|
y=2
|
|
z=x+y
|
|
|
|
# E111: Bad indentation
|
|
def bad_indentation():
|
|
return "bad"
|
|
|
|
# W292: No newline at end of file
|
|
result = "no newline"
|
|
''')
|
|
|
|
# Run flake8 and check for specific error codes
|
|
try:
|
|
result = subprocess.run(
|
|
["flake8", test_file],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=30
|
|
)
|
|
|
|
# Should find errors
|
|
assert result.returncode != 0, "flake8 should find style errors"
|
|
|
|
output = result.stdout + result.stderr
|
|
|
|
# Check for specific error codes
|
|
expected_errors = ["E501", "E201", "E202", "E225", "E111", "W292"]
|
|
found_errors = []
|
|
|
|
for error_code in expected_errors:
|
|
if error_code in output:
|
|
found_errors.append(error_code)
|
|
|
|
# Should find at least some of the expected errors
|
|
assert len(found_errors) >= 3, f"Expected more error codes. Found: {found_errors}"
|
|
logger.info(f"Found flake8 error codes: {found_errors}")
|
|
|
|
except subprocess.TimeoutExpired:
|
|
pytest.fail("flake8 error codes test timed out")
|
|
except Exception as e:
|
|
pytest.fail(f"flake8 error codes test failed: {e}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
pytest.main([__file__])
|