Skip to content

Commit f16d005

Browse files
committed
remove SetExecutionEnvironment calls from various classes and add EnvWrapperTests for environment variable validation
1 parent 92316fd commit f16d005

File tree

4 files changed

+259
-6
lines changed

4 files changed

+259
-6
lines changed

libraries/src/AWS.Lambda.Powertools.EventHandler.Resolvers.BedrockAgentFunction/BedrockAgentFunctionResolver.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ private readonly
4040
public BedrockAgentFunctionResolver(IJsonTypeInfoResolver? typeResolver = null)
4141
{
4242
_parameterMapper = new ParameterMapper(typeResolver);
43-
PowertoolsEnvironment.Instance.SetExecutionEnvironment(this);
4443
}
4544

4645
/// <summary>

libraries/src/AWS.Lambda.Powertools.EventHandler/AppSyncEvents/AppSyncEventsResolver.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Amazon.Lambda.Core;
2-
using AWS.Lambda.Powertools.Common;
32
using AWS.Lambda.Powertools.EventHandler.Internal;
43

54
namespace AWS.Lambda.Powertools.EventHandler.AppSyncEvents;
@@ -21,7 +20,6 @@ public AppSyncEventsResolver()
2120
{
2221
_publishRoutes = new RouteHandlerRegistry<AppSyncEventsRequest, object>();
2322
_subscribeRoutes = new RouteHandlerRegistry<AppSyncEventsRequest, bool>();
24-
PowertoolsEnvironment.Instance.SetExecutionEnvironment(this);
2523
}
2624

2725
#region OnPublish Methods

libraries/src/AWS.Lambda.Powertools.Kafka/PowertoolsKafkaSerializerBase.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
using System.Text.Json;
77
using System.Text.Json.Serialization;
88
using System.Text.Json.Serialization.Metadata;
9-
using AWS.Lambda.Powertools.Common;
109

