8
8
9
9
#include < executorch/runtime/backend/options.h>
10
10
#include < executorch/runtime/backend/options_map.h>
11
+ #include < executorch/runtime/backend/interface.h>
11
12
#include < executorch/runtime/platform/runtime.h>
12
13
13
14
#include < gtest/gtest.h>
@@ -21,6 +22,18 @@ using executorch::runtime::Error;
21
22
using executorch::runtime::IntKey;
22
23
using executorch::runtime::OptionKey;
23
24
using executorch::runtime::StrKey;
25
+ using executorch::runtime::BackendInterface;
26
+ using executorch::runtime::BackendInitContext;
27
+ using executorch::runtime::BackendExecutionContext;
28
+ using executorch::runtime::BackendUpdateContext;
29
+ using executorch::runtime::DelegateHandle;
30
+ using executorch::runtime::CompileSpec;
31
+ using executorch::runtime::Backend;
32
+ using executorch::runtime::FreeableBuffer;
33
+ using executorch::runtime::EValue;
34
+ using executorch::runtime::ArrayRef;
35
+ using executorch::runtime::Result;
36
+ using executorch::runtime::register_backend;
24
37
25
38
namespace executorch {
26
39
namespace runtime {
@@ -147,5 +160,156 @@ TEST_F(BackendOptionsMapTest, OptionIsolation) {
147
160
EXPECT_EQ (gpu_opts[2 ].key , " Hardware" );
148
161
EXPECT_EQ (std::get<const char *>(gpu_opts[2 ].value ), " H100" );
149
162
}
163
+
164
+ // Mock backend for testing
165
+ class StubBackend : public BackendInterface {
166
+ public:
167
+ ~StubBackend () override = default ;
168
+
169
+ bool is_available () const override {
170
+ return true ;
171
+ }
172
+
173
+ Result<DelegateHandle*> init (
174
+ BackendInitContext& context,
175
+ FreeableBuffer* processed,
176
+ ArrayRef<CompileSpec> compile_specs) const override {
177
+ return nullptr ;
178
+ }
179
+
180
+ Error execute (
181
+ BackendExecutionContext& context,
182
+ DelegateHandle* handle,
183
+ EValue** args) const override {
184
+ return Error::Ok;
185
+ }
186
+
187
+ Error get_option (
188
+ BackendUpdateContext& context,
189
+ executorch::runtime::Span<executorch::runtime::BackendOption>&
190
+ backend_options) override {
191
+ // For testing purposes, just record that get_option was called
192
+ // and verify the input parameters
193
+ get_option_called = true ;
194
+ get_option_call_count++;
195
+ last_get_option_size = backend_options.size ();
196
+
197
+ // Verify that the expected option key is present and modify the value
198
+ for (size_t i = 0 ; i < backend_options.size (); ++i) {
199
+ if (strcmp (backend_options[i].key , " NumberOfThreads" ) == 0 ) {
200
+ // Set the value to what was stored by set_option
201
+ backend_options[i].value = last_num_threads;
202
+ found_expected_key = true ;
203
+ break ;
204
+ }
205
+ }
206
+
207
+ return Error::Ok;
208
+ }
209
+
210
+ Error set_option (
211
+ BackendUpdateContext& context,
212
+ const Span<executorch::runtime::BackendOption>& backend_options)
213
+ override {
214
+ // Store the options for verification
215
+ last_options_size = backend_options.size ();
216
+ if (backend_options.size () > 0 ) {
217
+ for (const auto & option : backend_options) {
218
+ if (strcmp (option.key , " NumberOfThreads" ) == 0 ) {
219
+ if (auto * val = std::get_if<int >(&option.value )) {
220
+ last_num_threads = *val;
221
+ }
222
+ }
223
+ }
224
+ }
225
+ return Error::Ok;
226
+ }
227
+
228
+ // Mutable for testing verification
229
+ size_t last_options_size = 0 ;
230
+ int last_num_threads = 0 ;
231
+ bool get_option_called = false ;
232
+ int get_option_call_count = 0 ;
233
+ size_t last_get_option_size = 0 ;
234
+ bool found_expected_key = false ;
235
+ };
236
+
237
+ class BackendUpdateTest : public ::testing::Test {
238
+ protected:
239
+ void SetUp () override {
240
+ // Since these tests cause ET_LOG to be called, the PAL must be initialized
241
+ // first.
242
+ executorch::runtime::runtime_init ();
243
+
244
+ // Register the stub backend
245
+ stub_backend = std::make_unique<StubBackend>();
246
+ Backend backend_config{" StubBackend" , stub_backend.get ()};
247
+ auto register_result = register_backend (backend_config);
248
+ ASSERT_EQ (register_result, Error::Ok);
249
+ }
250
+
251
+ std::unique_ptr<StubBackend> stub_backend;
252
+ };
253
+
254
+ // Test basic string functionality
255
+ TEST_F (BackendUpdateTest, TestSetOption) {
256
+ BackendOptionsMap<3 > map;
257
+ BackendOptions<1 > backend_options;
258
+ int new_num_threads = 4 ;
259
+ backend_options.set_option (IntKey (" NumberOfThreads" ), new_num_threads);
260
+ map.add (" StubBackend" , backend_options.view ());
261
+
262
+ auto status = set_option (map.entries ());
263
+ ASSERT_EQ (status, Error::Ok);
264
+
265
+ // Verify the map contains the expected data
266
+ ASSERT_EQ (map.size (), 1 );
267
+ auto options = map.get (" StubBackend" );
268
+ ASSERT_EQ (options.size (), 1 );
269
+
270
+ // Verify that the backend actually received the options
271
+ ASSERT_EQ (stub_backend->last_options_size , 1 );
272
+ ASSERT_EQ (stub_backend->last_num_threads , new_num_threads);
273
+ }
274
+
275
+ // Test get_option functionality
276
+ TEST_F (BackendUpdateTest, TestGetOption) {
277
+ // First, set some options in the backend
278
+ BackendOptionsMap<3 > set_map;
279
+ BackendOptions<1 > set_backend_options;
280
+ int expected_num_threads = 8 ;
281
+ set_backend_options.set_option (
282
+ IntKey (" NumberOfThreads" ), expected_num_threads);
283
+ set_map.add (" StubBackend" , set_backend_options.view ());
284
+
285
+ auto set_status = set_option (set_map.entries ());
286
+ ASSERT_EQ (set_status, Error::Ok);
287
+ ASSERT_EQ (stub_backend->last_num_threads , expected_num_threads);
288
+
289
+ // Reset get_option tracking variables
290
+ stub_backend->get_option_called = false ;
291
+ stub_backend->get_option_call_count = 0 ;
292
+ stub_backend->found_expected_key = false ;
293
+
294
+ // Now create a map with options for get_option to process
295
+ BackendOptionsMap<3 > get_map;
296
+ BackendOptions<1 > get_backend_options;
297
+ get_backend_options.set_option (IntKey (" NumberOfThreads" ), 0 );
298
+ get_map.add (" StubBackend" , get_backend_options.view ());
299
+
300
+ // Call get_option to test the API
301
+ auto get_status = get_option (get_map.entries ());
302
+ ASSERT_EQ (get_status, Error::Ok);
303
+
304
+ ASSERT_TRUE (
305
+ std::get<int >(get_map.entries ()[0 ].options [0 ].value ) ==
306
+ expected_num_threads);
307
+
308
+ // Verify that the backend's get_option method was called correctly
309
+ ASSERT_TRUE (stub_backend->get_option_called );
310
+ ASSERT_EQ (stub_backend->get_option_call_count , 1 );
311
+ ASSERT_EQ (stub_backend->last_get_option_size , 1 );
312
+ ASSERT_TRUE (stub_backend->found_expected_key );
313
+ }
150
314
} // namespace runtime
151
315
} // namespace executorch
0 commit comments