LCOV - code coverage report
Current view: top level - include/base - CapabilityRegistry.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 7 7 100.0 %
Date: 2026-05-29 20:35:17 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #pragma once
      11             : 
      12             : #include "Capability.h"
      13             : 
      14             : #include <map>
      15             : #include <set>
      16             : #include <string>
      17             : #include <utility>
      18             : 
      19             : #ifdef MOOSE_UNIT_TEST
      20             : class CapabilitiesTest;
      21             : #endif
      22             : 
      23             : namespace Moose::internal
      24             : {
      25             : 
      26             : class Capabilities;
      27             : 
      28             : /**
      29             :  * Registry of capabilities that checks capability requirements.
      30             :  *
      31             :  * This registry is used both within MOOSE (in framework/src/base/Capabilities.C)
      32             :  * and within the python interface (in python/pycapabilities/_pycapabilities.C).
      33             :  */
      34             : class CapabilityRegistry
      35             : {
      36             : public:
      37             :   /// Capabilities that are reserved and can only be augmented
      38             :   static const std::set<std::string, std::less<>> augmented_capability_names;
      39             : 
      40          32 :   ~CapabilityRegistry() = default;
      41             : 
      42             :   /// Type for the registry
      43             :   using RegistryType = std::map<std::string, Capability, std::less<>>;
      44             : 
      45             :   /**
      46             :    * Return state for check. We use a plain enum because we rely on implicit conversion to int.
      47             :    * Capability checks are run in the test harness using the JSON dump exported from the
      48             :    * executable using `--show-capabilities`. This static check does not take dynamic loading into
      49             :    * account, as capabilities that would be registered after initializing the dynamically loaded
      50             :    * application will not exist with `--show-capabilities`.
      51             :    *
      52             :    * A requested capability that is not registered at all is considered in a "possible" state,
      53             :    * as we cannot guarantee that it does or not exist with a dynamic application. If no dynamic
      54             :    * application loading is used, the possible states can be considered certain states.
      55             :    *
      56             :    * When the test harness Tester specification "dynamic_capabilities" is set to True,
      57             :    * it will run the test unless the result of the check is CERTAIN_FAIL. In this case,
      58             :    * the runtime check in the executable will terminate if the result is either CERTAIN_FAIL
      59             :    * or POSSIBLE_FAIL.
      60             :    */
      61             :   enum CheckState
      62             :   {
      63             :     CERTAIN_FAIL = 0,
      64             :     POSSIBLE_FAIL = 1,
      65             :     UNKNOWN = 2,
      66             :     POSSIBLE_PASS = 3,
      67             :     CERTAIN_PASS = 4,
      68             :     IGNORE = 5
      69             :   };
      70             : 
      71             :   /**
      72             :    * Storage for the result from check().
      73             :    */
      74             :   struct CheckResult
      75             :   {
      76             :     /// State of the check
      77             :     CheckState state;
      78             :     /// The capability names that existed in the check string
      79             :     std::set<std::string> capability_names;
      80             :   };
      81             : 
      82             :   /**
      83             :    * Options for check().
      84             :    */
      85             :   struct CheckOptions
      86             :   {
      87        8493 :     CheckOptions() : certain(true), ignore_capabilities() {}
      88             : 
      89             :     /// Whether or not all capabilities must be known
      90             :     bool certain;
      91             :     /// Capabilities to ignore; checks using them will always pass
      92             :     std::set<std::string> ignore_capabilities;
      93             :   };
      94             : 
      95             :   /**
      96             :    * Add a capability.
      97             :    *
      98             :    * @param registry The registry
      99             :    * @param capability The name of the capability
     100             :    * @param value The value of the capability
     101             :    * @param doc The documentation string
     102             :    * @return The capability
     103             :    */
     104             :   Capability & add(const std::string_view name,
     105             :                    const Moose::Capability::Value & value,
     106             :                    const std::string_view doc);
     107             : 
     108             :   /**
     109             :    * Query a capability, if it exists, otherwise nullptr.
     110             :    *
     111             :    * Will convert the capability name to lowercase.
     112             :    */
     113             :   ///@{
     114             :   const Capability * query(std::string capability) const;
     115             : #if defined(MOOSE_UNIT_TEST) || defined(FOR_PYCAPABILITIES)
     116             :   inline Capability * query(std::string capability);
     117             : #endif
     118             :   ///@}
     119             : 
     120             :   /**
     121             :    * Get a capability.
     122             :    *
     123             :    * Will convert the capability name to lowercase.
     124             :    */
     125             :   ///@{
     126             :   const Capability & get(const std::string & capability) const;
     127             : #ifdef MOOSE_UNIT_TEST
     128             :   inline Capability & get(const std::string & capability);
     129             : #endif
     130             :   ///@}
     131             : 
     132             :   /**
     133             :    * @return The size of the registry (number of capabilities registered).
     134             :    */
     135           8 :   std::size_t size() const { return _registry.size(); }
     136             : 
     137             :   /**
     138             :    * Checks if a set of requirements is satisified by the capabilities
     139             :    *
     140             :    * @param requirements The requirement string
     141             :    * @param options Options to apply to the check
     142             :    *
     143             :    * This method is exposed to Python within pycapabilities.Capabilities.check in
     144             :    * python/pycapabilities/_pycapabilities.C. This external method is used
     145             :    * significantly by the TestHarness to check capabilities for individual test specs.
     146             :    *
     147             :    * Additionally, this method is used by the MooseApp command line option
     148             :    * "--required-capabilities ...".
     149             :    *
     150             :    * Requirements can use comparison operators (>,<,>=,<=,=!,=), where the name of
     151             :    * the capability must always be on the left hand side. Comparisons can be performed
     152             :    * on strings "compiler!=GCC" (which are case insensitive), integer numbers
     153             :    * "ad_size>=50", and version numbers "petsc>3.8.0". The state of a boolean
     154             :    * valued capability can be tested by just specifying the capability name "chaco".
     155             :    * This check can be inverted using the ! operator as "!chaco".
     156             :    *
     157             :    * The logic operators & and | can be used to chain multiple checks as
     158             :    * "thermochimica & thermochimica>1.0". Parenthesis can be used to build
     159             :    * complex logic expressions.
     160             :    */
     161             :   CheckResult check(
     162             :       std::string requirements,
     163             :       const CapabilityRegistry::CheckOptions & options = CapabilityRegistry::CheckOptions()) const;
     164             : 
     165             : protected:
     166             : #ifdef MOOSE_UNIT_TEST
     167             :   friend class ::CapabilitiesTest;
     168             : #endif
     169             : 
     170             :   /// Registry storage
     171             :   RegistryType _registry;
     172             : };
     173             : 
     174             : #if defined(MOOSE_UNIT_TEST) || defined(FOR_PYCAPABILITIES)
     175             : Capability *
     176          32 : CapabilityRegistry::query(std::string capability)
     177             : {
     178          32 :   return const_cast<Capability *>(std::as_const(*this).query(capability));
     179             : }
     180             : #endif
     181             : 
     182             : #ifdef MOOSE_UNIT_TEST
     183             : Capability &
     184          20 : CapabilityRegistry::get(const std::string & capability)
     185             : {
     186          20 :   return const_cast<Capability &>(std::as_const(*this).get(capability));
     187             : }
     188             : #endif
     189             : } // namespace Moose::internal

Generated by: LCOV version 1.14