Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions sdk/resourcemanager/azure-resourcemanager-test/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Release History

## 2.0.0-beta.1 (Unreleased)
## 2.0.0-beta.1 (2025-08-12)

- TODO
### Features Added

- Initial release of the `azure-resourcemanager-test` library.
151 changes: 145 additions & 6 deletions sdk/resourcemanager/azure-resourcemanager-test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,159 @@ For documentation on how to use this package, please see [Azure Management Libra
```
[//]: # ({x-version-update-end})

### (Optional) Install TestProxy

TestProxy will be automatically downloaded when running tests. Though you may need to install it to push the recordings to remote repository.
Refer to [TestProxy documentation](https://github.com/Azure/azure-sdk-tools/blob/main/tools/test-proxy/Azure.Sdk.Tools.TestProxy/README.md).

## Key concepts

The Azure Resource Manager Test library provides a specialized test base class and utilities for testing Azure Resource Manager SDKs. It extends the core testing framework with ARM-specific functionality.

### Core Components

* **ResourceManagerTestProxyTestBase**: The main test base class that provides Azure Resource Manager-specific testing capabilities. It extends `TestProxyTestBase` from azure-core-test and adds:
- Azure credential management using `DefaultAzureCredential`
- Azure profile configuration with tenant, subscription, and environment
- HTTP pipeline configuration with Azure-specific policies
- Built-in sanitizers for common Azure secrets and sensitive data
- Resource naming utilities for generating unique test resource names

* **Test Modes**: Like the core test framework, supports three test modes:
- **LIVE**: Tests run against actual Azure resources
- **RECORD**: Tests run against Azure resources and HTTP interactions are recorded
- **PLAYBACK**: Tests use recorded HTTP interactions without hitting Azure services

* **Azure-specific Sanitization**: Automatically sanitizes common Azure secrets including:
- Subscription IDs, tenant IDs, and client IDs
- Storage account keys and connection strings
- Database passwords and connection strings
- Service principal secrets and certificates
- API keys and access tokens

### Test Environment Setup

For LIVE/RECORD tests, you need:
1. Azure CLI authentication (`az login`)
2. Environment variables:
- `AZURE_TENANT_ID`: Your Azure tenant ID
- `AZURE_SUBSCRIPTION_ID`: Your target subscription ID
- `AZURE_CLIENT_ID` and `AZURE_CLIENT_SECRET`: Service principal credentials (optional if using Azure CLI)

### Utility Methods

The base class provides several utility methods:
- `generateRandomResourceName(prefix, maxLen)`: Creates unique resource names for tests
- `generateRandomUuid()`: Generates random UUIDs
- `password()`: Generates random passwords for test resources
- `sshPublicKey()`: Generates SSH public keys for VM tests
- `profile()`: Access to the Azure profile being used
- `isPlaybackMode()`: Check if running in playback mode
- `skipInPlayback()`: Skip test execution in playback mode

## Examples

Here's how to create a test class for RECORD/PLAYBACK using ResourceManagerTestProxyTestBase:

### For azure-resourcemanager libraries

```java
public class AzureResourceManagerTests extends ResourceManagerTestProxyTestBase {
private AzureResourceManager manager;
private ResourceManager resourceManager;
private String resourceGroupName;

public MyServiceManagerTests() {
// Add any custom sanitizers in constructor
addSanitizers(
new TestProxySanitizer("$.properties.customSecret", null, REDACTED_VALUE, TestProxySanitizerType.BODY_KEY)
);
}

@Override
protected HttpPipeline buildHttpPipeline(TokenCredential credential, AzureProfile profile,
HttpLogOptions httpLogOptions, List<HttpPipelinePolicy> policies, HttpClient httpClient) {
// Build HTTP pipeline with your service-specific requirements
return HttpPipelineProvider.buildHttpPipeline(credential, profile, null, httpLogOptions, null,
new RetryPolicy("Retry-After", ChronoUnit.SECONDS), policies, httpClient);
}

@Override
protected void initializeClients(HttpPipeline httpPipeline, AzureProfile profile) {
// Set up correct delay configuration for recording/playback. In RECORD mode, LROs (long-running operations) need a configured delay between each polling. While in PLAYBACK, no delay is needed.
ResourceManagerUtils.InternalRuntimeContext.setDelayProvider(new TestDelayProvider(!isPlaybackMode()));
ResourceManagerUtils.InternalRuntimeContext internalContext = new ResourceManagerUtils.InternalRuntimeContext();
// Set up namer context for recording/playback, in case random names are used for implicit resource creation. Otherwise, PLAYBACK won't be able to pick up the names during RECORD.
internalContext.setIdentifierFunction(name -> new TestIdentifierProvider(testResourceNamer));

// Initialize your service manager and any other required clients
resourceManager = ResourceManager.authenticate(httpPipeline, profile).withDefaultSubscription();
manager = AzureResourceManager.authenticate(httpPipeline, profile);

// Reflectively set the test context for Manager classes
setInternalContext(internalContext, manager, resourceManager);

// Generate resource group name for tests
resourceGroupName = generateRandomResourceName("rg", 20);
}

@Override
protected void cleanUpResources() {
// Clean up any resources created during tests
resourceManager.resourceGroups().beginDeleteByName(resourceGroupName);
}

@Test
public void testCreateResource() {
// Write your own test case here
}
}
```

### For libraries not listed in azure-resourcemanager

Mostly same as [For azure-resourcemanager libraries](#for-azure-resourcemanager-libraries).
Except that in `initializeClient`, you'll need to set the defaultPollInterval in the entry class(XXManager).
```java
ContainerAppsApiManager manager = ContainerAppsApiManager
.configure()
.withDefaultPollInterval(ResourceManagerUtils.InternalRuntimeContext.getDelayDuration(Duration.ofSeconds(30)))
.withHttpClient(httpPipeline.getHttpClient())
.authenticate(new DefaultAzureCredentialBuilder().build(), profile);

// instead of ContainerAppsApiManager.authenticate(httpPipeline, profile);
```

## Troubleshooting

## Next steps
### Common Issues

**Authentication Errors in Live/Record Mode**
- Ensure you have run `az login` and have valid Azure credentials
- Verify that `AZURE_TENANT_ID` and `AZURE_SUBSCRIPTION_ID` environment variables are set
- Check that your account has sufficient permissions in the target subscription

**Recording Issues**
- Recordings may contain secrets if sanitizers are not properly configured

**Resource Naming Conflicts**
- Use `generateRandomResourceName()` to ensure unique resource names
- Be aware that some Azure resources require globally unique names
- Clean up resources properly in `cleanUpResources()` to avoid conflicts

### Debug Options

Enable detailed HTTP logging by setting the `AZURE_TEST_LOG_LEVEL` environment variable:
```bash
export AZURE_TEST_LOG_LEVEL=BODY_AND_HEADERS
```

## Contributing

For details on contributing to this repository, see the [contributing guide](https://github.com/Azure/azure-sdk-for-java/blob/main/CONTRIBUTING.md).

1. Fork it
1. Create your feature branch (`git checkout -b my-new-feature`)
1. Commit your changes (`git commit -am 'Add some feature'`)
1. Push to the branch (`git push origin my-new-feature`)
1. Create new Pull Request
- Fork it
- Create your feature branch (`git checkout -b my-new-feature`)
- Commit your changes (`git commit -am 'Add some feature'`)
- Push to the branch (`git push origin my-new-feature`)
- Create new Pull Request
11 changes: 8 additions & 3 deletions sdk/resourcemanager/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,10 @@ parameters:
displayName: 'azure-resourcemanager-trafficmanager'
type: boolean
default: true
- name: release_azureresourcemanagertest
displayName: 'azure-resourcemanager-test'
type: boolean
default: false

extends:
template: ../../eng/pipelines/templates/stages/archetype-sdk-client.yml
Expand Down Expand Up @@ -268,14 +272,15 @@ extends:
groupId: com.azure.resourcemanager
safeName: azureresourcemanagertrafficmanager
releaseInBatch: ${{ parameters.release_azureresourcemanagertrafficmanager }}
- name: azure-resourcemanager-test
groupId: com.azure.resourcemanager
safeName: azureresourcemanagertest
releaseInBatch: ${{ parameters.release_azureresourcemanagertest }}
AdditionalModules:
- name: azure-resourcemanager-samples
groupId: com.azure.resourcemanager
safeName: azureresourcemanagersamples
- name: azure-resourcemanager-perf
groupId: com.azure.resourcemanager
- name: azure-resourcemanager-test
groupId: com.azure.resourcemanager
# required by the above perf library
- name: perf-test-core
groupId: com.azure