Repository: terrapower/armi
Pull request #1228 (2023-03-29 23:49:00)

Update executer to use Temporary or ForcedCreation
## Description
---

PR #1219  changed the `DefaultExecuter` class to always use a `TemporaryDirectoryChanger` instead of a `ForcedCreationDirectoryChanger`. This is usually okay, but it was found that at least one downstream repo needs the runDir to persist after the `DirectoryChanger.__exit__()`, so it needs to use a `ForcedCreationDirectoryChanger`. This PR adds a feature where the `Executer` class now has a `dcType` attribute that determines the type of `DirectoryChanger` that gets used during the `run()`.

## Checklist

- [x] This PR has only one purpose or idea.
- [x] Tests have been added/updated to verify that the new/changed code works.

<!-- Check the code quality -->

- [x] The code style follows [good practices](https://terrapower.github.io/armi/developer/standards_and_practices.html).
- [x] The commit message(s) follow [good practices](https://terrapower.github.io/armi/developer/tooling.html).

<!-- Check the project-level cruft -->

- [x] The [release notes](https://terrapower.github.io/armi/release/index.html) (location `doc/release/0.X.rst`) are up-to-date with any bug fixes or new features.
- [x] The documentation is still up-to-date in the `doc` folder.
- [x] The dependencies are still up-to-date in `setup.py`.




Patch:
diff --git a/armi/physics/executers.py b/armi/physics/executers.py
index c88a919f..657821a2 100644
--- a/armi/physics/executers.py
+++ b/armi/physics/executers.py
@@ -134,6 +134,7 @@ class Executer:
     def __init__(self, options, reactor):
         self.options = options
         self.r = reactor
+        self.dcType = directoryChangers.TemporaryDirectoryChanger
 
     def run(self):
         """
@@ -198,14 +199,14 @@ class DefaultExecuter(Executer):
         # must either write input to CWD for analysis and then copy to runDir
         # or not list it in inputs (for optimization)
         self.writeInput()
-        with directoryChangers.TemporaryDirectoryChanger(
-            root=self.options.runDir,
+        with self.dcType(
+            self.options.runDir,
             filesToMove=inputs,
             filesToRetrieve=outputs,
             outputPath=outputDir,
         ) as dc:
             self.options.workingDir = dc.initial
-            self.options.runDir = dc.destination
+            self._updateRunDir(dc.destination)
             self._execute()
             output = self._readOutput()
             if self.options.applyResultsToReactor:
@@ -213,6 +214,20 @@ class DefaultExecuter(Executer):
         self._undoGeometryTransformations()
         return output
 
+    def _updateRunDir(self, directory):
+        """
+        If a TemporaryDirectoryChanger is used, the runDir needs to be updated
+
+        If a ForcedCreationDirectoryChanger is used instead, nothing needs to be done.
+
+        Parameters
+        ----------
+        directory : str
+            New path for runDir
+        """
+        if self.dcType == directoryChangers.TemporaryDirectoryChanger:
+            self.options.runDir = directory
+
     def _collectInputsAndOutputs(self):
         """
         Get total lists of input and output files.
diff --git a/doc/release/0.2.rst b/doc/release/0.2.rst
index a6ccff32..1e90a12e 100644
--- a/doc/release/0.2.rst
+++ b/doc/release/0.2.rst
@@ -12,6 +12,7 @@ What's new in ARMI
 #. Added documentation for the thermal expansion approach used in ARMI. (`PR#1204 <https://github.com/terrapower/armi/pull/1204>`_)
 #. Use TemporaryDirectoryChanger for executer.run() so dirs are cleaned up during run. (`PR#1219 <https://github.com/terrapower/armi/pull/1219>`_)
 #. New option ``copyOutput`` for globalFluxInterface to not copy output back to working directory. (`PR#1218 <https://github.com/terrapower/armi/pull/1218>`_, `PR#1227 <https://github.com/terrapower/armi/pull/1227>`_)
+#. `Executer` class has a ``dcType`` attribute to define the type of ``DirectoryChanger`` it will use. (`PR#1228 <https://github.com/terrapower/armi/pull/1228>`_)
 
 Bug fixes
 ---------


Test patch:
diff --git a/armi/physics/tests/test_executers.py b/armi/physics/tests/test_executers.py
index 4c34c98a..7550fb8c 100644
--- a/armi/physics/tests/test_executers.py
+++ b/armi/physics/tests/test_executers.py
@@ -18,7 +18,7 @@ import os
 import unittest
 
 from armi.reactor import geometry
-from armi import settings
+from armi.utils import directoryChangers
 from armi.physics import executers
 
 # pylint: disable=abstract-method
@@ -75,7 +75,6 @@ class TestExecuters(unittest.TestCase):
         """
         Verify that the executer can select to not copy back output.
         """
-        cs = settings.Settings()
         self.executer.options.inputFile = "test.inp"
         self.executer.options.outputFile = "test.out"
         self.executer.options.copyOutput = False
@@ -94,6 +93,24 @@ class TestExecuters(unittest.TestCase):
             "test.out", outputs[0], "Output file was not successfully identified."
         )
 
+    def test_updateRunDir(self):
+        """
+        Verify that runDir is updated when TemporaryDirectoryChanger is used and
+        not updated when ForcedCreationDirectoryChanger is used
+        """
+
+        self.assertEqual(
+            self.executer.dcType, directoryChangers.TemporaryDirectoryChanger
+        )
+        self.executer._updateRunDir("updatedRunDir")
+        self.assertEqual(self.executer.options.runDir, "updatedRunDir")
+
+        # change directoryChanger type, runDir not updated
+        self.executer.options.runDir = "runDir"
+        self.executer.dcType = directoryChangers.ForcedCreationDirectoryChanger
+        self.executer._updateRunDir("notThisString")
+        self.assertEqual(self.executer.options.runDir, "runDir")
+
 
 if __name__ == "__main__":
     unittest.main()