Apply generator fix for extensible enum member normalization collision - #263
Apply generator fix for extensible enum member normalization collision#263David Burg (daviburg) wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates the Connectors SDK to reflect an upstream CodefulSdkGenerator fix for extensible-enum member name normalization collisions (including reserved struct member names), and adds regression tests to lock the Plumsail Timezone extensible-enum member-to-wire-value mapping.
Changes:
- Add
GeneratedEnumMemberTestscovering PlumsailTimezoneserialization/deserialization and equality semantics for selected wire values. - Update
CHANGELOG.mdandrelease_notes.mdto document the upstream generator fix and the empirical scan results.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| tests/Azure.Connectors.Sdk.Tests/GeneratedEnumMemberTests.cs | Adds regression tests asserting stable member↔wire-value mappings for Plumsail Timezone extensible enum. |
| release_notes.md | Documents the generator normalization-collision fix and the empirical scan (no regenerated connectors). |
| CHANGELOG.md | Mirrors the same fix note under [Unreleased] for changelog tracking. |
Suppressed comments (1)
tests/Azure.Connectors.Sdk.Tests/GeneratedEnumMemberTests.cs:104
- These tests introduce single-letter local variables (
a,b). The repo coding guidelines require descriptive, non-abbreviated identifiers; please rename to meaningful names (e.g.,leftTimezone/rightTimezone) to keep tests consistent with the rest of the codebase.
var a = PlumsailTimezone.EtcGMT6;
var b = PlumsailTimezone.EtcGMT7;
Assert.IsTrue(a != b);
Assert.IsFalse(a.Equals(b));
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
ff79a5b to
6d5bd87
Compare
The frozen 2026-08-28 ARM swagger snapshot (cache manifest SHA256 ED9C3FB8911D0F28C8D5038CE33ABEE38F7265D186249C8C66CC5C4B7B7CF2C8) shows Plumsail's Timezone enum contains both Etc/GMT+N and Etc/GMT-N for the same N. These normalize to the same C# identifier (EtcGMTN), causing the pre-fix generator to silently drop the alphabetically-later -N value. Comparison methodology: BPM worktree built twice — once from true pre-fix base d5cb672 (no reserved-name fix, no normalization-collision fix; binary SHA256 61D177482F51C722...) and once from the full-fix tip 07b2718 (binary SHA256 D22694EB1113337C...). Both ran against the same frozen 99-file cache with the 100-connector filter matching all checked-in SDK clients. Of the 97 connectors that generated at both commits (MsGraphGroupsAndUsers failed at both; ConnectorNames/ManagedConnectors skipped by filter), PlumsailExtensions.cs was the only file with a non-encoding-artifact difference. 96 connector clients are byte-identical. The eleven historically-affected connectors (Blackbaudaltruconsti, Blackbaudcrmconstitu, Dataflows, Documentscorepackapi, Dynamicssmbsaas, Etsy, Iaconnectmsoffice, Meisterplan, Powerassist, Tabscannerreceiptocr, Workpoint365) are not present in the current catalog. Changes: - PlumsailExtensions.cs: regenerated from BPM 07b2718 with frozen cache; EtcGMT2-9 and EtcGMT11 now map to +N values (sorted first); 14 new members added for previously-dropped -N values; gen SHA256 CE8A13EDEA... - GeneratedEnumMemberTests.cs: replaced tests that verified the incorrect pre-fix assignment (EtcGMT4 -> "-4") with tests that lock the correct post-fix mapping (EtcGMT4 -> "+4", EtcGMT42 -> "-4", EtcGMT62 -> "-6") - CHANGELOG.md, release_notes.md: corrected to name Plumsail as the one affected client, document the breaking-change set, true baseline d5cb672, and cache provenance; removed incorrect "zero collisions" claim Fixes: #181 Co-authored-by: Dobby <dobby@microsoft.com>
6d5bd87 to
11442d2
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.
Suppressed comments (4)
tests/Azure.Connectors.Sdk.Tests/GeneratedEnumMemberTests.cs:50
- Local variable name 'tz' is an abbreviation; prefer a descriptive local name per repo conventions (complete English terms).
var tz = PlumsailTimezone.EtcGMT42;
Assert.AreEqual(expected: "Etc/GMT-4", actual: (string)tz);
var json = JsonSerializer.Serialize(tz, RelaxedEscapeOptions);
Assert.AreEqual(expected: "\"Etc/GMT-4\"", actual: json);
tests/Azure.Connectors.Sdk.Tests/GeneratedEnumMemberTests.cs:104
- Single-letter locals ('a', 'b') violate the repo naming guideline (no single-letter identifiers). Using descriptive names makes it clearer which value is coming from the known member vs an arbitrary wire value.
var namedMember = PlumsailTimezone.EtcGMT4;
var constructedMember = new PlumsailTimezone("Etc/GMT+4");
Assert.IsTrue(namedMember == constructedMember);
Assert.IsTrue(namedMember.Equals(constructedMember));
tests/Azure.Connectors.Sdk.Tests/GeneratedEnumMemberTests.cs:114
- Single-letter locals ('a', 'b') violate the repo naming guideline (no single-letter identifiers). Descriptive names also help distinguish the +4 and -4 cases at a glance.
var plusFour = PlumsailTimezone.EtcGMT4;
var minusFour = PlumsailTimezone.EtcGMT42;
Assert.IsTrue(plusFour != minusFour);
Assert.IsFalse(plusFour.Equals(minusFour));
tests/Azure.Connectors.Sdk.Tests/GeneratedEnumMemberTests.cs:62
- Local variable name 'tz' is an abbreviation; use a descriptive local name (and similarly rename 'json' to reflect what it contains) to align with the repo naming rules.
var tz = PlumsailTimezone.EtcGMT62;
Assert.AreEqual(expected: "Etc/GMT-6", actual: (string)tz);
var json = JsonSerializer.Serialize(tz, RelaxedEscapeOptions);
Assert.AreEqual(expected: "\"Etc/GMT-6\"", actual: json);
Fix Issue #181: Extensible enum normalization collision — Plumsail regenerated
Problem
The generator assigned C# identifiers to swagger enum values in Swagger-definition order without handling normalization collisions (two values that reduce to the same identifier, e.g.
Etc/GMT+4andEtc/GMT-4both →EtcGMT4). The first claimant silently won; all later claimants were dropped. For reserved struct member names (Equals,GetHashCode,ToString) the generator emitted a property that clashed with mandatory override methods, causing CS0102.Solution
AzureUX-BPM PR 16971205 (commits d5cb672..07b2718; rebased 2026-08-28, current PR tip 96b674e —
git diff 07b2718 96b674e -- src/tools/CodefulSdkGenerator/empty, generator source identical) introduces a two-phase assignment:+4(lower ASCII) ownsEtcGMT4and-4getsEtcGMT42.Empirical audit (Phase 2 methodology)
Built two binaries from the BPM worktree against the same frozen 2026-08-28 ARM swagger cache (99 files, manifest SHA256
ED9C3FB8911D0F28C8D5038CE33ABEE38F7265D186249C8C66CC5C4B7B7CF2C8):61D177482F51C722...D22694EB1113337C...Both ran with
--connectors=<100-client-filter>. 97 connectors generated at both commits (MsGraphGroupsAndUsersfailed at both;ConnectorNames/ManagedConnectorsskipped by filter). 96 clients are byte-identical. One client differs: PlumsailExtensions.cs.Historical connector audit
The eleven connectors named in the original issue as affected by the reserved-name variant (Blackbaudaltruconsti, Blackbaudcrmconstitu, Dataflows, Documentscorepackapi, Dynamicssmbsaas, Etsy, Iaconnectmsoffice, Meisterplan, Powerassist, Tabscannerreceiptocr, Workpoint365):
Affected connector: Plumsail
The Plumsail swagger (frozen 2026-08-28) contains both
Etc/GMT+NandEtc/GMT-Nfor the same N. At the true baseline (d5cb672),-Nvalues were first in Swagger order for most entries and claimed the clean identifier; the+Nvalues were silently dropped. The fix recovers 14 dropped values and reassigns 7 identifiers to the correct+Nwire value.PlumsailExtensions.cs SHA256:
CE8A13EDEAB683099A0D319A3225ED61AF52AE90E44870EE46038552BAD6F1C8(generated from BPM 07b2718; BPM PR rebased to 96b674e with identical generator source).Changes
src/Azure.Connectors.Sdk/Generated/PlumsailExtensions.cs: regenerated; 14 new Timezone members added for previously-dropped wire values; 7 existing members (EtcGMT2,EtcGMT3,EtcGMT4,EtcGMT7,EtcGMT8,EtcGMT9,EtcGMT11) now map to the+Nwire value (breaking change for callers).tests/Azure.Connectors.Sdk.Tests/GeneratedEnumMemberTests.cs: replaced tests that locked the incorrect pre-fix assignment (EtcGMT4→"-4") with tests that lock the correct post-fix contract (EtcGMT4→"+4",EtcGMT42→"-4",EtcGMT62→"-6").CHANGELOG.md,release_notes.md: corrected to name Plumsail as the one affected client, document the breaking-change set, true baseline d5cb672, and cache provenance.Validation
dotnet format --verify-no-changes: cleangit diff --check: cleanFixes #181