Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding the client code for supporting experiments #5034

Open
wants to merge 16 commits into
base: master
Choose a base branch
from

Conversation

AmelBawa-msft
Copy link
Contributor

@AmelBawa-msft AmelBawa-msft commented Dec 3, 2024

Adding the client-side code for supporting running experiments in winget-cli.

Group policy:

  • EnableExperiments: Disabling this group policy will prevent any experiment from running.

User settings:

  • "experiments": Enable the user to control whether or not an experiment should run or not.

  • I have signed the Contributor License Agreement.

  • This pull request is related to an issue.


Microsoft Reviewers: Open in CodeFlow

@AmelBawa-msft AmelBawa-msft marked this pull request as ready for review December 9, 2024 21:26
@AmelBawa-msft AmelBawa-msft requested a review from a team as a code owner December 9, 2024 21:26
@@ -25,6 +25,12 @@ If you disable this setting, users will not be able to change settings for the W
If you enable or do not configure this setting, users will be able to enable experimental features for the Windows Package Manager.

If you disable this setting, users will not be able to enable experimental features for the Windows Package Manager.</string>
<string id="EnableExperiments">Enable Windows Package Manager Experiments</string>
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding @RDMacLachlan to help with the strings to be used in the adml file

src/Internal/Experiment/Experiment.vcxproj Outdated Show resolved Hide resolved
src/Internal/Experiment/Experiment.vcxproj Outdated Show resolved Hide resolved
src/Internal/Experiment/Experiment.h Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/Experiment.cpp Show resolved Hide resolved
@@ -25,6 +25,12 @@ If you disable this setting, users will not be able to change settings for the W
If you enable or do not configure this setting, users will be able to enable experimental features for the Windows Package Manager.

If you disable this setting, users will not be able to enable experimental features for the Windows Package Manager.</string>
<string id="EnableExperiments">Enable Windows Package Manager Experiments</string>
<string id="EnableExperimentsExplanation">This policy controls whether users can enable experiments in the Windows Package Manager.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may need to expand on what an experiment is, and how it differs from an experimental feature, so that IT admins can make the decision

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 this is a placeholder text I added and will be replaced by PM's suggestion 😊

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use "Experimentation" rather than "Experiments"

The policy controls whether users can have experiments run in WinGet on their device.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the policy control:

  1. experimentation all up
  2. experiment state being driven externally
  3. user control over experiment state

This string seems to indicate only 3, but my expectation would be either 1 or 2.

src/AppInstallerRepositoryCore/SourceList.cpp Outdated Show resolved Hide resolved
src/AppInstallerRepositoryCore/SourceList.cpp Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/Experiment.cpp Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/Public/winget/Experiment.h Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/Experiment.cpp Outdated Show resolved Hide resolved
@microsoft-github-policy-service microsoft-github-policy-service bot added the Issue-Feature This is a feature request for the Windows Package Manager client. label Dec 10, 2024
@@ -25,6 +25,12 @@ If you disable this setting, users will not be able to change settings for the W
If you enable or do not configure this setting, users will be able to enable experimental features for the Windows Package Manager.

If you disable this setting, users will not be able to enable experimental features for the Windows Package Manager.</string>
<string id="EnableExperiments">Enable Windows Package Manager Experiments</string>
<string id="EnableExperimentsExplanation">This policy controls whether users can enable experiments in the Windows Package Manager.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the policy control:

  1. experimentation all up
  2. experiment state being driven externally
  3. user control over experiment state

This string seems to indicate only 3, but my expectation would be either 1 or 2.

src/AppInstallerCommonCore/AppInstallerTelemetry.cpp Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/AppInstallerTelemetry.cpp Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/AppInstallerTelemetry.cpp Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/AppInstallerTelemetry.cpp Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/Experiment.cpp Outdated Show resolved Hide resolved
src/AppInstallerCommonCore/UserSettings.cpp Show resolved Hide resolved
src/AppInstallerRepositoryCore/SourceList.cpp Outdated Show resolved Hide resolved
src/AppInstallerSharedLib/JsonUtil.cpp Show resolved Hide resolved
src/AppInstallerSharedLib/JsonUtil.cpp Outdated Show resolved Hide resolved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I imagine there is already a policy to disable experimentation across Windows as a whole. I found AllowExperimentation but I'm not sure if it does what I think.

If there is such a policy, I think we would be better off not having our own and just pointing people to that one. If somebody disables it system-wide, then our policy won't do anything because the infrastructure we use will be disabled. The only case where it would be useful to have both is if somebody wants to have experimentation in Windows as a whole, but not on winget specifically, which I don't think is a common scenario

@@ -25,6 +25,12 @@ If you disable this setting, users will not be able to change settings for the W
If you enable or do not configure this setting, users will be able to enable experimental features for the Windows Package Manager.

