Browse Source

More yaml verification for a few scenarios (#322)

pull/327/head
Justin Kotalik 6 years ago
committed by GitHub
parent
commit
703e5398d7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 41
      src/Microsoft.Tye.Core/ConfigModel/ConfigApplication.cs
  2. 18
      src/Microsoft.Tye.Core/CoreStrings.resx
  3. 73
      test/UnitTests/TyeDeserializationValidationTests.cs

41
src/Microsoft.Tye.Core/ConfigModel/ConfigApplication.cs

@ -66,11 +66,26 @@ namespace Microsoft.Tye.ConfigModel
string.Join(Environment.NewLine, results.Select(r => r.ErrorMessage)));
}
if (config.Services.Where(o => o.Name == service.Name).Count() > 1)
if (config.Services.Count(o => o.Name == service.Name) > 1)
{
throw new TyeYamlException(CoreStrings.ServiceMustHaveUniqueNames);
}
if (service.Project != null && service.Image != null)
{
throw new TyeYamlException(CoreStrings.FormatProjectImageExecutableExclusive("project", "image"));
}
if (service.Project != null && service.Executable != null)
{
throw new TyeYamlException(CoreStrings.FormatProjectImageExecutableExclusive("project", "executable"));
}
if (service.Image != null && service.Executable != null)
{
throw new TyeYamlException(CoreStrings.FormatProjectImageExecutableExclusive("image", "executable"));
}
foreach (var binding in service.Bindings)
{
context = new ValidationContext(binding);
@ -83,11 +98,17 @@ namespace Microsoft.Tye.ConfigModel
if (string.IsNullOrEmpty(binding.Name) && service.Bindings.Count > 1)
{
throw new TyeYamlException(CoreStrings.MultipleServiceBindingsWithoutName);
throw new TyeYamlException(CoreStrings.FormatMultipleBindingWithoutName("service"));
}
if (service.Bindings.Where(o => o.Name == binding.Name).Count() > 1)
if (service.Bindings.Count(o => o.Name == binding.Name) > 1)
{
throw new TyeYamlException(CoreStrings.MultipleServiceBindingsWithSameName);
throw new TyeYamlException(CoreStrings.FormatMultipleBindingWithSameName("service"));
}
if (service.Bindings.Count(o => o.Port == binding.Port) > 1)
{
throw new TyeYamlException(CoreStrings.FormatMultipleBindingWithSamePort("service"));
}
}
@ -135,16 +156,20 @@ namespace Microsoft.Tye.ConfigModel
}
if (string.IsNullOrEmpty(binding.Name) && ingress.Bindings.Count > 1)
{
throw new TyeYamlException(CoreStrings.MultipleIngressBindingWithoutName);
throw new TyeYamlException(CoreStrings.FormatMultipleBindingWithoutName("ingress"));
}
if (ingress.Bindings.Where(o => o.Name == binding.Name).Count() > 1)
if (ingress.Bindings.Count(o => o.Name == binding.Name) > 1)
{
throw new TyeYamlException(CoreStrings.MultipleIngressBindingWithSameName);
throw new TyeYamlException(CoreStrings.FormatMultipleBindingWithSameName("ingress"));
}
if (binding.Protocol != "http" && binding.Protocol != "https" && binding.Protocol != null)
{
throw new TyeYamlException(CoreStrings.IngressBindingMustBeHttpOrHttps);
}
if (ingress.Bindings.Count(o => o.Port == binding.Port) > 1)
{
throw new TyeYamlException(CoreStrings.FormatMultipleBindingWithSamePort("ingress"));
}
}
// Make sure all ingress rules have an associated service
@ -158,7 +183,7 @@ namespace Microsoft.Tye.ConfigModel
string.Join(Environment.NewLine, results.Select(r => r.ErrorMessage)));
}
if (config.Services.Where(o => o.Name == rule.Service).Count() != 1)
if (config.Services.Count(o => o.Name == rule.Service) != 1)
{
throw new TyeYamlException(CoreStrings.IngressRuleMustReferenceService);
}

18
src/Microsoft.Tye.Core/CoreStrings.resx

