Skip to content

Commit f9de4e2

Browse files
committed
Add some additional tests
1 parent c8bb3d7 commit f9de4e2

5 files changed

Lines changed: 238 additions & 0 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#pragma warning disable OTEL1006
5+
6+
namespace OpenTelemetry.Configuration.Declarative.Tests;
7+
8+
public sealed class ConfigPropertyTests
9+
{
10+
[Fact]
11+
public void IsAbsent_WhenAbsent_ReturnsTrue() =>
12+
Assert.True(ConfigProperty<string>.Absent.IsAbsent);
13+
14+
[Fact]
15+
public void IsAbsent_WhenNull_ReturnsFalse() =>
16+
Assert.False(ConfigProperty<string>.Null.IsAbsent);
17+
18+
[Fact]
19+
public void IsAbsent_WhenPresent_ReturnsFalse() =>
20+
Assert.False(ConfigProperty<string>.Create("x").IsAbsent);
21+
22+
[Fact]
23+
public void IsNull_WhenNull_ReturnsTrue() =>
24+
Assert.True(ConfigProperty<string>.Null.IsNull);
25+
26+
[Fact]
27+
public void IsNull_WhenAbsent_ReturnsFalse() =>
28+
Assert.False(ConfigProperty<string>.Absent.IsNull);
29+
30+
[Fact]
31+
public void IsNull_WhenPresent_ReturnsFalse() =>
32+
Assert.False(ConfigProperty<string>.Create("x").IsNull);
33+
34+
[Fact]
35+
public void Value_WhenPresent_ReturnsValue() =>
36+
Assert.Equal("hello", ConfigProperty<string>.Create("hello").Value);
37+
38+
[Fact]
39+
public void Value_WhenAbsent_ThrowsInvalidOperationException() =>
40+
Assert.Throws<InvalidOperationException>(() => ConfigProperty<string>.Absent.Value);
41+
42+
[Fact]
43+
public void Value_WhenNull_ThrowsInvalidOperationException() =>
44+
Assert.Throws<InvalidOperationException>(() => ConfigProperty<string>.Null.Value);
45+
46+
[Fact]
47+
public void Deconstruct_WhenPresent_YieldsStateAndValue()
48+
{
49+
var (state, value) = ConfigProperty<string>.Create("hello");
50+
51+
Assert.Equal(ConfigPropertyState.Present, state);
52+
Assert.Equal("hello", value);
53+
}
54+
55+
[Fact]
56+
public void Deconstruct_WhenAbsent_YieldsStateAndDefault()
57+
{
58+
var (state, value) = ConfigProperty<string>.Absent;
59+
60+
Assert.Equal(ConfigPropertyState.Absent, state);
61+
Assert.Null(value);
62+
}
63+
64+
[Fact]
65+
public void Deconstruct_WhenNull_YieldsStateAndDefault()
66+
{
67+
var (state, value) = ConfigProperty<string>.Null;
68+
69+
Assert.Equal(ConfigPropertyState.Null, state);
70+
Assert.Null(value);
71+
}
72+
}

test/OpenTelemetry.Configuration.Declarative.Tests/DeclarativeConfigurationEventSourceTests.cs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Collections.ObjectModel;
99
using System.Diagnostics.Tracing;
1010
using Microsoft.Extensions.Configuration;
11+
using Microsoft.Extensions.DependencyInjection;
1112
using OpenTelemetry.Tests;
1213

1314
namespace OpenTelemetry.Configuration.Declarative.Tests;
@@ -208,6 +209,28 @@ public void ReadConfiguration_ResourceAttributeNullValue_EmitsNullValueWarning()
208209
Assert.DoesNotContain("missing", message, StringComparison.OrdinalIgnoreCase);
209210
}
210211

