Thanks to visit codestin.com
Credit goes to github.com

Skip to content
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
13 changes: 8 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ CWD=$(shell pwd)
PULL ?=True
CONTAINER_ENGINE ?=docker
RUN_FLAGS ?=--rm
CHECK_CHANGED_SCRIPT=$(CWD)/changed_from_main.py


build:
Expand All @@ -18,16 +19,18 @@ dev:
$(FV3GFS_IMAGE) bash

test_util:
$(MAKE) -C fv3gfs-util test
if [ $(shell $(CHECK_CHANGED_SCRIPT) fv3gfs-util) != false ]; then \
$(MAKE) -C fv3gfs-util test; \
fi

savepoint_tests:
$(MAKE) -C fv3core savepoint_tests
$(MAKE) -C fv3core $@

savepoint_tests_mpi:
$(MAKE) -C fv3core savepoint_tests_mpi
$(MAKE) -C fv3core $@

dependencies.svg:
dot -Tsvg dependencies.dot -o $@
dependencies.svg: dependencies.dot
dot -Tsvg $< -o $@

constraints.txt: fv3core/requirements.txt fv3core/requirements/requirements_wrapper.txt fv3core/requirements/requirements_lint.txt fv3gfs-util/requirements.txt fv3gfs-physics/requirements.txt
pip-compile $^ --output-file constraints.txt
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Currently, we support tests in the dynamical core, physics, and util.

This git repository is laid out as a mono-repo, containing multiple independent projects. Because of this, it is important not to introduce unintended dependencies between projects. The graph below indicates a project depends on another by an arrow pointing from the parent project to its dependency. For example, the tests for fv3core should be able to run with only files contained under the fv3core and util projects, and should not access any files in the driver or physics packages. Only the top-level tests in Pace are allowed to read all files.

![Graph of interdependencies of Pace modules](./dependencies.svg)
![Graph of interdependencies of Pace modules, generated from dependences.dot](./dependencies.svg)

### Dynamical core tests

Expand Down
102 changes: 102 additions & 0 deletions changed_from_main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
#!/usr/bin/env python3
"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coming from a linux/unix environment, I have a tendency to make scripts like these executable and start with a #!/usr/bin/env python3.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to keep the python here because hash bangs for python make me uncomfortable (do they use your active python env?).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

This script determines whether one of the projects in the repo or any of its
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this really be in the top level directory?

In fv3core we did use a .jenkins folder for these type of things as it is pretty CI related. Or we could put this into a util folder?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If our top level directory gets cluttered I could see moving this eventually, but this is an integral part of running the top-level Makefile targets as we're currently planning to use it. If we call it directly in Jenkins instead of calling it inside the Makefile (as I did for test_util), we can move it then.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good to me

dependencies are different from the version on the `main` branch.

This is useful for running tests only on projects that have changed.

This script should depend only on Python 3.6+ standard libraries.
"""
import argparse
import re
import os
import subprocess
from typing import Any, Dict, Set


DIRNAME = os.path.dirname(os.path.abspath(__file__))
DEPENDENCIES_DOTFILE = os.path.join(DIRNAME, "dependencies.dot")

DEFINITION_PATTERN = re.compile(r"\s*([a-zA-Z0-9]+) \[.*label=\"(.*)\".*\]")
DEPENDENCY_PATTERN = re.compile(r"\s*([a-zA-Z0-9]+) -> ([a-zA-Z0-9]+)")


def get_dependencies() -> Dict[str, Set[str]]:
name_to_subdir = {}
subdir_dependencies = {}
with open(DEPENDENCIES_DOTFILE, "r") as f:
dotfile_text = f.read()
for groups in DEFINITION_PATTERN.findall(dotfile_text):
name_to_subdir[groups[0]] = groups[1]
subdir_dependencies[groups[1]] = set()
for groups in DEPENDENCY_PATTERN.findall(dotfile_text):
name = groups[0]
dependency_name = groups[1]
if name in name_to_subdir:
subdir = name_to_subdir[name]
dependency_subdir = name_to_subdir[dependency_name]
subdir_dependencies[subdir].add(dependency_subdir)
add_nested_dependencies(subdir_dependencies)
return subdir_dependencies


def add_nested_dependencies(dependency_map: Dict[str, Set[str]]) -> Dict[str, Set[str]]:
"""
Given a dictionary mapping keys to dependent keys which may or may
not contain dependencies of dependencies, update it in-place so that
dependencies include all sub-dependencies.

