Set mutually exclusive variables in CMake? - cmake

I have a project where i use 2 different libraries depending on the user interest. While generating, i would like to give the user a choice to select which library to build. So far, i used something like this:
set(BUILD_WITH_IR OFF CACHE BOOL "build ir")
set(BUILD_WITH_TOF OFF CACHE BOOL "build tof")
Problem:
I see 2 checkboxes in CMake GUI to select. I choose one and click configure. CMake resets both the checkboxes to OFF (deselected). Understandably, because both are set to OFF every time CMake configures.
I would like the user be able choose only one option at a time. Based on the user selection, i configure rest of my project.
How can i make these variables mutually exclusive?

This looks like a single option that takes multiple values, rather then two separate unrelated options. Try:
set(YOURLIB_BUILD_WITH "NOTHING" CACHE STRING "build with that thing")
set_property(CACHE YOURLIB_BUILD_WITH PROPERTY STRINGS "NOTHING" "IR" "TOF")

Related

XCUITest pass arguments to the test

i have an app that can show many popups in various scenarios, and i would like to verify their text using XCUITest. but would like to be able to do that with no effort for multiple text configurations. for multiple languages for instance.
Is there a way to pass arguments through the .xctestrun file or through the "xcodebuild test-without-building" command? some way to pass the dictionary, or a file that i can parse at the beginning of the XCTestCase to know the correct text values to predict? preferably without the need to rebuild the project.
Found the answer.
The test host (and your XCTestCases) can view its arguments same as the test target, using NSProcessInfo.processInfo.environment and NSProcessInfo.processInfo.arguments.
Using the scheme for "Test" in XCode, you can add arguments and environment variables that the test host itself can read. The test host can read these by using the process info as mentioned above.
Another way to do this would be by editing the xctestrun file for your test. In it, you can add the key CommandLineArguments as an array of strings for the process info arguments, or add EnvironmentVariables as a dictionary from key to string value.
An easy way to go about adding the arguments/variables to the xctestrun file manually would be to first add them to the Test scheme in XCode, see the changes to the xctestrun file, and modify them accordingly.
other xctestrun variables are described in https://www.manpagez.com/man/5/xcodebuild.xctestrun/

How can I use Smarty templates with A/B testing?

I am attempting to build a little modification in our code to allow easier A/B testing.
I'd like to know if I can somehow
have my regular code under the /templates directory
have any a/b code under /templates/_abtests/, but also follow the same hierarchy as the regular code. for example... an ab test can overwrite a file like '/templates/foo.tpl', and use instead '/templates/_abtests/testfoo/foo.tpl'
I tried changing the template directory when in a test. Right before calling the display method, I would check if a user is in a test, and if so, set up the template_dir accordingly. I'd assign an array with the 'ab' directory first, then the default. I am using Smarty2.
the problem with this is that it caches the first instance, and uses that as the template for the baseline and ab test case. ie: i have a parameter to force me into a test bucket, but the template is the same.
thoughts on how to achieve this? goal is to not have to add a bunch of template hooks (if/else) in the templates. and achieve this by simple template/file includes.
I believe that the solution to my problem could be to put templates into folders. ie: /templates/base/, /templates/test_foo/, etc.". then in my template_dir setting, set the array up based on what test we are in.
I had tried this with mobile/desktop before, and forgot about this solution.
I can extend the smarty_template class and override the display method to change the template_dir. adding the test directory first.

CMake User String Input

I am attempting to use CMake to convert a generic wrapper into a specific one, via token replacement. I hope that all the user would have to do is input a specific set of strings, have CMake do configure_file, and the wrapper would read in the values and work as intended.
I am aware of the possibility to use set to set the token that needs to be replaced:
set(FAV_FOOD "Sushi" CACHE STRING "What is your favorite food?")
As well as the option to have the user select from a set of answers like so:
set(MY_SELECTION "Option A" CACHE STRING "Help message for this variable")
set_property(
CACHE MY_SELECTION
PROPERTY STRINGS
"Option A" "Option B" "Option C"
)
The problem with this is that I can't enumerate all valid answers. Is there any way for CMake to have a GUI pop up and allow the user to answer with any string? I could just have the user fill out these values in a file before calling make, but I'd like to avoid the users doing anything by hand in the files, and I want to take advance of the CMake cache and avoid assuming that the user has already filled out the variables in a file.
Any advice would be most helpful. Thanks.
Your first example is the standard way to provide user-specified options to CMake, typically including some suitable default value just as you have demonstrated.
You could omit the default value (pass the empty string) and then check to see if the value has been specified so an error will be generated when the user tries to configure.
In order to provide these values automatically the user can specific them on the command line using -D= syntax:
cmake -DSOME_VAR=some_val <path_to_CMakeLists.txt>
I typically use cmake/ccmake, and I assume you are using windows cmake-gui, which is very similar to ccmake. I know of no method to pop up some additional windows using cmake-gui. However, it does appear possible to invoke cmake-gui with the aforementioned options, as described here. Using this method you could provide a .bat file the user could edit in order to enter the settings that you wish them to specify.
In my opinion, as long as you're already having them run the cmake-gui, then simply utilizing your first proposed solution and letting them change the values in the gui "the old fashioned way" is really the most appropriate option.

