Skip to content

Commit

Permalink
Adding code coverage (#1735)
Browse files Browse the repository at this point in the history
Adding coverage to:

- VisFileEntryPoint.invoke()
- VisFileEntryPoint.parse()
- RunSuiteCommand.invoke()
- CompareIsotxsLibraries.invoke()
- makeCoreDesignReport
- CLI for extracting inputs from DB
  • Loading branch information
john-science committed Jun 18, 2024
1 parent 8ab9099 commit 7251796
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 43 deletions.
1 change: 0 additions & 1 deletion armi/bookkeeping/report/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ def setData(name, value, group=None, reports=None):
Any value desired.
group : data.Group
reports : data.Report
"""
from armi.bookkeeping.report.reportInterface import ReportInterface

Expand Down
7 changes: 5 additions & 2 deletions armi/bookkeeping/report/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ def writeGroupsHTML(self, f):
class Group:
"""Abstract class, when extended is used for storage for data within a report.
Only accepts things wrapped in the ReportDatum class
Only accepts things wrapped in the ReportDatum class.
"""

def __init__(self, title, description=""):
Expand Down Expand Up @@ -193,6 +192,10 @@ def __init__(self, title, description="", header=None):

def __str__(self):
"""Truer to content representation."""
# error handling
if not len(self.data):
return ""

# set up
prototypical_data = list(self.data.values())[0]
num_cols = len(prototypical_data) + 1
Expand Down
8 changes: 7 additions & 1 deletion armi/bookkeeping/report/tests/test_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@
# limitations under the License.

"""Really basic tests of the report Utils."""
from glob import glob
from unittest.mock import patch
import logging
import os
import subprocess
import sys
import unittest
from unittest.mock import patch

from armi import runLog, settings
from armi.bookkeeping import report
Expand All @@ -30,6 +31,7 @@
getNodeName,
getSystemInfo,
makeBlockDesignReport,
makeCoreDesignReport,
setNeutronBalancesReport,
summarizePinDesign,
summarizePower,
Expand Down Expand Up @@ -182,6 +184,10 @@ def test_reactorSpecificReporting(self):
"""Test a number of reporting utils that require reactor/core information."""
o, r = loadTestReactor()

# make sure makeCoreDesignReport() doesn't fail, though it won't generate an output here
makeCoreDesignReport(r.core, o.cs)
self.assertEqual(len(glob("*.html")), 0)

with mockRunLogs.BufferLog() as mock:
# we should start with a clean slate
self.assertEqual("", mock.getStdout())
Expand Down
150 changes: 111 additions & 39 deletions armi/cli/tests/test_runEntryPoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@
# limitations under the License.
"""Test for run cli entry point."""
from shutil import copyfile
import logging
import os
import sys
import unittest

from armi import runLog
from armi.__main__ import main
from armi.bookkeeping.db.databaseInterface import DatabaseInterface
from armi.bookkeeping.visualization.entryPoint import VisFileEntryPoint
from armi.cli.checkInputs import CheckInputEntryPoint, ExpandBlueprints
from armi.cli.clone import CloneArmiRunCommandBatch, CloneSuiteCommand
Expand All @@ -30,6 +33,7 @@
from armi.cli.run import RunEntryPoint
from armi.cli.runSuite import RunSuiteCommand
from armi.physics.neutronics.diffIsotxs import CompareIsotxsLibraries
from armi.reactor.tests.test_reactors import loadTestReactor, reduceTestReactorRings
from armi.tests import mockRunLogs, TEST_ROOT, ARMI_RUN_PATH
from armi.utils.directoryChangers import TemporaryDirectoryChanger
from armi.utils.dynamicImporter import getEntireFamilyTree
Expand Down Expand Up @@ -90,6 +94,8 @@ def test_checkInputEntryPointInvoke(self):
ci.parse_args([ARMI_RUN_PATH])

with mockRunLogs.BufferLog() as mock:
runLog.LOG.startLog("test_checkInputEntryPointInvoke")
runLog.LOG.setVerbosity(logging.INFO)
self.assertEqual("", mock.getStdout())

ci.invoke()
Expand Down Expand Up @@ -171,24 +177,30 @@ def test_cloneSuiteCommandBasics(self):

class TestCompareCases(unittest.TestCase):
def test_compareCasesBasics(self):
cc = CompareCases()
cc.addOptions()
cc.parse_args(["/path/to/fake1.h5", "/path/to/fake2.h5"])
with TemporaryDirectoryChanger():
cc = CompareCases()
cc.addOptions()
cc.parse_args(["/path/to/fake1.h5", "/path/to/fake2.h5"])

self.assertEqual(cc.name, "compare")
self.assertIsNone(cc.args.timestepCompare)
self.assertIsNone(cc.args.weights)

self.assertEqual(cc.name, "compare")
self.assertIsNone(cc.args.timestepCompare)
self.assertIsNone(cc.args.weights)
with self.assertRaises(ValueError):
# The "fake" files do exist, so this should fail.
cc.invoke()


class TestCompareSuites(unittest.TestCase):
def test_compareSuitesBasics(self):
cs = CompareSuites()
cs.addOptions()
cs.parse_args(["/path/to/fake1.h5", "/path/to/fake2.h5"])
with TemporaryDirectoryChanger():
cs = CompareSuites()
cs.addOptions()
cs.parse_args(["/path/to/fake1.h5", "/path/to/fake2.h5"])

self.assertEqual(cs.name, "compare-suites")
self.assertEqual(cs.args.reference, "/path/to/fake1.h5")
self.assertIsNone(cs.args.weights)
self.assertEqual(cs.name, "compare-suites")
self.assertEqual(cs.args.reference, "/path/to/fake1.h5")
self.assertIsNone(cs.args.weights)


class TestExpandBlueprints(unittest.TestCase):
Expand All @@ -202,25 +214,41 @@ def test_expandBlueprintsBasics(self):

# Since the file is fake, invoke() should exit early.
with mockRunLogs.BufferLog() as mock:
runLog.LOG.startLog("test_expandBlueprintsBasics")
runLog.LOG.setVerbosity(logging.INFO)
self.assertEqual("", mock.getStdout())
ebp.invoke()
self.assertIn("does not exist", mock.getStdout())


class TestExtractInputs(unittest.TestCase):
def test_extractInputsBasics(self):
ei = ExtractInputs()
ei.addOptions()
ei.parse_args(["/path/to/fake"])

self.assertEqual(ei.name, "extract-inputs")
self.assertEqual(ei.args.output_base, "/path/to/fake")

with mockRunLogs.BufferLog() as mock:
self.assertEqual("", mock.getStdout())
with self.assertRaises(FileNotFoundError):
# The "fake" file doesn't exist, so this should fail.
with TemporaryDirectoryChanger() as newDir:
# build test DB
o, r = loadTestReactor(TEST_ROOT)
dbi = DatabaseInterface(r, o.cs)
dbPath = os.path.join(newDir.destination, f"{self._testMethodName}.h5")
dbi.initDB(fName=dbPath)
db = dbi.database
db.writeToDB(r)

# init the CLI
ei = ExtractInputs()
ei.addOptions()
ei.parse_args([dbPath])

# test the CLI initialization
self.assertEqual(ei.name, "extract-inputs")
self.assertEqual(ei.args.output_base, dbPath[:-3])

# run the CLI on a test DB, verify it worked via logging
with mockRunLogs.BufferLog() as mock:
runLog.LOG.startLog("test_extractInputsBasics")
runLog.LOG.setVerbosity(logging.INFO)
self.assertEqual("", mock.getStdout())
ei.invoke()
self.assertIn("Writing settings to", mock.getStdout())
self.assertIn("Writing blueprints to", mock.getStdout())


class TestInjectInputs(unittest.TestCase):
Expand All @@ -238,6 +266,8 @@ def test_injectInputsInvokeIgnore(self):
ii.parse_args(["/path/to/fake.h5"])

with mockRunLogs.BufferLog() as mock:
runLog.LOG.startLog("test_injectInputsInvokeIgnore")
runLog.LOG.setVerbosity(logging.INFO)
self.assertEqual("", mock.getStdout())
ii.invoke()
self.assertIn("No settings", mock.getStdout())
Expand All @@ -252,11 +282,9 @@ def test_injectInputsInvokeNoData(self):
ii.parse_args(["/path/to/fake.h5", "--blueprints", bp])

# invoke and check log
with mockRunLogs.BufferLog() as mock:
self.assertEqual("", mock.getStdout())
with self.assertRaises(FileNotFoundError):
# The "fake.h5" doesn't exist, so this should fail.
ii.invoke()
with self.assertRaises(FileNotFoundError):
# The "fake.h5" doesn't exist, so this should fail.
ii.invoke()


class TestMigrateInputs(unittest.TestCase):
Expand Down Expand Up @@ -311,11 +339,9 @@ def test_reportsEntryPointBasics(self):
self.assertEqual(rep.name, "report")
self.assertEqual(rep.settingsArgument, "optional")

with mockRunLogs.BufferLog() as mock:
self.assertEqual("", mock.getStdout())
with self.assertRaises(ValueError):
# The "fake.h5" doesn't exist, so this should fail.
rep.invoke()
with self.assertRaises(ValueError):
# The "fake.h5" doesn't exist, so this should fail.
rep.invoke()


class TestCompareIsotxsLibsEntryPoint(unittest.TestCase):
Expand All @@ -329,6 +355,10 @@ def test_compareIsotxsLibsBasics(self):
self.assertEqual(com.name, "diff-isotxs")
self.assertIsNone(com.settingsArgument)

with self.assertRaises(FileNotFoundError):
# The provided files don't exist, so this should fail.
com.invoke()


class TestRunEntryPoint(unittest.TestCase):
def test_runEntryPointBasics(self):
Expand Down Expand Up @@ -363,17 +393,59 @@ class TestRunSuiteCommand(unittest.TestCase):
def test_runSuiteCommandBasics(self):
rs = RunSuiteCommand()
rs.addOptions()
rs.parse_args(["/path/to/fake.yaml"])
rs.parse_args(["/path/to/fake.yaml", "-l"])

self.assertEqual(rs.name, "run-suite")
self.assertIsNone(rs.settingsArgument)

# test the invoke method
with mockRunLogs.BufferLog() as mock:
runLog.LOG.startLog("test_runSuiteCommandBasics")
runLog.LOG.setVerbosity(logging.INFO)
self.assertEqual("", mock.getStdout())
rs.invoke()
self.assertIn("Finding potential settings files", mock.getStdout())
self.assertIn("Checking for valid settings", mock.getStdout())
self.assertIn("Primary Log Verbosity", mock.getStdout())


class TestVisFileEntryPointCommand(unittest.TestCase):
def test_visFileEntryPointBasics(self):
vf = VisFileEntryPoint()
vf.addOptions()
vf.parse_args(["/path/to/fake.h5"])
with TemporaryDirectoryChanger() as newDir:
# build test DB
self.o, self.r = loadTestReactor(
TEST_ROOT, customSettings={"reloadDBName": "reloadingDB.h5"}
)
reduceTestReactorRings(self.r, self.o.cs, maxNumRings=2)
self.dbi = DatabaseInterface(self.r, self.o.cs)
dbPath = os.path.join(newDir.destination, f"{self._testMethodName}.h5")
self.dbi.initDB(fName=dbPath)
self.db = self.dbi.database
self.db.writeToDB(self.r)

# create Viz entry point
vf = VisFileEntryPoint()
vf.addOptions()
vf.parse_args([dbPath])

self.assertEqual(vf.name, "vis-file")
self.assertIsNone(vf.settingsArgument)

# test the invoke method
with mockRunLogs.BufferLog() as mock:
runLog.LOG.startLog("test_visFileEntryPointBasics")
runLog.LOG.setVerbosity(logging.INFO)
self.assertEqual("", mock.getStdout())

vf.invoke()

desired = "Creating visualization file for cycle 0, time node 0..."
self.assertIn(desired, mock.getStdout())

self.assertEqual(vf.name, "vis-file")
self.assertIsNone(vf.settingsArgument)
# test the parse method (using the same DB to save time)
vf = VisFileEntryPoint()
vf.parse([dbPath])
self.assertIsNone(vf.args.nodes)
self.assertIsNone(vf.args.min_node)
self.assertIsNone(vf.args.max_node)
self.assertEqual(vf.args.output_name, "test_visFileEntryPointBasics")

0 comments on commit 7251796

Please sign in to comment.