Assumes the dependencies contain no cycles.
"""
# path can be at most as long as the total number of items
for _ in range(len(dependency_map)):
for dependencies in dependency_map.values():
for dependent_key in dependencies:
dependencies.update(dependency_map[dependent_key])


def parse_args(subdir_dependencies: Dict[str, Any]):
parser = argparse.ArgumentParser(
description=(
"Determines whether one of the projects in the repo or any of its "
"dependencies are different from the version on the `main` branch. "
"Prints \"false\" if the subdirectory and its dependencies are "
"unchanged, or \"true\" if they have changed."
)
)
parser.add_argument(
"project_name", type=str, help="subdirectory name of project to check", choices=subdir_dependencies.keys()
)
return parser.parse_args()


def unstaged_files(dirname) -> bool:
result = subprocess.check_output(
["git", "ls-files", "--other", "--directory", "--exclude-standard", dirname]
)
return len(result) > 0


def staged_files_changed(dirname) -> bool:
result = subprocess.check_output(
["git", "diff", "main", dirname]
)
return len(result) > 0


def changed(dirname) -> bool:
return unstaged_files(dirname) or staged_files_changed(dirname)


if __name__ == '__main__':
subdir_dependencies = get_dependencies()
args = parse_args(subdir_dependencies)
if changed(args.project_name):
print("true")
else:
for dependency_subdir in subdir_dependencies[args.project_name]:
if changed(dependency_subdir):
print("true")
break
else:
print("false")
24 changes: 15 additions & 9 deletions dependencies.dot
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
# this dotfile is used as a reference source for project dependencies
# each folder entry must have a "label" equal to its directory name
#
# If you update this file, please re-generate the svg with `make dependencies.svg`
# and commit it to the repository

digraph {
Pace [shape=box]
fv3core [shape=oval]
driver [shape=oval]
physics [shape=oval]
util [shape=oval]
pace [shape=box]
fv3core [shape=oval, label="fv3core"]
driver [shape=oval, label="driver"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

driver does not exist yet. should it already be here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No harm in including it because it's not depended on by any other components, it can happen now or when the folder gets added. I believe it will be added as part of Rhea's current PR(s).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's fine if it is here. Right now it exits not very gracefully if you call changed_from_main.py driver but this is very temporary. If it is not blocking any CI related work this is totally fine!

physics [shape=oval, label="fv3gfs-physics"]
util [shape=oval, label="fv3gfs-util"]

Pace -> fv3core
Pace -> physics
Pace -> util
Pace -> driver
pace -> fv3core
pace -> physics
pace -> util
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you actually need all of these dependencies explicitly? Or otherwise put, since the dependecy path pace -> fv3core -> util already exists, do we need pace -> util? In any case, we should make sure that for testing we do bottom -> up.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, pace and driver both directly depend on util, apart from their indirect dependence through other packages.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I get it. I guess my question is more related to what these dependencies actually imply w.r.t. testing order. Removing these dependencies could favor a bottom-up testing strategy (so we don't test pace right after util, but rather fv3core first).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All tests which need to run are run simultaneously. These dependencies are not used for testing order and do not imply anything w.r.t. testing order.

pace -> driver
driver -> fv3core
driver -> physics
driver -> util
Expand Down
58 changes: 29 additions & 29 deletions dependencies.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.