1 // Copyright 2023 The Kyua Authors. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // * Neither the name of Google Inc. nor the names of its contributors 14 // may be used to endorse or promote products derived from this software 15 // without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 /// \file engine/execenv/execenv.hpp 30 /// Execution environment subsystem interface. 31 32 #if !defined(ENGINE_EXECENV_EXECENV_HPP) 33 #define ENGINE_EXECENV_EXECENV_HPP 34 35 #include "model/test_program.hpp" 36 #include "utils/optional.ipp" 37 #include "utils/process/operations_fwd.hpp" 38 39 using utils::process::args_vector; 40 using utils::optional; 41 42 namespace engine { 43 namespace execenv { 44 45 46 extern const char* default_execenv_name; 47 48 49 /// Abstract interface of an execution environment. 50 class interface { 51 protected: 52 const model::test_program& _test_program; 53 const std::string& _test_case_name; 54 55 public: 56 /// Constructor. 57 /// 58 /// \param program The test program. 59 /// \param test_case_name Name of the test case. 60 interface(const model::test_program& test_program, 61 const std::string& test_case_name) : 62 _test_program(test_program), 63 _test_case_name(test_case_name) 64 {} 65 66 /// Destructor. 67 virtual ~interface() {} 68 69 /// Initializes execution environment. 70 /// 71 /// It's expected to be called inside a fork which runs 72 /// scheduler::interface::exec_test(), so we can fail a test fast if its 73 /// execution environment setup fails, and test execution could use the 74 /// configured proc environment, if expected. 75 virtual void init() const = 0; 76 77 /// Cleanups or removes execution environment. 78 /// 79 /// It's expected to be called inside a fork for execenv cleanup. 80 virtual void cleanup() const = 0; 81 82 /// Executes a test within the execution environment. 83 /// 84 /// It's expected to be called inside a fork which runs 85 /// scheduler::interface::exec_test() or exec_cleanup(). 86 /// 87 /// \param args The arguments to pass to the binary. 88 virtual void exec(const args_vector& args) const UTILS_NORETURN = 0; 89 }; 90 91 92 /// Abstract interface of an execution environment manager. 93 class manager { 94 public: 95 /// Destructor. 96 virtual ~manager() {} 97 98 /// Returns name of an execution environment. 99 virtual const std::string& name() const = 0; 100 101 /// Returns whether this execution environment is actually supported. 102 /// 103 /// It can be compile time and/or runtime check. 104 virtual bool is_supported() const = 0; 105 106 /// Returns execution environment for a test. 107 /// 108 /// It checks if the given test is designed for this execution environment. 109 /// 110 /// \param program The test program. 111 /// \param test_case_name Name of the test case. 112 /// 113 /// \return An execenv object if the test conforms, or none. 114 virtual std::unique_ptr< interface > probe( 115 const model::test_program& test_program, 116 const std::string& test_case_name) const = 0; 117 118 // TODO: execenv related extra metadata could be provided by a manager 119 // not to know how exactly and where it should be added to the kyua 120 }; 121 122 123 /// Registers an execution environment. 124 /// 125 /// \param manager Execution environment manager. 126 void register_execenv(const std::shared_ptr< manager > manager); 127 128 129 /// Returns list of registered execenv managers, except default host one. 130 /// 131 /// \return A vector of pointers to execenv managers. 132 const std::vector< std::shared_ptr< manager> > execenvs(); 133 134 135 /// Returns execution environment for a test case. 136 /// 137 /// \param program The test program. 138 /// \param test_case_name Name of the test case. 139 /// 140 /// \return An execution environment of a test. 141 std::unique_ptr< execenv::interface > get( 142 const model::test_program& test_program, 143 const std::string& test_case_name); 144 145 146 } // namespace execenv 147 } // namespace engine 148 149 #endif // !defined(ENGINE_EXECENV_EXECENV_HPP) 150