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 "engine/execenv/execenv_fwd.hpp" 36 #include "model/test_program.hpp" 37 #include "utils/optional.ipp" 38 #include "utils/process/operations_fwd.hpp" 39 40 using utils::process::args_vector; 41 using utils::optional; 42 43 namespace engine { 44 namespace execenv { 45 46 47 /// Abstract interface of an execution environment. 48 class interface { 49 protected: 50 const model::test_program& _test_program; 51 const std::string& _test_case_name; 52 53 public: 54 /// Constructor. 55 /// 56 /// \param program The test program. 57 /// \param test_case_name Name of the test case. 58 interface(const model::test_program& test_program, 59 const std::string& test_case_name) : 60 _test_program(test_program), 61 _test_case_name(test_case_name) 62 {} 63 64 /// Destructor. 65 virtual ~interface() {} 66 67 /// Initializes execution environment. 68 /// 69 /// It's expected to be called inside a fork which runs 70 /// scheduler::interface::exec_test(), so we can fail a test fast if its 71 /// execution environment setup fails, and test execution could use the 72 /// configured proc environment, if expected. 73 virtual void init() const = 0; 74 75 /// Cleanups or removes execution environment. 76 /// 77 /// It's expected to be called inside a fork for execenv cleanup. 78 virtual void cleanup() const = 0; 79 80 /// Executes a test within the execution environment. 81 /// 82 /// It's expected to be called inside a fork which runs 83 /// scheduler::interface::exec_test() or exec_cleanup(). 84 /// 85 /// \param args The arguments to pass to the binary. 86 virtual void exec [[noreturn]] (const args_vector& args) const = 0; 87 }; 88 89 90 /// Abstract interface of an execution environment manager. 91 class manager { 92 public: 93 /// Destructor. 94 virtual ~manager() {} 95 96 /// Returns name of an execution environment. 97 virtual const std::string& name() const = 0; 98 99 /// Returns whether this execution environment is actually supported. 100 /// 101 /// It can be compile time and/or runtime check. 102 virtual bool is_supported() const = 0; 103 104 /// Returns execution environment for a test. 105 /// 106 /// It checks if the given test is designed for this execution environment. 107 /// 108 /// \param program The test program. 109 /// \param test_case_name Name of the test case. 110 /// 111 /// \return An execenv object if the test conforms, or none. 112 virtual std::unique_ptr< interface > probe( 113 const model::test_program& test_program, 114 const std::string& test_case_name) const = 0; 115 116 // TODO: execenv related extra metadata could be provided by a manager 117 // not to know how exactly and where it should be added to the kyua 118 }; 119 120 121 /// Registers an execution environment. 122 /// 123 /// \param manager Execution environment manager. 124 void register_execenv(const std::shared_ptr< manager > manager); 125 126 127 /// Returns list of registered execenv managers, except default host one. 128 /// 129 /// \return A vector of pointers to execenv managers. 130 const std::vector< std::shared_ptr< manager> > execenvs(); 131 132 133 /// Returns execution environment for a test case. 134 /// 135 /// \param program The test program. 136 /// \param test_case_name Name of the test case. 137 /// 138 /// \return An execution environment of a test. 139 std::unique_ptr< execenv::interface > get( 140 const model::test_program& test_program, 141 const std::string& test_case_name); 142 143 144 } // namespace execenv 145 } // namespace engine 146 147 #endif // !defined(ENGINE_EXECENV_EXECENV_HPP) 148