1110
#if KAFKA_JSON
1211
namespace AWS.Lambda.Powertools.Kafka.Json;
@@ -77,8 +76,6 @@ protected PowertoolsKafkaSerializerBase(JsonSerializerOptions jsonOptions, JsonS
7776
{
7877
JsonOptions = jsonOptions ?? new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
7978
SerializerContext = serializerContext;
80-
81-
PowertoolsEnvironment.Instance.SetExecutionEnvironment(this);
8279
}
8380

8481
/// <summary>
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
using System;
2+
using System.Text.RegularExpressions;
3+
using AWS.Lambda.Powertools.Common;
4+
using AWS.Lambda.Powertools.Logging.Internal;
5+
using AWS.Lambda.Powertools.Tracing.Internal;
6+
using AWS.Lambda.Powertools.BatchProcessing.Internal;
7+
using AWS.Lambda.Powertools.Idempotency.Internal;
8+
using AWS.Lambda.Powertools.Metrics.Internal;
9+
using AWS.Lambda.Powertools.Parameters.Internal;
10+
using AWS.Lambda.Powertools.EventHandler.Internal;
11+
using AWS.Lambda.Powertools.EventHandler.Resolvers.BedrockAgentFunction.Internal;
12+
using AWS.Lambda.Powertools.Kafka.Avro.Internal;
13+
using AWS.Lambda.Powertools.Kafka.Json.Internal;
14+
using AWS.Lambda.Powertools.Kafka.Protobuf.Internal;
15+
using Xunit;
16+
using Xunit.Abstractions;
17+
18+
namespace AWS.Lambda.Powertools.ModuleInitializer.Tests;
19+
20+
public class EnvWrapperTests
21+
{
22+
private readonly ITestOutputHelper _output;
23+
private readonly string? _appId;
24+
25+
public EnvWrapperTests(ITestOutputHelper output)
26+
{
27+
_output = output;
28+
29+
// Clear any existing environment variable to start fresh
30+
Environment.SetEnvironmentVariable("AWS_SDK_UA_APP_ID", null);
31+
32+
// Call the method we want to test - this should set the environment variable
33+
AWS.Lambda.Powertools.Logging.Internal.EnvWrapper.SetExecutionEnvironment();
34+
35+
_appId = Environment.GetEnvironmentVariable("AWS_SDK_UA_APP_ID");
36+
37+
// Log the current state for debugging
38+
_output.WriteLine($"AWS_SDK_UA_APP_ID after SetExecutionEnvironment(): '{_appId ?? "null"}'");
39+
}
40+
41+
[Fact]
42+
public void SetExecutionEnvironment_Should_Set_AWS_SDK_UA_APP_ID()
43+
{
44+
// Verify that calling SetExecutionEnvironment() sets the environment variable
45+
Assert.NotNull(_appId);
46+
Assert.NotEmpty(_appId);
47+
_output.WriteLine($"Environment variable set: {_appId}");
48+
}
49+
50+
[Fact]
51+
public void Is_PTENV_Set()
52+
{
53+
Assert.NotNull(_appId);
54+
Assert.Contains("PTENV/", _appId);
55+
_output.WriteLine(_appId);
56+
// check that it is last in the string
57+
Assert.EndsWith("PTENV/", _appId, StringComparison.OrdinalIgnoreCase);
58+
}
59+
60+
[Fact]
61+
public void SetExecutionEnvironment_Should_Set_Logging_Utility()
62+
{
63+
// Since we're calling EnvWrapper from the Logging library, it should set the Logging utility
64+
Assert.NotNull(_appId);
65+
Assert.Contains("PT/Logging/", _appId);
66+
_output.WriteLine($"Environment variable contains Logging utility: {_appId}");
67+
}
68+
69+
[Fact]
70+
public void SetExecutionEnvironment_Should_Have_Correct_Format()
71+
{
72+
Assert.NotNull(_appId);
73+
74+
// Should end with PTENV/
75+
Assert.EndsWith("PTENV/", _appId);
76+
77+
// Should contain at least one PT/ entry
78+
var ptEntries = Regex.Matches(_appId, @"PT/[^/]+/\d+\.\d+\.\d+");
79+
Assert.True(ptEntries.Count >= 1, $"Expected at least 1 PT/ entry, found {ptEntries.Count}");
80+
81+
_output.WriteLine($"Found {ptEntries.Count} PT/ entries in the environment variable");
82+
}
83+
84+
[Fact]
85+
public void SetExecutionEnvironment_Should_Include_Version_Number()
86+
{
87+
Assert.NotNull(_appId);
88+
89+
// Should contain a version number in the format x.y.z
90+
var versionPattern = @"PT/Logging/\d+\.\d+\.\d+";
91+
Assert.Matches(versionPattern, _appId);
92+
93+
_output.WriteLine($"Environment variable contains version: {_appId}");
94+
}
95+
96+
[Fact]
97+
public void SetExecutionEnvironment_Should_Only_Include_Logging_Once()
98+
{
99+
Assert.NotNull(_appId);
100+
101+
// Check that Logging utility appears exactly once
102+
var pattern = @"PT/Logging/\d+\.\d+\.\d+";
103+
var matches = Regex.Matches(_appId, pattern);
104+
Assert.Single(matches);
105+
106+
_output.WriteLine($"Logging utility appears exactly once: {matches[0].Value}");
107+
}
108+
109+
[Fact]
110+
public void SetExecutionEnvironment_Multiple_Calls_Should_Not_Duplicate()
111+
{
112+
// Clear and call multiple times to ensure no duplication
113+
Environment.SetEnvironmentVariable("AWS_SDK_UA_APP_ID", null);
114+
115+
AWS.Lambda.Powertools.Logging.Internal.EnvWrapper.SetExecutionEnvironment();
116+
var firstCall = Environment.GetEnvironmentVariable("AWS_SDK_UA_APP_ID");
117+
118+
AWS.Lambda.Powertools.Logging.Internal.EnvWrapper.SetExecutionEnvironment();
119+
var secondCall = Environment.GetEnvironmentVariable("AWS_SDK_UA_APP_ID");
120+
121+
// Both calls should produce the same result (no duplication)
122+
Assert.Equal(firstCall, secondCall);
123+
124+
_output.WriteLine($"First call: {firstCall}");
125+
_output.WriteLine($"Second call: {secondCall}");
126+
}
127+
128+
[Fact]
129+
public void SetExecutionEnvironment_All_Libraries_Should_Set_All_Utilities()
130+
{
131+
// Clear environment variable to start fresh
132+
Environment.SetEnvironmentVariable("AWS_SDK_UA_APP_ID", null);
133+
134+
// Call SetExecutionEnvironment from all EnvWrapper classes to simulate
135+
// what would happen when all libraries are used in a real application
136+
AWS.Lambda.Powertools.Logging.Internal.EnvWrapper.SetExecutionEnvironment();
137+
AWS.Lambda.Powertools.Tracing.Internal.EnvWrapper.SetExecutionEnvironment();
138+
AWS.Lambda.Powertools.BatchProcessing.Internal.EnvWrapper.SetExecutionEnvironment();
139+
AWS.Lambda.Powertools.Idempotency.Internal.EnvWrapper.SetExecutionEnvironment();
140+
AWS.Lambda.Powertools.Metrics.Internal.EnvWrapper.SetExecutionEnvironment();
141+
AWS.Lambda.Powertools.Parameters.Internal.EnvWrapper.SetExecutionEnvironment();
142+
AWS.Lambda.Powertools.EventHandler.Internal.EnvWrapper.SetExecutionEnvironment();
143+
AWS.Lambda.Powertools.EventHandler.Resolvers.BedrockAgentFunction.Internal.EnvWrapper.SetExecutionEnvironment();
144+
AWS.Lambda.Powertools.Kafka.Avro.Internal.EnvWrapper.SetExecutionEnvironment();
145+
AWS.Lambda.Powertools.Kafka.Json.Internal.EnvWrapper.SetExecutionEnvironment();
146+
AWS.Lambda.Powertools.Kafka.Protobuf.Internal.EnvWrapper.SetExecutionEnvironment();
147+
148+
var appId = Environment.GetEnvironmentVariable("AWS_SDK_UA_APP_ID");
149+
Assert.NotNull(appId);
150+
151+
_output.WriteLine($"Complete environment variable: {appId}");
152+
153+
// Verify all expected utilities are present
154+
var expectedUtilities = new[]
155+
{
156+
"Logging",
157+
"Tracing",
158+
"BatchProcessing",
159+
"Idempotency",
160+
"Metrics",
161+
"Parameters",
162+
"EventHandler",
163+
"BedrockAgentFunction",
164+
"Kafka.Avro",
165+
"Kafka.Json",
166+
"Kafka.Protobuf"
167+
};
168+
169+
foreach (var utility in expectedUtilities)
170+
{
171+
Assert.Contains($"PT/{utility}/", appId);
172+
_output.WriteLine($"✓ Found utility: {utility}");
173+
}
174+
175+
// Verify PTENV/ is at the end
176+
Assert.EndsWith("PTENV/", appId);
177+
178+
// Verify each utility appears exactly once
179+
foreach (var utility in expectedUtilities)
180+
{
181+
var pattern = $@"PT/{Regex.Escape(utility)}/\d+\.\d+\.\d+";
182+
var matches = Regex.Matches(appId, pattern);
183+
Assert.Single(matches);
184+
}
185+
186+
// Count total PT/ entries
187+
var ptEntries = Regex.Matches(appId, @"PT/[^/]+/\d+\.\d+\.\d+");
188+
Assert.Equal(expectedUtilities.Length, ptEntries.Count);
189+
190+
_output.WriteLine($"Total utilities found: {ptEntries.Count}");
191+
}
192+
193+
[Theory]
194+
[InlineData("Logging")]
195+
[InlineData("Tracing")]
196+
[InlineData("BatchProcessing")]
197+
[InlineData("Idempotency")]
198+
[InlineData("Metrics")]
199+
[InlineData("Parameters")]
200+
[InlineData("EventHandler")]
201+
[InlineData("BedrockAgentFunction")]
202+
[InlineData("Kafka.Avro")]
203+
[InlineData("Kafka.Json")]
204+
[InlineData("Kafka.Protobuf")]
205+
public void SetExecutionEnvironment_Individual_Library_Should_Set_Specific_Utility(string expectedUtility)
206+
{
207+
// Clear environment variable
208+
Environment.SetEnvironmentVariable("AWS_SDK_UA_APP_ID", null);
209+
210+
// Call the appropriate EnvWrapper based on the utility name
211+
switch (expectedUtility)
212+
{
213+
case "Logging":
214+
AWS.Lambda.Powertools.Logging.Internal.EnvWrapper.SetExecutionEnvironment();
215+
break;
216+
case "Tracing":
217+
AWS.Lambda.Powertools.Tracing.Internal.EnvWrapper.SetExecutionEnvironment();
218+
break;
219+
case "BatchProcessing":
220+
AWS.Lambda.Powertools.BatchProcessing.Internal.EnvWrapper.SetExecutionEnvironment();
221+
break;
222+
case "Idempotency":
223+
AWS.Lambda.Powertools.Idempotency.Internal.EnvWrapper.SetExecutionEnvironment();
224+
break;
225+
case "Metrics":
226+
AWS.Lambda.Powertools.Metrics.Internal.EnvWrapper.SetExecutionEnvironment();
227+
break;
228+
case "Parameters":
229+
AWS.Lambda.Powertools.Parameters.Internal.EnvWrapper.SetExecutionEnvironment();
230+
break;
231+
case "EventHandler":
232+
AWS.Lambda.Powertools.EventHandler.Internal.EnvWrapper.SetExecutionEnvironment();
233+
break;
234+
case "BedrockAgentFunction":
235+
AWS.Lambda.Powertools.EventHandler.Resolvers.BedrockAgentFunction.Internal.EnvWrapper.SetExecutionEnvironment();
236+
break;
237+
case "Kafka.Avro":
238+
AWS.Lambda.Powertools.Kafka.Avro.Internal.EnvWrapper.SetExecutionEnvironment();
239+
break;
240+
case "Kafka.Json":
241+
AWS.Lambda.Powertools.Kafka.Json.Internal.EnvWrapper.SetExecutionEnvironment();
242+
break;
243+
case "Kafka.Protobuf":
244+
AWS.Lambda.Powertools.Kafka.Protobuf.Internal.EnvWrapper.SetExecutionEnvironment();
245+
break;
246+
}
247+
248+
var appId = Environment.GetEnvironmentVariable("AWS_SDK_UA_APP_ID");
249+
Assert.NotNull(appId);
250+
251+
// Verify the specific utility is present
252+
Assert.Contains($"PT/{expectedUtility}/", appId);
253+
254+
// Verify PTENV/ is at the end
255+
Assert.EndsWith("PTENV/", appId);
256+
257+
_output.WriteLine($"Testing {expectedUtility}: {appId}");
258+
}
259+
}

0 commit comments

Comments
 (0)