fix(arm): resolveArmResources returns duplicate resources for versioned specs#4005
fix(arm): resolveArmResources returns duplicate resources for versioned specs#4005
Conversation
…ources Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
…s duplicate ARM resources Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
|
@copilot sample tests are failing |
… changeset description Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Investigated the sample test failures thoroughly. The failures fall into two categories:
I've reverted the incorrect ARM fix from Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot Please create a test that reproduces the issue - the key appears to be that the spec is versioned and contains 2 or more versions when createSDKContext is called. Then please fix the issue so that the test passes. |
|
@copilot also, please ensure to pull the latest from main, ensure that build and tests pass, and that there are no formatting or spelling issues (pnpm format, pnpm cspell) |
…sources in versioned specs Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
Done in commit Fix: Instead of blocking registration of realm types (which broke export function listArmResources(program: Program): ArmResourceDetails[] {
return [...armResourceStateMap(program).values()].filter(
(r) => !unsafe_Realm.realmForType.has(r.typespecType),
);
}This way:
All 270 ARM tests pass, and both regression tests pass with 2-version specs. |
…rm-resources-issue
Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com>
|
All changed packages have been documented.
Show changes
|
|
You can try these changes here
|
| // registers them in the state map alongside the originals, causing duplicates. We keep them | ||
| // registered so that getArmResource() direct lookups still work (used by getArmResourceInfo), | ||
| // but exclude them here so that resolveArmResources returns only the canonical resource list. | ||
| return [...armResourceStateMap(program).values()].filter( |
There was a problem hiding this comment.
Wouldn't it be better here to not use the state map list but iterate over models under the service and filter ones marked with arm resource
There was a problem hiding this comment.
I would worry about the performance in this case, especially since this will get called by linters and the like. Alternatively, we could use a map keyed by resource fully-qualified name and not overwrite existing values. in the setter. This wouldn't require any realm check.
|
@copilot Instead of filtering out all of the mutated resource models from this list, why not change the list to a Map, keying on the namespace-qualified name of the resource, and only add an entry to the map if that key has not been added to the map before? This would ensure that resources were only added to the map once, regardless of whether there were mutated copies of the resource in different realms, and it would not require any use of realms at all in the resource manager code. If this sounds like a reasonable plan, please change the implementation. As always, pull the latest from main, ensure that all tests pass, and ensure that there are no formatting problems using pnpm format. If this is not a reasonable solution, explain why you make that conclusion |
…rm-resources-issue
…ARM resources Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com> Agent-Logs-Url: https://github.com/Azure/typespec-azure/sessions/fda28043-4965-4e62-a337-d4d0bb3dafaf
Implemented in commit |
packages/typespec-azure-resource-manager/src/private.decorators.ts
Outdated
Show resolved
Hide resolved
Co-authored-by: markcowl <1054056+markcowl@users.noreply.github.com> Agent-Logs-Url: https://github.com/Azure/typespec-azure/sessions/97f510ea-0fb2-4301-b853-ae23d5333c5e
Fix
resolveArmResourcesreturning duplicate resources for versioned specs by deduplicating entries inlistArmResourcesusing aSet-based filter keyed by namespace-qualified resource name (first-write-wins). This removes the dependency onunsafe_Realmfrom the resource manager code.Changes Made
listArmResourcesdeduplication: Changed from returning all state map entries to deduplicating bygetTypeName(resource.typespecType)using aSet-based.filter(). Only the first entry per qualified name is kept, so realm copies created by versioning mutations are excluded without any realm checks.unsafe_Realmimport: The resource manager code no longer depends on@typespec/compiler/experimental.Why this approach
Versioning mutations (from TCGC's
createSdkContextor autorest's per-version snapshots) re-apply decorators on realm copies, which registers duplicate entries in the ARM resource state map. By deduplicating on qualified name at read time, we ensure each resource appears exactly once regardless of how many realm copies exist, while keeping all entries in the state map so that directgetArmResource()lookups (used by linter rules) continue to work.Testing
createSdkContextbeforeresolveArmResources)pnpm format)Original prompt
This section details on the original issue you should resolve
<issue_title>[resource-manager] calling TCGC's
createSdkContextchanges the result ofresolveArmResources??</issue_title><issue_description>I have this spec:
and I did this test on it:
where the


createCSharpSdkContextcalls thecreateSdkContextmethod.When I debug the above test, I get 6 resources. The content might also be problematic but not the point of this issue.
If I uncomment the
ppart, when I debug:now we have 4 resources instead.
I was told that TCGC runs mutator - should resource manager library also consider it?
If resource manager library's API is returning an object from typespec which is different from the return value of TCGC, I think it becomes a little bit unreliable.
BTW TCGC has
onValidateruns beforepin the above code, which might be the reason why we have 4 resources instead of 2 (I only defined 2 resources in the spec)So in summary:
we have two layers of issues now.
resolveArmResourcesI get 4 resources, in which, each resource gets a duplicate.resolveArmResourcesafter I called TCGC'screateSdkContext, I get 6 resources, in which each resource gets two duplicates.Maybe currently this issue would not cause an issue, because we are deduplicating them by model's id. But there is concern if one spec has complicated versioning and breaks it.</issue_description>
Comments on the Issue (you are @copilot in this section)
@markcowl Need much more detail on what is actually in the program to start with to have any idea of how tocategorize this. @tadelesh `createSdkContext` API in TCGC uses mutation to get calculate...createSdkContextchanges the result ofresolveArmResources?? #3691🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.