Jmeter Set Variable as a Property's Default Value

This doesn't seem like a situation that is unique to me, but I haven't been able to find an answer anywhere.
I am attempting to build Jmeter scripts that can be executed both in the GUI and command line. The command line is going to need values to pass into the test cases, but the same test cases need to be executed via the GUI as well. I initially had separate scripts for GUI and command line, but it seemed redundant to have the same test cases duplicated with just a couple parameters changed.
For example, the GUI test case has the Web Server name set to:
<!-- ${ENV} set in User Defined Variables -->
<stringProp name="HTTPSampler.domain">${ENV}</stringProp>
The command line test case uses the following for parameters:
<!-- Define via command line w/ -JCMDDEV -->
<stringProp name="HTTPSampler.domain">${__P(CMDENV)}</stringProp>
Both work for their served purpose, but I want to combine the tests to be easier maintained and to have the ability to run them via GUI or command line.
I got passed one hurdle, which was combining the GUI Variables to be used as well as Properties for the command line by setting the User Defined Variable ${ENV} as the following:
Name Value
----- --------
ENV ${__P(ENV,dev.address.com)}
I am now able to run the same test case via GUI and command line (defining a new environment with -JENV)
I'm not sure if I'm overthinking this, but I want to be able to add a variable to the property default in order to avoid typos, etc while handing it off to others. I tried a few variations that didn't seem to work:
Name Value
----- --------
ENV ${__P(ENV,${__V(DEV)})}
DEV dev.address.com
This gave me the following Request:
POST http://DEV/servlet
Instead of:
POST http://dev.address.com/servlet
I also tried using:
${__P(ENV,${DEV})}
${__property(ENV,,${__V(DEV)})}
${__property(ENV,,${DEV})}
I was looking into Jmeter nested variables, but it didn't provide any working solutions.
So to my main question, am I able to use variables as the property defaults. If so, how would I achieve that?
I found a way around this. It's not exactly how I wanted it, but it could work for right now.
I really wanted to keep everything in one place where people had to make edits, but I was able to get the User Defined Variables to work by adding the ${__P(ENV,${DEV})} to the HTTP Request Defaults Web Server Name instead of pre-defining it as a variable.
Now there are two Config Elements that potentially need to be edited with GUI execution, but I think it should work out better in the long run.
Yes, seems the author is right - looks like nested variable can't be evaluated in JMeter from the same variables scope.
I've created a different "User Defined Variables" set, added there "defaultValue" - and after that this option works:
${__P(myProperty, ${defaultValue})}

Windows Workflow 4.0 for Simple Orchestration?

I have 4 classes, each with a couple of methods (all the same, they implement a common Interface) and a Dictionary<> containing stuff the instances need to know to do work. They operate serially, "A" finishes and then writes some stuff to state (either file or a DB), then "B" does its work, then "C", then "D". Right now a console app just runs each.
I will soon come on a time when I need to put something between "A" and "B", and later "C" and "D". You get the idea.
I thought that Windows Workflow on Framework 4.0 would be a good candidate for simple sequence orchestration. So I added a new XAML file, fired up the designer, and.... I'm not sure what to do next. I just want to instance objects and set their Dictionary and run them.
How can I get started with that? Simple orchestration searches on Google are not helping.
Thanks.
In order to help the next WF newbie:
Open the designer.
Drag a "Sequence" onto the design surface.
Drag an "InvokeMethod" inside the Sequence.
Target type should be null for Instance Types.
Target object should be "New my.namespace.my.class" (note New is VBasic syntax, required even if you are doing C#)
MethodName should have the name of the method you want to call.
Get Properties and click the elipsis and add the properties in the same order as they are specified in the class definition in your code.
Done.
I stumbled for a while until I found the right word to Bing for - InvokeMethod is the sweetness that lets you run custom code as an activity. There are at least 99e99 other ways to do it I am sure, but this is what works for me.
Thanks.