Skip to content

Commit f12322c

Browse files
committed
fix(otlp): add explicit test case for negative structured metadata bytes
Signed-off-by: Jordan Rushing <[email protected]>
1 parent da2751b commit f12322c

File tree

1 file changed

+82
-2
lines changed

1 file changed

+82
-2
lines changed

pkg/loghttp/push/otlp_test.go

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -975,8 +975,6 @@ func TestOTLPLogAttributesAsIndexLabels(t *testing.T) {
975975
func TestOTLPStructuredMetadataCalculation(t *testing.T) {
976976
now := time.Unix(0, time.Now().UnixNano())
977977

978-
// Create test with resource, scope, and entry metadata that would previously cause negative calculations
979-
// when subtracting resource/scope attribute sizes from the total structured metadata size
980978
generateLogs := func() plog.Logs {
981979
ld := plog.NewLogs()
982980

@@ -1057,6 +1055,88 @@ func TestOTLPStructuredMetadataCalculation(t *testing.T) {
10571055
require.True(t, entryMetadataFound, "Entry metadata should be present in the entry")
10581056
}
10591057

1058+
func TestNegativeMetadataScenarioExplicit(t *testing.T) {
1059+
// This test explicitly demonstrates how negative structured metadata size values
1060+
// could occur when subtracting resource/scope attributes from total structured metadata size
1061+
1062+
// Setup: Create metadata with a label that would be excluded from size calculation
1063+
resourceMeta := push.LabelsAdapter{
1064+
{Name: "resource_key", Value: "resource_value"}, // 27 bytes
1065+
{Name: "excluded_label", Value: "value"}, // This would be excluded from size calculation
1066+
}
1067+
1068+
scopeMeta := push.LabelsAdapter{
1069+
{Name: "scope_key", Value: "scope_value"}, // 21 bytes
1070+
}
1071+
1072+
entryMeta := push.LabelsAdapter{
1073+
{Name: "entry_key", Value: "entry_value"}, // 21 bytes
1074+
}
1075+
1076+
// ExcludedStructuredMetadataLabels would exclude certain labels
1077+
// from size calculations.
1078+
calculateSize := func(labels push.LabelsAdapter) int {
1079+
size := 0
1080+
for _, label := range labels {
1081+
// Simulate a label being excluded from size calc
1082+
if label.Name != "excluded_label" {
1083+
size += len(label.Name) + len(label.Value)
1084+
}
1085+
}
1086+
return size
1087+
}
1088+
1089+
// Calculate sizes with simulated exclusions
1090+
resourceSize := calculateSize(resourceMeta) // 27 bytes (excluded_label not counted)
1091+
scopeSize := calculateSize(scopeMeta) // 21 bytes
1092+
entrySize := calculateSize(entryMeta) // 21 bytes
1093+
1094+
// The original approach:
1095+
// 1. Add resource and scope attributes to entry metadata
1096+
combined := make(push.LabelsAdapter, 0)
1097+
combined = append(combined, entryMeta...)
1098+
combined = append(combined, resourceMeta...)
1099+
combined = append(combined, scopeMeta...)
1100+
1101+
// 2. Calculate combined size (with certain labels excluded)
1102+
combinedSize := calculateSize(combined) // Should be 27 + 21 + 21 = 69 bytes
1103+
1104+
// 3. Calculate entry-specific metadata by subtraction
1105+
// metadataSize := int64(combinedSize - resourceSize - scopeSize)
1106+
oldCalculation := combinedSize - resourceSize - scopeSize
1107+
1108+
// Should be: 69 - 27 - 21 = 21 bytes, which equals entrySize
1109+
1110+
t.Logf("Resource size: %d bytes", resourceSize)
1111+
t.Logf("Scope size: %d bytes", scopeSize)
1112+
t.Logf("Entry size: %d bytes", entrySize)
1113+
t.Logf("Combined size: %d bytes", combinedSize)
1114+
t.Logf("Old calculation (combined - resource - scope): %d bytes", oldCalculation)
1115+
1116+
// Now, to demonstrate how this could produce negative values:
1117+
// In reality, due to potential inconsistencies in how labels were excluded/combined/normalized,
1118+
// the combined size could be LESS than the sum of parts
1119+
simulatedRealCombinedSize := resourceSize + scopeSize - 5 // 5 bytes less than sum
1120+
1121+
// Using the original calculation method:
1122+
simulatedRealCalculation := simulatedRealCombinedSize - resourceSize - scopeSize
1123+
// This will be: (27 + 21 - 5) - 27 - 21 = 43 - 48 = -5 bytes
1124+
1125+
t.Logf("Simulated real combined size: %d bytes", simulatedRealCombinedSize)
1126+
t.Logf("Simulated real calculation (old method): %d bytes", simulatedRealCalculation)
1127+
1128+
// This would be a negative value!
1129+
require.Less(t, simulatedRealCalculation, 0,
1130+
"This demonstrates how the old calculation could produce negative values")
1131+
1132+
// Directly use entry's size before combining
1133+
t.Logf("New calculation (direct entry size): %d bytes", entrySize)
1134+
require.Equal(t, entrySize, 20,
1135+
"New calculation provides correct entry size")
1136+
require.Greater(t, entrySize, 0,
1137+
"New calculation always produces non-negative values")
1138+
}
1139+
10601140
func TestOTLPSeverityTextAsLabel(t *testing.T) {
10611141
now := time.Unix(0, time.Now().UnixNano())
10621142

0 commit comments

Comments
 (0)