Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
pinzart90 committed Nov 6, 2024
1 parent 3a23e80 commit d8d91fe
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 10 deletions.
31 changes: 26 additions & 5 deletions src/DynamoUtilities/DynamoFeatureFlagsManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;

namespace DynamoUtilities
{

internal interface IFFlags
{
internal T CheckFeatureFlag<T>(DynamoFeatureFlagsManager mgr, string featureFlagKey, T defaultval);
}

/// <summary>
/// A wrapper around the DynamoFeatureFlags CLI tool.
Expand All @@ -20,9 +21,21 @@ namespace DynamoUtilities
/// </summary>
internal class DynamoFeatureFlagsManager : CLIWrapper
{
// Utility class that supports mocking during tests
class FFlags : IFFlags
{
T IFFlags.CheckFeatureFlag<T>(DynamoFeatureFlagsManager mgr, string featureFlagKey, T defaultval)
{
return mgr.CheckFeatureFlagInternal(featureFlagKey, defaultval);
}
}

// Useful for mocking in tests
internal IFFlags flags { get; set; } = new FFlags();
private string relativePath = Path.Combine("DynamoFeatureFlags", "DynamoFeatureFlags.exe");
private Dictionary<string, object> AllFlagsCache { get; set; }//TODO lock is likely overkill.
private SynchronizationContext syncContext;
private readonly bool testmode = false;
internal static event Action FlagsRetrieved;

//TODO(DYN-6464)- remove this field!.
Expand All @@ -43,8 +56,10 @@ internal class DynamoFeatureFlagsManager : CLIWrapper
/// <param name="syncContext">context used for raising FlagRetrieved event.</param>
/// <param name="testmode">will not contact feature flag service in testmode, will respond with defaults.</param>
internal DynamoFeatureFlagsManager(string userkey, SynchronizationContext syncContext, bool testmode=false)
{
{
this.syncContext = syncContext;
this.testmode = testmode;

//dont pass userkey arg if null/empty
var userkeyarg = $"-u {userkey}";
var testmodearg = string.Empty;
Expand All @@ -62,7 +77,6 @@ internal DynamoFeatureFlagsManager(string userkey, SynchronizationContext syncCo

internal void CacheAllFlags()
{

//wait for response
var dataFromCLI = GetData(featureFlagTimeoutMs);
//convert from json string to dictionary.
Expand Down Expand Up @@ -91,6 +105,13 @@ internal void CacheAllFlags()
/// <param name="defaultval">Currently the flag and default val MUST be a bool or string.</param>
/// <returns></returns>
internal T CheckFeatureFlag<T>(string featureFlagKey, T defaultval)
{
// with testmode = true, the call goes through an interface so that we can intercept it with Mock
// with testmode = false, the call simply goes to the CheckFeatureFlagInternal
return testmode ? flags.CheckFeatureFlag(this, featureFlagKey, defaultval) : CheckFeatureFlagInternal(featureFlagKey, defaultval);
}

private T CheckFeatureFlagInternal<T>(string featureFlagKey, T defaultval)
{
if(!(defaultval is bool || defaultval is string)){
throw new ArgumentException("unsupported flag type", defaultval.GetType().ToString());
Expand Down
2 changes: 2 additions & 0 deletions src/DynamoUtilities/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,5 @@
[assembly: InternalsVisibleTo("Notifications")]
[assembly: InternalsVisibleTo("SystemTestServices")]
[assembly: InternalsVisibleTo("PackageManagerTests")]
//DynamicProxyGenAssembly2 is used by Mock to allow stubbing internal interfaces
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
4 changes: 1 addition & 3 deletions src/Tools/DynamoFeatureFlags/FeatureFlagsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,7 @@ internal FeatureFlagsClient(string userkey, string mobileKey = null, bool testMo
AllFlags = LdValue.ObjectFrom(new Dictionary<string,LdValue> { { "TestFlag1",LdValue.Of(true) },
{ "TestFlag2", LdValue.Of("I am a string") },
//in tests we want instancing on so we can test it.
{ "graphics-primitive-instancing", LdValue.Of(true) },
{ "IsolatePackages", LdValue.Of("Package1,Package2,Package") },
{ "DoNotIsolatePackages", LdValue.Of("Package") }
{ "graphics-primitive-instancing", LdValue.Of(true) }
});
return;
}
Expand Down
12 changes: 10 additions & 2 deletions test/Libraries/PackageManagerTests/PackageLoaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -652,13 +652,21 @@ public void PlacingCustomNodeInstanceFromPackageRetainsCorrectPackageInfoState()
[Test]
public void LoadPackagesInAssemblyIsolation()
{
var ff = new Mock<DynamoUtilities.IFFlags>();
DynamoModel.FeatureFlags.flags = ff.Object;
ff.Setup(x => x.CheckFeatureFlag<string>(DynamoModel.FeatureFlags, "IsolatePackages", "")).Returns(() => "Package1,Package2,Package");
ff.Setup(x => x.CheckFeatureFlag<string>(DynamoModel.FeatureFlags, "DoNotIsolatePackages", "")).Returns(() => "Package");

// Needed for FeatureFlags
Assert.IsTrue(DynamoModel.IsTestMode);
Assert.AreEqual("Package1,Package2,Package", DynamoModel.FeatureFlags.CheckFeatureFlag<string>("IsolatePackages", ""));
Assert.AreEqual("Package", DynamoModel.FeatureFlags.CheckFeatureFlag<string>("DoNotIsolatePackages", ""));


var loader = GetPackageLoader();
var pathManager = new Mock<Dynamo.Interfaces.IPathManager>();
pathManager.SetupGet(x => x.PackagesDirectories).Returns(
() => new List<string> { PackagesDirectory });

var loader = new PackageLoader(pathManager.Object);
var libraryLoader = new ExtensionLibraryLoader(CurrentDynamoModel);

loader.PackagesLoaded += libraryLoader.LoadPackages;
Expand Down

0 comments on commit d8d91fe

Please sign in to comment.