Skip to content

Commit

Permalink
Add lint for topology and workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
pulsejet committed May 9, 2024
1 parent ead1bc1 commit 9167288
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 9 deletions.
16 changes: 16 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: Lint
on: [push]

jobs:
lint:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Set up Python 3
uses: actions/setup-python@v5
with:
python-version: 3.x

- name: Install dependencies
run: python -m pip install PyYAML
55 changes: 46 additions & 9 deletions framework/lint.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import os
import sys
import yaml

import internal.utils as utils
Expand All @@ -8,6 +10,16 @@
# Read config file
config = conf.get()

# Validation of links
NEIGHBORS = {}

# Configuration has errors
HAS_ERRORS = False
def log_error(message: str):
print(message, file=sys.stderr)
global HAS_ERRORS
HAS_ERRORS = True

def check_type(key: str, value: Any, typ: str, path: str):
"""
Validate a value against a type.
Expand All @@ -27,19 +39,23 @@ def check_type(key: str, value: Any, typ: str, path: str):
elif typ == 'dict':
valid_type = isinstance(value, dict)
else:
print(f"WARNING: Unknown type '{typ}' for key '{key}'")
log_error(f"WARNING: Unknown type '{typ}' for key '{key}'")

if not valid_type:
print(f"WARNING: Key '{key}' has invalid type (got '{type(value).__name__}', epxected '{typ}') in file: {path}")
log_error(f"WARNING: Key '{key}' has invalid type (got '{type(value).__name__}', epxected '{typ}') in file: {path}")

def lint(path: str):
node_name = os.path.basename(path)

# Read YAML file
raw_content = None
content = None
with open(path, 'r') as stream:
try:
content = yaml.safe_load(stream)
raw_content = stream.read()
content = yaml.safe_load(raw_content)
except yaml.YAMLError as exc:
print("Error reading YAML file: ", path, exc)
log_error("Error reading YAML file: ", path, exc)
return

# Create an ordered dict with the same order as the config file
Expand All @@ -56,18 +72,39 @@ def lint(path: str):
check_type(key, content[key], typ, path)
ordered_content[key] = content[key]
elif not is_optional:
print(f"WARNING: Missing key '{key}' in file: {path}")
log_error(f"WARNING: Missing key '{key}' in file: {path}")

# Check for any unknown keys
for key in content:
if key not in config.variables:
print(f"WARNING: Unknown key '{key}' in file: {path}")
log_error(f"WARNING: Unknown key '{key}' in file: {path}")
ordered_content[key] = content[key]

# Sort keys by name and write the file back
# Sort keys by name and check file
raw_ordered_content = yaml.dump(ordered_content, sort_keys=False)
if raw_content != raw_ordered_content:
log_error(f"WARNING: File '{path}' was incorrectly formatted or last errors.")

# Write the file back
with open(path, 'w') as stream:
yaml.dump(ordered_content, stream, sort_keys=False)
stream.write(raw_ordered_content)

# Validate neighbor pairs
for name, params in ordered_content['neighbors'].items():
flip = name + ':' + node_name
if flip in NEIGHBORS:
if NEIGHBORS[flip] != params:
log_error(f"ERROR: Parameter mismatch in link '{flip}' ({path})")
del NEIGHBORS[name + ':' + node_name]
continue
NEIGHBORS[node_name + ':' + name] = params

if __name__ == '__main__':
for file in utils.get_files(config.host_vars_path):
lint(file)
lint(file)

# Any entries that remain are incomplete
for invalid in NEIGHBORS:
log_error(f"ERROR: Neighbor '{invalid}' is not symmetric")

sys.exit(1 if HAS_ERRORS else 0)
2 changes: 2 additions & 0 deletions host_vars/WU
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ neighbors:
link_cost: 33
MEMPHIS:
link_cost: 17
BERN:
link_cost: 60
hr_angle: 4.31067
hr_radius: 19.4268
ethernet_device: eth0

0 comments on commit 9167288

Please sign in to comment.