Skip to content

Commit

Permalink
Merge 74dc627 into 33e3a88
Browse files Browse the repository at this point in the history
  • Loading branch information
opotowsky committed Apr 23, 2024
2 parents 33e3a88 + 74dc627 commit 8710b69
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 3 deletions.
27 changes: 24 additions & 3 deletions armi/utils/__init__.py
Expand Up @@ -806,17 +806,38 @@ def merge(self, *otherDictionaries) -> None:

def safeCopy(src: str, dst: str) -> None:
"""This copy overwrites ``shutil.copy`` and checks that copy operation is truly completed before continuing."""
waitTime = 0.01 # 10 ms
# Convert files to OS-independence
src = os.path.abspath(src)
dst = os.path.abspath(dst)
if os.path.isdir(dst):
dst = os.path.join(dst, os.path.basename(src))
srcSize = os.path.getsize(src)
shutil.copyfile(src, dst)
shutil.copymode(src, dst)
if "win" in sys.platform:
cmd = f'copy "{src}" "{dst}"'
elif "linux" in sys.platform:
cmd = f'cp "{src}" "{dst}"'
else:
raise OSError(
"Cannot perform ``safeCopy`` on files because ARMI only supports "
+ "Linux and Windows."
)
os.system(cmd)
waitTime = 0.01 # 10 ms
maxWaitTime = 1800 # 30 min
totalWaitTime = 0
while True:
dstSize = os.path.getsize(dst)
if srcSize == dstSize:
break
time.sleep(waitTime)
totalWaitTime += waitTime
if totalWaitTime > maxWaitTime:
runLog.warning(
f"File copy from {dst} to {src} has failed due to exceeding "
+ f"a maximum wait time of {maxWaitTime/60} minutes."
)
break

runLog.extra("Copied {} -> {}".format(src, dst))


Expand Down
30 changes: 30 additions & 0 deletions armi/utils/tests/test_utils.py
Expand Up @@ -14,13 +14,15 @@

"""Testing some utility functions."""
from collections import defaultdict
import os
import unittest

import numpy as np

from armi import utils
from armi.reactor.tests.test_reactors import loadTestReactor
from armi.settings.caseSettings import Settings
from armi.tests import mockRunLogs
from armi.utils import (
directoryChangers,
getPowerFractions,
Expand All @@ -37,6 +39,7 @@
getCumulativeNodeNum,
hasBurnup,
codeTiming,
safeCopy,
)


Expand Down Expand Up @@ -166,6 +169,33 @@ def testFunc():
self.assertEqual(getattr(testFunc, "__doc__"), "Test function docstring.")
self.assertEqual(getattr(testFunc, "__name__"), "testFunc")

def test_safeCopy(self):
with directoryChangers.TemporaryDirectoryChanger():
os.mkdir("dir1")
os.mkdir("dir2")
file1 = "dir1/file1.txt"
with open(file1, "w") as f:
f.write("Hello")
file2 = "dir1\\file2.txt"
with open(file2, "w") as f:
f.write("Hello2")

with mockRunLogs.BufferLog() as mock:
# Test Linuxy file path
self.assertEqual("", mock.getStdout())
safeCopy(file1, "dir2")
self.assertIn("Copied", mock.getStdout())
self.assertIn("file1", mock.getStdout())
self.assertIn("->", mock.getStdout())
# Clean up for next safeCopy
mock.emptyStdout()
# Test Windowsy file path
self.assertEqual("", mock.getStdout())
safeCopy(file2, "dir2")
self.assertIn("Copied", mock.getStdout())
self.assertIn("file2", mock.getStdout())
self.assertIn("->", mock.getStdout())


class CyclesSettingsTests(unittest.TestCase):
"""
Expand Down
1 change: 1 addition & 0 deletions doc/release/0.3.rst
Expand Up @@ -38,6 +38,7 @@ API Changes
Bug Fixes
---------
#. Fixed four bugs with "corners up" hex grids. (`PR#1649 <https://github.com/terrapower/armi/pull/1649>`_)
#. Fixed ``safeCopy`` to work on both Windows and Linux with strict permissions (`PR#1691 <https://github.com/terrapower/armi/pull/1691>`_)
#. TBD

Quality Work
Expand Down

0 comments on commit 8710b69

Please sign in to comment.