@ -132,17 +132,14 @@
<data name="IngressRuleMustReferenceService" xml:space="preserve">
<value>Ingress rules references a service that does not exist.</value>
</data>
<data name="MultipleIngressBindingWithoutName" xml:space="preserve">
<value>Cannot have multiple ingress bindings without names. Please specify names for each ingress binding.</value>
<data name="MultipleBindingWithoutName" xml:space="preserve">
<value>Cannot have multiple {0} bindings without names. Please specify names for each {0} binding.</value>
</data>
<data name="MultipleIngressBindingWithSameName" xml:space="preserve">
<value>Cannot have multiple ingress bindings with the same name.</value>
<data name="MultipleBindingWithSameName" xml:space="preserve">
<value>Cannot have multiple {0} bindings with the same name.</value>
</data>
<data name="MultipleServiceBindingsWithoutName" xml:space="preserve">
<value>Cannot have multiple service bindings without names. Please specify names for each service binding.</value>
</data>
<data name="MultipleServiceBindingsWithSameName" xml:space="preserve">
<value>Cannot have multiple service bindings with the same name.</value>
<data name="MultipleBindingWithSamePort" xml:space="preserve">
<value>Cannot have multiple {0} bindings with the same port.</value>
</data>
<data name="MustBeABoolean" xml:space="preserve">
<value>"{value}" must be a boolean value (true/false).</value>
@ -153,6 +150,9 @@
<data name="MustBePositive" xml:space="preserve">
<value>"{value}" value cannot be negative.</value>
</data>
<data name="ProjectImageExecutableExclusive" xml:space="preserve">
<value>Cannot have both "{0}" and "{1}" set for a service. Only one of project, image, and executable can be set for a given service.</value>
</data>
<data name="ServiceMustHaveUniqueNames" xml:space="preserve">
<value>Services must have unique names.</value>
</data>

73
test/UnitTests/TyeDeserializationValidationTests.cs

@ -24,7 +24,7 @@ ingress:
using var parser = new YamlParser(input);
var app = parser.ParseConfigApplication();
var exception = Assert.Throws<TyeYamlException>(() => app.Validate());
Assert.Contains(CoreStrings.MultipleIngressBindingWithoutName, exception.Message);
Assert.Contains(CoreStrings.FormatMultipleBindingWithoutName("ingress"), exception.Message);
}
[Fact]
@ -36,13 +36,13 @@ services:
bindings:
- port: 8080
protocol: http
- port: 8080
- port: 8081
protocol: http";
using var parser = new YamlParser(input);
var app = parser.ParseConfigApplication();
var exception = Assert.Throws<TyeYamlException>(() => app.Validate());
Assert.Contains(CoreStrings.MultipleServiceBindingsWithoutName, exception.Message);
Assert.Contains(CoreStrings.FormatMultipleBindingWithoutName("service"), exception.Message);
}
[Fact]
@ -62,7 +62,7 @@ ingress:
using var parser = new YamlParser(input);
var app = parser.ParseConfigApplication();
var exception = Assert.Throws<TyeYamlException>(() => app.Validate());
Assert.Contains(CoreStrings.MultipleIngressBindingWithSameName, exception.Message);
Assert.Contains(CoreStrings.FormatMultipleBindingWithSameName("ingress"), exception.Message);
}
@ -100,7 +100,7 @@ services:
using var parser = new YamlParser(input);
var app = parser.ParseConfigApplication();
var exception = Assert.Throws<TyeYamlException>(() => app.Validate());
Assert.Contains(CoreStrings.MultipleServiceBindingsWithSameName, exception.Message);
Assert.Contains(CoreStrings.FormatMultipleBindingWithSameName("service"), exception.Message);
}
[Fact]
@ -129,5 +129,68 @@ ingress:
var exception = Assert.Throws<TyeYamlException>(() => app.Validate());
Assert.Contains(CoreStrings.IngressRuleMustReferenceService, exception.Message);
}
[Fact]
public void IngressMustHaveUniquePorts()
{
var input = @"
ingress:
- name: ingress
bindings:
- port: 8080
protocol: http
name: foo
- port: 8080
protocol: https
name: bar";
using var parser = new YamlParser(input);
var app = parser.ParseConfigApplication();
var exception = Assert.Throws<TyeYamlException>(() => app.Validate());
Assert.Contains(CoreStrings.FormatMultipleBindingWithSamePort("ingress"), exception.Message);
}
[Fact]
public void ServicesMustHaveUniquePorts()
{
var input = @"
services:
- name: app
bindings:
- port: 8080
protocol: http
name: a
- port: 8080
protocol: https
name: b";
using var parser = new YamlParser(input);
var app = parser.ParseConfigApplication();
var exception = Assert.Throws<TyeYamlException>(() => app.Validate());
Assert.Contains(CoreStrings.FormatMultipleBindingWithSamePort("service"), exception.Message);
}
[Theory]
[InlineData("image", "executable")]
[InlineData("project", "image")]
[InlineData("project", "executable")]
public void ImageExeProjectMutuallyExclusive(string a, string b)
{
var input = @$"
services:
- name: app
{a}: foo
{b}: baz
bindings:
- port: 8080
protocol: http";
using var parser = new YamlParser(input);
var app = parser.ParseConfigApplication();
var exception = Assert.Throws<TyeYamlException>(() => app.Validate());
Assert.Contains(CoreStrings.FormatProjectImageExecutableExclusive(a, b), exception.Message);
}
}
}

Loading…
Cancel
Save