212+
[Fact]
213+
public void ReadConfiguration_ResourceAttributeAbsentValue_EmitsMissingValueWarning()
214+
{
215+
// No 'value' key at all: distinct from value: ~ (NullScalar) and value: {mapping}.
216+
// The warning must say "missing", not "null" or "mapping".
217+
const string yaml = """
218+
file_format: "1.0"
219+
resource:
220+
attributes:
221+
- name: my.attr
222+
""";
223+
224+
using var listener = CreateWarningListener();
225+
226+
_ = ReadConfiguration(yaml);
227+
228+
var warning = Assert.Single(listener.Messages, e => e.EventId == 3);
229+
var message = warning.Payload![0] as string;
230+
Assert.Contains("missing", message, StringComparison.OrdinalIgnoreCase);
231+
Assert.DoesNotContain("null", message, StringComparison.OrdinalIgnoreCase);
232+
}
233+
211234
[Theory]
212235
[InlineData("bool", "yes")]
213236
[InlineData("bool", "no")]
@@ -387,6 +410,26 @@ public void AddOpenTelemetryDeclarativeConfiguration_Parameterless_NoEnvVar_Emit
387410
Assert.Single(listener.Messages, e => e.EventId == 17);
388411
}
389412

413+
[Fact]
414+
public void UseDeclarativeConfiguration_FactoryDescriptorReturnsNull_EmitsPriorConfigurationResolutionFailedWarning()
415+
{
416+
// Register an IConfiguration factory that returns null to exercise the path where
417+
// a descriptor was found but resolves to null at runtime (Event 19).
418+
using var yamlFile = DeclarativeYamlTestFile.CreateDeclarativeYaml(disabled: true);
419+
420+
var services = new ServiceCollection();
421+
services.AddSingleton<IConfiguration>(_ => null!);
422+
423+
new TestEventSourceBuilder(services).UseDeclarativeConfiguration(yamlFile.Path);
424+
425+
using var listener = CreateWarningListener();
426+
427+
var config = services.BuildServiceProvider().GetRequiredService<IConfiguration>();
428+
429+
Assert.Single(listener.Messages, e => e.EventId == 19);
430+
Assert.Equal("true", config[OtelEnvironmentVariables.SdkDisabled]);
431+
}
432+
390433
private static TestEventListener CreateVerboseListener()
391434
{
392435
var listener = new TestEventListener();
@@ -412,4 +455,14 @@ private static TestEventListener CreateWarningListener()
412455
using var factory = new DeclarativeYamlTestFileFactory();
413456
return DeclarativeConfigurationReader.Read(new FilePath(factory.CreateYamlFile(yaml)));
414457
}
458+
459+
private sealed class TestEventSourceBuilder : IOpenTelemetryBuilder
460+
{
461+
public TestEventSourceBuilder(IServiceCollection services)
462+
{
463+
this.Services = services;
464+
}
465+
466+
public IServiceCollection Services { get; }
467+
}
415468
}

test/OpenTelemetry.Configuration.Declarative.Tests/DeclarativeConfigurationFilePathTests.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,48 @@ public void ToString_ReturnsOriginalPath()
8282
Assert.Equal(path, new FilePath(path).ToString());
8383
}
8484

