Skip to content

Commit

Permalink
Implement per-service test setup (#1985)
Browse files Browse the repository at this point in the history
* Implement per-service test setup

* Removed one spurious .net reference
  • Loading branch information
LarryOsterman authored Jan 15, 2025
1 parent 6d1f558 commit 6d89f3a
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 40 deletions.
2 changes: 1 addition & 1 deletion SUPPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ To ensure the relevance and manageability of our issue queue, we have an automat

- Take a look at the [Azure SDK blog](https://devblogs.microsoft.com/azure-sdk/).
- Search for similar issues in [our GitHub repository](https://github.com/Azure/azure-sdk-for-rust/issues)
- Ask a question on [StackOverflow](https://stackoverflow.com/questions/tagged/azure-sdk-rust) and tag it with azure-sdk-.net
- Ask a question on [StackOverflow](https://stackoverflow.com/questions/tagged/azure-sdk-rust) and tag it with azure-sdk-rust
- Share or upvote feature requests on [Feedback Page](https://feedback.azure.com/forums/34192--general-feedback).
- Ask a question on [Twitter](https://twitter.com/AzureSDK)
- Ask a question at [Microsoft Q&A](https://learn.microsoft.com/answers/products/azure?WT.mc_id=Portal-Microsoft_Azure_Support&product=all)
Expand Down
20 changes: 20 additions & 0 deletions eng/scripts/Test-Packages.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ $env:RUSTFLAGS = "-Dwarnings"
foreach ($package in $packagesToTest) {
Push-Location ([System.IO.Path]::Combine($RepoRoot, $package.DirectoryPath))
try {
$packageDirectory = ([System.IO.Path]::Combine($RepoRoot, $package.DirectoryPath))

$setupScript = Join-Path $packageDirectory "Test-Setup.ps1"
if (Test-Path $setupScript) {
Write-Host "`n`nRunning test setup script for package: '$($package.Name)'`n"
Invoke-LoggedCommand $setupScript
if (!$? -ne 0) {
Write-Error "Test setup script failed for package: '$($package.Name)'"
exit 1
}
}

Write-Host "`n`nTesting package: '$($package.Name)'`n"

Invoke-LoggedCommand "cargo +$Toolchain build --keep-going"
Expand All @@ -68,6 +80,14 @@ foreach ($package in $packagesToTest) {

Invoke-LoggedCommand "cargo +$Toolchain test --doc --no-fail-fast"
Write-Host "`n`n"

$cleanupScript = Join-Path $packageDirectory "Test-Cleanup.ps1"
if (Test-Path $cleanupScript) {
Write-Host "`n`nRunning test cleanup script for package: '$($package.Name)'`n"
Invoke-LoggedCommand $cleanupScript
# We ignore the exit code of the cleanup script.

}
}
finally {
Pop-Location
Expand Down
70 changes: 58 additions & 12 deletions sdk/core/azure_core_amqp/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,69 @@ NOTE: THIS IS NOT A GENERAL PURPOSE AMQP LIBRARY AND SHOULD NOT BE USED AS SUCH.

This crate is part of a collection of crates: for more information please refer to [https://github.com/azure/azure-sdk-for-rust](https://github.com/azure/azure-sdk-for-rust).

## Example
## Testing the AMQP Client.

```rust,no_run
use azure_messaging::*;
The AMQP package is tested using the standard `cargo test` command line:

#[tokio::main]
async fn main() -> azure_core::Result<()> {
let eventhubs_namespace = std::env::var("AZURE_EVENTHUB_NAMESPACE").expect("missing AZURE_EVENTHUB_NAMESPACE");
```bash
cargo test --package azure_core_amqp --all-features
```

Certain AMQP tests requires that there be a running AMQP broker on the machine at the time of the test (the tests will run without the broker, the relevant tests will just be skipped).

One existing AMQP broker is the "TestAMQPBroker" from the azure-amqp GitHub repository.

To launch the TestAMQPBroker, there are two ways of installing and running the TestAmqpBroker, Scripted and Manual.

### Scripted Broker Install
Running the broker from a script requires that you first [install Powershell](https://learn.microsoft.com/powershell/scripting/install/installing-powershell?view=powershell-7.4).
From a running powershell instance, run the powershell script in the sdk/core/azure_core_amqp directory:

```
./sdk/core/azure_core_amqp/Test-Setup.ps1
```

This will download the TestAmqpBroker, build it and launch the executable in the background.

Note that this requires that you have the [.NET SDK](https://dot.net/download) installed on your machine.

You can then run the azure_core_amqp package tests.

Once you have finished running your tests, you run:

```
./sdk/core/azure_core_amqp/Test-Cleanup.ps1
```

let client = ProducerClient::new(
eventhubs_namespace, credential,
)?;
which will terminate the test broker.

client.send_event("hello world").await?;
### Manual Broker Install
For Manual testing, first clone the azure-amqp repository to a local directory:

Ok(())
}
```bash
cd <Test Working Directory>
git clone https://github.com/Azure/azure-amqp
```

Alternately, you can clone to a specific release in the azure-amqp repository:

```
git clone https://github.com/Azure/azure-amqp.git --branch hotfix
```

Set an environment variable the test AMQP broker should listen on:

```powershell
$env:TEST_BROKER_ADDRESS = 'amqp://127.0.0.1:25672'
```

And launch the test broker:

```powershell
cd azure-amqp/test/TestAmqpBroker
dotnet run -- $env:TEST_BROKER_ADDRESS
```

Now, when you run the cargo tests, the networking functionality of the AMQP APIs will be executed.

License: MIT
21 changes: 21 additions & 0 deletions sdk/core/azure_core_amqp/Test-Cleanup.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
# cspell: ignore JOBID

. "$PSScriptRoot\..\..\..\eng\common\scripts\common.ps1"

Write-Host "Test Broker output:"
Receive-Job -Id $env:TEST_BROKER_JOBID

# Check if the test broker job is still running
$job = Get-Job -Id $env:TEST_BROKER_JOBID
if ($job.State -ne "Running") {
Write-Host "Test broker terminated unexpectedly."
exit 1
}

# Stop the test broker job started in Test-Setup.ps1
Write-Host "Stopping test broker"
Stop-Job -Id $env:TEST_BROKER_JOBID
Remove-Job -Id $env:TEST_BROKER_JOBID
Write-Host "Test broker stopped."
69 changes: 69 additions & 0 deletions sdk/core/azure_core_amqp/Test-Setup.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
# cspell: ignore JOBID depsfile


# Load common ES scripts
. "$PSScriptRoot\..\..\..\eng\common\scripts\common.ps1"

# Create the test binary *outside* the repo root to avoid polluting the repo.
$WorkingDirectory = ([System.IO.Path]::Combine($RepoRoot, "../TestArtifacts"))

# Create the working directory if it does not exist.
Write-Host "Using Working Directory $WorkingDirectory"

if (-not (Test-Path $WorkingDirectory)) {
Write-Host "Working directory does not exist, creating working directory: $WorkingDirectory"
New-Item -ItemType Directory -Path $WorkingDirectory
}

Write-Host "Setting current directory to working directory: $WorkingDirectory"
Push-Location -Path $WorkingDirectory

# Clone and build the Test Amqp Broker.
try {

$repositoryUrl = "https://github.com/Azure/azure-amqp.git"
# We would like to use the "hotfix" branch because that is current, but unfortunately it references System.Net.Security version 4.0.0
$repositoryBranch = "master"
$cloneCommand = "git clone $repositoryUrl --branch $repositoryBranch"

Write-Host "Cloning repository from $repositoryUrl..."
Invoke-LoggedCommand $cloneCommand

Set-Location -Path "./azure-amqp/test/TestAmqpBroker"

Invoke-LoggedCommand "dotnet build -p RollForward=LatestMajor --framework net6.0"
if (!$? -ne 0) {
Write-Error "Failed to build TestAmqpBroker."
exit 1
}

Write-Host "Test broker built successfully."

# now that the Test broker has been built, launch the broker on a local address.
$env:TEST_BROKER_ADDRESS = 'amqp://127.0.0.1:25672'

Write-Host "Starting test broker listening on ${env:TEST_BROKER_ADDRESS} ..."

Set-Location -Path $WorkingDirectory/azure-amqp/bin/Debug/TestAmqpBroker/net6.0

$job = dotnet exec ./TestAmqpBroker.dll ${env:TEST_BROKER_ADDRESS} /headless &

$env:TEST_BROKER_JOBID = $job.Id

Write-Host "Waiting for test broker to start..."
Start-Sleep -Seconds 3

Write-Host "Job Output after wait:"
Receive-Job $job.Id

$job = Get-Job -Id $env:TEST_BROKER_JOBID
if ($job.State -ne "Running") {
Write-Host "Test broker failed to start."
exit 1
}
}
finally {
Pop-Location
}
11 changes: 6 additions & 5 deletions sdk/core/azure_core_amqp/examples/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
// 1. Clone the repository:
// git clone https://github.com/Azure/azure-amqp
// 2. Build the project:
// dotnet restore
// dotnet build
// 3. Run the broker:
// dotnet run --project .\test\TestAmqpBroker\TestAmqpBroker.csproj --framework net462 amqp://localhost:25672
Expand Down Expand Up @@ -74,8 +73,10 @@ async fn amqp_connection_close_with_error() {
pub async fn main() {
tracing_subscriber::fmt::init();

amqp_connection_open().await;
amqp_connection_open_with_error().await;
amqp_connection_close().await;
amqp_connection_close_with_error().await;
tokio::join!(
amqp_connection_open(),
amqp_connection_open_with_error(),
amqp_connection_close(),
amqp_connection_close_with_error()
);
}
50 changes: 30 additions & 20 deletions sdk/core/azure_core_amqp/src/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,50 +245,58 @@ mod tests {
);
}

// Tests disabled until we have a way to start the AMQP test broker in CI
#[allow(dead_code)]
mod disabled {
use super::super::*;

// #[tokio::test]
async fn amqp_connection_open() {
tracing_subscriber::fmt::init();
#[tokio::test]
async fn amqp_connection_open() {
let address = std::env::var("TEST_BROKER_ADDRESS");
if address.is_ok() {
let connection = AmqpConnection::new();

let url = Url::parse("amqp://localhost:25672").unwrap();
let url = Url::parse(&address.unwrap()).unwrap();
connection
.open("test".to_string(), url, None)
.await
.unwrap();
} else {
println!("TEST_BROKER_ADDRESS is not set. Skipping test.");
}
}

// #[tokio::test]
async fn amqp_connection_open_with_error() {
tracing_subscriber::fmt::try_init().unwrap();
#[tokio::test]
async fn amqp_connection_open_with_error() {
let address = std::env::var("TEST_BROKER_ADDRESS");
if address.is_ok() {
let connection = AmqpConnection::new();
let url = Url::parse("amqp://localhost:32767").unwrap();
assert!(connection
.open("test".to_string(), url, None)
.await
.is_err());
} else {
println!("TEST_BROKER_ADDRESS is not set. Skipping test.");
}
}

// #[tokio::test]
async fn amqp_connection_close() {
#[tokio::test]
async fn amqp_connection_close() {
let address = std::env::var("TEST_BROKER_ADDRESS");
if address.is_ok() {
let connection = AmqpConnection::new();
let url = Url::parse("amqp://localhost:25672").unwrap();
let url = Url::parse(&address.unwrap()).unwrap();
connection
.open("test".to_string(), url, None)
.await
.unwrap();
connection.close().await.unwrap();
} else {
println!("TEST_BROKER_ADDRESS is not set. Skipping test.");
}
}

// #[tokio::test]
async fn amqp_connection_close_with_error() {
tracing_subscriber::fmt::try_init().unwrap();
#[tokio::test]
async fn amqp_connection_close_with_error() {
let address = std::env::var("TEST_BROKER_ADDRESS");
if address.is_ok() {
let connection = AmqpConnection::new();
let url = Url::parse("amqp://localhost:25672").unwrap();
let url = Url::parse(&address.unwrap()).unwrap();
connection
.open("test".to_string(), url, None)
.await
Expand All @@ -306,6 +314,8 @@ mod tests {
assert!(err.to_string().contains("Internal error."));
}
}
} else {
println!("TEST_BROKER_ADDRESS is not set. Skipping test.");
}
}
}
4 changes: 2 additions & 2 deletions sdk/core/azure_core_amqp/src/fe2o3/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use async_std::sync::Mutex;
use azure_core::{Result, Url};
use fe2o3_amqp::connection::ConnectionHandle;
use std::{borrow::BorrowMut, sync::OnceLock};
use tracing::{debug, info, warn};
use tracing::{debug, warn};

use super::error::{AmqpConnection, AmqpOpen};

Expand Down Expand Up @@ -166,7 +166,7 @@ impl AmqpConnectionApis for Fe2o3AmqpConnection {
Ok(_) => Ok(()),
Err(e) => match e.0 {
fe2o3_amqp::connection::Error::TransportError(e) => {
info!(
debug!(
"Transport error closing connection with error: {:?} - ignored",
e
);
Expand Down
1 change: 1 addition & 0 deletions sdk/core/azure_core_amqp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ use std::fmt::Debug;

// AMQP Settle mode:
// https://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-transport-v1.0-os.html#type-sender-settle-mode

const AMQP_SENDER_SETTLE_MODE_UNSETTLED: isize = 0;
const AMQP_SENDER_SETTLE_MODE_SETTLED: isize = 1;
const AMQP_SENDER_SETTLE_MODE_MIXED: isize = 2;
Expand Down

0 comments on commit 6d89f3a

Please sign in to comment.