-
Notifications
You must be signed in to change notification settings - Fork 8
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
Refactor plugins #76
Refactor plugins #76
Conversation
1044434
to
6079b08
Compare
6079b08
to
505040f
Compare
.circleci/config.yml
Outdated
@@ -47,16 +55,17 @@ jobs: | |||
bin/build | |||
mkdir -p /tmp/docker/images | |||
docker save -o /tmp/docker/images/arnold.tar "${ARNOLD_IMAGE}" | |||
# Store the built as an artifact that can be reused in other jobs | |||
# Save built to the workspace so that it can be reused in other jobs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/built/build?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant save the built to the workspace.
- *docker_load | ||
- run: bin/lint plugins | ||
|
||
test-built: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/built/build?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test the build 😉
.circleci/config.yml
Outdated
@@ -105,22 +129,54 @@ jobs: | |||
"${ARNOLD_IMAGE}" \ | |||
ansible --version | |||
|
|||
# FIXME: we have deactivated plugins test coverage as the container user is | |||
# not allowed to write to /app/.coverage and CircleCI does not allowed to | |||
# mount volumes with "docker run" commands. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you're saying this and then below you're mounting /app/.pytest_cache?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not a classical volume it's a tmpfs
. Concerning volumes, I think I cannot use them since we are in "dind" mode. We need to switch to the machine executor at least for this task.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So why can't you use a tmpfs for /app/.coverage also?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because it's a file, not a directory.
.circleci/config.yml
Outdated
@@ -105,22 +129,54 @@ jobs: | |||
"${ARNOLD_IMAGE}" \ | |||
ansible --version | |||
|
|||
# FIXME: we have deactivated plugins test coverage as the container user is | |||
# not allowed to write to /app/.coverage and CircleCI does not allowed to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/allowed/allow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 it's the container user that is not allowed to
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I nearly apologized... then I realized that there are 2 "allowed" in this sentence ^^
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops. you're right.
- lint-plugins: | ||
requires: | ||
- build | ||
- test-built: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok... maybe you really meant built instead of build...
assert deep_sort_dict(d) == expected | ||
|
||
def test_deep_embedded_dict(self): | ||
"""Avoid testing recursivity""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wrong docstring
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Sorry for that.
"bar": ["a", "b", "c", "d"], | ||
} | ||
|
||
assert deep_sort_dict(d) == expected |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should add:
assert d == {
"foo": {"baz": [4, 1, 6, {"lol": ["x", "z", "y"]}]},
"bar": ["c", "b", "d", "a"],
}
Same on all tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not if we test immutability separately?
maxDiff = None | ||
|
||
def assertDictDeepEqual(self, a, b): | ||
"""Use a sorted json string to deep compare apps (dictionaries)""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The docstring seems wrong. Here you are testing that they are pointing to the same reference, not that their json representation is the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow. I should have carefully check my docstring. This is an old dumb implementation.
) | ||
|
||
def test_submitted_apps_name_is_not_empty(self): | ||
"""Submitted apps should have the same ``name`` key""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copy/paste fail
|
||
def test_services_merge_with_empty_new_services(self): | ||
""" | ||
Test app services merge with no services or volumes for tje new |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/tje/the
|
||
def test_services_merge_without_duplicates(self): | ||
""" | ||
Test app services merge does not creates duplicates if same items |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/creates/create
"name": "baz", | ||
"configs": ["baz.conf"], | ||
"templates": ["baz/dc.yml", "baz/svc.yml", "baz/ep.yml"], | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the fun service is gone is it what you expect?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we take data from right (new) to left (base) if the app is defined in left (base), i.e. you cannot define a new app that is not listed as available (with files in apps/).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the moment I just read the tests. Maybe it deserves a line in the docstring.
Then the concept could be explained in some documentation (in another PR is fine)?
Instead of using the pipe lookup with an executed python program output, we implemented our own lookup plugin. It should have already been this way from the start.
Following Ansible's guidelines, this work adds a fully fonctionnal test environment using pytest.
85acc55
to
3913584
Compare
d = {"foo": 1, "bar": ["c", "b", "d", "a"]} | ||
s = deep_sort_dict(d) | ||
|
||
assert d != s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
assertion is good but you didn't test that it does not modify d :-)
assert d == {"foo": 1, "bar": ["c", "b", "d", "a"]} ?
│ │ ├── dc.yml.j2 | ||
│ │ └── svc.yml.j2 | ||
│ ├── nginx | ||
│ │ ├── _configs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think singular is better: config
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see plural everywhere (volumes, templates, etc). Let's stick to it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but config is "the config"? Pick what you prefer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There may be more that once configuration for a service (e.g. edxapp cms + lms ngnix configurations).
plugins/filter/merge.py
Outdated
"""Merge data from the "new" application to the "base" application""" | ||
""" | ||
Merge data from the "new" application to the "base" application. | ||
Services listed in "new" that does not exist in "base" will be ignored. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/does/do
plugins/filter/merge.py
Outdated
for k in ("configs", "templates"): | ||
if new_service.get(k) is None: | ||
continue | ||
base_service[k] = sorted(list(set(new_service[k] + base_service[k]))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe add a comment to explain that you do list(set( to deduplicate?
Switch to our own apps merge implementation to avoid duplicates in lists.
The merge_with_app filter reliability is a core part of the app discovery feature. It requires intense testing to ensure consistency of our whole strategy.
A cosmetic update to make job names more homogeneous in FUN's projects.
We now run unit tests of Arnold's plugins in the CI.
We now use pylint, isort and flake8 to lint our custom plugins. Unfortunately black cannot be used as we are running python 2.7 and it requires at least python 3.6.
* apply black-style formatting * fix flake8 and isort warnings
11dda21
to
3f8248b
Compare
Purpose
Current "plugins" implementation is far from academic. We should follow Ansible's recommendations to improve them.
Proposal
deepmerge
and make our own)