Skip to content

Commit

Permalink
Fix name collision in indexer cache (#2645)
Browse files Browse the repository at this point in the history
  • Loading branch information
mathewc committed Feb 2, 2021
1 parent 21d9d4e commit edb5eda
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
12 changes: 10 additions & 2 deletions src/Microsoft.Azure.WebJobs.Host/Indexers/FunctionIndex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,17 @@ public void Add(IFunctionDefinition function, FunctionDescriptor descriptor, Met
_functionsByMethod.Add(method, function);

// For compat, accept either the short name ("Class.Name") or log name (just "Name")
_functionsByName.Add(descriptor.LogName, function);
if (descriptor.ShortName != descriptor.LogName)
if (!_functionsByName.ContainsKey(descriptor.LogName))
{
// since there can be duplicate method names across job classes, it's first one
// wins for this cache
_functionsByName.Add(descriptor.LogName, function);
}
if (descriptor.ShortName != descriptor.LogName &&
!_functionsByName.ContainsKey(descriptor.ShortName))
{
// we do a duplicate check here as well for completeness, though a conflict here
// is much less likely (could only happen if functions are coming from multiple assemblies).
_functionsByName.Add(descriptor.ShortName, function);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,41 @@ public void IsJobMethod_ReturnsFalse_IfMethodHasNoSdkAttributes()
Assert.Equal(false, actual);
}

[Fact]
public async Task IndexMethod_SameName_Succeeds()
{
FunctionIndex index = new FunctionIndex();
FunctionIndexer product = CreateProductUnderTest();

await product.IndexMethodAsync(typeof(ClassA).GetMethod("Test"), index, CancellationToken.None);
await product.IndexMethodAsync(typeof(ClassB).GetMethod("Test"), index, CancellationToken.None);

var functions = index.ReadAll().ToArray();
Assert.Equal(2, functions.Length);

Assert.Equal("ClassA.Test", index.LookupByName("Test").Descriptor.ShortName);
Assert.Equal("ClassA.Test", index.LookupByName("ClassA.Test").Descriptor.ShortName);
Assert.Equal("ClassB.Test", index.LookupByName("ClassB.Test").Descriptor.ShortName);
}

public class ClassA
{
[NoAutomaticTrigger]
public void Test(string test, ILogger logger)
{
logger.LogInformation("Test invoked!");
}
}

public class ClassB
{
[NoAutomaticTrigger]
public void Test(string test, ILogger logger)
{
logger.LogInformation("Test invoked!");
}
}

private class TestExtensionBindingProvider : IBindingProvider
{
public Task<IBinding> TryCreateAsync(BindingProviderContext context)
Expand Down

0 comments on commit edb5eda

Please sign in to comment.