xref: /freebsd/contrib/kyua/engine/execenv/execenv.hpp (revision 257e70f1d5ee61037c8c59b116538d3b6b1427a2)
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.
interface(const model::test_program & test_program,const std::string & test_case_name)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.
~interface()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.
~manager()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