Source code for sirepo.pkcli.nersc_test

# -*- coding: utf-8 -*-
"""Allow NERSC to run tests of Sirepo images in their infrastructure

:copyright: Copyright (c) 2023 RadiaSoft LLC.  All Rights Reserved.
:license: http://www.apache.org/licenses/LICENSE-2.0.html
"""
from pykern.pkcollections import PKDict
from pykern.pkdebug import pkdc, pkdexc, pkdp, pkdlog
import os
import pykern.pkio
import pykern.pkjinja
import pykern.pkjson
import sirepo.const
import sirepo.resource
import sirepo.sim_data
import subprocess


[docs] def sequential(pkunit_deviance=None): """Test sequential process for use by NERSC inside SHIFTER Simulates the operation that Sirepo does when it executes a sequential process on a login node in SHIFTER. On success, will return (output) ``nersc_test.sequential PASS`` Args: pkunit_deviance (str): used only by internal unit test to test deviance case Returns: str: PASS or fail with diagnostic information """ s = _Sequential() try: s.prepare(pkunit_deviance) s.execute() return "nersc_test.sequential PASS" except Exception as e: return f"nersc_test sequential fail: error={e}\nunix_uid={os.geteuid()}\n{s}{pkdexc()}"
class _Sequential(PKDict): """Run a sequential job by mocking the input to job_cmd""" JOB_CMD_FILE = "sequential_job_cmd.json" RESOURCE_DIR = "nersc_test" RESULT_FILE = "sequential_result.json" RUN_DIR = "sirepo_run_dir" RUN_FILE = "sequential_run.sh" def prepare(self, pkunit_deviance): self.pkunit_deviance = pkunit_deviance self.run_dir = pykern.pkio.py_path(self.RUN_DIR) pykern.pkio.unchecked_remove(self.run_dir) self.run_dir.ensure(dir=True) self.result_file = self.run_dir.join(self.RESULT_FILE) self.user = sirepo.const.MOCK_UID # job_cmd_file must be first, because used by _render_resource self.job_cmd_file = self._job_cmd_file() if not self.pkunit_deviance: d = pykern.pkjson.load_any(self.job_cmd_file).data sirepo.sim_data.get_class(d.simulationType).sim_run_input_to_run_dir( d, self.run_dir, ) self.run_file = self._render_resource(self.RUN_FILE) def execute(self): p = subprocess.run(["bash", self.run_file], capture_output=True, text=True) if p.returncode != 0: raise RuntimeError( f"unexpected returncode={p.returncode} stderr={p.stderr}" ) self.result_file.write(p.stdout) self.result_text = p.stdout self.result_parsed = pykern.pkjson.load_any(self.result_text) if self.result_parsed.state != "completed": raise RuntimeError(f"unexpected result state={self.result_parsed.state}") def _job_cmd_file(self): if self.pkunit_deviance: return pykern.pkio.py_path(self.pkunit_deviance) return self._render_resource(self.JOB_CMD_FILE) def __str__(self): res = "Internal state:\n" for k in ("run_dir", "run_file", "result_file"): res += f"{k}={self.get(k)}\n" if "result_text" in self: if "result_parsed" in self: res += "result_parsed=" + pykern.pkjson.dump_pretty(self.result_parsed) else: res += "result_text=" + self.result_text return res def _render_resource(self, filename): return sirepo.resource.render_jinja( self.RESOURCE_DIR, filename, target_dir=self.run_dir, j2_ctx=PKDict( job_cmd_file=self.get("job_cmd_file"), run_dir=self.run_dir, user=self.user, ), )