If you disable this setting, users will not be able to enable experimental features for the Windows Package Manager.</string>
<string id="EnableExperiments">Enable Windows Package Manager Experiments</string>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest the policy be called "Allow" instead of "Enable" even if it is not consistent with the other policies.
To me, "Enable" means that the experiments will be turned on but that's not what happens. What happens is that experiments may be turned on depending on the control/treatment groups; which is better described by "Allow"

It probably should also mention that they are Microsoft-run experiments for new features/changes

bool m_isEnabled;
};

struct Experiment
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make experiments part of the experimental features?

Experimental features already have most of the things we may want: settings to be turned on/off, GPO to disable them wholesale, an API to check the state, a command to show the current state. The only thing we would need to add is the option that they may be set remotely for an experiment if there is no local override.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we might still want a new GP for "allow experimental feature state to be changed remotely", but other than that it was my original thought that all experiments would likely have a feature. I forget the reasons why I softened on that, but I do think that there may be some value to separating them as they are slightly different semantics. One potential large reason is that if we use EFs exclusively, then a disabled GP for EFs also disables experiments. Moving experiments out to their own thing means an admin can disable in-development features while still allowing for experiments.

Typically, an EF is work-in-progress and will eventually be released. Using an experiment on an EF is more akin to controlled feature rollout. I think it will probably happen that we hook that up so that an EF can be controlled by an experiment and thus we get CFR.

On the other hand, a true experiment is typically a small configuration or code change that is itself not risky from a local functionality perspective (the impact, such as changing the CDN could have major impacts on the overall system of course). We might be testing something that we want to make permanent like where the DNS for the CDN points, or we might be checking to see if customer satisfaction numbers are higher if the default progress style is rainbow.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as they are slightly different semantics

If users are going to come across the two concepts, do we think the difference is clear enough for them to understand?

an admin can disable in-development features while still allowing for experiments

Do we expect there will be admins wanting to do that?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want users to come across experiments really; the major reason for the control via settings is to enable us to test.

As to admins wanting to do that; I'm not sure. But if we are not going to build any user facing interfaces around them, then I see the minor additional cost as acceptable.

" is disabled due to group policy: " << TogglePolicy::GetPolicy(TogglePolicy::Policy::Experiments).RegValueName());
return { false, ExperimentToggleSource::Policy };
}

auto experiments = userSettings.Get<Setting::Experiments>();
if (key == Experiment::Key::None)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this back to first. While I'm not sure that we need a None, if we have one then checks against it should not end up logging about group policy being disabled.

src/AppInstallerCommonCore/Experiment.cpp Outdated Show resolved Hide resolved
Experiment(std::string_view name, std::string_view jsonName, std::string_view link, std::string key) :
m_name(name), m_jsonName(jsonName), m_link(link), m_key(key) {}
Experiment(std::string name, std::string jsonName, std::string link, std::string key) :
m_name(std::move(name)), m_jsonName(jsonName), m_link(std::move(link)), m_key(std::move((key))) {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
m_name(std::move(name)), m_jsonName(jsonName), m_link(std::move(link)), m_key(std::move((key))) {}
m_name(std::move(name)), m_jsonName(std::move(jsonName)), m_link(std::move(link)), m_key(std::move((key))) {}

Accompanied by making m_jsonName not a view.


static ExperimentState GetState(Key feature);
static ExperimentState GetStateInternal(Key feature);
static Experiment GetExperiment(Key key);
static std::vector<Experiment> GetAllExperiments();

std::string_view Name() const { return m_name; }
std::string Name() const { return m_name; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::string Name() const { return m_name; }
const std::string& Name() const { return m_name; }

And the rest as const&.

std::string GetKey() const { return m_key; }

private:
std::string_view m_name;
std::string m_name;
Utility::LocIndView m_jsonName;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not need to be a localized value, does it?

"type": "object",
"properties": {
"CDN": {
"description": "Enables the use of an alternative CDN for package downloads",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Packages are not downloaded from our CDN AFAIK

Suggested change
"description": "Enables the use of an alternative CDN for package downloads",
"description": "Enables the use of an alternative CDN for the winget source",

ExperimentState() = default;
ExperimentState(bool isEnabled, ExperimentToggleSource toggleSource) : m_isEnabled(isEnabled), m_toggleSource(toggleSource) {}

/// <summary>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use this doc string format in C++. I think we just add the comment above.

{
SECTION("Not configured")
{
Experiment::ResetStates();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer this to be a struct that resets the state on destruction, like GroupPolicyTestOverride and TestUserSettings. Just to be sure that nothing we set here can escape and affect other tests

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of extra tests that would be good:

  • Policy=Disabled and Global Allow=True -> disabled
  • Policy=Enabled and Global Allow=False -> disabled
  • Policy=Enabled and Individual Allow=False-> Disabled

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Feature This is a feature request for the Windows Package Manager client.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

(GPO) Group Policy Object - Enable Experimentation Support experimentation
4 participants