Skip to content

Add Python Black format check and apply format changes #3

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,22 @@ on:
- pull_request

jobs:
lint-unit-and-func-tests:
name: Lint, Unit, & Functional Tests
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Install Tox
run: pip install tox
- name: Run lint
run: tox -e lint
unit-and-func-tests:
name: Unit, & Functional Tests
runs-on: ubuntu-latest
strategy:
matrix:
Expand All @@ -19,8 +33,8 @@ jobs:
python-version: ${{ matrix.python }}
- name: Install Tox
run: pip install tox
- name: Run lint, unit, and functional tests
run: tox
- name: Run unit & functional tests
run: tox -e unit,functional

# TODO
#integration-test:
Expand Down
24 changes: 14 additions & 10 deletions loadbalancer_interface/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,40 @@ def __init__(self, charm, relation_name):
# Future-proof against the need to evolve the relation protocol
# by ensuring that we agree on a version number before starting.
# This may or may not be made moot by a future feature in Juju.
for event in (charm.on[relation_name].relation_created,
charm.on.leader_elected,
charm.on.upgrade_charm):
for event in (
charm.on[relation_name].relation_created,
charm.on.leader_elected,
charm.on.upgrade_charm,
):
self.framework.observe(event, self._set_version)

def _set_version(self, event):
if self.unit.is_leader():
if hasattr(event, 'relation'):
if hasattr(event, "relation"):
relations = [event.relation]
else:
relations = self.model.relations.get(self.relation_name, [])
for relation in relations:
relation.data[self.app]['version'] = str(schemas.max_version)
relation.data[self.app]["version"] = str(schemas.max_version)

@cached_property
def relations(self):
relations = self.model.relations.get(self.relation_name, [])
return [relation
for relation in sorted(relations, key=attrgetter('id'))
if self._schema(relation)]
return [
relation
for relation in sorted(relations, key=attrgetter("id"))
if self._schema(relation)
]

def _schema(self, relation=None):
if relation is None:
return schemas.versions[schemas.max_version]
if relation.app not in relation.data:
return None
data = relation.data[relation.app]
if 'version' not in data:
if "version" not in data:
return None
remote_version = int(data['version'])
remote_version = int(data["version"])
return schemas.versions[min((schemas.max_version, remote_version))]

@property
Expand Down
70 changes: 36 additions & 34 deletions loadbalancer_interface/consumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ class LBConsumersEvents(ObjectEvents):


class LBConsumers(VersionedInterface):
""" API used to interact with consumers of a loadbalancer provider.
"""
"""API used to interact with consumers of a loadbalancer provider."""

state = StoredState()
on = LBConsumersEvents()

Expand All @@ -31,9 +31,11 @@ def __init__(self, charm, relation_name):
self.relation_name = relation_name
self.state.set_default(known_requests={})

for event in (charm.on[relation_name].relation_created,
charm.on[relation_name].relation_joined,
charm.on[relation_name].relation_changed):
for event in (
charm.on[relation_name].relation_created,
charm.on[relation_name].relation_joined,
charm.on[relation_name].relation_changed,
):
self.framework.observe(event, self._check_consumers)

def _check_consumers(self, event):
Expand All @@ -42,8 +44,7 @@ def _check_consumers(self, event):

@cached_property
def all_requests(self):
""" A list of all current consumer requests.
"""
"""A list of all current consumer requests."""
if not self.unit.is_leader():
# Only the leader can process requests, so avoid mistakes
# by not even reading the requests if not the leader.
Expand All @@ -54,17 +55,15 @@ def all_requests(self):
local_data = relation.data[self.app]
remote_data = relation.data[relation.app]
for key, request_sdata in sorted(remote_data.items()):
if not key.startswith('request_'):
if not key.startswith("request_"):
continue
name = key[len('request_'):]
response_sdata = local_data.get('response_' + name)
request = schema.Request.loads(name,
request_sdata,
response_sdata)
name = key[len("request_") :]
response_sdata = local_data.get("response_" + name)
request = schema.Request.loads(name, request_sdata, response_sdata)
request.relation = relation
if not request.backends:
for unit in sorted(relation.units, key=attrgetter('name')):
addr = relation.data[unit].get('ingress-address')
for unit in sorted(relation.units, key=attrgetter("name")):
addr = relation.data[unit].get("ingress-address")
if addr:
request.backends.append(addr)
requests.append(request)
Expand All @@ -73,53 +72,56 @@ def all_requests(self):

@property
def new_requests(self):
""" A list of requests with changes or no response.
"""
return [request for request in self.all_requests
if request.hash != self.state.known_requests[request.id]]
"""A list of requests with changes or no response."""
return [
request
for request in self.all_requests
if request.hash != self.state.known_requests[request.id]
]

@property
def removed_requests(self):
""" A list of requests which have been removed, either explicitly or
"""A list of requests which have been removed, either explicitly or
because the relation was removed.
"""
current_ids = {request.id for request in self.all_requests}
unknown_ids = self.state.known_requests.keys() - current_ids
schema = self._schema()
return [schema.Request._from_id(req_id, self.relations)
for req_id in sorted(unknown_ids)]
return [
schema.Request._from_id(req_id, self.relations)
for req_id in sorted(unknown_ids)
]

def send_response(self, request):
""" Send a specific request's response.
"""
"""Send a specific request's response."""
request.response.received_hash = request.sent_hash
key = 'response_' + request.name
key = "response_" + request.name
request.relation.data[self.app][key] = request.response.dumps()
self.state.known_requests[request.id] = request.hash
if not self.new_requests:
try:
from charms.reactive import clear_flag
prefix = 'endpoint.' + self.relation_name
clear_flag(prefix + '.requests_changed')

prefix = "endpoint." + self.relation_name
clear_flag(prefix + ".requests_changed")
except ImportError:
pass # not being used in a reactive charm

def revoke_response(self, request):
""" Revoke / remove the response for a given request.
"""
"""Revoke / remove the response for a given request."""
if request.id:
self.state.known_requests.pop(request.id, None)
if request.relation:
key = 'response_' + request.name
key = "response_" + request.name
request.relation.data.get(self.app, {}).pop(key, None)

@property
def is_changed(self):
return bool(self.new_requests or self.removed_requests)

def manage_flags(self):
""" Used to interact with charms.reactive-base charms.
"""
"""Used to interact with charms.reactive-base charms."""
from charms.reactive import toggle_flag
prefix = 'endpoint.' + self.relation_name
toggle_flag(prefix + '.requests_changed', self.is_changed)

prefix = "endpoint." + self.relation_name
toggle_flag(prefix + ".requests_changed", self.is_changed)
Loading