Fix execution of TimerProxy (#2133)

* Fix execution of timerProxy
- fixed behavior of Container.SaveBlob (file was not being overwritten)
- added support for default value in the entity converter
- fix scaleset size data type
- added initialization of Subnet
- renamed TestHook Info to _Info to prevent clashing of name function mame
- added target framework to ApiServiceProject to help local debugging

* fix unit tests

* fix unit tests

* remove unused property

* fix typo

* removing partial class TimerProxy
This commit is contained in:
Cheick Keita
2022-07-07 09:25:51 -07:00
committed by GitHub
parent 0f0fd8ee9c
commit aa2e76e7e9
11 changed files with 118 additions and 68 deletions

View File

@ -3,6 +3,7 @@
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<WarningLevel>5</WarningLevel>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.ResourceManager.Monitor" Version="1.0.0-beta.2" />

View File

@ -195,7 +195,7 @@ public record EventScalesetFailed(
public record EventScalesetResizeScheduled(
Guid ScalesetId,
PoolName PoolName,
int size
long size
) : BaseEvent();

View File

@ -310,12 +310,13 @@ public record InstanceConfig
(
[PartitionKey, RowKey] string InstanceName,
Guid[]? Admins,
bool? AllowPoolManagement,
string[] AllowedAadTenants,
NetworkConfig NetworkConfig,
NetworkSecurityGroupConfig ProxyNsgConfig,
[DefaultValue(InitMethod.DefaultConstructor)] NetworkConfig NetworkConfig,
[DefaultValue(InitMethod.DefaultConstructor)] NetworkSecurityGroupConfig ProxyNsgConfig,
AzureVmExtensionConfig? Extensions,
string ProxyVmSku,
string? ProxyVmSku,
bool AllowPoolManagement = true,
IDictionary<Endpoint, ApiAccessRule>? ApiAccessRules = null,
IDictionary<PrincipalId, GroupId[]>? GroupMembership = null,
IDictionary<string, string>? VmTags = null,
@ -325,13 +326,13 @@ public record InstanceConfig
public InstanceConfig(string instanceName) : this(
instanceName,
null,
true,
Array.Empty<string>(),
new NetworkConfig(),
new NetworkSecurityGroupConfig(),
null,
"Standard_B2s") { }
public InstanceConfig() : this(String.Empty) { }
"Standard_B2s",
true
) { }
public static List<Guid>? CheckAdmins(List<Guid>? value) {
if (value is not null && value.Count == 0) {
@ -341,6 +342,8 @@ public record InstanceConfig
}
}
public InstanceConfig() : this(String.Empty) { }
//# At the moment, this only checks allowed_aad_tenants, however adding
//# support for 3rd party JWT validation is anticipated in a future release.
public ResultVoid<List<string>> CheckInstanceConfig() {
@ -373,12 +376,12 @@ public record Scaleset(
string VmSku,
string Image,
Region Region,
int Size,
bool SpotInstance,
long Size,
bool? SpotInstances,
bool EphemeralOsDisks,
bool NeedsConfigUpdate,
Error? Error,
List<ScalesetNodeState> Nodes,
List<ScalesetNodeState>? Nodes,
Guid? ClientId,
Guid? ClientObjectId,
Dictionary<string, string> Tags

View File

@ -112,6 +112,7 @@ public class Program {
.AddScoped<IOnefuzzContext, OnefuzzContext>()
.AddScoped<IEndpointAuthorization, EndpointAuthorization>()
.AddScoped<INodeMessageOperations, NodeMessageOperations>()
.AddScoped<ISubnet, Subnet>()
.AddSingleton<ICreds, Creds>()
.AddSingleton<IServiceConfig, ServiceConfiguration>()

View File

@ -26,7 +26,7 @@ public class TestHooks {
_logAnalytics = logAnalytics;
}
[Function("Info")]
[Function("_Info")]
public async Task<HttpResponseData> Info([HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "testhooks/info")] HttpRequestData req) {
_log.Info("Creating function info response");
var response = req.CreateResponse();

View File

@ -2,8 +2,7 @@
namespace Microsoft.OneFuzz.Service;
public partial class TimerProxy {
public class TimerProxy {
private readonly ILogTracer _logger;
private readonly IOnefuzzContext _context;

View File

@ -145,7 +145,7 @@ public class Containers : IContainers {
public async Async.Task SaveBlob(Container container, string name, string data, StorageType storageType) {
var client = await FindContainer(container, storageType) ?? throw new Exception($"unable to find container: {container.ContainerName} - {storageType}");
await client.UploadBlobAsync(name, new BinaryData(data));
await client.GetBlobClient(name).UploadAsync(new BinaryData(data), overwrite: true);
}
public Async.Task<Guid> GetInstanceId() => _getInstanceId.Value;

View File

@ -2,8 +2,6 @@
namespace Microsoft.OneFuzz.Service;
public partial class TimerProxy {
public class Network {
private readonly string _name;
private readonly string _group;
@ -51,6 +49,3 @@ public partial class TimerProxy {
return _context.Subnet.GetVnet(_name);
}
}
}

View File

@ -20,6 +20,21 @@ public abstract record EntityBase {
public abstract record StatefulEntityBase<T>([property: JsonIgnore] T State) : EntityBase() where T : Enum;
/// How the value is populated
public enum InitMethod {
//T() will be used
DefaultConstructor,
}
[AttributeUsage(AttributeTargets.Parameter)]
public class DefaultValueAttribute : Attribute {
public InitMethod InitMethod { get; }
public DefaultValueAttribute(InitMethod initMethod) {
InitMethod = initMethod;
}
}
/// Indicates that the enum cases should no be renamed
[AttributeUsage(AttributeTargets.Enum)]
public class SerializeValueAttribute : Attribute { }
@ -56,7 +71,15 @@ public enum EntityPropertyKind {
RowKey,
Column
}
public record EntityProperty(string name, string columnName, Type type, EntityPropertyKind kind, (TypeDiscrimnatorAttribute, ITypeProvider)? discriminator);
public record EntityProperty(
string name,
string columnName,
Type type,
EntityPropertyKind kind,
(TypeDiscrimnatorAttribute, ITypeProvider)? discriminator,
DefaultValueAttribute? defaultValue,
ParameterInfo parameterInfo
);
public record EntityInfo(Type type, ILookup<string, EntityProperty> properties, Func<object?[], object> constructor);
class OnefuzzNamingPolicy : JsonNamingPolicy {
@ -108,6 +131,8 @@ public class EntityConverter {
var isPartitionkey = parameterInfo.GetCustomAttribute(typeof(PartitionKeyAttribute)) != null;
var discriminatorAttribute = typeof(T).GetProperty(name)?.GetCustomAttribute<TypeDiscrimnatorAttribute>();
var defaultValueAttribute = parameterInfo.GetCustomAttribute<DefaultValueAttribute>();
(TypeDiscrimnatorAttribute, ITypeProvider)? discriminator = null;
if (discriminatorAttribute != null) {
@ -117,16 +142,16 @@ public class EntityConverter {
if (isPartitionkey) {
yield return new EntityProperty(name, "PartitionKey", parameterType, EntityPropertyKind.PartitionKey, discriminator);
yield return new EntityProperty(name, "PartitionKey", parameterType, EntityPropertyKind.PartitionKey, discriminator, defaultValueAttribute, parameterInfo);
}
if (isRowkey) {
yield return new EntityProperty(name, "RowKey", parameterType, EntityPropertyKind.RowKey, discriminator);
yield return new EntityProperty(name, "RowKey", parameterType, EntityPropertyKind.RowKey, discriminator, defaultValueAttribute, parameterInfo);
}
if (!isPartitionkey && !isRowkey) {
var columnName = typeof(T).GetProperty(name)?.GetCustomAttribute<JsonPropertyNameAttribute>()?.Name ?? CaseConverter.PascalToSnake(name);
yield return new EntityProperty(name, columnName, parameterType, EntityPropertyKind.Column, discriminator);
yield return new EntityProperty(name, columnName, parameterType, EntityPropertyKind.Column, discriminator, defaultValueAttribute, parameterInfo);
}
}
@ -218,7 +243,15 @@ public class EntityConverter {
var fieldName = ef.columnName;
var obj = entity[fieldName];
if (obj == null) {
return null;
if (ef.parameterInfo.HasDefaultValue) {
return ef.parameterInfo.DefaultValue;
}
return ef.defaultValue switch {
DefaultValueAttribute { InitMethod: InitMethod.DefaultConstructor } => Activator.CreateInstance(ef.type),
_ => null,
};
}
var objType = obj.GetType();

View File

@ -164,7 +164,7 @@ namespace Tests {
public static Gen<InstanceConfig> InstanceConfig() {
return Arb.Generate<Tuple<
Tuple<string, Guid[]?, bool?, string[], NetworkConfig, NetworkSecurityGroupConfig, AzureVmExtensionConfig?>,
Tuple<string, Guid[]?, bool, string[], NetworkConfig, NetworkSecurityGroupConfig, AzureVmExtensionConfig?>,
Tuple<string, IDictionary<string, ApiAccessRule>?, IDictionary<Guid, Guid[]>?, IDictionary<string, string>?, IDictionary<string, string>?>>>().Select(
arg =>
new InstanceConfig(
@ -221,7 +221,7 @@ namespace Tests {
Region: arg.Item1.Item6,
Size: arg.Item2.Item1,
SpotInstance: arg.Item2.Item2,
SpotInstances: arg.Item2.Item2,
EphemeralOsDisks: arg.Item2.Item3,
NeedsConfigUpdate: arg.Item2.Item4,
Error: arg.Item2.Item5,

View File

@ -380,6 +380,24 @@ namespace Tests {
}
class TestClass {
public string Name { get; }
public TestClass() {
Name = "testName";
}
}
record TestIinit([DefaultValue(InitMethod.DefaultConstructor)] TestClass testClass, string test = "default_test") : EntityBase();
[Fact]
public void TestInitValue() {
var entityConverter = new EntityConverter();
var tableEntity = new TableEntity();
var actual = entityConverter.ToRecord<TestIinit>(tableEntity);
Assert.Equal("testName", actual.testClass.Name);
Assert.Equal("default_test", actual.test);
}
}
}