85+
[Fact]
86+
public void GetHashCode_EqualFilePaths_SameHashCode()
87+
{
88+
using var factory = new DeclarativeYamlTestFileFactory();
89+
var absolutePath = factory.CreateDeclarativeYaml(disabled: true);
90+
var originalDirectory = Directory.GetCurrentDirectory();
91+
92+
try
93+
{
94+
Directory.SetCurrentDirectory(factory.TempDirectory);
95+
var relativePath = Path.GetFileName(absolutePath);
96+
97+
var a = new FilePath(absolutePath);
98+
var b = new FilePath(relativePath);
99+
100+
Assert.Equal(a, b);
101+
Assert.Equal(a.GetHashCode(), b.GetHashCode());
102+
}
103+
finally
104+
{
105+
Directory.SetCurrentDirectory(originalDirectory);
106+
}
107+
}
108+
109+
[Fact]
110+
public void GetHashCode_DifferentPathCasingOnWindows_SameHashCode()
111+
{
112+
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
113+
{
114+
return;
115+
}
116+
117+
using var factory = new DeclarativeYamlTestFileFactory();
118+
var absolutePath = factory.CreateDeclarativeYaml(disabled: true);
119+
120+
var a = new FilePath(absolutePath);
121+
var b = new FilePath(absolutePath.ToUpperInvariant());
122+
123+
Assert.Equal(a, b);
124+
Assert.Equal(a.GetHashCode(), b.GetHashCode());
125+
}
126+
85127
[Fact]
86128
public void Path_RelativeInput_IsAbsolute()
87129
{

test/OpenTelemetry.Configuration.Declarative.Tests/DeclarativeConfigurationReaderTests.cs

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,22 @@ public void Translate_EmptyYaml_ProducesNoKeys()
9595
Assert.Empty(data);
9696
}
9797

98+
[Fact]
99+
public void Translate_NonScalarTopLevelKey_IsIgnoredWithoutThrowing()
100+
{
101+
// YAML supports non-scalar (e.g. sequence) keys via the explicit '? ...' syntax.
102+
// Such a key can never be a valid OTel section name; it must be skipped without throwing.
103+
const string yaml = """
104+
file_format: "1.0"
105+
? [a, b]
106+
: some_value
107+
""";
108+
109+
var data = ReadConfiguration(yaml);
110+
111+
Assert.Empty(data);
112+
}
113+
98114
[Fact]
99115
public void Translate_UnknownTopLevelSection_IsIgnoredWithoutThrowing()
100116
{
@@ -737,6 +753,43 @@ public void Translate_ResourceAttributeNullValue_IsSkipped(string nullValue)
737753
Assert.Equal("service.name=my-service", data[DeclarativeConfigurationConverter.ResourceAttributesKey]);
738754
}
739755

756+
[Fact]
757+
public void Translate_ResourceAttributeMissingValue_IsSkipped()
758+
{
759+
// The absent-value entry is skipped; a valid sibling must still be emitted.
760+
const string yaml = """
761+
file_format: "1.0"
762+
resource:
763+
attributes:
764+
- name: my.attr
765+
- name: service.name
766+
value: my-service
767+
""";
768+
769+
var data = ReadConfiguration(yaml);
770+
771+
Assert.Equal("service.name=my-service", data[DeclarativeConfigurationConverter.ResourceAttributesKey]);
772+
}
773+
774+
[Fact]
775+
public void Translate_ResourceAttributeNonMappingSequenceItem_IsSkipped()
776+
{
777+
// A sequence item that is a scalar (not a mapping) cannot be parsed as an attribute
778+
// entry and is skipped; a valid sibling must still be emitted.
779+
const string yaml = """
780+
file_format: "1.0"
781+
resource:
782+
attributes:
783+
- not-a-mapping
784+
- name: service.name
785+
value: my-service
786+
""";
787+
788+
var data = ReadConfiguration(yaml);
789+
790+
Assert.Equal("service.name=my-service", data[DeclarativeConfigurationConverter.ResourceAttributesKey]);
791+
}
792+
740793
[Theory]
741794
[InlineData("~")]
742795
[InlineData("null")]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright The OpenTelemetry Authors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
#pragma warning disable OTEL1006
5+
6+
using YamlDotNet.RepresentationModel;
7+
8+
namespace OpenTelemetry.Configuration.Declarative.Tests;
9+
10+
public sealed class YamlNodeReaderTests
11+
{
12+
[Fact]
13+
public void GetScalarString_NullScalarValue_ReturnsNull()
14+
{
15+
var scalar = new YamlScalarNode((string?)null);
16+
Assert.Null(scalar.GetScalarString());
17+
}
18+
}

0 commit comments

Comments
 (0)