-
Notifications
You must be signed in to change notification settings - Fork 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
Remove dependence on build script #139
Conversation
Codecov Report
@@ Coverage Diff @@
## master #139 +/- ##
==========================================
+ Coverage 88.47% 88.77% +0.29%
==========================================
Files 27 27
Lines 1527 1630 +103
==========================================
+ Hits 1351 1447 +96
- Misses 176 183 +7
|
0a7c6c5
to
69a0ef2
Compare
Currently benchcab uses the `offline/build3.sh` script to build the CABLE executable. The `build3.sh` is a wrapper around `Makefile`, `parallel_cable` and `serial_cable` scripts. Using `build3.sh` is convenient for CABLE developers, however it has its draw backs when building executables for benchcab, these are outlined in #138. This change removes the dependence on `build3.sh` from the build and instead invokes the `Makefile`, `parallel_cable` and `serial_cable` scripts directly. Fixes #138
69a0ef2
to
5cf2f4a
Compare
Integration testsTest: compare new build against old build
Standard output from job:
|
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 I am done. I think we really need to work on the organisation of the tests but that's for another issue. Maybe something to bring in Ben's view on.
Split up the default build function into smaller `pre_build`, `run_build` and `post_build` functions to improve code readability. Simplify unit tests for `*_build` functions. Add `benchcab/utils/fs.py` for defining utility functions for interacting with the file system.
I'm definitely happy to discuss the unit testing approach and general code architecture. It is good to get a fresh pair of eyes on the code base. |
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.
Just one minor thing in the tests. Otherwise it looks good to me.
(tmp_dir / internal.CABLE_EXE).touch() | ||
repo = get_mock_repo() | ||
repo.post_build() | ||
assert (offline_dir / internal.CABLE_EXE).exists() |
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.
If we actually want to test a move, we should add an assert to check the file isn't under tmp_dir
. It's a detail but it might be important to get it to fail if we decide to change to a copy later on.
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.
agreed.
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.
Just some minor suggestions from me. Without being well-versed in the codebase as yet to form strong opinions blocking a merge. It would be good to have a chat around the coding approaches you have so I know where my reviews can be more helpful.
benchcab/benchcab.py
Outdated
) | ||
else: | ||
print( | ||
f"Compiling CABLE {'with MPI' if internal.MPI else 'serially'} for " |
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.
This may be semantics, but you don't often see conditionals embedded directly into an f-string, rather, the conditional bits are evaluated prior then subbed in place for clarity.
(tmp_dir / internal.CABLE_EXE).touch() | ||
repo = get_mock_repo() | ||
repo.post_build() | ||
assert (offline_dir / internal.CABLE_EXE).exists() |
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.
agreed.
with chdir(build_script_path.parent), self.modules_handler.load( | ||
modules, verbose=verbose | ||
): | ||
self.subprocess_handler.run_cmd( | ||
shlex.join([f"./{tmp_script_path.name}", *args]), |
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.
Suggestion, but why not abstract the shlex wrapping in the subprocess handler itself, rather than having to manually wrap arguments each time it is called?
Consider changing the subprocess handler(?) to accept the script and subsequent arguments, applying the shlex wrapping and executing.
i.e. something along the lines of...
# UNTESTED!!!
def execute(script, *args):
subprocess.run(shlex.join([script, args]))
...obviously following the execution logic you already having in place.
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 I will leave out the shlex wrapping feature for now as this was actually the only place where we used shlex.join()
and it has now been removed. But it might be an idea for the future since shell-escaped commands are currently not enforced by the subprocess handler.
Currently benchcab uses the
offline/build3.sh
script to build the CABLE executable. Thebuild3.sh
is a wrapper aroundMakefile
,parallel_cable
andserial_cable
scripts. Usingbuild3.sh
is convenient for CABLE developers, however it has its draw backs when building executables for benchcab, these are outlined in #138.This change removes the dependence on
build3.sh
from the build and instead invokes theMakefile
,parallel_cable
andserial_cable
scripts directly. The new build system currently reproduces the previous build system exactly.Fixes #138