Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Re-add test  that got removed during a merge conflict resolution, GetFunctionMetadata().
  • Loading branch information
MikeStall committed Dec 14, 2017
1 parent 37e5484 commit ec0f826
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,11 @@ public IEnumerable<BindingRule> GetRules()
}

// Listed in precedence for providing via DefaultType.
private static readonly Type[] _defaultTypes = new Type[] { typeof(JObject), typeof(byte[]), typeof(string) };
// Precdence is more important than how we produce the default type (a direct conversion vs. a converter)
private static readonly Type[] _defaultTypes = new Type[] {
typeof(byte[]),
typeof(JObject),
typeof(string) };

public Type GetDefaultType(Attribute attribute, FileAccess access, Type requestedType)
{
Expand All @@ -219,23 +223,17 @@ public Type GetDefaultType(Attribute attribute, FileAccess access, Type requeste
var openType = OpenType.FromType<TType>();

// Check for a direct match.
// This is critical when there are no converters, such as if TType is an OpenType
foreach (var target in _defaultTypes)
{
if (openType.IsMatch(target))
{
return typeof(IAsyncCollector<>).MakeGenericType(target);
}
}

// Check if there's a converter
// This is critical when there are no converters, such as if TType is an OpenType
foreach (var target in _defaultTypes)
{
if (_converterManager.HasConverter<TAttribute>(target, typeof(TType)))
if (openType.IsMatch(target) ||
_converterManager.HasConverter<TAttribute>(target, typeof(TType)))
{
return typeof(IAsyncCollector<>).MakeGenericType(target);
}
}

return null;
}
return null;
Expand Down
12 changes: 10 additions & 2 deletions src/Microsoft.Azure.WebJobs.Host/IConverterManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,16 @@ internal static FuncAsyncConverter<TSource, TDestination> AsTyped<TSource, TDest
internal static bool HasConverter<TAttribute>(this IConverterManager converterManager, Type typeSource, Type typeDest)
where TAttribute : Attribute
{
var converter = converterManager.GetConverter<TAttribute>(typeSource, typeDest);
return converter != null;
try
{
var converter = converterManager.GetConverter<TAttribute>(typeSource, typeDest);
return converter != null;
}
catch (InvalidOperationException)
{
// OpenType match could have thrown.
return false;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,13 @@ public void DefaultTypeForQueue()
var t2 = metadataProvider.GetDefaultType(new QueueTriggerAttribute("q"), FileAccess.Read, null);
Assert.Equal(typeof(string), t2);

// Very important that this is byte[].
// Script doesn't require Function.json for JScript to specify datatype.
// JScript can convert Jobject, string to byte[].
// But can't convert byte[] to JObject.
// so byte[] is the safest default.
var t3 = metadataProvider.GetDefaultType(new QueueAttribute("q"), FileAccess.Write, null);
Assert.Equal(typeof(IAsyncCollector<JObject>), t3);
Assert.Equal(typeof(IAsyncCollector<byte[]>), t3);
}

// This is a setup used by CosmoDb.
Expand All @@ -191,7 +196,8 @@ public void DefaultTypeForOpenTypeCollector()
var attr = new Test9Attribute(null);
var type = metadataProvider.GetDefaultType(attr, FileAccess.Write, null);

Assert.Equal(typeof(IAsyncCollector<JObject>), type);
// The collector handles Open type, which means it will first pull byte[].
Assert.Equal(typeof(IAsyncCollector<byte[]>), type);
}

// Setup similar to CosmoDb
Expand All @@ -204,6 +210,63 @@ public void Initialize(ExtensionConfigContext context)
}
}

// Verify for a Jobject-only collector.
[Fact]
public void DefaultTypeForJObjectCollector()
{
var ext = new TestExtension3();
var prog = new FakeTypeLocator();
JobHostConfiguration config = TestHelpers.NewConfig(prog, ext);
var host = new JobHost(config);
IJobHostMetadataProvider metadataProvider = host.CreateMetadataProvider();

var attr = new Test9Attribute(null);
var type = metadataProvider.GetDefaultType(attr, FileAccess.Write, null);

// Explicitly should be Jobject since that's all the collector is registered as.
Assert.Equal(typeof(IAsyncCollector<JObject>), type);
}

public class TestExtension3 : IExtensionConfigProvider
{
public void Initialize(ExtensionConfigContext context)
{
context.AddBindingRule<Test9Attribute>().
BindToCollector<JObject>(attr => (IAsyncCollector<JObject>)null);
}
}

[Fact]
public void GetFunctionMetadata()
{
JobHostConfiguration config = TestHelpers.NewConfig();
var host = new JobHost(config);

var mockFunctionIndexProvider = new Mock<IFunctionIndexProvider>();

var functionDescriptor = new FunctionDescriptor()
{
IsDisabled = true
};
var mockFunctionIndex = new Mock<IFunctionIndex>();
mockFunctionIndex.Setup(i => i.LookupByName("testMethod")).Returns(new FunctionDefinition(functionDescriptor, null, null));
var token = new CancellationToken();
mockFunctionIndexProvider.Setup(p => p.GetAsync(token)).Returns(Task.FromResult(mockFunctionIndex.Object));

Func<IFunctionIndexProvider> getter = (() =>
{
return mockFunctionIndexProvider.Object;
});

IJobHostMetadataProvider provider = new JobHostMetadataProvider(getter);

var functionMetadata = provider.GetFunctionMetadata("testNotExists");
Assert.Equal(functionMetadata, null);

functionMetadata = provider.GetFunctionMetadata("testMethod");
Assert.Equal(functionMetadata.IsDisabled, true);
}

// Give this a unique name within the assembly so that the name --> type
// reverse lookup can be unambiguous.
[Binding]
Expand Down

0 comments on commit ec0f826

Please sign in to comment.