1# SPDX-License-Identifier: Apache-2.0
2
3cmake_minimum_required(VERSION 3.20.0)
4
5find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
6project(zephyr_get_test)
7target_sources(app PRIVATE ${ZEPHYR_BASE}/misc/empty_file.c)
8
9if(SYSBUILD)
10  get_property(IMAGE_NAME TARGET sysbuild_cache PROPERTY SYSBUILD_NAME)
11else()
12  set(IMAGE_NAME "no_sysbuild")
13endif()
14
15# Usage:
16#   - run_suite(<test-1> [<test-2> ...])
17#
18# Run tests and count assert failures. An error report will be shown
19# at the end, either here or in sysbuild.cmake.
20#
21macro(run_suite)
22  set(ASSERT_FAIL_COUNT 0 CACHE INTERNAL "")
23
24  foreach(TEST_NAME ${ARGV})
25    cmake_language(CALL ${TEST_NAME})
26  endforeach()
27
28  if($CACHE{ASSERT_FAIL_COUNT} GREATER 0)
29    if(NOT SYSBUILD)
30      set(mode FATAL_ERROR)
31    else()
32      set(mode WARNING)
33    endif()
34    message(${mode} "$CACHE{ASSERT_FAIL_COUNT} assertion(s) failed")
35  endif()
36endmacro()
37
38# Usage:
39#   - assert_equal(<variable> <expected-value>)
40#
41#   - assert_equal(<variable>
42#       IMAGE <image-1> <expected-value-for-image-1>
43#      [IMAGE <image-2> <expected-value-for-image-2> ...]
44#     )
45#
46function(assert_equal variable expected_value)
47  if("${variable}" MATCHES "{.+}$")
48    string(CONFIGURE "$${variable}" actual_value)
49  else()
50    set(actual_value "${${variable}}")
51  endif()
52
53  if(expected_value STREQUAL "IMAGE")
54    set(i 1)
55    while(i LESS ARGC)
56      if(NOT ARGV${i} STREQUAL "IMAGE")
57        message(FATAL_ERROR "Invalid argument ${i}: '${ARGV${i}}' (expected 'IMAGE')")
58      endif()
59      math(EXPR i "${i} + 1")
60      set(image_name "${ARGV${i}}")
61      math(EXPR i "${i} + 1")
62      set(expected_value "${ARGV${i}}")
63      math(EXPR i "${i} + 1")
64
65      if(image_name STREQUAL IMAGE_NAME)
66        break()
67      endif()
68      set(expected_value)
69    endwhile()
70    if(NOT DEFINED expected_value)
71      message(FATAL_ERROR "No value provided for image: '${IMAGE_NAME}'")
72    endif()
73  endif()
74
75  set(info "${TEST_NAME}: ${variable} == '${actual_value}'")
76  if("${actual_value}" STREQUAL "${expected_value}")
77    message("PASS: ${info}")
78  else()
79    message("FAIL: ${info}\n      expected '${expected_value}'")
80    math(EXPR ASSERT_FAIL_COUNT "$CACHE{ASSERT_FAIL_COUNT} + 1")
81    set(ASSERT_FAIL_COUNT ${ASSERT_FAIL_COUNT} CACHE INTERNAL "")
82  endif()
83endfunction()
84
85
86function(test_precedence)
87  # Test with a local variable not controlled by sysbuild.
88  set(ENV{VARIABLE} "environment")
89  set(VARIABLE "cmake cache" CACHE INTERNAL "")
90  set(VARIABLE "local")
91
92  # CMake cache value has the highest precedence.
93  zephyr_get(VARIABLE)
94  assert_equal(VARIABLE "cmake cache")
95
96  # Environment value has the next highest precedence.
97  unset(VARIABLE CACHE)
98  unset(VARIABLE)
99
100  zephyr_get(VARIABLE)
101  assert_equal(VARIABLE "environment")
102
103  # Environment value is cached after it's retrieved.
104  assert_equal(CACHE{VARIABLE} "environment")
105
106  # Locally scoped value has the lowest precedence.
107  unset(VARIABLE CACHE)
108  unset(ENV{VARIABLE})
109  set(VARIABLE "local")
110
111  zephyr_get(VARIABLE)
112  assert_equal(VARIABLE "local")
113  assert_equal(CACHE{VARIABLE} "")
114
115  unset(VARIABLE)
116  zephyr_get(VARIABLE)
117  assert_equal(VARIABLE "")
118endfunction()
119
120
121function(test_precedence_with_sysbuild)
122  # Test with an external variable provided in testcase.yaml
123  set(ENV{TESTCASE_VARIABLE} "environment")
124  set(TESTCASE_VARIABLE "cmake cache" CACHE INTERNAL "")
125  set(TESTCASE_VARIABLE "local")
126
127  zephyr_get(TESTCASE_VARIABLE SYSBUILD GLOBAL)
128  assert_equal(TESTCASE_VARIABLE
129    IMAGE no_sysbuild    "cmake cache"
130    # Provided -DTESTCASE_VARIABLE=<...> serves as the
131    # LOCAL sysbuild-defined value for this primary image.
132    IMAGE zephyr_get     "sysbuild.main"
133    # Provided -Dzephyr_get_2nd_TESTCASE_VARIABLE=<...> serves as
134    # the LOCAL sysbuild-defined value for this secondary image.
135    IMAGE zephyr_get_2nd "sysbuild.2nd"
136    # Provided -DTESTCASE_VARIABLE=<...> serves as the
137    # GLOBAL sysbuild-defined value for this tertiary image;
138    # it has no LOCAL value of its own.
139    IMAGE zephyr_get_3rd "sysbuild.main"
140  )
141
142  unset(TESTCASE_VARIABLE CACHE)
143  unset(TESTCASE_VARIABLE)
144
145  zephyr_get(TESTCASE_VARIABLE SYSBUILD LOCAL)
146  assert_equal(TESTCASE_VARIABLE
147    IMAGE no_sysbuild    "environment"
148    IMAGE zephyr_get     "sysbuild.main"
149    IMAGE zephyr_get_2nd "sysbuild.2nd"
150    # This image has no LOCAL sysbuild-defined value.
151    IMAGE zephyr_get_3rd "environment"
152  )
153  assert_equal(CACHE{TESTCASE_VARIABLE}
154    IMAGE no_sysbuild    "environment"
155    IMAGE zephyr_get     ""
156    IMAGE zephyr_get_2nd ""
157    IMAGE zephyr_get_3rd "environment"
158  )
159
160  unset(TESTCASE_VARIABLE CACHE)
161  unset(ENV{TESTCASE_VARIABLE})
162  set(TESTCASE_VARIABLE "local")
163
164  # This should be equivalent to: zephyr_get(... SYSBUILD GLOBAL)
165  zephyr_get(TESTCASE_VARIABLE)
166  assert_equal(TESTCASE_VARIABLE
167    IMAGE no_sysbuild    "local"
168    IMAGE zephyr_get     "sysbuild.main"
169    IMAGE zephyr_get_2nd "sysbuild.2nd"
170    IMAGE zephyr_get_3rd "sysbuild.main"
171  )
172endfunction()
173
174
175function(test_merge)
176  # Test with a local variable not controlled by sysbuild.
177  set(ENV{VARIABLE} "environment")
178  set(VARIABLE "cmake cache" CACHE INTERNAL "")
179  set(VARIABLE "local")
180
181  zephyr_get(VARIABLE MERGE)
182  assert_equal(VARIABLE "cmake cache;environment;local")
183
184  # Environment is not cached when using MERGE.
185  unset(VARIABLE CACHE)
186  unset(VARIABLE)
187
188  zephyr_get(VARIABLE MERGE)
189  assert_equal(VARIABLE "environment")
190  assert_equal(CACHE{VARIABLE} "")
191
192  unset(ENV{VARIABLE})
193  set(VARIABLE "cmake cache" CACHE INTERNAL "")
194  set(VARIABLE "local")
195
196  zephyr_get(VARIABLE MERGE)
197  assert_equal(VARIABLE "cmake cache;local")
198
199  unset(VARIABLE CACHE)
200  unset(VARIABLE)
201
202  zephyr_get(VARIABLE MERGE)
203  assert_equal(VARIABLE "")
204
205  # Lists are combined and *rightmost* duplicates are removed.
206  set(ENV{VARIABLE} "A;B;C;D")
207  set(VARIABLE "F;E;D;C")
208
209  zephyr_get(VARIABLE MERGE)
210  assert_equal(VARIABLE "A;B;C;D;F;E")
211
212  # Test with an external variable provided in testcase.yaml
213  unset(ENV{TESTCASE_VARIABLE})
214  unset(TESTCASE_VARIABLE CACHE)
215
216  zephyr_get(TESTCASE_VARIABLE MERGE SYSBUILD LOCAL)
217  assert_equal(TESTCASE_VARIABLE
218    IMAGE no_sysbuild    ""
219    IMAGE zephyr_get     "sysbuild.main"
220    IMAGE zephyr_get_2nd "sysbuild.2nd"
221    # This image has no LOCAL sysbuild-defined value.
222    IMAGE zephyr_get_3rd ""
223  )
224
225  unset(TESTCASE_VARIABLE)
226
227  # Add the GLOBAL sysbuild-defined value.
228  zephyr_get(TESTCASE_VARIABLE MERGE SYSBUILD GLOBAL)
229  assert_equal(TESTCASE_VARIABLE
230    IMAGE no_sysbuild    ""
231    # This image's LOCAL and GLOBAL are identical; duplicates are removed.
232    IMAGE zephyr_get     "sysbuild.main"
233    IMAGE zephyr_get_2nd "sysbuild.2nd;sysbuild.main"
234    IMAGE zephyr_get_3rd "sysbuild.main"
235  )
236
237  # Add more variable scopes.
238  set(ENV{TESTCASE_VARIABLE} "environment")
239  set(TESTCASE_VARIABLE "cmake cache" CACHE INTERNAL "")
240  set(TESTCASE_VARIABLE "local")
241
242  zephyr_get(TESTCASE_VARIABLE MERGE SYSBUILD GLOBAL)
243  assert_equal(TESTCASE_VARIABLE
244    IMAGE no_sysbuild    "cmake cache;environment;local"
245    IMAGE zephyr_get     "sysbuild.main;cmake cache;environment;local"
246    IMAGE zephyr_get_2nd "sysbuild.2nd;sysbuild.main;cmake cache;environment;local"
247    IMAGE zephyr_get_3rd "sysbuild.main;cmake cache;environment;local"
248  )
249
250  unset(TESTCASE_VARIABLE)
251  zephyr_get(TESTCASE_VARIABLE MERGE SYSBUILD LOCAL)
252  assert_equal(TESTCASE_VARIABLE
253    IMAGE no_sysbuild    "cmake cache;environment"
254    IMAGE zephyr_get     "sysbuild.main;cmake cache;environment"
255    IMAGE zephyr_get_2nd "sysbuild.2nd;cmake cache;environment"
256    IMAGE zephyr_get_3rd "cmake cache;environment"
257  )
258
259  unset(TESTCASE_VARIABLE)
260  unset(TESTCASE_VARIABLE CACHE)
261
262  # This should be equivalent to: zephyr_get(... SYSBUILD GLOBAL)
263  zephyr_get(TESTCASE_VARIABLE MERGE)
264  assert_equal(TESTCASE_VARIABLE
265    IMAGE no_sysbuild    "environment"
266    IMAGE zephyr_get     "sysbuild.main;environment"
267    IMAGE zephyr_get_2nd "sysbuild.2nd;sysbuild.main;environment"
268    IMAGE zephyr_get_3rd "sysbuild.main;environment"
269  )
270  assert_equal(CACHE{TESTCASE_VARIABLE} "")
271endfunction()
272
273
274function(test_multivar)
275  # Test with local variables not controlled by sysbuild.
276  foreach(var VARIABLE_1 VARIABLE_2 VARIABLE_3)
277    unset(ENV{${var}})
278    unset(${var} CACHE)
279    unset(${var})
280  endforeach()
281
282  set(ENV{VARIABLE_1} "environment 1")
283  set(ENV{VARIABLE_3} "environment 3")
284  set(VARIABLE_2 "cmake cache 2" CACHE INTERNAL "")
285  set(VARIABLE_2 "local 2")
286  set(VARIABLE_3 "local 3")
287
288  # Highest precedence scope always wins.
289  zephyr_get(RESULT VAR VARIABLE_1 VARIABLE_2 VARIABLE_3)
290  assert_equal(RESULT "cmake cache 2")
291  zephyr_get(RESULT VAR VARIABLE_3 VARIABLE_1 VARIABLE_2)
292  assert_equal(RESULT "cmake cache 2")
293
294  # With multiple variables in the same scope, the first variable wins.
295  set(VARIABLE_1 "cmake cache 1" CACHE INTERNAL "")
296  zephyr_get(RESULT VAR VARIABLE_1 VARIABLE_2 VARIABLE_3)
297  assert_equal(RESULT "cmake cache 1")
298  zephyr_get(RESULT VAR VARIABLE_2 VARIABLE_3 VARIABLE_1)
299  assert_equal(RESULT "cmake cache 2")
300
301  unset(ENV{RESULT})
302  unset(RESULT CACHE)
303  unset(RESULT)
304
305  # With MERGE, all scopes are reflected subject to variable order.
306  zephyr_get(RESULT MERGE VAR VARIABLE_1 VARIABLE_2 VARIABLE_3)
307  assert_equal(RESULT "cmake cache 1;cmake cache 2;environment 1;environment 3;local 2;local 3")
308
309  set(ENV{RESULT} "environment r")
310  set(RESULT "cmake cache r" CACHE INTERNAL "")
311  set(RESULT "local r")
312
313  # Unless RESULT is included in VAR, it does not affect the output.
314  zephyr_get(RESULT MERGE VAR VARIABLE_3 VARIABLE_2 VARIABLE_1)
315  assert_equal(RESULT "cmake cache 2;cmake cache 1;environment 3;environment 1;local 3;local 2")
316
317  set(RESULT "local r")
318  zephyr_get(RESULT MERGE VAR RESULT VARIABLE_3 VARIABLE_2 VARIABLE_1)
319  assert_equal(RESULT "cmake cache r;cmake cache 2;cmake cache 1;environment r;environment 3;environment 1;local r;local 3;local 2")
320
321  set(RESULT "local r")
322  zephyr_get(RESULT MERGE VAR VARIABLE_2 VARIABLE_3 VARIABLE_1 RESULT)
323  assert_equal(RESULT "cmake cache 2;cmake cache 1;cmake cache r;environment 3;environment 1;environment r;local 2;local 3;local r")
324
325  unset(ENV{RESULT})
326  unset(RESULT CACHE)
327  unset(RESULT)
328
329  # If an environment value wins, it is cached afterwards.
330  unset(VARIABLE_1 CACHE)
331  unset(VARIABLE_2 CACHE)
332
333  zephyr_get(RESULT VAR VARIABLE_1 VARIABLE_2 VARIABLE_3)
334  assert_equal(RESULT "environment 1")
335  assert_equal(CACHE{VARIABLE_1} "environment 1")
336  assert_equal(CACHE{VARIABLE_2} "")
337  assert_equal(CACHE{VARIABLE_3} "")
338  assert_equal(CACHE{RESULT} "")
339
340  unset(VARIABLE_1 CACHE)
341  unset(VARIABLE_3)
342
343  zephyr_get(RESULT VAR VARIABLE_3 VARIABLE_1 VARIABLE_2)
344  assert_equal(RESULT "environment 3")
345  assert_equal(CACHE{VARIABLE_1} "")
346  assert_equal(CACHE{VARIABLE_2} "")
347  assert_equal(CACHE{VARIABLE_3} "environment 3")
348  assert_equal(CACHE{RESULT} "")
349
350  set(VARIABLE_2 "cmake cache 2" CACHE INTERNAL "")
351  set(VARIABLE_2 "local 2")
352  set(VARIABLE_3 "local 3")
353  unset(VARIABLE_3 CACHE)
354
355  # Include the external variable provided in testcase.yaml
356  set(ENV{TESTCASE_VARIABLE} "environment s")
357  set(TESTCASE_VARIABLE "cmake cache s" CACHE INTERNAL "")
358  set(TESTCASE_VARIABLE "local s")
359
360  zephyr_get(RESULT SYSBUILD GLOBAL VAR TESTCASE_VARIABLE VARIABLE_1 VARIABLE_2 VARIABLE_3)
361  assert_equal(RESULT
362    IMAGE no_sysbuild    "cmake cache s"
363    IMAGE zephyr_get     "sysbuild.main"
364    IMAGE zephyr_get_2nd "sysbuild.2nd"
365    IMAGE zephyr_get_3rd "sysbuild.main"
366  )
367  zephyr_get(RESULT SYSBUILD LOCAL VAR TESTCASE_VARIABLE VARIABLE_1 VARIABLE_2 VARIABLE_3)
368  assert_equal(RESULT
369    IMAGE no_sysbuild    "cmake cache s"
370    IMAGE zephyr_get     "sysbuild.main"
371    IMAGE zephyr_get_2nd "sysbuild.2nd"
372    IMAGE zephyr_get_3rd "cmake cache s"
373  )
374
375  unset(RESULT)
376  zephyr_get(RESULT SYSBUILD GLOBAL MERGE VAR TESTCASE_VARIABLE VARIABLE_1 VARIABLE_2 VARIABLE_3)
377  assert_equal(RESULT
378    IMAGE no_sysbuild    "cmake cache s;cmake cache 2;environment s;environment 1;environment 3;local s;local 2;local 3"
379    IMAGE zephyr_get     "sysbuild.main;cmake cache s;cmake cache 2;environment s;environment 1;environment 3;local s;local 2;local 3"
380    IMAGE zephyr_get_2nd "sysbuild.2nd;sysbuild.main;cmake cache s;cmake cache 2;environment s;environment 1;environment 3;local s;local 2;local 3"
381    IMAGE zephyr_get_3rd "sysbuild.main;cmake cache s;cmake cache 2;environment s;environment 1;environment 3;local s;local 2;local 3"
382  )
383  unset(RESULT)
384  zephyr_get(RESULT SYSBUILD LOCAL MERGE VAR TESTCASE_VARIABLE VARIABLE_1 VARIABLE_2 VARIABLE_3)
385  assert_equal(RESULT
386    IMAGE no_sysbuild    "cmake cache s;cmake cache 2;environment s;environment 1;environment 3;local s;local 2;local 3"
387    IMAGE zephyr_get     "sysbuild.main;cmake cache s;cmake cache 2;environment s;environment 1;environment 3;local s;local 2;local 3"
388    IMAGE zephyr_get_2nd "sysbuild.2nd;cmake cache s;cmake cache 2;environment s;environment 1;environment 3;local s;local 2;local 3"
389    IMAGE zephyr_get_3rd "cmake cache s;cmake cache 2;environment s;environment 1;environment 3;local s;local 2;local 3"
390  )
391  unset(RESULT)
392  zephyr_get(RESULT SYSBUILD GLOBAL MERGE VAR VARIABLE_3 VARIABLE_2 VARIABLE_1 TESTCASE_VARIABLE)
393  assert_equal(RESULT
394    IMAGE no_sysbuild    "cmake cache 2;cmake cache s;environment 3;environment 1;environment s;local 3;local 2;local s"
395    IMAGE zephyr_get     "sysbuild.main;cmake cache 2;cmake cache s;environment 3;environment 1;environment s;local 3;local 2;local s"
396    IMAGE zephyr_get_2nd "sysbuild.2nd;sysbuild.main;cmake cache 2;cmake cache s;environment 3;environment 1;environment s;local 3;local 2;local s"
397    IMAGE zephyr_get_3rd "sysbuild.main;cmake cache 2;cmake cache s;environment 3;environment 1;environment s;local 3;local 2;local s"
398  )
399  unset(RESULT)
400  zephyr_get(RESULT SYSBUILD LOCAL MERGE VAR VARIABLE_3 VARIABLE_2 VARIABLE_1 TESTCASE_VARIABLE)
401  assert_equal(RESULT
402    IMAGE no_sysbuild    "cmake cache 2;cmake cache s;environment 3;environment 1;environment s;local 3;local 2;local s"
403    IMAGE zephyr_get     "sysbuild.main;cmake cache 2;cmake cache s;environment 3;environment 1;environment s;local 3;local 2;local s"
404    IMAGE zephyr_get_2nd "sysbuild.2nd;cmake cache 2;cmake cache s;environment 3;environment 1;environment s;local 3;local 2;local s"
405    IMAGE zephyr_get_3rd "cmake cache 2;cmake cache s;environment 3;environment 1;environment s;local 3;local 2;local s"
406  )
407endfunction()
408
409
410function(test_merge_reverse)
411  # Test with local variables not controlled by sysbuild.
412  foreach(var VARIABLE_1 VARIABLE_2 VARIABLE_3)
413    unset(ENV{${var}})
414    unset(${var} CACHE)
415    unset(${var})
416  endforeach()
417
418  set(ENV{VARIABLE_1} "environment 1")
419  set(ENV{VARIABLE_2} "environment 2")
420  set(VARIABLE_1 "cmake cache 1" CACHE INTERNAL "")
421  set(VARIABLE_2 "cmake cache 2" CACHE INTERNAL "")
422  set(VARIABLE_1 "local 1")
423  set(VARIABLE_2 "local 2")
424
425  # Only scopes are reversed; not variables.
426  zephyr_get(VARIABLE_1 MERGE REVERSE)
427  assert_equal(VARIABLE_1 "local 1;environment 1;cmake cache 1")
428
429  zephyr_get(RESULT MERGE REVERSE VAR VARIABLE_1 VARIABLE_2)
430  assert_equal(RESULT "local 1;local 2;environment 1;environment 2;cmake cache 1;cmake cache 2")
431
432  # Lists are combined and *leftmost* duplicates are removed.
433  set(ENV{VARIABLE_3} "A;B;C;D")
434  set(VARIABLE_3 "F;E;D;C")
435  unset(RESULT)
436
437  zephyr_get(VARIABLE_3 MERGE REVERSE)
438  assert_equal(VARIABLE_3 "F;E;A;B;C;D")
439
440  zephyr_get(RESULT MERGE REVERSE VAR VARIABLE_1 VARIABLE_2 VARIABLE_3)
441  assert_equal(RESULT "local 1;local 2;F;E;environment 1;environment 2;A;B;C;D;cmake cache 1;cmake cache 2")
442
443  # Test with an external variable provided in testcase.yaml
444  unset(ENV{TESTCASE_VARIABLE})
445  unset(TESTCASE_VARIABLE CACHE)
446
447  # In REVERSE, the GLOBAL value goes before the LOCAL.
448  zephyr_get(TESTCASE_VARIABLE MERGE REVERSE SYSBUILD GLOBAL)
449  assert_equal(TESTCASE_VARIABLE
450    IMAGE no_sysbuild    ""
451    IMAGE zephyr_get     "sysbuild.main"
452    IMAGE zephyr_get_2nd "sysbuild.main;sysbuild.2nd"
453    IMAGE zephyr_get_3rd "sysbuild.main"
454  )
455
456  # Add more variable scopes.
457  set(ENV{TESTCASE_VARIABLE} "environment s")
458  set(TESTCASE_VARIABLE "cmake cache s" CACHE INTERNAL "")
459  set(TESTCASE_VARIABLE "local s")
460
461  zephyr_get(TESTCASE_VARIABLE MERGE REVERSE SYSBUILD GLOBAL)
462  assert_equal(TESTCASE_VARIABLE
463    IMAGE no_sysbuild    "local s;environment s;cmake cache s"
464    IMAGE zephyr_get     "local s;environment s;cmake cache s;sysbuild.main"
465    IMAGE zephyr_get_2nd "local s;environment s;cmake cache s;sysbuild.main;sysbuild.2nd"
466    IMAGE zephyr_get_3rd "local s;environment s;cmake cache s;sysbuild.main"
467  )
468
469  unset(TESTCASE_VARIABLE)
470  zephyr_get(TESTCASE_VARIABLE MERGE REVERSE SYSBUILD LOCAL)
471  assert_equal(TESTCASE_VARIABLE
472    IMAGE no_sysbuild    "environment s;cmake cache s"
473    IMAGE zephyr_get     "environment s;cmake cache s;sysbuild.main"
474    IMAGE zephyr_get_2nd "environment s;cmake cache s;sysbuild.2nd"
475    IMAGE zephyr_get_3rd "environment s;cmake cache s"
476  )
477
478  unset(RESULT)
479  set(TESTCASE_VARIABLE "local s")
480
481  # This should be equivalent to: zephyr_get(... SYSBUILD GLOBAL)
482  zephyr_get(RESULT MERGE REVERSE VAR TESTCASE_VARIABLE VARIABLE_1 VARIABLE_2)
483  assert_equal(RESULT
484    IMAGE no_sysbuild    "local s;local 1;local 2;environment s;environment 1;environment 2;cmake cache s;cmake cache 1;cmake cache 2"
485    IMAGE zephyr_get     "local s;local 1;local 2;environment s;environment 1;environment 2;cmake cache s;cmake cache 1;cmake cache 2;sysbuild.main"
486    IMAGE zephyr_get_2nd "local s;local 1;local 2;environment s;environment 1;environment 2;cmake cache s;cmake cache 1;cmake cache 2;sysbuild.main;sysbuild.2nd"
487    IMAGE zephyr_get_3rd "local s;local 1;local 2;environment s;environment 1;environment 2;cmake cache s;cmake cache 1;cmake cache 2;sysbuild.main"
488  )
489endfunction()
490
491
492function(test_snippets_scope)
493  if(NOT TARGET snippets_scope)
494    zephyr_create_scope(snippets)
495  endif()
496
497  zephyr_set(VARIABLE_1 "snippet 1" SCOPE snippets)
498  zephyr_set(VARIABLE_2 "snippet 2" SCOPE snippets)
499  zephyr_set(VARIABLE_3 "snippet 3" SCOPE snippets)
500  zephyr_set(TESTCASE_VARIABLE "snippet s" SCOPE snippets)
501
502  foreach(var VARIABLE_1 VARIABLE_2 VARIABLE_3 TESTCASE_VARIABLE)
503    unset(ENV{${var}})
504    unset(${var} CACHE)
505    unset(${var})
506  endforeach()
507
508  set(ENV{VARIABLE_1} "environment 1")
509  set(ENV{VARIABLE_3} "environment 3")
510  set(VARIABLE_2 "cmake cache 2" CACHE INTERNAL "")
511  set(VARIABLE_3 "cmake cache 3" CACHE INTERNAL "")
512
513  # Snippets have higher precedence than environment, but lower than CMake cache.
514  zephyr_get(VARIABLE_1)
515  assert_equal(VARIABLE_1 "snippet 1")
516  unset(VARIABLE_1)
517  zephyr_get(VARIABLE_1 MERGE)
518  assert_equal(VARIABLE_1 "snippet 1;environment 1")
519
520  zephyr_get(VARIABLE_2)
521  assert_equal(VARIABLE_2 "cmake cache 2")
522  set(VARIABLE_2 "local 2")
523  zephyr_get(VARIABLE_2 MERGE)
524  assert_equal(VARIABLE_2 "cmake cache 2;snippet 2;local 2")
525
526  zephyr_get(VARIABLE_3)
527  assert_equal(VARIABLE_3 "cmake cache 3")
528  set(VARIABLE_3 "local 3")
529  zephyr_get(VARIABLE_3 MERGE)
530  assert_equal(VARIABLE_3 "cmake cache 3;snippet 3;environment 3;local 3")
531
532  unset(VARIABLE_1)
533  set(VARIABLE_2 "local 2")
534  set(VARIABLE_3 "local 3")
535
536  zephyr_get(RESULT MERGE REVERSE VAR VARIABLE_1 VARIABLE_2 VARIABLE_3)
537  assert_equal(RESULT "local 2;local 3;environment 1;environment 3;snippet 1;snippet 2;snippet 3;cmake cache 2;cmake cache 3")
538
539  # Transitively, snippets have lower precedence than sysbuild-defined values.
540  zephyr_get(TESTCASE_VARIABLE)
541  assert_equal(TESTCASE_VARIABLE
542    IMAGE no_sysbuild    "snippet s"
543    IMAGE zephyr_get     "sysbuild.main"
544    IMAGE zephyr_get_2nd "sysbuild.2nd"
545    IMAGE zephyr_get_3rd "sysbuild.main"
546  )
547  zephyr_get(TESTCASE_VARIABLE SYSBUILD LOCAL)
548  assert_equal(TESTCASE_VARIABLE
549    IMAGE no_sysbuild    "snippet s"
550    IMAGE zephyr_get     "sysbuild.main"
551    IMAGE zephyr_get_2nd "sysbuild.2nd"
552    IMAGE zephyr_get_3rd "snippet s"
553  )
554  unset(TESTCASE_VARIABLE)
555  zephyr_get(TESTCASE_VARIABLE MERGE SYSBUILD GLOBAL)
556  assert_equal(TESTCASE_VARIABLE
557    IMAGE no_sysbuild    "snippet s"
558    IMAGE zephyr_get     "sysbuild.main;snippet s"
559    IMAGE zephyr_get_2nd "sysbuild.2nd;sysbuild.main;snippet s"
560    IMAGE zephyr_get_3rd "sysbuild.main;snippet s"
561  )
562
563  # If an environment value wins, it gets cached and promoted above snippets.
564  zephyr_set(VARIABLE_1 SCOPE snippets)
565  zephyr_get(VARIABLE_1)
566  assert_equal(VARIABLE_1 "environment 1")
567  assert_equal(CACHE{VARIABLE_1} "environment 1")
568
569  zephyr_set(VARIABLE_1 "snippet 1" SCOPE snippets)
570  zephyr_get(VARIABLE_1)
571  assert_equal(VARIABLE_1 "environment 1")
572
573  unset(VARIABLE_1 CACHE)
574  zephyr_get(VARIABLE_1)
575  assert_equal(VARIABLE_1 "snippet 1")
576endfunction()
577
578run_suite(
579  test_precedence
580  test_precedence_with_sysbuild
581  test_merge
582  test_multivar
583  test_merge_reverse
584  test_snippets_scope
585)
586