diff --git a/src/client/Microsoft.Identity.Client/AuthenticationResultMetadata.cs b/src/client/Microsoft.Identity.Client/AuthenticationResultMetadata.cs
index 58fce3acbf..ec07ecb171 100644
--- a/src/client/Microsoft.Identity.Client/AuthenticationResultMetadata.cs
+++ b/src/client/Microsoft.Identity.Client/AuthenticationResultMetadata.cs
@@ -97,5 +97,10 @@ public AuthenticationResultMetadata(TokenSource tokenSource)
/// See https://aka.ms/msal-net-logging for more details about logging.
///
public string Telemetry { get; set; }
+
+ ///
+ /// The number of access tokens in the cache.
+ ///
+ public int CachedAccessTokenCount { get; set; }
}
}
diff --git a/src/client/Microsoft.Identity.Client/Cache/CacheSessionManager.cs b/src/client/Microsoft.Identity.Client/Cache/CacheSessionManager.cs
index d4b74143ae..d7c1334385 100644
--- a/src/client/Microsoft.Identity.Client/Cache/CacheSessionManager.cs
+++ b/src/client/Microsoft.Identity.Client/Cache/CacheSessionManager.cs
@@ -48,9 +48,11 @@ public async Task FindAccessTokenAsync()
return await TokenCacheInternal.FindAccessTokenAsync(_requestParams).ConfigureAwait(false);
}
- public Task> SaveTokenResponseAsync(MsalTokenResponse tokenResponse)
+ public async Task> SaveTokenResponseAsync(MsalTokenResponse tokenResponse)
{
- return TokenCacheInternal.SaveTokenResponseAsync(_requestParams, tokenResponse);
+ var result = await TokenCacheInternal.SaveTokenResponseAsync(_requestParams, tokenResponse).ConfigureAwait(false);
+ RequestContext.ApiEvent.CachedAccessTokenCount = TokenCacheInternal.Accessor.EntryCount;
+ return result;
}
public async Task GetAccountAssociatedWithAccessTokenAsync(MsalAccessTokenCacheItem msalAccessTokenCacheItem)
@@ -181,6 +183,8 @@ private async Task RefreshCacheForReadOperationsAsync()
{
RequestContext.ApiEvent.CacheLevel = CacheLevel.L1Cache;
}
+
+ RequestContext.ApiEvent.CachedAccessTokenCount = TokenCacheInternal.Accessor.EntryCount;
}
}
}
diff --git a/src/client/Microsoft.Identity.Client/Cache/ITokenCacheAccessor.cs b/src/client/Microsoft.Identity.Client/Cache/ITokenCacheAccessor.cs
index 5efa34cb7c..1d73a84dcf 100644
--- a/src/client/Microsoft.Identity.Client/Cache/ITokenCacheAccessor.cs
+++ b/src/client/Microsoft.Identity.Client/Cache/ITokenCacheAccessor.cs
@@ -10,6 +10,8 @@ namespace Microsoft.Identity.Client.Cache
{
internal interface ITokenCacheAccessor
{
+ int EntryCount { get; }
+
void SaveAccessToken(MsalAccessTokenCacheItem item);
void SaveRefreshToken(MsalRefreshTokenCacheItem item);
diff --git a/src/client/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs b/src/client/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs
index 69a3cbb876..0ac5bd3627 100644
--- a/src/client/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs
+++ b/src/client/Microsoft.Identity.Client/Internal/Requests/RequestBase.cs
@@ -223,6 +223,7 @@ private void UpdateTelemetry(long elapsedMilliseconds, ApiEvent apiEvent, Authen
authenticationResult.AuthenticationResultMetadata.CacheLevel = GetCacheLevel(authenticationResult);
authenticationResult.AuthenticationResultMetadata.Telemetry = apiEvent.MsalRuntimeTelemetry;
authenticationResult.AuthenticationResultMetadata.RegionDetails = CreateRegionDetails(apiEvent);
+ authenticationResult.AuthenticationResultMetadata.CachedAccessTokenCount = apiEvent.CachedAccessTokenCount;
Metrics.IncrementTotalDurationInMs(authenticationResult.AuthenticationResultMetadata.DurationTotalInMs);
}
diff --git a/src/client/Microsoft.Identity.Client/Platforms/Android/AndroidTokenCacheAccessor.cs b/src/client/Microsoft.Identity.Client/Platforms/Android/AndroidTokenCacheAccessor.cs
index 47eb369779..cf501fe35f 100644
--- a/src/client/Microsoft.Identity.Client/Platforms/Android/AndroidTokenCacheAccessor.cs
+++ b/src/client/Microsoft.Identity.Client/Platforms/Android/AndroidTokenCacheAccessor.cs
@@ -161,6 +161,8 @@ public List GetAllAccounts(string optionalPartitionKey = n
}
#endregion
+ public int EntryCount { get; } = 0; // not implemented for Android
+
public MsalAccountCacheItem GetAccount(MsalAccountCacheItem accountCacheItem)
{
return MsalAccountCacheItem.FromJsonString(_accountSharedPreference.GetString(accountCacheItem.CacheKey, null));
diff --git a/src/client/Microsoft.Identity.Client/Platforms/iOS/iOSTokenCacheAccessor.cs b/src/client/Microsoft.Identity.Client/Platforms/iOS/iOSTokenCacheAccessor.cs
index 47dddc5cdb..89892e874a 100644
--- a/src/client/Microsoft.Identity.Client/Platforms/iOS/iOSTokenCacheAccessor.cs
+++ b/src/client/Microsoft.Identity.Client/Platforms/iOS/iOSTokenCacheAccessor.cs
@@ -167,7 +167,10 @@ public List GetAllAccounts(string optionalPartitionKey = n
.Select(x => MsalAccountCacheItem.FromJsonString(x))
.ToList();
}
-#endregion
+ #endregion
+
+ public int EntryCount { get; } = 0; // not implemented for iOS
+
internal SecStatusCode TryGetBrokerApplicationToken(string clientId, out string appToken)
{
diff --git a/src/client/Microsoft.Identity.Client/PlatformsCommon/Shared/InMemoryPartitionedAppTokenCacheAccessor.cs b/src/client/Microsoft.Identity.Client/PlatformsCommon/Shared/InMemoryPartitionedAppTokenCacheAccessor.cs
index 8ae392d260..1a732eb856 100644
--- a/src/client/Microsoft.Identity.Client/PlatformsCommon/Shared/InMemoryPartitionedAppTokenCacheAccessor.cs
+++ b/src/client/Microsoft.Identity.Client/PlatformsCommon/Shared/InMemoryPartitionedAppTokenCacheAccessor.cs
@@ -5,6 +5,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
+using System.Threading;
using Microsoft.Identity.Client.Cache;
using Microsoft.Identity.Client.Cache.Items;
using Microsoft.Identity.Client.Core;
@@ -34,6 +35,11 @@ internal class InMemoryPartitionedAppTokenCacheAccessor : ITokenCacheAccessor
protected readonly ILoggerAdapter _logger;
private readonly CacheOptions _tokenCacheAccessorOptions;
+ private int _entryCount = 0;
+ private static int s_entryCount = 0;
+
+ public int EntryCount => GetEntryCountRef();
+
public InMemoryPartitionedAppTokenCacheAccessor(
ILoggerAdapter logger,
CacheOptions tokenCacheAccessorOptions)
@@ -59,9 +65,18 @@ public void SaveAccessToken(MsalAccessTokenCacheItem item)
string itemKey = item.CacheKey;
string partitionKey = CacheKeyFactory.GetAppTokenCacheItemKey(item.ClientId, item.TenantId, item.KeyId, item.AdditionalCacheKeyComponents);
- // if a conflict occurs, pick the latest value
- AccessTokenCacheDictionary
- .GetOrAdd(partitionKey, new ConcurrentDictionary())[itemKey] = item;
+ var partition = AccessTokenCacheDictionary.GetOrAdd(partitionKey, _ => new ConcurrentDictionary());
+ bool added = partition.TryAdd(itemKey, item);
+
+ // only increment the entry count if the item was added, not updated
+ if (added)
+ {
+ Interlocked.Increment(ref GetEntryCountRef());
+ }
+ else
+ {
+ partition[itemKey] = item;
+ }
}
///
@@ -129,12 +144,19 @@ public void DeleteAccessToken(MsalAccessTokenCacheItem item)
{
var partitionKey = CacheKeyFactory.GetAppTokenCacheItemKey(item.ClientId, item.TenantId, item.KeyId);
- AccessTokenCacheDictionary.TryGetValue(partitionKey, out var partition);
- if (partition == null || !partition.TryRemove(item.CacheKey, out _))
+ if (AccessTokenCacheDictionary.TryGetValue(partitionKey, out var partition))
{
- _logger.InfoPii(
- () => $"[Internal cache] Cannot delete access token because it was not found in the cache. Key {item.CacheKey}.",
- () => "[Internal cache] Cannot delete access token because it was not found in the cache.");
+ bool removed = partition.TryRemove(item.CacheKey, out _);
+ if (removed)
+ {
+ Interlocked.Decrement(ref GetEntryCountRef());
+ }
+ else
+ {
+ _logger.InfoPii(
+ () => $"[Internal cache] Cannot delete access token because it was not found in the cache. Key {item.CacheKey}.",
+ () => "[Internal cache] Cannot delete access token because it was not found in the cache.");
+ }
}
}
@@ -219,6 +241,7 @@ public virtual void Clear(ILoggerAdapter requestlogger = null)
{
var logger = requestlogger ?? _logger;
AccessTokenCacheDictionary.Clear();
+ Interlocked.Exchange(ref GetEntryCountRef(), 0);
logger.Always("[Internal cache] Clearing app token cache accessor.");
// app metadata isn't removable
}
@@ -227,5 +250,11 @@ public virtual bool HasAccessOrRefreshTokens()
{
return AccessTokenCacheDictionary.Any(partition => partition.Value.Any(token => !token.Value.IsExpiredWithBuffer()));
}
+
+ private ref int GetEntryCountRef()
+ {
+ return ref _tokenCacheAccessorOptions.UseSharedCache ? ref s_entryCount : ref _entryCount;
+ }
+
}
}
diff --git a/src/client/Microsoft.Identity.Client/PlatformsCommon/Shared/InMemoryPartitionedUserTokenCacheAccessor.cs b/src/client/Microsoft.Identity.Client/PlatformsCommon/Shared/InMemoryPartitionedUserTokenCacheAccessor.cs
index 4e3800129b..0d23372704 100644
--- a/src/client/Microsoft.Identity.Client/PlatformsCommon/Shared/InMemoryPartitionedUserTokenCacheAccessor.cs
+++ b/src/client/Microsoft.Identity.Client/PlatformsCommon/Shared/InMemoryPartitionedUserTokenCacheAccessor.cs
@@ -41,9 +41,15 @@ internal class InMemoryPartitionedUserTokenCacheAccessor : ITokenCacheAccessor
private static readonly ConcurrentDictionary s_appMetadataDictionary =
new ConcurrentDictionary();
+ private static int s_entryCount = 0;
+
protected readonly ILoggerAdapter _logger;
private readonly CacheOptions _tokenCacheAccessorOptions;
+ private int _entryCount = 0;
+
+ public int EntryCount => GetEntryCountRef();
+
public InMemoryPartitionedUserTokenCacheAccessor(ILoggerAdapter logger, CacheOptions tokenCacheAccessorOptions)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
@@ -73,8 +79,17 @@ public void SaveAccessToken(MsalAccessTokenCacheItem item)
string itemKey = item.CacheKey;
string partitionKey = CacheKeyFactory.GetKeyFromCachedItem(item);
- AccessTokenCacheDictionary
- .GetOrAdd(partitionKey, new ConcurrentDictionary())[itemKey] = item; // if a conflict occurs, pick the latest value
+ var partition = AccessTokenCacheDictionary.GetOrAdd(partitionKey, _ => new ConcurrentDictionary());
+ bool added = partition.TryAdd(itemKey, item);
+ // only increment the entry count if this is a new item
+ if (added)
+ {
+ System.Threading.Interlocked.Increment(ref GetEntryCountRef());
+ }
+ else
+ {
+ partition[itemKey] = item;
+ }
}
public void SaveRefreshToken(MsalRefreshTokenCacheItem item)
@@ -151,12 +166,19 @@ public void DeleteAccessToken(MsalAccessTokenCacheItem item)
{
string partitionKey = CacheKeyFactory.GetKeyFromCachedItem(item);
- AccessTokenCacheDictionary.TryGetValue(partitionKey, out var partition);
- if (partition == null || !partition.TryRemove(item.CacheKey, out _))
+ if (AccessTokenCacheDictionary.TryGetValue(partitionKey, out var partition))
{
- _logger.InfoPii(
- () => $"[Internal cache] Cannot delete access token because it was not found in the cache. Key {item.CacheKey}.",
- () => "[Internal cache] Cannot delete access token because it was not found in the cache.");
+ bool removed = partition.TryRemove(item.CacheKey, out _);
+ if (removed)
+ {
+ System.Threading.Interlocked.Decrement(ref GetEntryCountRef());
+ }
+ else
+ {
+ _logger.InfoPii(
+ () => $"[Internal cache] Cannot delete access token because it was not found in the cache. Key {item.CacheKey}.",
+ () => "[Internal cache] Cannot delete access token because it was not found in the cache.");
+ }
}
}
@@ -246,7 +268,7 @@ public virtual List GetAllRefreshTokens(string partit
if (RefreshTokenCacheDictionary.Count == 1 && result.Count == 0)
{
logger.VerbosePii(
- () => $"[Internal cache] 0 RTs and 1 partition. Partition in cache is {RefreshTokenCacheDictionary.Keys.First()}",
+ () => $"[Internal cache] 0 RTs and 1 partition. Partition in cache is {RefreshTokenCacheDictionary.Keys.First()}",
() => "[Internal cache] 0 RTs and 1 partition] 0 RTs and 1 partition.");
}
}
@@ -290,7 +312,7 @@ public virtual List GetAllAccounts(string partitionKey = n
{
AccountCacheDictionary.TryGetValue(partitionKey, out ConcurrentDictionary partition);
result = partition?.Select(kv => kv.Value)?.ToList() ?? CollectionHelpers.GetEmptyList();
-
+
if (logger.IsLoggingEnabled(LogLevel.Verbose))
{
logger.Verbose(() => $"[Internal cache] GetAllAccounts (with partition - exists? {partition != null}) found {result.Count} accounts.");
@@ -327,6 +349,8 @@ public virtual void Clear(ILoggerAdapter requestlogger = null)
IdTokenCacheDictionary.Clear();
AccountCacheDictionary.Clear();
// app metadata isn't removable
+ System.Threading.Interlocked.Exchange(ref GetEntryCountRef(), 0);
+
}
/// WARNING: this API is slow as it loads all tokens, not just from 1 partition.
@@ -336,5 +360,10 @@ public virtual bool HasAccessOrRefreshTokens()
return RefreshTokenCacheDictionary.Any(partition => partition.Value.Count > 0) ||
AccessTokenCacheDictionary.Any(partition => partition.Value.Any(token => !token.Value.IsExpiredWithBuffer()));
}
+
+ private ref int GetEntryCountRef()
+ {
+ return ref _tokenCacheAccessorOptions.UseSharedCache ? ref s_entryCount : ref _entryCount;
+ }
}
}
diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt
index 1164619fd4..9b7aaf512c 100644
--- a/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt
+++ b/src/client/Microsoft.Identity.Client/PublicApi/net462/PublicAPI.Unshipped.txt
@@ -5,3 +5,5 @@ Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsRunning() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func asyncAction) -> System.Threading.Tasks.Task
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void
+Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int
+Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
\ No newline at end of file
diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt
index 1164619fd4..9b7aaf512c 100644
--- a/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt
+++ b/src/client/Microsoft.Identity.Client/PublicApi/net472/PublicAPI.Unshipped.txt
@@ -5,3 +5,5 @@ Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsRunning() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func asyncAction) -> System.Threading.Tasks.Task
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void
+Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int
+Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
\ No newline at end of file
diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt
index 1164619fd4..9b7aaf512c 100644
--- a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt
+++ b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-android/PublicAPI.Unshipped.txt
@@ -5,3 +5,5 @@ Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsRunning() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func asyncAction) -> System.Threading.Tasks.Task
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void
+Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int
+Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
\ No newline at end of file
diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt
index 1164619fd4..9b7aaf512c 100644
--- a/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt
+++ b/src/client/Microsoft.Identity.Client/PublicApi/net8.0-ios/PublicAPI.Unshipped.txt
@@ -5,3 +5,5 @@ Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsRunning() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func asyncAction) -> System.Threading.Tasks.Task
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void
+Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int
+Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
\ No newline at end of file
diff --git a/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt
index 1164619fd4..9b7aaf512c 100644
--- a/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt
+++ b/src/client/Microsoft.Identity.Client/PublicApi/net8.0/PublicAPI.Unshipped.txt
@@ -5,3 +5,5 @@ Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsRunning() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func asyncAction) -> System.Threading.Tasks.Task
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void
+Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int
+Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
\ No newline at end of file
diff --git a/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt
index 1164619fd4..9b7aaf512c 100644
--- a/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt
+++ b/src/client/Microsoft.Identity.Client/PublicApi/netstandard2.0/PublicAPI.Unshipped.txt
@@ -5,3 +5,5 @@ Microsoft.Identity.Client.Utils.MacMainThreadScheduler.IsRunning() -> bool
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.Stop() -> void
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.RunOnMainThreadAsync(System.Func asyncAction) -> System.Threading.Tasks.Task
Microsoft.Identity.Client.Utils.MacMainThreadScheduler.StartMessageLoop() -> void
+Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.get -> int
+Microsoft.Identity.Client.AuthenticationResultMetadata.CachedAccessTokenCount.set -> void
\ No newline at end of file
diff --git a/src/client/Microsoft.Identity.Client/TelemetryCore/Internal/Events/ApiEvent.cs b/src/client/Microsoft.Identity.Client/TelemetryCore/Internal/Events/ApiEvent.cs
index 301a196c7b..abd5bac980 100644
--- a/src/client/Microsoft.Identity.Client/TelemetryCore/Internal/Events/ApiEvent.cs
+++ b/src/client/Microsoft.Identity.Client/TelemetryCore/Internal/Events/ApiEvent.cs
@@ -62,6 +62,8 @@ public string ApiIdString
public string ApiErrorCode { get; set; }
+ public int CachedAccessTokenCount { get; set; }
+
#region Region
public string RegionUsed { get; set; }
diff --git a/tests/Microsoft.Identity.Test.Performance/AcquireTokenForClientCacheTests.cs b/tests/Microsoft.Identity.Test.Performance/AcquireTokenForClientCacheTests.cs
index 360466710c..548d6a330d 100644
--- a/tests/Microsoft.Identity.Test.Performance/AcquireTokenForClientCacheTests.cs
+++ b/tests/Microsoft.Identity.Test.Performance/AcquireTokenForClientCacheTests.cs
@@ -46,7 +46,6 @@ public class AcquireTokenForClientCacheTests
[ParamsAllValues]
public bool EnableCacheSerialization { get; set; }
-
//[Params(false)]
public bool UseMicrosoftIdentityWebCache { get; set; }
diff --git a/tests/Microsoft.Identity.Test.Unit/CacheTests/InternalCacheOptionsTests.cs b/tests/Microsoft.Identity.Test.Unit/CacheTests/InternalCacheOptionsTests.cs
index de87882209..333255bedd 100644
--- a/tests/Microsoft.Identity.Test.Unit/CacheTests/InternalCacheOptionsTests.cs
+++ b/tests/Microsoft.Identity.Test.Unit/CacheTests/InternalCacheOptionsTests.cs
@@ -96,13 +96,13 @@ public async Task ClientCreds_StaticCache_Async()
.BuildConcrete();
httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage();
- await ClientCredsAcquireAndAssertTokenSourceAsync(app1, "S1", TokenSource.IdentityProvider).ConfigureAwait(false);
+ await ClientCredsAcquireAndAssertTokenSourceAsync(app1, "S1", TokenSource.IdentityProvider, 1).ConfigureAwait(false);
httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage();
- await ClientCredsAcquireAndAssertTokenSourceAsync(app1, "S2", TokenSource.IdentityProvider).ConfigureAwait(false);
+ await ClientCredsAcquireAndAssertTokenSourceAsync(app1, "S2", TokenSource.IdentityProvider, 2).ConfigureAwait(false);
- await ClientCredsAcquireAndAssertTokenSourceAsync(app2, "S1", TokenSource.Cache).ConfigureAwait(false);
- await ClientCredsAcquireAndAssertTokenSourceAsync(app2, "S2", TokenSource.Cache).ConfigureAwait(false);
+ await ClientCredsAcquireAndAssertTokenSourceAsync(app2, "S1", TokenSource.Cache, 2).ConfigureAwait(false);
+ await ClientCredsAcquireAndAssertTokenSourceAsync(app2, "S2", TokenSource.Cache, 2).ConfigureAwait(false);
ConfidentialClientApplication app3 =
ConfidentialClientApplicationBuilder.Create(TestConstants.ClientId)
@@ -111,14 +111,16 @@ public async Task ClientCreds_StaticCache_Async()
.WithCacheOptions(CacheOptions.EnableSharedCacheOptions)
.BuildConcrete();
- await ClientCredsAcquireAndAssertTokenSourceAsync(app3, "S1", TokenSource.Cache).ConfigureAwait(false);
- await ClientCredsAcquireAndAssertTokenSourceAsync(app3, "S2", TokenSource.Cache).ConfigureAwait(false);
+ await ClientCredsAcquireAndAssertTokenSourceAsync(app3, "S1", TokenSource.Cache, 2).ConfigureAwait(false);
+ await ClientCredsAcquireAndAssertTokenSourceAsync(app3, "S2", TokenSource.Cache, 2).ConfigureAwait(false);
+ httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage();
+ await ClientCredsAcquireAndAssertTokenSourceAsync(app3, "S3", TokenSource.IdentityProvider, 3).ConfigureAwait(false);
httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage();
- await ClientCredsAcquireAndAssertTokenSourceAsync(app_withoutStaticCache, "S1", TokenSource.IdentityProvider).ConfigureAwait(false);
+ await ClientCredsAcquireAndAssertTokenSourceAsync(app_withoutStaticCache, "S1", TokenSource.IdentityProvider, 1).ConfigureAwait(false);
httpManager.AddMockHandlerSuccessfulClientCredentialTokenResponseMessage();
- await ClientCredsAcquireAndAssertTokenSourceAsync(app_withoutStaticCache, "S2", TokenSource.IdentityProvider).ConfigureAwait(false);
+ await ClientCredsAcquireAndAssertTokenSourceAsync(app_withoutStaticCache, "S2", TokenSource.IdentityProvider, 2).ConfigureAwait(false);
}
}
@@ -145,9 +147,12 @@ public async Task PublicClient_StaticCache_Async()
.AcquireTokenInteractive(TestConstants.s_scope)
.ExecuteAsync().ConfigureAwait(false);
+ Assert.AreEqual(1, result.AuthenticationResultMetadata.CachedAccessTokenCount);
+
var accounts = await app1.GetAccountsAsync().ConfigureAwait(false);
Assert.AreEqual(1, accounts.Count());
result = await app1.AcquireTokenSilent(TestConstants.s_scope, accounts.Single()).ExecuteAsync().ConfigureAwait(false);
+ Assert.AreEqual(1, result.AuthenticationResultMetadata.CachedAccessTokenCount);
var app2 = PublicClientApplicationBuilder
.Create(TestConstants.ClientId)
@@ -159,17 +164,29 @@ public async Task PublicClient_StaticCache_Async()
accounts = await app2.GetAccountsAsync().ConfigureAwait(false);
Assert.AreEqual(1, accounts.Count());
result = await app2.AcquireTokenSilent(TestConstants.s_scope, accounts.Single()).ExecuteAsync().ConfigureAwait(false);
+ Assert.AreEqual(1, result.AuthenticationResultMetadata.CachedAccessTokenCount);
}
}
- private async Task ClientCredsAcquireAndAssertTokenSourceAsync(IConfidentialClientApplication app, string scope, TokenSource expectedSource)
+ private async Task ClientCredsAcquireAndAssertTokenSourceAsync(
+ IConfidentialClientApplication app,
+ string scope,
+ TokenSource expectedSource,
+ int expectedAccessTokenCount)
{
var result = await app.AcquireTokenForClient(new[] { scope })
.WithTenantId(TestConstants.Utid)
.ExecuteAsync().ConfigureAwait(false);
+
Assert.AreEqual(
expectedSource,
result.AuthenticationResultMetadata.TokenSource);
+
+
+ Assert.AreEqual(expectedAccessTokenCount,
+ result.AuthenticationResultMetadata.CachedAccessTokenCount);
+
+ return result;
}
}
}
diff --git a/tests/Microsoft.Identity.Test.Unit/CacheTests/LoadingProjectsTests.cs b/tests/Microsoft.Identity.Test.Unit/CacheTests/LoadingProjectsTests.cs
index 4f7fc5b791..c22bda6088 100644
--- a/tests/Microsoft.Identity.Test.Unit/CacheTests/LoadingProjectsTests.cs
+++ b/tests/Microsoft.Identity.Test.Unit/CacheTests/LoadingProjectsTests.cs
@@ -8,7 +8,6 @@
namespace Microsoft.Identity.Test.Unit.CacheTests
{
-#if !ANDROID && !iOS // custom token cache serialization not available
[TestClass]
public class LoadingProjectsTests
{
@@ -27,5 +26,4 @@ public void CanDeserializeTokenCache()
};
}
}
-#endif
}