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